Python Tips
PURPOSE
Sharing a collection of quick references for common issues encountered when coding in Python
-
- Round Robin Ticket Assigner
- 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
- Sending List/Array as data while making a request
- Supress error of Subprocess check Output
- Make multilevel directories
- Store temporary information to Temp Folder
- Restore Timestamps of Extracted Files
- Binomial Coefficent - nCr
- Python not able to detect folders as packages
- Upgrade Pip in Venv
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
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.
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.
- go over each agent one by one
-
if agent has capacity to accept ticket
- give them one ticket
- reduce capacity by one
- 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
) toDEVNULL
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.