Difference between revisions of "Python"
(Created page with "Python Tips and Tricks === Array enumeration === For numpy <syntaxhighlight lang="python" highlight="1,5-7"> a = np.array([[1, 2], [3, 4]]) for index, x in np.ndenumerate(...") |
|||
| (29 intermediate revisions by the same user not shown) | |||
| Line 1: | Line 1: | ||
Python Tips and Tricks | Python Tips and Tricks | ||
| + | === Debugger === | ||
| + | pdb is a python native debugger. | ||
| + | To call the debugger with a program main.py just run the following command | ||
| + | <syntaxhighlight lang="python" > | ||
| + | pdb python -m main.py | ||
| + | </syntaxhighlight> | ||
| + | You can introduce breakpoint manually in your code by typing command | ||
| + | <syntaxhighlight lang="python" > | ||
| + | breakpoint() | ||
| + | </syntaxhighlight> | ||
| + | Alternatively you can introduce breakpoint directly in pdb shell by typing | ||
| + | <syntaxhighlight lang="python" > | ||
| + | >> bN | ||
| + | </syntaxhighlight> | ||
| + | where N is a line number for execution, e.g. 100 | ||
| + | Few useful commands: | ||
| + | [[File:PDB.png|400px|thumb|center|Useful PDB commands ]] | ||
| + | === if one liner === | ||
| + | Sometimes it is convenient to use one liner instead of long if-else statement: | ||
| + | <syntaxhighlight lang="python" > | ||
| + | device_type = 'cuda' if 'cuda' in device else 'cpu' # for later use in torch.autocast | ||
| + | </syntaxhighlight> | ||
| + | |||
| + | |||
| + | |||
| + | === F string === | ||
| + | You may print the string with a nice format: | ||
| + | <syntaxhighlight lang="python" > | ||
| + | number = 2 | ||
| + | print(f' The number is {number:2f}') | ||
| + | </syntaxhighlight> | ||
| + | [https://fstring.help/cheat/ The cheat sheet] for f-number formatting. | ||
| + | |||
| + | === Cache === | ||
| + | You can cache a number results of a deterministic function by using the following decorator from functools module | ||
| + | <syntaxhighlight lang="python" > | ||
| + | import functools | ||
| + | @functools.lru_cache(maxsize = 4096) | ||
| + | def foo(x): | ||
| + | ..... | ||
| + | </syntaxhighlight> | ||
| + | maxsize is size of cache. The argument of None removes the limit | ||
=== Array enumeration === | === Array enumeration === | ||
For numpy | For numpy | ||
| − | <syntaxhighlight lang="python | + | <syntaxhighlight lang="python" > |
a = np.array([[1, 2], [3, 4]]) | a = np.array([[1, 2], [3, 4]]) | ||
for index, x in np.ndenumerate(a): | for index, x in np.ndenumerate(a): | ||
print(index, x) | print(index, x) | ||
| − | </syntaxhighlight> === | + | </syntaxhighlight> |
| + | For usual python | ||
| + | <syntaxhighlight lang="python"> | ||
| + | a = np.array([[1, 2], [3, 4]]) | ||
| + | for index, x in enumerate(a): | ||
| + | print(index, x) | ||
| + | </syntaxhighlight> | ||
| + | |||
| + | ==== Partial Functions==== | ||
| + | You can define new function out of already defined one with some argument being applied. | ||
| + | <syntaxhighlight lang="python" > | ||
| + | from functools import partial | ||
| + | |||
| + | def foo(x,y) -> float: | ||
| + | return x*y | ||
| + | |||
| + | new_func = partial(foo,y=5) | ||
| + | </syntaxhighlight> | ||
| + | |||
| + | ==== Zip ==== | ||
| + | For iterating along the several list it is a good practice to use zip: | ||
| + | |||
| + | <syntaxhighlight lang="python" > | ||
| + | a = [1,2,3,4] | ||
| + | b = [5,6,7,8] | ||
| + | for av, bv in zip(a, b): | ||
| + | print(av) | ||
| + | print(bv) | ||
| + | </syntaxhighlight> | ||
| + | |||
| + | === Multiprocessing === | ||
| + | |||
| + | |||
| + | <syntaxhighlight lang="python"> | ||
| + | from multiprocessing import Pool | ||
| + | def run_with_mp_map(items, do_work, processes=None, chunksize=None): | ||
| + | print(f"running using multiprocessing with {processes=}, {chunksize=}") | ||
| + | start_t = time.perf_counter() | ||
| + | with Pool(processes=processes) as pool: | ||
| + | results = pool.imap(do_work, items, chunksize=chunksize) | ||
| + | end_t = time.perf_counter() | ||
| + | wall_duration = end_t - start_t | ||
| + | print(f"it took: {wall_duration:.2f}s") | ||
| + | return results | ||
| + | </syntaxhighlight> | ||
| + | |||
| + | === Context manager === | ||
| + | <syntaxhighlight lang="python"> | ||
| + | with open(filename, "w") as f: | ||
| + | f.write("hello!\n") | ||
| + | # close automatic, even if exception | ||
| + | </syntaxhighlight> | ||
| + | |||
| + | |||
| + | === PEP8 Checker === | ||
| + | It is a good practice to follow PEP8 standard when writing code. | ||
| + | In jupyter the PEP8 syntax checker may help highlight the errors. | ||
| + | To load the checker into a jupyter notebook: | ||
| + | <syntaxhighlight lang="python"> | ||
| + | %load_ext pycodestyle_magic | ||
| + | </syntaxhighlight> | ||
| + | |||
| + | To switch on the checker: | ||
| + | <syntaxhighlight lang="python"> | ||
| + | %pycodestyle_on | ||
| + | </syntaxhighlight> | ||
| + | To switch off the checker: | ||
| + | <syntaxhighlight lang="python"> | ||
| + | %pycodestyle_off | ||
| + | </syntaxhighlight> | ||
| + | |||
| + | ===Main function === | ||
| + | It is a good practice to indicate whether your python file will be executed as a script by including | ||
| + | "if __name__ == '__main__':" statement: | ||
| + | <syntaxhighlight lang="python"> | ||
| + | def main(): | ||
| + | pass | ||
| + | # Do Something: | ||
| + | |||
| + | if __name__ == '__main__': | ||
| + | main() | ||
| + | </syntaxhighlight> | ||
| + | |||
| + | === Measure execution timing === | ||
| + | In jupyter it is possible to use "magic" command to measure execution time. | ||
| + | For exmple, the code below run function foo for 1000 times and returns average execution time | ||
| + | <syntaxhighlight lang="python"> | ||
| + | %timeit n 1000 -r1 foo(x) | ||
| + | </syntaxhighlight> | ||
| + | Alternatively, the time can be measured directly by including the following code: | ||
| + | <syntaxhighlight lang="python"> | ||
| + | import time | ||
| + | start = time.perf_counter() | ||
| + | time.sleep(1) | ||
| + | end = time.perf_counter() | ||
| + | print(end - start) | ||
| + | </syntaxhighlight> | ||
Latest revision as of 17:41, 22 December 2023
Python Tips and Tricks
Contents
Debugger
pdb is a python native debugger. To call the debugger with a program main.py just run the following command
pdb python -m main.py
You can introduce breakpoint manually in your code by typing command
breakpoint()
Alternatively you can introduce breakpoint directly in pdb shell by typing
>> bN
where N is a line number for execution, e.g. 100 Few useful commands:
if one liner
Sometimes it is convenient to use one liner instead of long if-else statement:
device_type = 'cuda' if 'cuda' in device else 'cpu' # for later use in torch.autocast
F string
You may print the string with a nice format:
number = 2
print(f' The number is {number:2f}')
The cheat sheet for f-number formatting.
Cache
You can cache a number results of a deterministic function by using the following decorator from functools module
import functools
@functools.lru_cache(maxsize = 4096)
def foo(x):
.....
maxsize is size of cache. The argument of None removes the limit
Array enumeration
For numpy
a = np.array([[1, 2], [3, 4]])
for index, x in np.ndenumerate(a):
print(index, x)
For usual python
a = np.array([[1, 2], [3, 4]])
for index, x in enumerate(a):
print(index, x)
Partial Functions
You can define new function out of already defined one with some argument being applied.
from functools import partial
def foo(x,y) -> float:
return x*y
new_func = partial(foo,y=5)
Zip
For iterating along the several list it is a good practice to use zip:
a = [1,2,3,4]
b = [5,6,7,8]
for av, bv in zip(a, b):
print(av)
print(bv)
Multiprocessing
from multiprocessing import Pool
def run_with_mp_map(items, do_work, processes=None, chunksize=None):
print(f"running using multiprocessing with {processes=}, {chunksize=}")
start_t = time.perf_counter()
with Pool(processes=processes) as pool:
results = pool.imap(do_work, items, chunksize=chunksize)
end_t = time.perf_counter()
wall_duration = end_t - start_t
print(f"it took: {wall_duration:.2f}s")
return results
Context manager
with open(filename, "w") as f:
f.write("hello!\n")
# close automatic, even if exception
PEP8 Checker
It is a good practice to follow PEP8 standard when writing code. In jupyter the PEP8 syntax checker may help highlight the errors. To load the checker into a jupyter notebook:
%load_ext pycodestyle_magic
To switch on the checker:
%pycodestyle_on
To switch off the checker:
%pycodestyle_off
Main function
It is a good practice to indicate whether your python file will be executed as a script by including "if __name__ == '__main__':" statement:
def main():
pass
# Do Something:
if __name__ == '__main__':
main()
Measure execution timing
In jupyter it is possible to use "magic" command to measure execution time. For exmple, the code below run function foo for 1000 times and returns average execution time
%timeit n 1000 -r1 foo(x)
Alternatively, the time can be measured directly by including the following code:
import time
start = time.perf_counter()
time.sleep(1)
end = time.perf_counter()
print(end - start)