From d8354f9608bf1c4a9690e9d2183aef05767684cd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jure=20=C5=A0orn?= Date: Wed, 5 Jan 2022 14:13:09 +0100 Subject: [PATCH] Arguments, Threading, Operator, Web --- README.md | 30 +++++++++++++++--------------- index.html | 37 +++++++++++++++++++------------------ pdf/remove_links.py | 2 +- 3 files changed, 35 insertions(+), 34 deletions(-) diff --git a/README.md b/README.md index 74ed731..dd9bdc0 100644 --- a/README.md +++ b/README.md @@ -676,7 +676,7 @@ def f(): # def f(x=0, y=0): def f(, ): # def f(x, y=0): ``` * **A function has its default values evaluated when it's first encountered in the scope.** -* **Any changes to mutable objects will persist between invocations.** +* **Any changes to default values that are mutable will persist between invocations.** Splat Operator @@ -722,13 +722,13 @@ def f(*args, z): # f(1, 2, z=3) ```python def f(**kwargs): # f(x=1, y=2, z=3) def f(x, **kwargs): # f(x=1, y=2, z=3) | f(1, y=2, z=3) +def f(*, x, **kwargs): # f(x=1, y=2, z=3) ``` ```python def f(*args, **kwargs): # f(x=1, y=2, z=3) | f(1, y=2, z=3) | f(1, 2, z=3) | f(1, 2, 3) def f(x, *args, **kwargs): # f(x=1, y=2, z=3) | f(1, y=2, z=3) | f(1, 2, z=3) | f(1, 2, 3) def f(*args, y, **kwargs): # f(x=1, y=2, z=3) | f(1, y=2, z=3) -def f(x, *args, z, **kwargs): # f(x=1, y=2, z=3) | f(1, y=2, z=3) | f(1, 2, z=3) ``` ### Other Uses @@ -2107,7 +2107,9 @@ with : # Enters the block by calling acq ``` ### Thread Pool Executor -**Object that manages thread execution.** +* **Object that manages thread execution.** +* **An object with the same interface called ProcessPoolExecutor provides true parallelism by running a separate interpreter in each process. All arguments must be [pickable](#pickle).** + ```python = ThreadPoolExecutor(max_workers=None) # Or: `with ThreadPoolExecutor() as : …` .shutdown(wait=True) # Blocks until all threads finish executing. @@ -2139,24 +2141,23 @@ Operator -------- **Module of functions that provide the functionality of operators.** ```python -from operator import add, sub, mul, truediv, floordiv, mod, pow, neg, abs -from operator import eq, ne, lt, le, gt, ge -from operator import and_, or_, xor, inv -from operator import itemgetter, attrgetter, methodcaller +import operator as op + = op.add/sub/mul/truediv/floordiv/mod(, ) # +, -, *, /, //, % + = op.and_/or_/xor(, ) # &, |, ^ + = op.eq/ne/lt/le/gt/ge(, ) # ==, !=, <, <=, >, >= + = op.itemgetter/attrgetter/methodcaller() # [], ., .() ``` ```python -import operator as op 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)) product_of_elems = functools.reduce(op.mul, ) union_of_sets = functools.reduce(op.or_, ) -last_element = op.methodcaller('pop')() +first_element = op.methodcaller('pop', 0)() ``` -* **Functions and\_(), or\_(), xor() and inv() correspond to operators '&', '|', '^' and '~'.** -* **They only work on objects with and(), or(), xor() and invert() special methods.** -* **Also: `' = &|^ '` and `' = &|^ '`.** +* **Binary operators require objects to have and(), or(), xor() and invert() special methods, unlike logical operators that work on all types of objects.** +* **Also: `' = &|^ '` and `' = &|^ '`.** Introspection @@ -2526,10 +2527,9 @@ def send_html(sport): @post('//odds') def send_json(sport): team = request.forms.get('team') - home_odds, away_odds = 2.44, 3.29 response.headers['Content-Type'] = 'application/json' response.headers['Cache-Control'] = 'no-cache' - return json.dumps([team, home_odds, away_odds]) + return json.dumps({'team': team, 'odds': [2.09, 3.74, 3.68]}) ``` #### Test: @@ -2541,7 +2541,7 @@ def send_json(sport): >>> data = {'team': 'arsenal f.c.'} >>> response = requests.post(url, data=data) >>> response.json() -['arsenal f.c.', 2.44, 3.29] +{'team': 'arsenal f.c.', 'odds': [2.09, 3.74, 3.68]} ``` diff --git a/index.html b/index.html index 25dcf98..d81b1f2 100644 --- a/index.html +++ b/index.html @@ -54,7 +54,7 @@
- +
@@ -599,7 +599,7 @@ to_exclusive = <range>.stop
  • A function has its default values evaluated when it's first encountered in the scope.
  • -
  • Any changes to mutable objects will persist between invocations.
  • +
  • Any changes to default values that are mutable will persist between invocations.

#Splat Operator

Inside Function Call

Splat expands a collection into positional arguments, while splatty-splat expands a dictionary into keyword arguments.

args   = (1, 2)
 kwargs = {'x': 3, 'y': 4, 'z': 5}
@@ -630,11 +630,11 @@ func(*args, **kwargs)
 
def f(**kwargs):               # f(x=1, y=2, z=3)
 def f(x, **kwargs):            # f(x=1, y=2, z=3) | f(1, y=2, z=3)
+def f(*, x, **kwargs):         # f(x=1, y=2, z=3)
 
def f(*args, **kwargs):        # f(x=1, y=2, z=3) | f(1, y=2, z=3) | f(1, 2, z=3) | f(1, 2, 3)
 def f(x, *args, **kwargs):     # f(x=1, y=2, z=3) | f(1, y=2, z=3) | f(1, 2, z=3) | f(1, 2, 3)
 def f(*args, y, **kwargs):     # f(x=1, y=2, z=3) | f(1, y=2, z=3)
-def f(x, *args, z, **kwargs):  # f(x=1, y=2, z=3) | f(1, y=2, z=3) | f(1, 2, z=3)
 

Other Uses

<list>  = [*<collection> [, ...]]
 <set>   = {*<collection> [, ...]}
@@ -1737,7 +1737,10 @@ CompletedProcess(args=['bc', # Wait() blocks until it's called n_times.
 
-

Thread Pool Executor

Object that manages thread execution.

<Exec> = ThreadPoolExecutor(max_workers=None)  # Or: `with ThreadPoolExecutor() as <name>: …`
+

Thread Pool Executor

    +
  • Object that manages thread execution.
  • +
  • An object with the same interface called ProcessPoolExecutor provides true parallelism by running a separate interpreter in each process. All arguments must be pickable.
  • +
<Exec> = ThreadPoolExecutor(max_workers=None)  # Or: `with ThreadPoolExecutor() as <name>: …`
 <Exec>.shutdown(wait=True)                     # Blocks until all threads finish executing.
 
@@ -1757,25 +1760,24 @@ CompletedProcess(args=['bc', # Blocks until queue stops being empty. <el> = <Queue>.get_nowait() # Raises queue.Empty exception if empty.
-

#Operator

Module of functions that provide the functionality of operators.

from operator import add, sub, mul, truediv, floordiv, mod, pow, neg, abs
-from operator import eq, ne, lt, le, gt, ge
-from operator import and_, or_, xor, inv
-from operator import itemgetter, attrgetter, methodcaller
+

#Operator

Module of functions that provide the functionality of operators.

import operator as op
+<el>      = op.add/sub/mul/truediv/floordiv/mod(<el>, <el>)   # +, -, *, /, //, %
+<int/set> = op.and_/or_/xor(<int/set>, <int/set>)             # &, |, ^
+<bool>    = op.eq/ne/lt/le/gt/ge(<sortable>, <sortable>)      # ==, !=, <, <=, >, >=
+<func>    = op.itemgetter/attrgetter/methodcaller(<int/str>)  # [<int/str>], .<str>, .<str>()
 
-
import operator as op
-elementwise_sum  = map(op.add, list_a, list_b)
+
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))
 product_of_elems = functools.reduce(op.mul, <collection>)
 union_of_sets    = functools.reduce(op.or_, <coll_of_sets>)
-last_element     = op.methodcaller('pop')(<list>)
+first_element    = op.methodcaller('pop', 0)(<list>)
 
    -
  • Functions and_(), or_(), xor() and inv() correspond to operators '&', '|', '^' and '~'.
  • -
  • They only work on objects with and(), or(), xor() and invert() special methods.
  • -
  • Also: '<int> = <int> &|^ <bool>' and '<bool> = <bool> &|^ <bool>'.
  • +
  • Binary operators require objects to have and(), or(), xor() and invert() special methods, unlike logical operators that work on all types of objects.
  • +
  • Also: '<bool> = <bool> &|^ <bool>' and '<int> = <bool> &|^ <int>'.

#Introspection

Inspecting code at runtime.

Variables

<list> = dir()                             # Names of local variables (incl. functions).
 <dict> = vars()                            # Dict of local variables. Also locals().
@@ -2062,10 +2064,9 @@ run(host='0.0.0.0', port=REST Request
@post('/<sport>/odds')
 def send_json(sport):
     team = request.forms.get('team')
-    home_odds, away_odds = 2.44, 3.29
     response.headers['Content-Type'] = 'application/json'
     response.headers['Cache-Control'] = 'no-cache'
-    return json.dumps([team, home_odds, away_odds])
+    return json.dumps({'team': team, 'odds': [2.09, 3.74, 3.68]})
 

Test:

# $ pip3 install requests
@@ -2075,7 +2076,7 @@ run(host='0.0.0.0', port=>>> data = {'team': 'arsenal f.c.'}
 >>> response = requests.post(url, data=data)
 >>> response.json()
-['arsenal f.c.', 2.44, 3.29]
+{'team': 'arsenal f.c.', 'odds': [2.09, 3.74, 3.68]}
 

#Profiling

Stopwatch

from time import time
@@ -2880,7 +2881,7 @@ $ pyinstaller script.py --add-data '<path>:.'  
  
 
   
 
diff --git a/pdf/remove_links.py b/pdf/remove_links.py
index 9ca06f5..1a98ae5 100755
--- a/pdf/remove_links.py
+++ b/pdf/remove_links.py
@@ -18,9 +18,9 @@ MATCHES = {
     'Objects returned by the itertools module, such as count, repeat and cycle.': 'Objects returned by the itertools module, such as count, repeat and cycle (p. 3).',
     'Generators returned by the generator functions and generator expressions.': 'Generators returned by the generator functions (p. 4) and generator expressions (p. 11).',
     'File objects returned by the open() function, etc.': 'File objects returned by the open() function (p. 22), etc.',
-    'Another solution in this particular case is to use functions and_() and or_() from the module operator.': 'Another solution in this particular case is to use functions and_() and or_() from the module \'operator\' (p. 31).',
     'Functions report OS related errors by raising either OSError or one of its subclasses.': 'Functions report OS related errors by raising OSError or one of its subclasses (p. 23).',
     '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. All arguments must be pickable.': 'An object with the same interface called ProcessPoolExecutor provides true parallelism by running a separate interpreter in each process. All arguments must be pickable (p. 25).',
     '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).',
 }