10.2. Utilities for Python#
10.2.1. Speed up For-Loop with joblib.Parallel
#
Donβt use plain for loops in Python.
Joblib
provides a Parallel
class to write parallel for loops using multiprocessing.
Below you can see an example of how to use it with all of your processors to speed up your calculations.
from joblib import Parallel, delayed
def process_image(path):
...
return image
image_paths = ["path1.jpg", "path2.jpg"]
result = Parallel(n_jobs = -1, backend = "multiprocessing")(
delayed(process_image)(path) for path in image_paths
)
10.2.2. Work with datetimes easily with pendulum
#
Tired of the difficulties of working with dates and times in Python?
Try pendulum
!
pendulum
takes the built-in datetime
library from Python to the next level with its intuitive and human-friendly way of handling dates and times.
This includes easy timezone manipulation, daylight saving time calculations, and more!
#!pip install pendulum
import pendulum
dt = pendulum.now()
print(dt.to_iso8601_string())
# Output: 2023-02-08T13:44:23.798316+01:00
now_in_london = pendulum.now('Europe/London')
print(now_in_london)
# Output: 2023-02-08T12:44:23.799317+00:00
past = pendulum.now().subtract(minutes=8)
print(past.diff_for_humans())
# Output: 8 minutes ago
delta = past - pendulum.now().subtract(weeks=1)
print(delta.in_words())
# Output: 6 days 23 hours 51 minutes 59 seconds
10.2.3. Prettify your Data Structures with pprint
#
Using print()
on your data structures can give you ugly outputs.
With pprint
, you can print data structures in a pretty way
Donβt use plain print()
for printing data structures anymore.
from pprint import pprint
data = [ (i, { 'a':'A',
'b':'B',
'c':'C',
'd':'D',
'e':'E',
'f':'F',
'g':'G',
'h':'H',
})
for i in range(2)
]
pprint(data)
10.2.4. Easy Logging with loguru
#
Are you too lazy for logging?
loguru
makes logging in Python easy.
It comes with pre-built formats and colors so you donβt have to set them manually.
A more elegant alternative to Pythonβs standard logging module.
from loguru import logger
def main():
logger.debug("DEBUG message")
logger.info("INFO message")
logger.warning("WARNING message")
logger.error("ERROR message")
logger.critical("CRITICAL message")
if __name__ == '__main__':
main()
10.2.5. Generate Truly Random Numbers#
How to generate truly
random numbers?
One problem with random number generators in your favourite programming language is:
They are pseudo-random
.
That means they are generated using a deterministic algorithm.
If you want to generate truly random numbers,
You have to make an API request to random(dot)org
.
They create random numbers based on atmospheric noise.
See below how you can use it with Python.
What do the Query Parameters mean?
num=1
: Specifies that only one integer should be generated.min=1
: Specifies that the minimum value for the generated integer should be 1.max=1000
: Specifies that the maximum value for the generated integer should be 1000.col=1
: Specifies that the output should be in a single column. Only useful for displaying purposes when you are generating more than one number.base=10
: Specifies that the generated integers should be in base 10 (decimal).format=plain
: Specifies that the output should be in plain text format.rnd=new
: Specifies that a new random sequence should be used for each request.
import requests
url = "https://www.random.org/integers/?num=1&min=1&max=1000&col=1&base=10&format=plain&rnd=new"
response = requests.get(url)
print(response.text)
10.2.6. Powerful Dictionaries with python-benedict
#
python-benedict
is a library for dictionaries on steroids.
You can access values of your nested dictionary with a neat syntax, perform searching and GroupBy, and much more.
Of course, Pandas offers similar functionalities, but takes also much memory when installing. But π©π²ππ‘π¨π§-πππ§πππ’ππ is more suitable for more unstructured data.
!pip install python-benedict
from benedict import benedict
my_dict = benedict({
'person': {
'name': 'John',
'age': 25,
'address': {
'street': '123 Main St',
'city': 'New York',
'country': 'USA'
}
}
})
my_dict.get("person.address.street")
my_dict.flatten()
10.2.7. Clear Exception Output with pretty_errors
#
Are you annoyed by the unclear Python error messages?
Try pretty_errors
.
Itβs a library to prettify Python exception output to make it more readable and clear.
It also allows you to configure the output like changing colors, separator character, displaying locals, etc..
You just have to:
Install it: pip install pretty_errors
Import it: import pretty_errors
.
!pip install pretty_errors
import pretty_errors
num = 1 / 0
10.2.8. Deprecate Functions with deprecated
#
How to deprecate functions in Python?
You can use the library deprecation
which offers decorators to wrap functions.
Proper warnings in documentation and in the console are displayed.
!pip install deprecation
from deprecation import deprecated
@deprecated(deprecated_in="0.10", removed_in="1.0", current_version=__version__, details="Use my_func2 instead")
def my_func():
print("Hello World")
my_func()
# UnsupportedWarning: my_func is unsupported as of 1.0. Use my_func2 instead
10.2.9. Case Insensitive Dictionaries#
Are you annoyed by case-sensitive dictionaries in Python?
Try πππ¬πππ§π¬ππ§π¬π’ππ’π―πππ’πππ¬.
As the name says, you can access values by the key without paying attention to lowercase or uppercase.
Itβs useful for everyone who is scraping API data.
from requests.structures import CaseInsensitiveDict
data: dict[str, str | int] = CaseInsensitiveDict(
{
"accept": "application/json",
"content-type": "application/json",
"User-Agent": "Mozilla/5.0",
}
)
print(data.get("Accept"))