From 36bb0aebb576d13284a137dbf2f6ca7d05a37065 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jure=20=C5=A0orn?= Date: Tue, 18 Jun 2024 21:40:48 +0200 Subject: [PATCH] Threading, Operator, Image --- README.md | 31 +++++++++++++++---------------- index.html | 31 +++++++++++++++---------------- pdf/remove_links.py | 3 +-- 3 files changed, 31 insertions(+), 34 deletions(-) diff --git a/README.md b/README.md index 4c11b1e..d5c640d 100644 --- a/README.md +++ b/README.md @@ -2100,15 +2100,14 @@ Threading --------- **CPython interpreter can only run a single thread at a time. Using multiple threads won't result in a faster execution, unless at least one of the threads contains an I/O operation.** ```python -from threading import Thread, RLock, Semaphore, Event, Barrier +from threading import Thread, Lock, RLock, Semaphore, Event, Barrier from concurrent.futures import ThreadPoolExecutor, as_completed ``` ### Thread ```python = Thread(target=) # Use `args=` to set the arguments. -.start() # Starts the thread. - = .is_alive() # Checks if the thread has finished executing. +.start() # Starts the thread. Also .is_alive(). .join() # Waits for the thread to finish. ``` * **Use `'kwargs='` to pass keyword arguments to the function.** @@ -2116,7 +2115,7 @@ from concurrent.futures import ThreadPoolExecutor, as_completed ### Lock ```python - = RLock() # Lock that can only be released by acquirer. + = Lock/RLock() # RLock can only be released by acquirer. .acquire() # Waits for the lock to be available. .release() # Makes the lock available again. ``` @@ -2159,7 +2158,7 @@ with : # Enters the block by calling acq ``` * **Map() and as\_completed() also accept 'timeout'. It causes futures.TimeoutError when next() is called/blocking. Map() times from original call and as_completed() from first call to next(). As\_completed() fails if next() is called too late, even if thread finished on time.** * **Exceptions that happen inside threads are raised when next() is called on map's iterator or when result() is called on a Future. Its exception() method returns exception or None.** -* **ProcessPoolExecutor provides true parallelism, but everything sent to/from workers must be [pickable](#pickle). Queues must be sent using executor's 'initargs' and 'initializer' parameters.** +* **ProcessPoolExecutor provides true parallelism but: everything sent to/from workers must be [pickable](#pickle), queues must be sent using executor's 'initargs' and 'initializer' parameters, and executor needs to be reachable via `'if __name__ == "__main__": ...'`.** Operator @@ -2167,20 +2166,20 @@ Operator **Module of functions that provide the functionality of operators. Functions are ordered by operator precedence, starting with least binding.** ```python import operator as op - = op.not_() # or, and, not (or/and missing) - = op.eq/ne/lt/le/gt/ge/is_/contains(, ) # ==, !=, <, <=, >, >=, is, in - = op.or_/xor/and_(, ) # |, ^, & - = op.lshift/rshift(, ) # <<, >> - = op.add/sub/mul/truediv/floordiv/mod(, ) # +, -, *, /, //, % - = op.neg/invert() # -, ~ - = op.pow(, ) # ** - = op.itemgetter/attrgetter/methodcaller( [, ...]) # [index/key], .name, .name() + = op.not_() # or, and, not (or/and missing) + = op.eq/ne/lt/le/gt/ge/is_/contains(, ) # ==, !=, <, <=, >, >=, is, in + = op.or_/xor/and_(, ) # |, ^, & + = op.lshift/rshift(, ) # <<, >> + = op.add/sub/mul/truediv/floordiv/mod(, ) # +, -, *, /, //, % + = op.neg/invert() # -, ~ + = op.pow(, ) # ** + = op.itemgetter/attrgetter/methodcaller( [, ...]) # [index/key], .name, .name() ``` ```python elementwise_sum = map(op.add, list_a, list_b) -sorted_by_second = sorted(, key=op.itemgetter(1)) -sorted_by_both = sorted(, key=op.itemgetter(1, 0)) +sorted_by_second = sorted(, key=op.itemgetter(1)) +sorted_by_both = sorted(, key=op.itemgetter(1, 0)) product_of_elems = functools.reduce(op.mul, ) first_element = op.methodcaller('pop', 0)() ``` @@ -2773,7 +2772,7 @@ from PIL import Image = Image.new('', (width, height)) # Creates new image. Also `color=`. = Image.open() # Identifies format based on file's contents. = .convert('') # Converts image to the new mode. -.save() # Selects format based on the path extension. +.save() # Selects format based on extension (png/jpg…). .show() # Opens image in the default preview app. ``` diff --git a/index.html b/index.html index 667cad6..f8f434e 100644 --- a/index.html +++ b/index.html @@ -1723,14 +1723,13 @@ CompletedProcess(args=['bc', 1) # Last element becomes first. <el> = <deque>.popleft() # Raises IndexError if deque is empty. -

#Threading

CPython interpreter can only run a single thread at a time. Using multiple threads won't result in a faster execution, unless at least one of the threads contains an I/O operation.

from threading import Thread, RLock, Semaphore, Event, Barrier
+

#Threading

CPython interpreter can only run a single thread at a time. Using multiple threads won't result in a faster execution, unless at least one of the threads contains an I/O operation.

from threading import Thread, Lock, RLock, Semaphore, Event, Barrier
 from concurrent.futures import ThreadPoolExecutor, as_completed
 

Thread

<Thread> = Thread(target=<function>)           # Use `args=<collection>` to set the arguments.
-<Thread>.start()                               # Starts the thread.
-<bool> = <Thread>.is_alive()                   # Checks if the thread has finished executing.
+<Thread>.start()                               # Starts the thread. Also <Thread>.is_alive().
 <Thread>.join()                                # Waits for the thread to finish.
 
@@ -1738,7 +1737,7 @@ CompletedProcess(args=['bc', 'kwargs=<dict>'
to pass keyword arguments to the function.
  • Use 'daemon=True', or the program will not be able to exit while the thread is alive.
  • -

    Lock

    <lock> = RLock()                               # Lock that can only be released by acquirer.
    +

    Lock

    <lock> = Lock/RLock()                          # RLock can only be released by acquirer.
     <lock>.acquire()                               # Waits for the lock to be available.
     <lock>.release()                               # Makes the lock available again.
     
    @@ -1773,23 +1772,23 @@ CompletedProcess(args=['bc', pickable. Queues must be sent using executor's 'initargs' and 'initializer' parameters. +
  • ProcessPoolExecutor provides true parallelism but: everything sent to/from workers must be pickable, queues must be sent using executor's 'initargs' and 'initializer' parameters, and executor needs to be reachable via 'if __name__ == "__main__": ...'.
  • #Operator

    Module of functions that provide the functionality of operators. Functions are ordered by operator precedence, starting with least binding.

    import operator as op
    -<bool> = op.not_(<obj>)                                         # or, and, not (or/and missing)
    -<bool> = op.eq/ne/lt/le/gt/ge/is_/contains(<obj>, <obj>)        # ==, !=, <, <=, >, >=, is, in
    -<obj>  = op.or_/xor/and_(<int/set>, <int/set>)                  # |, ^, &
    -<int>  = op.lshift/rshift(<int>, <int>)                         # <<, >>
    -<obj>  = op.add/sub/mul/truediv/floordiv/mod(<obj>, <obj>)      # +, -, *, /, //, %
    -<num>  = op.neg/invert(<num>)                                   # -, ~
    -<num>  = op.pow(<num>, <num>)                                   # **
    -<func> = op.itemgetter/attrgetter/methodcaller(<obj> [, ...])   # [index/key], .name, .name()
    +<bool> = op.not_(<obj>)                                        # or, and, not (or/and missing)
    +<bool> = op.eq/ne/lt/le/gt/ge/is_/contains(<obj>, <obj>)       # ==, !=, <, <=, >, >=, is, in
    +<obj>  = op.or_/xor/and_(<int/set>, <int/set>)                 # |, ^, &
    +<int>  = op.lshift/rshift(<int>, <int>)                        # <<, >>
    +<obj>  = op.add/sub/mul/truediv/floordiv/mod(<obj>, <obj>)     # +, -, *, /, //, %
    +<num>  = op.neg/invert(<num>)                                  # -, ~
    +<num>  = op.pow(<num>, <num>)                                  # **
    +<func> = op.itemgetter/attrgetter/methodcaller(<obj> [, ...])  # [index/key], .name, .name()
     
    elementwise_sum  = map(op.add, list_a, list_b)
    -sorted_by_second = sorted(<collection>, key=op.itemgetter(1))
    -sorted_by_both   = sorted(<collection>, key=op.itemgetter(1, 0))
    +sorted_by_second = sorted(<coll.>, key=op.itemgetter(1))
    +sorted_by_both   = sorted(<coll.>, key=op.itemgetter(1, 0))
     product_of_elems = functools.reduce(op.mul, <collection>)
     first_element    = op.methodcaller('pop', 0)(<list>)
     
    @@ -2265,7 +2264,7 @@ right = [[0.1, 0.6<Image> = Image.new('<mode>', (width, height)) # Creates new image. Also `color=<int/tuple>`. <Image> = Image.open(<path>) # Identifies format based on file's contents. <Image> = <Image>.convert('<mode>') # Converts image to the new mode. -<Image>.save(<path>) # Selects format based on the path extension. +<Image>.save(<path>) # Selects format based on extension (png/jpg…). <Image>.show() # Opens image in the default preview app.
    <int/tuple> = <Image>.getpixel((x, y))          # Returns pixel's value (its color).
    diff --git a/pdf/remove_links.py b/pdf/remove_links.py
    index 937990e..72dcc50 100755
    --- a/pdf/remove_links.py
    +++ b/pdf/remove_links.py
    @@ -24,8 +24,7 @@ MATCHES = {
         'To print the spreadsheet to the console use Tabulate library.': 'To print the spreadsheet to the console use Tabulate library (p. 34).',
         'For XML and binary Excel files (xlsx, xlsm and xlsb) use Pandas library.': 'For XML and binary Excel files (xlsx, xlsm and xlsb) use Pandas library (p. 46).',
         'Bools will be stored and returned as ints and dates as ISO formatted strings.': 'Bools will be stored and returned as ints and dates as ISO formatted strings (p. 9).',
    -    'An object with the same interface called ProcessPoolExecutor provides true parallelism by running a separate interpreter in each process. Arguments/results must be pickable.': 'An object with the same interface called ProcessPoolExecutor provides true parallelism by running a separate interpreter in each process. Arguments/results must be pickable.',
    -    'ProcessPoolExecutor provides true parallelism, but everything sent to/from workers must be pickable. Queues must be sent using executor\'s \'initargs\' and \'initializer\' parameters.': 'ProcessPoolExecutor provides true parallelism, but everything sent to/from workers must be pickable. Queues must be sent using executor\'s \'initargs\' and \'initializer\' parameters.',
    +    'ProcessPoolExecutor provides true parallelism but: everything sent to/from workers must be pickable, queues must be sent using executor\'s \'initargs\' and \'initializer\' parameters, and executor needs to be reachable via \'if __name__ == "__main__": ...\'.': 'ProcessPoolExecutor provides true parallelism but: everything sent to/from workers must be pickable, queues must be sent using executor\'s \'initargs\' and \'initializer\' parameters, and executor needs to be reachable via \'if __name__ == "__main__": ...\'.',
         'Asyncio module also provides its own Queue, Event, Lock and Semaphore classes.': 'Asyncio module also provides its own Queue, Event, Lock and Semaphore classes (p. 30).',
         'Install a WSGI server like Waitress and a HTTP server such as Nginx for better security.': 'Install a WSGI server like Waitress and a HTTP server such as Nginx for better security.',
         'The "latest and greatest" profiler that can also monitor GPU usage is called Scalene.': 'The "latest and greatest" profiler that can also monitor GPU usage is called Scalene.',