feat: 新增技能扩展 N3 一章相关示例源码
This commit is contained in:
330
code/newsletter/N3/collections.ipynb
Normal file
330
code/newsletter/N3/collections.ipynb
Normal file
@@ -0,0 +1,330 @@
|
||||
{
|
||||
"cells": [
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"# namedtuple"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## namedtuple 使用示例"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 5,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"Point 1: Point(x=1, y=1), Point 2: Point(x=2, y=3)\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"from collections import namedtuple\n",
|
||||
"\n",
|
||||
"Point = namedtuple(\"Point\", [\"x\", \"y\"])\n",
|
||||
"p1 = Point(x=1, y=1)\n",
|
||||
"p2 = Point(2, 3)\n",
|
||||
"print(f\"Point 1: {p1}, Point 2: {p2}\")"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 6,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"text/plain": [
|
||||
"{'x': 3, 'y': 4}"
|
||||
]
|
||||
},
|
||||
"execution_count": 6,
|
||||
"metadata": {},
|
||||
"output_type": "execute_result"
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"p3 = Point(p1.x + p2.x, p1.y + p2.y)\n",
|
||||
"p3._asdict()"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## 自定义 `Point` 类"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"class Point:\n",
|
||||
" def __init__(self, x: int, y: int):\n",
|
||||
" self.x = x\n",
|
||||
" self.y = y\n",
|
||||
"\n",
|
||||
" def __repr__(self):\n",
|
||||
" return f\"{self.__class__.__name__}(x={self.x}, y={self.y})\"\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"p = Point(x=3, y=4)\n",
|
||||
"p\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## 使用 `NamedTuple` 类"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 3,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"text/plain": [
|
||||
"Point(x=0, y=0)"
|
||||
]
|
||||
},
|
||||
"execution_count": 3,
|
||||
"metadata": {},
|
||||
"output_type": "execute_result"
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"from typing import NamedTuple\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"class Point(NamedTuple):\n",
|
||||
" x: int = 0\n",
|
||||
" y: int = 0\n",
|
||||
"\n",
|
||||
" def __repr__(self):\n",
|
||||
" return f\"{self.__class__.__name__}(x={self.x}, y={self.y})\"\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"p = Point()\n",
|
||||
"p"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"# Counter"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 1,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"text/plain": [
|
||||
"[('is', 10),\n",
|
||||
" ('better', 8),\n",
|
||||
" ('than', 8),\n",
|
||||
" ('to', 5),\n",
|
||||
" ('the', 5),\n",
|
||||
" ('of', 3),\n",
|
||||
" ('Although', 3),\n",
|
||||
" ('be', 3),\n",
|
||||
" ('should', 2),\n",
|
||||
" ('never', 2)]"
|
||||
]
|
||||
},
|
||||
"execution_count": 1,
|
||||
"metadata": {},
|
||||
"output_type": "execute_result"
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"from collections import Counter\n",
|
||||
"from itertools import chain\n",
|
||||
"\n",
|
||||
"poem = \"\"\"\n",
|
||||
"The Zen of Python, by Tim Peters\n",
|
||||
"\n",
|
||||
"Beautiful is better than ugly.\n",
|
||||
"Explicit is better than implicit.\n",
|
||||
"Simple is better than complex.\n",
|
||||
"Complex is better than complicated.\n",
|
||||
"Flat is better than nested.\n",
|
||||
"Sparse is better than dense.\n",
|
||||
"Readability counts.\n",
|
||||
"Special cases aren't special enough to break the rules.\n",
|
||||
"Although practicality beats purity.\n",
|
||||
"Errors should never pass silently.\n",
|
||||
"Unless explicitly silenced.\n",
|
||||
"In the face of ambiguity, refuse the temptation to guess.\n",
|
||||
"There should be one-- and preferably only one --obvious way to do it.\n",
|
||||
"Although that way may not be obvious at first unless you're Dutch.\n",
|
||||
"Now is better than never.\n",
|
||||
"Although never is often better than *right* now.\n",
|
||||
"If the implementation is hard to explain, it's a bad idea.\n",
|
||||
"If the implementation is easy to explain, it may be a good idea.\n",
|
||||
"Namespaces are one honking great idea -- let's do more of those!\n",
|
||||
"\"\"\"\n",
|
||||
"split = [line.split() for line in poem.splitlines()]\n",
|
||||
"words = list(chain(*[elem for elem in split if elem]))\n",
|
||||
"words[1:10]\n",
|
||||
"\n",
|
||||
"counter = Counter(words)\n",
|
||||
"counter.most_common(10)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"# deque "
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 8,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"text/plain": [
|
||||
"deque([])"
|
||||
]
|
||||
},
|
||||
"execution_count": 8,
|
||||
"metadata": {},
|
||||
"output_type": "execute_result"
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"from collections import deque\n",
|
||||
"\n",
|
||||
"queue = deque()\n",
|
||||
"queue"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 9,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"text/plain": [
|
||||
"deque(['foo'])"
|
||||
]
|
||||
},
|
||||
"execution_count": 9,
|
||||
"metadata": {},
|
||||
"output_type": "execute_result"
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"queue.append(\"foo\")\n",
|
||||
"queue"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 11,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"text/plain": [
|
||||
"deque(['bar', 'bar', 'foo'])"
|
||||
]
|
||||
},
|
||||
"execution_count": 11,
|
||||
"metadata": {},
|
||||
"output_type": "execute_result"
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"queue.appendleft(\"bar\")\n",
|
||||
"queue"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"queue.extendleft([\"zoo\", \"fuzz\"])\n",
|
||||
"queue"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 19,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"text/plain": [
|
||||
"deque(['foo', 'bar', 'baz'])"
|
||||
]
|
||||
},
|
||||
"execution_count": 19,
|
||||
"metadata": {},
|
||||
"output_type": "execute_result"
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"queue.rotate(1)\n",
|
||||
"queue"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": []
|
||||
}
|
||||
],
|
||||
"metadata": {
|
||||
"kernelspec": {
|
||||
"display_name": "Python 3.9.0 ('pandas-startup')",
|
||||
"language": "python",
|
||||
"name": "python3"
|
||||
},
|
||||
"language_info": {
|
||||
"codemirror_mode": {
|
||||
"name": "ipython",
|
||||
"version": 3
|
||||
},
|
||||
"file_extension": ".py",
|
||||
"mimetype": "text/x-python",
|
||||
"name": "python",
|
||||
"nbconvert_exporter": "python",
|
||||
"pygments_lexer": "ipython3",
|
||||
"version": "3.9.0"
|
||||
},
|
||||
"orig_nbformat": 4,
|
||||
"vscode": {
|
||||
"interpreter": {
|
||||
"hash": "13977d4cc82dee5f9d9535ceb495bd0ab12a43c33c664e5f0d53c24cf634b67f"
|
||||
}
|
||||
}
|
||||
},
|
||||
"nbformat": 4,
|
||||
"nbformat_minor": 2
|
||||
}
|
||||
409
code/newsletter/N3/functools.ipynb
Normal file
409
code/newsletter/N3/functools.ipynb
Normal file
@@ -0,0 +1,409 @@
|
||||
{
|
||||
"cells": [
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"# reduce"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 11,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"text/plain": [
|
||||
"[1, 2, 3, 4, 5]"
|
||||
]
|
||||
},
|
||||
"execution_count": 11,
|
||||
"metadata": {},
|
||||
"output_type": "execute_result"
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"from functools import reduce\n",
|
||||
"\n",
|
||||
"numbers = list(range(1, 6))\n",
|
||||
"numbers"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 12,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"text/plain": [
|
||||
"15"
|
||||
]
|
||||
},
|
||||
"execution_count": 12,
|
||||
"metadata": {},
|
||||
"output_type": "execute_result"
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"int(reduce(lambda x, y: x + y, numbers))"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 13,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"text/plain": [
|
||||
"120"
|
||||
]
|
||||
},
|
||||
"execution_count": 13,
|
||||
"metadata": {},
|
||||
"output_type": "execute_result"
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"int(reduce(lambda x, y: x * y, numbers))"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 21,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"text/plain": [
|
||||
"15"
|
||||
]
|
||||
},
|
||||
"execution_count": 21,
|
||||
"metadata": {},
|
||||
"output_type": "execute_result"
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"def accumulate(sequence):\n",
|
||||
" result = sequence[0]\n",
|
||||
" for index, _ in enumerate(sequence[1:], start=1):\n",
|
||||
" right = sequence[index]\n",
|
||||
" result += right\n",
|
||||
"\n",
|
||||
" return result\n",
|
||||
"\n",
|
||||
"accumulate(numbers)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 22,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"text/plain": [
|
||||
"25"
|
||||
]
|
||||
},
|
||||
"execution_count": 22,
|
||||
"metadata": {},
|
||||
"output_type": "execute_result"
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"int(reduce(lambda x, y: x+y, numbers, 10))"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"# partial"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 36,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"from functools import partial\n",
|
||||
"from math import log\n",
|
||||
"\n",
|
||||
"def custom_log(x, base):\n",
|
||||
" return log(x, base)\n",
|
||||
"\n",
|
||||
"log2 = partial(custom_log, base=2)\n",
|
||||
"log10 = partial(custom_log, base=10)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 38,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"text/plain": [
|
||||
"2.0"
|
||||
]
|
||||
},
|
||||
"execution_count": 38,
|
||||
"metadata": {},
|
||||
"output_type": "execute_result"
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"log2(4)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 39,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"text/plain": [
|
||||
"2.0"
|
||||
]
|
||||
},
|
||||
"execution_count": 39,
|
||||
"metadata": {},
|
||||
"output_type": "execute_result"
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"log10(100)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 40,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"text/plain": [
|
||||
"2.0"
|
||||
]
|
||||
},
|
||||
"execution_count": 40,
|
||||
"metadata": {},
|
||||
"output_type": "execute_result"
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"log2(9, base=3)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"# wraps"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"### without wraps function"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 42,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"Monitoring request...\n",
|
||||
"request https://sspai.com using GET method...\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"def monitor(func):\n",
|
||||
" print(f\"Monitoring {func.__name__}...\") \n",
|
||||
" def wrapper(*args, **kwargs):\n",
|
||||
" return func(*args, **kwargs)\n",
|
||||
" return wrapper\n",
|
||||
"\n",
|
||||
"@monitor\n",
|
||||
"def request(url, method=\"GET\"):\n",
|
||||
" \"\"\"Request from target url\n",
|
||||
" :param url: string, the target url.\n",
|
||||
" :param method: string, the request method, default is GET.\n",
|
||||
" \"\"\"\n",
|
||||
" print(f\"request {url} using {method} method...\")\n",
|
||||
"\n",
|
||||
"request(\"https://sspai.com\")\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 46,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"text/plain": [
|
||||
"<function __main__.monitor.<locals>.wrapper(*args, **kwargs)>"
|
||||
]
|
||||
},
|
||||
"execution_count": 46,
|
||||
"metadata": {},
|
||||
"output_type": "execute_result"
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"request"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 47,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"wrapper\n",
|
||||
"None\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"print(request.__name__)\n",
|
||||
"print(request.__doc__)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"### with wraps function"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 48,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"Monitoring request...\n",
|
||||
"request https://sspai.com using GET method...\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"from functools import wraps\n",
|
||||
"\n",
|
||||
"def monitor(func):\n",
|
||||
" print(f\"Monitoring {func.__name__}...\")\n",
|
||||
"\n",
|
||||
" @wraps(func)\n",
|
||||
" def wrapper(*args, **kwargs):\n",
|
||||
" return func(*args, **kwargs)\n",
|
||||
" return wrapper\n",
|
||||
"\n",
|
||||
"@monitor\n",
|
||||
"def request(url, method=\"GET\"):\n",
|
||||
" \"\"\"Request from target url\n",
|
||||
" :param url: string, the target url.\n",
|
||||
" :param method: string, the request method, default is GET.\n",
|
||||
" \"\"\"\n",
|
||||
" print(f\"request {url} using {method} method...\")\n",
|
||||
"\n",
|
||||
"request(\"https://sspai.com\")"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 49,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"text/plain": [
|
||||
"<function __main__.request(url, method='GET')>"
|
||||
]
|
||||
},
|
||||
"execution_count": 49,
|
||||
"metadata": {},
|
||||
"output_type": "execute_result"
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"request"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 50,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"request\n",
|
||||
"Request from target url\n",
|
||||
" :param url: string, the target url.\n",
|
||||
" :param method: string, the request method, default is GET.\n",
|
||||
" \n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"print(request.__name__)\n",
|
||||
"print(request.__doc__)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": []
|
||||
}
|
||||
],
|
||||
"metadata": {
|
||||
"kernelspec": {
|
||||
"display_name": "Python 3.9.0 ('pandas-startup')",
|
||||
"language": "python",
|
||||
"name": "python3"
|
||||
},
|
||||
"language_info": {
|
||||
"codemirror_mode": {
|
||||
"name": "ipython",
|
||||
"version": 3
|
||||
},
|
||||
"file_extension": ".py",
|
||||
"mimetype": "text/x-python",
|
||||
"name": "python",
|
||||
"nbconvert_exporter": "python",
|
||||
"pygments_lexer": "ipython3",
|
||||
"version": "3.9.0"
|
||||
},
|
||||
"orig_nbformat": 4,
|
||||
"vscode": {
|
||||
"interpreter": {
|
||||
"hash": "13977d4cc82dee5f9d9535ceb495bd0ab12a43c33c664e5f0d53c24cf634b67f"
|
||||
}
|
||||
}
|
||||
},
|
||||
"nbformat": 4,
|
||||
"nbformat_minor": 2
|
||||
}
|
||||
53
code/newsletter/N3/futures_example.py
Normal file
53
code/newsletter/N3/futures_example.py
Normal file
@@ -0,0 +1,53 @@
|
||||
import time
|
||||
from concurrent.futures import ThreadPoolExecutor
|
||||
|
||||
import requests
|
||||
|
||||
|
||||
def timer(func):
|
||||
def wrapper(*args, **kwargs):
|
||||
start = time.perf_counter()
|
||||
func(*args, **kwargs)
|
||||
usage = time.perf_counter() - start
|
||||
return usage
|
||||
|
||||
return wrapper
|
||||
|
||||
|
||||
def fetch(url, method="GET"):
|
||||
resp = requests.request(method=method, url=url)
|
||||
resp.raise_for_status()
|
||||
data = resp.json()
|
||||
return data
|
||||
|
||||
|
||||
@timer
|
||||
def hacking(urls, methods, workers=2):
|
||||
with ThreadPoolExecutor(max_workers=workers) as pool:
|
||||
futures = [
|
||||
pool.submit(fetch, url=url, method=method)
|
||||
for url, method in zip(urls, methods)
|
||||
]
|
||||
_ = [future.result() for future in futures]
|
||||
|
||||
|
||||
@timer
|
||||
def normal(urls, methods):
|
||||
for url, method in zip(urls, methods):
|
||||
fetch(url=url, method=method)
|
||||
|
||||
|
||||
def main():
|
||||
base = "https://httpbin.org/"
|
||||
methods = ["GET", "POST", "PATCH", "DELETE"]
|
||||
urls = [base + method.lower() for method in methods]
|
||||
|
||||
normal_usage = normal(urls, methods)
|
||||
hacking_usage = hacking(urls, methods)
|
||||
|
||||
print(f"normal usage: {normal_usage: .2f}s")
|
||||
print(f"hacking usage: {hacking_usage: .2f}s")
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
19
code/newsletter/N3/futures_map_example.py
Normal file
19
code/newsletter/N3/futures_map_example.py
Normal file
@@ -0,0 +1,19 @@
|
||||
from concurrent.futures import ProcessPoolExecutor
|
||||
|
||||
|
||||
def fib(n):
|
||||
if n <= 1:
|
||||
return n
|
||||
return fib(n - 1) + fib(n - 2)
|
||||
|
||||
|
||||
def main():
|
||||
n = [1, 3, 5, 10, 20]
|
||||
|
||||
with ProcessPoolExecutor(max_workers=4) as pool:
|
||||
result = pool.map(fib, n)
|
||||
print(list(result))
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
304
code/newsletter/N3/itertools.ipynb
Normal file
304
code/newsletter/N3/itertools.ipynb
Normal file
@@ -0,0 +1,304 @@
|
||||
{
|
||||
"cells": [
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"# chain"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 32,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"text/plain": [
|
||||
"[['The', 'Zen', 'of', 'Python,', 'by', 'Tim', 'Peters'],\n",
|
||||
" ['Beautiful', 'is', 'better', 'than', 'ugly.'],\n",
|
||||
" ['Explicit', 'is', 'better', 'than', 'implicit.'],\n",
|
||||
" ['Simple', 'is', 'better', 'than', 'complex.'],\n",
|
||||
" ['Complex', 'is', 'better', 'than', 'complicated.'],\n",
|
||||
" ['Flat', 'is', 'better', 'than', 'nested.'],\n",
|
||||
" ['Sparse', 'is', 'better', 'than', 'dense.'],\n",
|
||||
" ['Readability', 'counts.'],\n",
|
||||
" ['Special',\n",
|
||||
" 'cases',\n",
|
||||
" \"aren't\",\n",
|
||||
" 'special',\n",
|
||||
" 'enough',\n",
|
||||
" 'to',\n",
|
||||
" 'break',\n",
|
||||
" 'the',\n",
|
||||
" 'rules.']]"
|
||||
]
|
||||
},
|
||||
"execution_count": 32,
|
||||
"metadata": {},
|
||||
"output_type": "execute_result"
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"from itertools import chain\n",
|
||||
"poem = \"\"\"\n",
|
||||
"The Zen of Python, by Tim Peters\n",
|
||||
"Beautiful is better than ugly.\n",
|
||||
"Explicit is better than implicit.\n",
|
||||
"Simple is better than complex.\n",
|
||||
"Complex is better than complicated.\n",
|
||||
"Flat is better than nested.\n",
|
||||
"Sparse is better than dense.\n",
|
||||
"Readability counts.\n",
|
||||
"Special cases aren't special enough to break the rules.\n",
|
||||
"Although practicality beats purity.\n",
|
||||
"Errors should never pass silently.\n",
|
||||
"Unless explicitly silenced.\n",
|
||||
"In the face of ambiguity, refuse the temptation to guess.\n",
|
||||
"There should be one-- and preferably only one --obvious way to do it.\n",
|
||||
"Although that way may not be obvious at first unless you're Dutch.\n",
|
||||
"Now is better than never.\n",
|
||||
"Although never is often better than *right* now.\n",
|
||||
"If the implementation is hard to explain, it's a bad idea.\n",
|
||||
"If the implementation is easy to explain, it may be a good idea.\n",
|
||||
"Namespaces are one honking great idea -- let's do more of those!\n",
|
||||
"\"\"\"\n",
|
||||
"\n",
|
||||
"split = [line.split() for line in poem.splitlines()]\n",
|
||||
"split[1:10]"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 33,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"text/plain": [
|
||||
"['Zen', 'of', 'Python,', 'by', 'Tim', 'Peters', 'Beautiful', 'is', 'better']"
|
||||
]
|
||||
},
|
||||
"execution_count": 33,
|
||||
"metadata": {},
|
||||
"output_type": "execute_result"
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"words = list(chain(*[elem for elem in split if elem]))\n",
|
||||
"words[1:10]"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 34,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"text/plain": [
|
||||
"['Zen', 'of', 'Python,', 'by', 'Tim', 'Peters', 'Beautiful', 'is', 'better']"
|
||||
]
|
||||
},
|
||||
"execution_count": 34,
|
||||
"metadata": {},
|
||||
"output_type": "execute_result"
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"words = list(chain.from_iterable(split))\n",
|
||||
"words[1:10]"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"# permutations、product"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 35,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"text/plain": [
|
||||
"1320"
|
||||
]
|
||||
},
|
||||
"execution_count": 35,
|
||||
"metadata": {},
|
||||
"output_type": "execute_result"
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"from itertools import permutations\n",
|
||||
"uppers = \"ABCD\"\n",
|
||||
"lowers = uppers.lower()\n",
|
||||
"numbers = \"1234\"\n",
|
||||
"elements = [*uppers, *lowers, *numbers]\n",
|
||||
"\n",
|
||||
"pairs = list(permutations(elements, 3))\n",
|
||||
"len(pairs)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 36,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"text/plain": [
|
||||
"[('A', 'B', 'D'),\n",
|
||||
" ('A', 'B', 'a'),\n",
|
||||
" ('A', 'B', 'b'),\n",
|
||||
" ('A', 'B', 'c'),\n",
|
||||
" ('A', 'B', 'd'),\n",
|
||||
" ('A', 'B', '1'),\n",
|
||||
" ('A', 'B', '2'),\n",
|
||||
" ('A', 'B', '3'),\n",
|
||||
" ('A', 'B', '4')]"
|
||||
]
|
||||
},
|
||||
"execution_count": 36,
|
||||
"metadata": {},
|
||||
"output_type": "execute_result"
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"pairs[1:10]"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 37,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"text/plain": [
|
||||
"[('A', 'b'),\n",
|
||||
" ('A', 'c'),\n",
|
||||
" ('A', 'd'),\n",
|
||||
" ('B', 'a'),\n",
|
||||
" ('B', 'b'),\n",
|
||||
" ('B', 'c'),\n",
|
||||
" ('B', 'd'),\n",
|
||||
" ('C', 'a'),\n",
|
||||
" ('C', 'b')]"
|
||||
]
|
||||
},
|
||||
"execution_count": 37,
|
||||
"metadata": {},
|
||||
"output_type": "execute_result"
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"from itertools import product\n",
|
||||
"\n",
|
||||
"pairs = list(product(uppers, lowers))\n",
|
||||
"pairs[1:10]"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## repeat、cycle"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 38,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"text/plain": [
|
||||
"['ABCD', 'ABCD', 'ABCD']"
|
||||
]
|
||||
},
|
||||
"execution_count": 38,
|
||||
"metadata": {},
|
||||
"output_type": "execute_result"
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"from itertools import repeat\n",
|
||||
"uppers = \"ABCD\"\n",
|
||||
"\n",
|
||||
"more = list(repeat(uppers, times=3))\n",
|
||||
"more"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 39,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"['A', 'B', 'C', 'D', 'A', 'B']\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"from itertools import cycle\n",
|
||||
"\n",
|
||||
"uppers = \"ABCD\"\n",
|
||||
"more = cycle(uppers)\n",
|
||||
"counter = 0\n",
|
||||
"result = []\n",
|
||||
"\n",
|
||||
"for letter in more:\n",
|
||||
" if counter <= 5:\n",
|
||||
" result.append(letter)\n",
|
||||
" counter += 1\n",
|
||||
" continue\n",
|
||||
" break\n",
|
||||
"\n",
|
||||
"print(result)\n",
|
||||
" "
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": []
|
||||
}
|
||||
],
|
||||
"metadata": {
|
||||
"kernelspec": {
|
||||
"display_name": "Python 3.9.0 ('pandas-startup')",
|
||||
"language": "python",
|
||||
"name": "python3"
|
||||
},
|
||||
"language_info": {
|
||||
"codemirror_mode": {
|
||||
"name": "ipython",
|
||||
"version": 3
|
||||
},
|
||||
"file_extension": ".py",
|
||||
"mimetype": "text/x-python",
|
||||
"name": "python",
|
||||
"nbconvert_exporter": "python",
|
||||
"pygments_lexer": "ipython3",
|
||||
"version": "3.9.0"
|
||||
},
|
||||
"orig_nbformat": 4,
|
||||
"vscode": {
|
||||
"interpreter": {
|
||||
"hash": "13977d4cc82dee5f9d9535ceb495bd0ab12a43c33c664e5f0d53c24cf634b67f"
|
||||
}
|
||||
}
|
||||
},
|
||||
"nbformat": 4,
|
||||
"nbformat_minor": 2
|
||||
}
|
||||
169
code/newsletter/N3/pathlib.ipynb
Normal file
169
code/newsletter/N3/pathlib.ipynb
Normal file
@@ -0,0 +1,169 @@
|
||||
{
|
||||
"cells": [
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 1,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"import pathlib\n",
|
||||
"path = pathlib.Path(\"~/Desktop/faker.py\").expanduser()"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 2,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"text/plain": [
|
||||
"PosixPath('/Users/Bobot/Desktop')"
|
||||
]
|
||||
},
|
||||
"execution_count": 2,
|
||||
"metadata": {},
|
||||
"output_type": "execute_result"
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"path.parent"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 3,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"text/plain": [
|
||||
"'.py'"
|
||||
]
|
||||
},
|
||||
"execution_count": 3,
|
||||
"metadata": {},
|
||||
"output_type": "execute_result"
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"path.suffix"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 4,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"text/plain": [
|
||||
"'faker.py'"
|
||||
]
|
||||
},
|
||||
"execution_count": 4,
|
||||
"metadata": {},
|
||||
"output_type": "execute_result"
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"path.name"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 5,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"# os version\n",
|
||||
"\n",
|
||||
"# import os\n",
|
||||
"\n",
|
||||
"# ROOT = os.path.expanduser(\"~/Desktop/test\")\n",
|
||||
"# file = os.path.join(str(ROOT), \"prime.txt\")\n",
|
||||
"\n",
|
||||
"# if not os.path.exists(file):\n",
|
||||
"# os.mkdir(ROOT)\n",
|
||||
"# with open(file, mode=\"w+\", encoding=\"utf-8\") as f:\n",
|
||||
"# f.write(\"Hello, World!\")\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 6,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"import pathlib\n",
|
||||
"\n",
|
||||
"file = pathlib.Path(\"~/Desktop/test\").expanduser().joinpath(\"prime.txt\")\n",
|
||||
"if not file.exists():\n",
|
||||
" file.parent.mkdir(parents=True, exist_ok=True)\n",
|
||||
" file.write_text(\"Hello, World!\", encoding=\"utf-8\")"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 7,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"text/plain": [
|
||||
"PosixPath('/Users/Bobot/Desktop/test/echo.md')"
|
||||
]
|
||||
},
|
||||
"execution_count": 7,
|
||||
"metadata": {},
|
||||
"output_type": "execute_result"
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"file = (\n",
|
||||
" pathlib.Path(\"~/Desktop/test\")\n",
|
||||
" .expanduser()\n",
|
||||
" .joinpath(\"prime.txt\")\n",
|
||||
" .with_stem(\"echo\")\n",
|
||||
" .with_suffix(\".md\")\n",
|
||||
")\n",
|
||||
"\n",
|
||||
"file\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": []
|
||||
}
|
||||
],
|
||||
"metadata": {
|
||||
"kernelspec": {
|
||||
"display_name": "Python 3.9.0 ('pandas-startup')",
|
||||
"language": "python",
|
||||
"name": "python3"
|
||||
},
|
||||
"language_info": {
|
||||
"codemirror_mode": {
|
||||
"name": "ipython",
|
||||
"version": 3
|
||||
},
|
||||
"file_extension": ".py",
|
||||
"mimetype": "text/x-python",
|
||||
"name": "python",
|
||||
"nbconvert_exporter": "python",
|
||||
"pygments_lexer": "ipython3",
|
||||
"version": "3.9.0"
|
||||
},
|
||||
"orig_nbformat": 4,
|
||||
"vscode": {
|
||||
"interpreter": {
|
||||
"hash": "13977d4cc82dee5f9d9535ceb495bd0ab12a43c33c664e5f0d53c24cf634b67f"
|
||||
}
|
||||
}
|
||||
},
|
||||
"nbformat": 4,
|
||||
"nbformat_minor": 2
|
||||
}
|
||||
58
code/newsletter/N3/threading_example.py
Normal file
58
code/newsletter/N3/threading_example.py
Normal file
@@ -0,0 +1,58 @@
|
||||
import threading
|
||||
import time
|
||||
|
||||
import requests
|
||||
|
||||
|
||||
def timer(func):
|
||||
def wrapper(*args, **kwargs):
|
||||
start = time.perf_counter()
|
||||
func(*args, **kwargs)
|
||||
usage = time.perf_counter() - start
|
||||
return usage
|
||||
|
||||
return wrapper
|
||||
|
||||
|
||||
def fetch(url, method="GET"):
|
||||
resp = requests.request(method=method, url=url)
|
||||
resp.raise_for_status()
|
||||
data = resp.json()
|
||||
return data
|
||||
|
||||
|
||||
@timer
|
||||
def hacking(urls, methods):
|
||||
threads = []
|
||||
for url, method in zip(urls, methods):
|
||||
thread = threading.Thread(
|
||||
target=fetch,
|
||||
kwargs=dict(url=url, method=method),
|
||||
)
|
||||
threads.append(thread)
|
||||
thread.start()
|
||||
|
||||
for thread in threads:
|
||||
thread.join()
|
||||
|
||||
|
||||
@timer
|
||||
def normal(urls, methods):
|
||||
for url, method in zip(urls, methods):
|
||||
fetch(url=url, method=method)
|
||||
|
||||
|
||||
def main():
|
||||
base = "https://httpbin.org/"
|
||||
methods = ["GET", "POST", "PATCH", "DELETE"]
|
||||
urls = [base + method.lower() for method in methods]
|
||||
|
||||
normal_usage = normal(urls, methods)
|
||||
hacking_usage = hacking(urls, methods)
|
||||
|
||||
print(f"normal usage: {normal_usage: .2f}s")
|
||||
print(f"hacking usage: {hacking_usage: .2f}s")
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
Reference in New Issue
Block a user