Python Tips

PURPOSE

Sharing a collection of quick references for common issues encountered when coding in Python

CLASSES

Using variables of Parent Class

To access variables from parent class in child class,

  • Call the constructor (__init__ method) of the Parent in the Child class's __init__ method.

Load value during Class Initialization using own function

This can be useful when you are going to read a file, such as a JSON, to fill values of your class variables.

FUNCTIONS

Get current function's name

There may be times where you want to dynamically get the current function's name, for example, when trying add functionality to test suite such as pytest. The simplest way is to use the inspect module.

You can also inspect the stack to get the complete function

Further Reading


Accessing Function attributes if you know it's name

Suppose you have a function name which belongs to a class and you want to call it or access it's attributes, you can use the getattr method to generate the function from name.

Further Reading

DICTIONARIES

Delete keys from dictionary

You can use the del keyword to delete keys from dictionary


Get the first key from a dictionary

Use dict.keys() get the keys and then fetch first one using index


Pretty print dictionaries while logging

When logging data structures such as dictionaries, you can't really decipher the contents unless you look very hard. This defeats the purpose of why you were logging in the first place. You might have used pprint.pprint for printing dictionaries to command line. Similary, we can use pprint.pformat. It takes the input, and generates a pretty printed string, which can then be passed to the logger. Furthermore, you can use the \n character, so that the dictionary is printed isn't awkwardly starting directly after the timestamp.


Use copy to make duplicate dictionaries

There could be times when you want to compare if a dictionary is changed. For this you think that you will store the current state in a temp dictionary, and do operations in the original one. After the operation, you think you can use a simple == check. Overall, a reasonable approach. So you start by saying,

You run the above code and you wonder, why the equality check is passing? The reason is, when you use the = operator to make a tempory copy, you are actually only creating a reference! Pointer Nightmares intensify

For this specific purpose, what you want is a shallow copy of the original dictionary and not a reference. In Python, you can do that by using the copy function.

Voila, you can now compare state between dictionaries!


Dictionary to JSON

LISTS

List slicing

Lists have special property where you can specify index from which you want to access the list.

  • start: read list starting from this index (inclusive)
  • stop: stop reading list just before this index (exclusive)
  • step: by default, lists will be iterated one element at time. To increase the step size, pass in the this input.

Convert list to indexed tuple list

Say you want to sort the elements of a list, but don't want to lose the original index,
you can convert your list to an indexed tuple list.

Unpacking lists to individual values

To unpack list and store in individual variables:


Combining lists together

To combine list together you can use the plus (+) operator

Bonus: You can also use the multiply (*) operator to generate a list with duplicate elements


Generating strings from lists after filtering False values

In case you want to join a list of string values while ignoring values that will evaluate to False

  • use a filter over join
  • Note that the filter function can also take functions as filterers.
  • The passed function must return True/False over the passed sequence of values after evaluation.
  • Read example here

Sort by length

There is a pythonic way to sort elements by their length, and it is to use the key param in the sorted function.

The key param can also be passed in max function

FORMATTING

Add 0 padding to strings

There are times when you would need to add a padding zeroes to the numbers you were converting to strings.

  • Use zfill, a standard string function specifically designed for this use case
  • For example, when calculating time differences and then printing the output

You could also general string formatting over numbers as well:


Stripping values generated during a split operation

  • Use list comprehension

Convert Numbers to Hex

The int method used for converting values to numbers also supports base conversion. To convert any string to hexadecimal number, just pass in the base number as 16.

Note that the number should be a valid hexadecimal (i.e. chars 0-9 & letters a-f are allowed when forming the number)


Convert bytes to Human Readable format

To convert bytes to human readable format, we simply divide the number by 2 (pow) 10 until we can no longer divide. This way, we can obtain the power label (KB/MB/GB) from the original input bytes.

Testing via Python

Good Testcase pattern to follow

Skip Test Cases based on command line arguments in Pytest

We can use pytest hook (pytest_collection_modifyitems) to dynamically skip test cases based on argument values.

MISC UTIL

Round Robin Ticket Assigner

We have an {agent_name:weightage} dictionary with us based on which we need to assign tickets in a round robin manner.

  1. go over each agent one by one
  2. if agent has capacity to accept ticket

    1. give them one ticket
    2. reduce capacity by one
  3. repeat step 1 & 2 till all agents have reached 0 capacity

Using map to get sum of a 2D array


Get files matching a regular expression

We can use glob and fnmatch for extracting files that match a specific pattern

Let's say you have a list of files

And you want to extract files that have the name test in them, or in other words, files that match the pattern: test*

  • Using glob
  • We get a list of files with their exact paths
  • Using fnmatch
  • We can see that fnmatch returns the filename only
  • To create the fullpath, we would need to use os.path.join on current_dir and filename

Note: The glob module uses the os and fnmatch module internally.


Sending List/Array as data while making a request

Suppose you want to send something like:

as data, when making a request. You can do this very easily with the requests library.

The json keyword will encode the data to (you guessed it) JSON. It will also set the Content-Type to application/json. I guess that's why requests has the tag line HTTP for Humans


Supress error of Subprocess check Output

In case you call a process via subprocess, but do not wish to see the error in case it throws one,

  • Just redirect the standard error (stderr) to DEVNULL

Make multilevel directories

Suppose you want to create folders in a path such as test\inner_folder\main\, but inner_folder does not exist, you can use os.makedirs


Store temporary information to Temp Folder

There could be situtation where you are generating files that are only relevant during the execution of your script and are not meant to be stored for long term purposes. Moreover, you don't want these files to be tracked by Git. While you could add these to .gitignore, a much cleaner way would be to use the Temp folder provided by the OS itself. Let's say you want to create a lock file during the execution of a particular script so that another instance of the script does not override current execution,

You can also use the tempfile.TemporaryFile() function to generate a temp file during run-time if you do not want a particular file name.


Restore Timestamps of Extracted Files

Usually when a zip is extracted, the timestamps of the files are the ones corresponding to the time the file was extracted at. This causes problems when we want to find out the most recent file from a list of files. To fix this problem, we can restore the timestamps of the file by reading them from the original zip file.

Just call the restore_timestamps_of_zip_contents function after extraction is done:


Binomial Coefficent - nCr

To calculate nCr, use the inbuilt moduel in the math library:


Python not able to detect folders as packages

There are times when you have a proper folder structure for a project, but python cannot interpret that you are importing a file from within the project directory. One way is to make calls from a proper starting point, which as the root of the directory and change your import statements relative to the starting point. However, this is a tedious process. A better hack is to append your project folder in system path using the sys module. In the file where you are importing the other file as a module, add this to the top:

Now, Python will look for this folder when importing modules as well.


Upgrade Pip in Venv

While using Python, you will see the warning about how you are using an old version of pip quite a lot. This is especially annoying because you cannot seemingly upgrade pip in a venv due to an Acess Denied eror. Well worry not, the fix is more simple than you think.

Just run this

Instead of this

This is because when you run without the py command, pip is trying replace itself, i.e. a running process is supposed to be uninstalled, which is denied by some Operating Systems. When you use it with py, the upgrade command is running inside a python shell, and hence this problem is avoided.


Thank the author. Fork this blog.


Tagged in python