Handling exceptions: the try-except constructs

There are instances when your code doesn't go as planned. Python provides the try-except constructs to handle such situations. If a statement in the try clause raises an error, code in the except construct is executed. Consider a situation where you are trying to open a file which does not exist. You want the user to see an elegant message telling what went wrong rather than a horrible cryptic traceback. Remember, users hate traceback.

Getting user input: builtin function input()

The builtin input() is used for receiving input from the user. The input() function takes an argument, which is what will be prompted on the screen before the user enters a value. We can assign the value entered to a variable that we can use later in the program.

It is worth emphasizing that the input function returns a string, so if you require it to be some other data type, it needs to be converted into the required data type using Type Casting, discussed earlier.

Archiving files using zipfile & tarfile modules

The standard libraries zipfile and tarfile facilitate creating and manipulating zip & Unix tar archive files. The tarfile is not limited to Unix, it can be used in Windows also, and is capable of working with bzip2 & gzip files as well. Expand the following code snippet to see how to create archives, append to them, extract them with primitive examples.

###### Creating new archives: zipfile.ZipFile().write() & tarfile.open().add() ########
The ZipFile class of zipfile module creates a ZipFile object, which provides us with write() method to create new archive files. The open() function of the tarfile module returns a TarFile object, which provides us with add() method to create archive files.
>>> import zipfile
>>> with zipfile.ZipFile('zipFileOne.zip', mode = 'w') as zF:
zF.write('fileOne.txt')
zF.write('fileTwo.txt')
>>> import tarfile
>>> with tarfile.open('tarFileOne.tar', mode = 'w') as tF:
tF.add('fileOne.txt')
tF.add('fileTwo.txt')
###### Appending to an archive ######
In order to append to existing archive files, change the mode in which you are opening archive files to 'a', signalling append mode, rather than 'w'.
>>> with zipfile.ZipFile('zipFileOne.zip', mode = 'a') as zF:
zF.write('fileThree.txt')
>>> with tarfile.open('tarFileOne.tar', mode = 'a') as tF:
tF.add('fileThree.txt')
###### Extracting archives: zipfile.ZipFile().extract(), zipfile.ZipFile().extractall() & tarfile.open().extract(), tarfile.open().extractall() ######
The ZipFile & TarFile objects provide two methods extract() and extractall() to extract contents from archive files. The extract() extracts the mentioned file from the archive whereas extractall() extracts all contents of the archive.
>>> with zipfile.ZipFile('zipFileOne.zip') as zF:
zF.extract('fileThree.txt') # returns 'complete_path_to_extracted_file'
>>> with zipfile.ZipFile('zipFileOne.zip') as zF:
zF.extractall()
>>> with tarfile.open('tarFileOne.tar') as tF:
tF.extract('fileThree.txt')
>>> with tarfile.open('tarFileOne.tar') as tF:
tF.extractall()

Handling CSV files using csv module

CSV (Comma-separated values) is a common data interchange format. Python's csv library makes it easy to work with files containing comma-separate values. Its reader() method can be used to read CSVs, while its writer() method helps to write to them.

Comparing two objects: Equality & Identity

While comparing two objects, there are two things to consider. One, whether the two objects refer to the same object in memory. Second, whether the values held by the two objects are the same.

To verify if two objects refer to the same object in memory, you can use the builtin id() function or use the is operator. The builtin id() function gives the "identity" of an object i.e. an integer which is guaranteed to be unique and constant for this object during its lifetime. Python's help() function suggests that the id() function returns the object's memory address. No two objects in the same program lifecycle can have the same id() value.

Using Augmented Assignments

There are cases when you are storing the result of a binary operation into one of the operands. For example, a = a + b or a = a + 1. In such cases, the operand a is evaluated twice. Python offers an alternative, known as Augmented Assignment, in which the operand a is evaluated only once. This alternative is more efficient and offers shorthand for binary operations.

The operator is not limited to +, it can be either of the following binary operators: +, -, *, /, //, %, **, >>, <.

Using the "if __name__ == '__main__':" construct

You may have encountered something like if __name__ == '__main__'. This if construct is used to execute the top-level code(i.e. at the first indent level) of a script ONLY IF it is being run directly(i.e. by double-clicking the .py file), and not if the module is being imported into another file. Let’s look at this in detail.

In other programming languages such as C++, there is a main() function (it has to named main, or else the code doesn't compile), declared explicitly by the user, from which the execution of a program begins. In Python, the main() function is composed of all the top-level code i.e. all statements written at indentation level 0. That’s it, you don’t have to declare the main() function, Python does it by itself.

The top-level code in a Python script gets executed as soon as it is run via command line (i.e. $ python myfile.py) or run directly by executing a .py file.

The __name__ dunder attribute of a module evaluates to the name of the module itself. However, if the module is being run directly by either of the two methods stated above, then the __name__ attribute is set to the string “__main__”. This enables the user to check if the script is being run directly (command line or execution of .py file) or it is being imported. The developer can place the functionality in this if clause ensuring that importing the module doesn't trigger the functionality. Only if the module is being executed will the functionality be triggered.

Below is a simple Python script that contains a function, a print statement, and the if construct. If the script is being run directly, the function is called with a sample value, and not if the script is being imported as a module.

# prime.py
def primeOrNot(num):
if num <= 1:
print(str(num), "is not a prime number.")
return False
for factor in range(2, num): # if there exists any number greater than 2 that
if num % factor == 0: # divides the given number evenly(with remainder 0, that is),
print(str(num), "is not a prime number.")
return False # then the given number is not prime
print(str(num), "is a prime number.")
return True
print("Top-level code being executed...")
if __name__ == '__main__':
primeOrNot(23)
# WHEN THE ABOVE SCRIPT IS RUN DIRECTLY VIA COMMAND LINE OR BY EXECUTING prime.py
Top-level code being executed...
23 is a prime number.
# WHEN THE ABOVE SCRIPT IS BEING IMPORTED AS A MODULE
# One way of importing the module is by going to Run Menu in IDLE window of above script > Python Shell
>>> import prime
Top-level code being executed...

Using Multiple Assignments

Python allows you to make multiple assignments in a single statment. This makes for a compact & concise code.

>>> a, b, c = 1, 2, 3
>>> a
1
>>> b
2
>>> c
3

Keep in mind that if this trait compromises the readability of your code, feel free to drop it.

Launching webpages using the webbrowser standard library module

Python's webbrowser module provides us with an interface to control the default web browser. You can use its open() function to launch webpages with provided URLs.