Skip to content

Commit 5b1ece2

Browse files
committed
Duck types, Logging, Coroutines, Web, Image
1 parent df38807 commit 5b1ece2

File tree

3 files changed

+47
-51
lines changed

3 files changed

+47
-51
lines changed

README.md

Lines changed: 22 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1327,8 +1327,7 @@ class MyAbcSequence(abc.Sequence):
13271327
+------------+------------+------------+------------+--------------+
13281328
```
13291329
* **Method iter() is required for `'isinstance(<obj>, abc.Iterable)'` to return True, however any object with getitem() will work with any code expecting an iterable.**
1330-
* **Other extendable ABCs: MutableSequence, Set, MutableSet, Mapping, MutableMapping.**
1331-
* **Names of their required methods are stored in `'<abc>.__abstractmethods__'`.**
1330+
* **MutableSequence, Set, MutableSet, Mapping and MutableMapping ABCs are also extendable. Use `'<abc>.__abstractmethods__'` to get names of required methods.**
13321331

13331332

13341333
Enum
@@ -2161,7 +2160,7 @@ with <lock>: # Enters the block by calling acq
21612160
<bool> = <Future>.cancel() # Cancels or returns False if running/finished.
21622161
<iter> = as_completed(<coll_of_Futures>) # `next(<iter>)` returns next completed Future.
21632162
```
2164-
* **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 all threads have finished.**
2163+
* **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 all threads are done.**
21652164
* **Exceptions that happen inside threads are raised when map iterator's next() or Future's result() are called. Future's exception() method returns exception object or None.**
21662165
* **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 should only be reachable via `'if __name__ == "__main__": ...'`.**
21672166

@@ -2245,9 +2244,9 @@ import logging as log
22452244

22462245
```python
22472246
log.basicConfig(filename=<path>, level='DEBUG') # Configures the root logger (see Setup).
2248-
log.debug/info/warning/error/critical(<str>) # Logs to the root logger.
2249-
<Logger> = log.getLogger(__name__) # Logger named after the module.
2250-
<Logger>.<level>(<str>) # Logs to the logger.
2247+
log.debug/info/warning/error/critical(<str>) # Sends message to the root logger.
2248+
<Logger> = log.getLogger(__name__) # Returns logger named after the module.
2249+
<Logger>.<level>(<str>) # Sends message to the logger.
22512250
<Logger>.exception(<str>) # Error() that appends caught exception.
22522251
```
22532252

@@ -2321,17 +2320,17 @@ Coroutines
23212320
----------
23222321
* **Coroutines have a lot in common with threads, but unlike threads, they only give up control when they call another coroutine and they don’t use as much memory.**
23232322
* **Coroutine definition starts with `'async'` and its call with `'await'`.**
2324-
* **`'asyncio.run(<coroutine>)'` is the main entry point for asynchronous programs.**
2323+
* **Use `'asyncio.run(<coroutine>)'` to start the first/main coroutine.**
23252324

23262325
```python
23272326
import asyncio as aio
23282327
```
23292328

23302329
```python
23312330
<coro> = <async_function>(<args>) # Creates a coroutine by calling async def function.
2332-
<obj> = await <coroutine> # Starts the coroutine and returns result.
2331+
<obj> = await <coroutine> # Starts the coroutine and returns its result.
23332332
<task> = aio.create_task(<coroutine>) # Schedules the coroutine for execution.
2334-
<obj> = await <task> # Returns result. Also <task>.cancel().
2333+
<obj> = await <task> # Returns coroutine's result. Also <task>.cancel().
23352334
```
23362335

23372336
```python
@@ -2355,7 +2354,7 @@ def main(screen):
23552354

23562355
async def main_coroutine(screen):
23572356
moves = asyncio.Queue()
2358-
state = {'*': P(0, 0), **{id_: P(W//2, H//2) for id_ in range(10)}}
2357+
state = {'*': P(0, 0)} | {id_: P(W//2, H//2) for id_ in range(10)}
23592358
ai = [random_controller(id_, moves) for id_ in range(10)]
23602359
mvc = [human_controller(screen, moves), model(moves, state), view(state, screen)]
23612360
tasks = [asyncio.create_task(coro) for coro in ai + mvc]
@@ -2549,12 +2548,12 @@ Web
25492548
**Flask is a micro web framework/server. If you just want to open a html file in a web browser use `'webbrowser.open(<path>)'` instead.**
25502549
```python
25512550
# $ pip3 install flask
2552-
import flask
2551+
import flask as fl
25532552
```
25542553

25552554
```python
2556-
app = flask.Flask(__name__) # Returns app object. Put at the top.
2557-
app.run(host=None, port=None, debug=None) # Or: $ flask --app FILE run [--ARG[=VAL]]
2555+
app = fl.Flask(__name__) # Returns app object. Put at the top.
2556+
app.run(host=None, port=None, debug=None) # Or: $ flask --app FILE run [--ARG[=VAL]]
25582557
```
25592558
* **Starts the app at `'http://localhost:5000'`. Use `'host="0.0.0.0"'` to run externally.**
25602559
* **Install a WSGI server like [Waitress](https://flask.palletsprojects.com/en/latest/deploying/waitress/) and a HTTP server such as [Nginx](https://flask.palletsprojects.com/en/latest/deploying/nginx/) for better security.**
@@ -2564,25 +2563,25 @@ app.run(host=None, port=None, debug=None) # Or: $ flask --app FILE run [--ARG[=
25642563
```python
25652564
@app.route('/img/<path:filename>')
25662565
def serve_file(filename):
2567-
return flask.send_from_directory('dirname/', filename)
2566+
return fl.send_from_directory('dirname/', filename)
25682567
```
25692568

25702569
### Dynamic Request
25712570
```python
25722571
@app.route('/<sport>')
25732572
def serve_html(sport):
2574-
return flask.render_template_string('<h1>{{title}}</h1>', title=sport)
2573+
return fl.render_template_string('<h1>{{title}}</h1>', title=sport)
25752574
```
2576-
* **Use `'render_template(filename, <kwargs>)'` to render file located in templates dir.**
2577-
* **To return an error code use `'abort(<int>)'` and to redirect use `'redirect(<url>)'`.**
2578-
* **`'request.args[<str>]'` returns parameter from the query string (URL part after '?').**
2579-
* **`'session[<str>] = <obj>'` stores session data. Needs `'app.secret_key = <str>'`.**
2575+
* **`'fl.render_template(filename, <kwargs>)'` renders a file located in 'templates' dir.**
2576+
* **`'fl.abort(<int>)'` returns error code and `'return fl.redirect(<url>)'` redirects.**
2577+
* **`'fl.request.args[<str>]'` returns parameter from the query string (URL right of '?').**
2578+
* **`'fl.session[<str>] = <obj>'` stores session data. It requires secret key to be set at the startup with `'app.secret_key = <str>'`.**
25802579

25812580
### REST Request
25822581
```python
25832582
@app.post('/<sport>/odds')
25842583
def serve_json(sport):
2585-
team = flask.request.form['team']
2584+
team = fl.request.form['team']
25862585
return {'team': team, 'odds': [2.09, 3.74, 3.68]}
25872586
```
25882587

@@ -2592,8 +2591,7 @@ def serve_json(sport):
25922591
>>> import threading, requests
25932592
>>> threading.Thread(target=app.run, daemon=True).start()
25942593
>>> url = 'http://localhost:5000/football/odds'
2595-
>>> request_data = {'team': 'arsenal f.c.'}
2596-
>>> response = requests.post(url, data=request_data)
2594+
>>> response = requests.post(url, data={'team': 'arsenal f.c.'})
25972595
>>> response.json()
25982596
{'team': 'arsenal f.c.', 'odds': [2.09, 3.74, 3.68]}
25992597
```
@@ -2833,10 +2831,10 @@ from PIL import ImageDraw
28332831
<Draw> = ImageDraw.Draw(<Image>) # Object for adding 2D graphics to the image.
28342832
<Draw>.point((x, y)) # Draws a point. Truncates floats into ints.
28352833
<Draw>.line((x1, y1, x2, y2 [, ...])) # To get anti-aliasing use Image's resize().
2836-
<Draw>.arc((x1, y1, x2, y2), deg1, deg2) # Always draws in clockwise direction.
2834+
<Draw>.arc((x1, y1, x2, y2), deg1, deg2) # Draws in clockwise dir. Also pieslice().
28372835
<Draw>.rectangle((x1, y1, x2, y2)) # To rotate use Image's rotate() and paste().
28382836
<Draw>.polygon((x1, y1, x2, y2, ...)) # Last point gets connected to the first.
2839-
<Draw>.ellipse((x1, y1, x2, y2)) # To rotate use Image's rotate() and paste().
2837+
<Draw>.ellipse((x1, y1, x2, y2)) # Also rounded_rectangle(), regular_polygon().
28402838
<Draw>.text((x, y), <str>, font=<Font>) # `<Font> = ImageFont.truetype(<path>, size)`
28412839
```
28422840
* **Use `'fill=<color>'` to set the primary color.**

0 commit comments

Comments
 (0)