You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
2519 lines
216 KiB
2519 lines
216 KiB
<!DOCTYPE html>
|
|
<html class="ocks-org do-not-copy">
|
|
|
|
<head>
|
|
<meta charset="utf-8">
|
|
<meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1" />
|
|
<title>Comprehensive Python Cheatsheet</title>
|
|
<meta name="description" content="Exhaustive, simple, beautiful and concise. A truly pythonic cheat sheet about Python programming language.">
|
|
<link rel="icon" href="web/favicon.png">
|
|
<link rel="stylesheet" href="web/default.min.css">
|
|
<link href="https://netdna.bootstrapcdn.com/font-awesome/3.2.1/css/font-awesome.css" rel="stylesheet">
|
|
<meta name="twitter:card" content="summary">
|
|
<meta name="twitter:title" content="Comprehensive Python Cheatsheet">
|
|
<meta name="twitter:description" content="Exhaustive, simple, beautiful and concise. A truly pythonic cheat sheet about Python programming language.">
|
|
<meta name="twitter:image" content="https://gto76.github.io/python-cheatsheet/web/image_twitter_card_2.jpeg">
|
|
<meta name="google-site-verification" content="w3rvuG0D1kUm_w20qsJecSEZh59Am8jK4eSPVU83e_M" />
|
|
</head>
|
|
|
|
<style>
|
|
@import url(web/style.css);
|
|
|
|
.join,
|
|
.link,
|
|
.node rect {
|
|
fill: none;
|
|
stroke: #636363;
|
|
stroke-width: 1.5px;
|
|
}
|
|
|
|
.link {
|
|
stroke: #969696;
|
|
}
|
|
|
|
.node rect {
|
|
fill: white;
|
|
}
|
|
|
|
.link path,
|
|
.node rect,
|
|
.node text,
|
|
.join {
|
|
-webkit-transition: stroke-opacity 500ms linear, fill-opacity 500ms linear;
|
|
-moz-transition: stroke-opacity 500ms linear, fill-opacity 500ms linear;
|
|
-ms-transition: stroke-opacity 500ms linear, fill-opacity 500ms linear;
|
|
-o-transition: stroke-opacity 500ms linear, fill-opacity 500ms linear;
|
|
transition: stroke-opacity 500ms linear, fill-opacity 500ms linear;
|
|
}
|
|
|
|
.node .element rect {
|
|
fill: #bdbdbd;
|
|
stroke: none;
|
|
}
|
|
|
|
.node .null rect {
|
|
fill: none;
|
|
stroke: none;
|
|
}
|
|
|
|
.node .null text {
|
|
fill: #636363;
|
|
}
|
|
|
|
.node .selection rect {
|
|
stroke: #e6550d;
|
|
}
|
|
|
|
.node .data rect {
|
|
stroke: #3182bd;
|
|
}
|
|
|
|
.node .datum rect {
|
|
fill: #d9d9d9;
|
|
stroke: none;
|
|
}
|
|
|
|
.node .code text {
|
|
font-family: monospace;
|
|
}
|
|
|
|
.node .key rect {
|
|
fill: #a1d99b;
|
|
stroke: none;
|
|
}
|
|
|
|
.link .to-key,
|
|
.join {
|
|
stroke: #a1d99b;
|
|
}
|
|
|
|
.join {
|
|
stroke-dasharray: 2,2;
|
|
}
|
|
|
|
.link .to-null {
|
|
stroke-dasharray: .5,3.5;
|
|
stroke-linecap: round;
|
|
}
|
|
|
|
.link .from-data {
|
|
stroke: #3182bd;
|
|
}
|
|
|
|
.play circle {
|
|
fill: #fff;
|
|
stroke: #000;
|
|
stroke-width: 3px;
|
|
}
|
|
|
|
.play:hover path {
|
|
fill: #f00;
|
|
}
|
|
|
|
.play.mousedown circle {
|
|
fill: #f00;
|
|
}
|
|
|
|
.play.mousedown path {
|
|
fill: #fff;
|
|
}
|
|
|
|
.play rect {
|
|
fill: none;
|
|
pointer-events: all;
|
|
cursor: pointer;
|
|
}
|
|
|
|
code span {
|
|
-webkit-transition: background 250ms linear;
|
|
-moz-transition: background 250ms linear;
|
|
-ms-transition: background 250ms linear;
|
|
-o-transition: background 250ms linear;
|
|
transition: background 250ms linear;
|
|
}
|
|
|
|
pre.prettyprint, code.prettyprint {
|
|
background-color: #222;
|
|
border-radius: 8px;
|
|
font-size: 15px;
|
|
}
|
|
|
|
pre.prettyprint {
|
|
width: 90%;
|
|
margin: 0.5em;
|
|
padding: 1em;
|
|
white-space: pre-wrap;
|
|
}
|
|
|
|
#return-to-top {
|
|
position: fixed;
|
|
bottom: 20px;
|
|
right: 20px;
|
|
background: rgb(0, 0, 0);
|
|
background: rgba(0, 0, 0, 0.2);
|
|
width: 50px;
|
|
height: 50px;
|
|
display: block;
|
|
text-decoration: none;
|
|
-webkit-border-radius: 35px;
|
|
-moz-border-radius: 35px;
|
|
border-radius: 35px;
|
|
display: none;
|
|
-webkit-transition: all 0.3s linear;
|
|
-moz-transition: all 0.3s ease;
|
|
-ms-transition: all 0.3s ease;
|
|
-o-transition: all 0.3s ease;
|
|
transition: all 0.3s ease;
|
|
}
|
|
|
|
#return-to-top i {
|
|
color: #fff;
|
|
margin: 0;
|
|
position: relative;
|
|
left: 16px;
|
|
top: 13px;
|
|
font-size: 19px;
|
|
-webkit-transition: all 0.3s ease;
|
|
-moz-transition: all 0.3s ease;
|
|
-ms-transition: all 0.3s ease;
|
|
-o-transition: all 0.3s ease;
|
|
transition: all 0.3s ease;
|
|
}
|
|
|
|
#return-to-top:hover {
|
|
background: rgba(0, 0, 0, 0.35);
|
|
}
|
|
|
|
#return-to-top:hover i {
|
|
color: #f0f0f0;
|
|
}
|
|
|
|
@media print {
|
|
.pagebreak {
|
|
page-break-before: always;
|
|
}
|
|
div {
|
|
page-break-inside: avoid;
|
|
}
|
|
pre {
|
|
page-break-inside: avoid;
|
|
}
|
|
}
|
|
</style>
|
|
|
|
<body>
|
|
<header>
|
|
<aside>December 15, 2019</aside>
|
|
<a href="../" rel="author">Jure Šorn</a>
|
|
</header>
|
|
|
|
<a href="javascript:" id="return-to-top"><i class="icon-chevron-up"></i></a>
|
|
<div><h1 id="comprehensivepythoncheatsheet">Comprehensive Python Cheatsheet</h1><p class="banner"><sup><a href="https://raw.githubusercontent.com/gto76/python-cheatsheet/master/README.md">Download text file</a>, <a href="https://transactions.sendowl.com/products/78175486/4422834F/view">Buy PDF</a>, <a href="https://github.com/gto76/python-cheatsheet">Fork me on GitHub</a> or <a href="https://github.com/gto76/python-cheatsheet/wiki/Frequently-Asked-Questions">Check out FAQ</a>.
|
|
</sup></p><p class="banner"><img src="web/image_888.jpeg" alt="Monty Python"></p><br><div><h2 id="toc"><a href="#toc" name="toc">#</a>Contents</h2><pre><code class="hljs bash"><strong>ToC</strong> = {
|
|
<strong><span class="hljs-string"><span class="hljs-string">'1. Collections'</span></span></strong>: [<a href="#list">List</a>, <a href="#dictionary">Dictionary</a>, <a href="#set">Set</a>, <a href="#tuple">Tuple</a>, <a href="#range">Range</a>, <a href="#enumerate">Enumerate</a>, <a href="#iterator">Iterator</a>, <a href="#generator">Generator</a>],
|
|
<strong><span class="hljs-string"><span class="hljs-string">'2. Types'</span></span></strong>: [<a href="#type">Type</a>, <a href="#string">String</a>, <a href="#regex">Regular_Exp</a>, <a href="#format">Format</a>, <a href="#numbers">Numbers</a>, <a href="#combinatorics">Combinatorics</a>, <a href="#datetime">Datetime</a>],
|
|
<strong><span class="hljs-string"><span class="hljs-string">'3. Syntax'</span></span></strong>: [<a href="#arguments">Args</a>, <a href="#inline">Inline</a>, <a href="#closure">Closure</a>, <a href="#decorator">Decorator</a>, <a href="#class">Class</a>, <a href="#ducktypes">Duck_Types</a>, <a href="#enum">Enum</a>, <a href="#exceptions">Exceptions</a>],
|
|
<strong><span class="hljs-string"><span class="hljs-string">'4. System'</span></span></strong>: [<a href="#print">Print</a>, <a href="#input">Input</a>, <a href="#commandlinearguments">Command_Line_Arguments</a>, <a href="#open">Open</a>, <a href="#path">Path</a>, <a href="#oscommands">Command_Execution</a>],
|
|
<strong><span class="hljs-string"><span class="hljs-string">'5. Data'</span></span></strong>: [<a href="#json">JSON</a>, <a href="#pickle">Pickle</a>, <a href="#csv">CSV</a>, <a href="#sqlite">SQLite</a>, <a href="#bytes">Bytes</a>, <a href="#struct">Struct</a>, <a href="#array">Array</a>, <a href="#memoryview">MemoryView</a>, <a href="#deque">Deque</a>],
|
|
<strong><span class="hljs-string"><span class="hljs-string">'6. Advanced'</span></span></strong>: [<a href="#threading">Threading</a>, <a href="#operator">Operator</a>, <a href="#introspection">Introspection</a>, <a href="#metaprograming">Metaprograming</a>, <a href="#eval">Eval</a>, <a href="#coroutines">Coroutine</a>],
|
|
<strong><span class="hljs-string"><span class="hljs-string">'7. Libraries'</span></span></strong>: [<a href="#progressbar">Progress_Bar</a>, <a href="#plot">Plot</a>, <a href="#table">Table</a>, <a href="#curses">Curses</a>, <a href="#logging">Logging</a>, <a href="#scraping">Scraping</a>, <a href="#web">Web</a>, <a href="#profiling">Profile</a>,
|
|
<a href="#numpy">NumPy</a>, <a href="#image">Image</a>, <a href="#animation">Animation</a>, <a href="#audio">Audio</a>]
|
|
}
|
|
</code></pre></div></div>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<div><h2 id="main"><a href="#main" name="main">#</a>Main</h2><pre><code class="python language-python hljs"><span class="hljs-keyword">if</span> __name__ == <span class="hljs-string">'__main__'</span>: <span class="hljs-comment"># Runs main() if file wasn't imported.</span>
|
|
main()
|
|
</code></pre></div>
|
|
|
|
<div><h2 id="list"><a href="#list" name="list">#</a>List</h2><pre><code class="python language-python hljs"><list> = <list>[from_inclusive : to_exclusive : ±step_size]
|
|
</code></pre></div>
|
|
|
|
<pre><code class="python language-python hljs"><list>.append(<el>) <span class="hljs-comment"># Or: <list> += [<el>]</span>
|
|
<list>.extend(<collection>) <span class="hljs-comment"># Or: <list> += <collection></span>
|
|
</code></pre>
|
|
<pre><code class="python language-python hljs"><list>.sort()
|
|
<list>.reverse()
|
|
<list> = sorted(<collection>)
|
|
<iter> = reversed(<list>)
|
|
</code></pre>
|
|
<pre><code class="python language-python hljs">sum_of_elements = sum(<collection>)
|
|
elementwise_sum = [sum(pair) <span class="hljs-keyword">for</span> pair <span class="hljs-keyword">in</span> zip(list_a, list_b)]
|
|
sorted_by_second = sorted(<collection>, key=<span class="hljs-keyword">lambda</span> el: el[<span class="hljs-number">1</span>])
|
|
sorted_by_both = sorted(<collection>, key=<span class="hljs-keyword">lambda</span> el: (el[<span class="hljs-number">1</span>], el[<span class="hljs-number">0</span>]))
|
|
flatter_list = list(itertools.chain.from_iterable(<list>))
|
|
product_of_elems = functools.reduce(<span class="hljs-keyword">lambda</span> out, x: out * x, <collection>)
|
|
list_of_chars = list(<str>)
|
|
</code></pre>
|
|
<ul>
|
|
<li><strong>Check out module <a href="#operator">operator</a> for alternative versions of examples.</strong></li>
|
|
</ul>
|
|
<pre><code class="python language-python hljs"><int> = <list>.count(<el>) <span class="hljs-comment"># Returns number of occurrences. Also works on strings.</span>
|
|
index = <list>.index(<el>) <span class="hljs-comment"># Returns index of first occurrence or raises ValueError.</span>
|
|
<list>.insert(index, <el>) <span class="hljs-comment"># Inserts item at index and moves the rest to the right.</span>
|
|
<el> = <list>.pop([index]) <span class="hljs-comment"># Removes and returns item at index or from the end.</span>
|
|
<list>.remove(<el>) <span class="hljs-comment"># Removes first occurrence of item or raises ValueError.</span>
|
|
<list>.clear() <span class="hljs-comment"># Removes all items. Also works on dictionary and set.</span>
|
|
</code></pre>
|
|
<div><h2 id="dictionary"><a href="#dictionary" name="dictionary">#</a>Dictionary</h2><pre><code class="python language-python hljs"><view> = <dict>.keys() <span class="hljs-comment"># Coll. of keys that reflects changes.</span>
|
|
<view> = <dict>.values() <span class="hljs-comment"># Coll. of values that reflects changes.</span>
|
|
<view> = <dict>.items() <span class="hljs-comment"># Coll. of key-value tuples that reflects chgs.</span>
|
|
</code></pre></div>
|
|
|
|
<pre><code class="python language-python hljs">value = <dict>.get(key, default=<span class="hljs-keyword">None</span>) <span class="hljs-comment"># Returns default if key is missing.</span>
|
|
value = <dict>.setdefault(key, default=<span class="hljs-keyword">None</span>) <span class="hljs-comment"># Returns and writes default if key is missing.</span>
|
|
<dict> = collections.defaultdict(<type>) <span class="hljs-comment"># Creates a dict with default value of type.</span>
|
|
<dict> = collections.defaultdict(<span class="hljs-keyword">lambda</span>: <span class="hljs-number">1</span>) <span class="hljs-comment"># Creates a dict with default value 1.</span>
|
|
</code></pre>
|
|
<pre><code class="python language-python hljs"><dict> = dict(<collection>) <span class="hljs-comment"># Creates a dict from coll. of key-value pairs.</span>
|
|
<dict> = dict(zip(keys, values)) <span class="hljs-comment"># Creates a dict from two collections.</span>
|
|
<dict> = dict.fromkeys(keys [, value]) <span class="hljs-comment"># Creates a dict from collection of keys.</span>
|
|
</code></pre>
|
|
<pre><code class="python language-python hljs"><dict>.update(<dict>) <span class="hljs-comment"># Adds items. Replaces ones with matching keys.</span>
|
|
value = <dict>.pop(key) <span class="hljs-comment"># Removes item or raises KeyError.</span>
|
|
{k <span class="hljs-keyword">for</span> k, v <span class="hljs-keyword">in</span> <dict>.items() <span class="hljs-keyword">if</span> v == value} <span class="hljs-comment"># Returns set of keys that point to the value.</span>
|
|
{k: v <span class="hljs-keyword">for</span> k, v <span class="hljs-keyword">in</span> <dict>.items() <span class="hljs-keyword">if</span> k <span class="hljs-keyword">in</span> keys} <span class="hljs-comment"># Returns a dictionary, filtered by keys.</span>
|
|
</code></pre>
|
|
<div><h3 id="counter">Counter</h3><pre><code class="python language-python hljs"><span class="hljs-meta">>>> </span><span class="hljs-keyword">from</span> collections <span class="hljs-keyword">import</span> Counter
|
|
<span class="hljs-meta">>>> </span>colors = [<span class="hljs-string">'blue'</span>, <span class="hljs-string">'red'</span>, <span class="hljs-string">'blue'</span>, <span class="hljs-string">'red'</span>, <span class="hljs-string">'blue'</span>]
|
|
<span class="hljs-meta">>>> </span>counter = Counter(colors)
|
|
<span class="hljs-meta">>>> </span>counter[<span class="hljs-string">'yellow'</span>] += <span class="hljs-number">1</span>
|
|
Counter({<span class="hljs-string">'blue'</span>: <span class="hljs-number">3</span>, <span class="hljs-string">'red'</span>: <span class="hljs-number">2</span>, <span class="hljs-string">'yellow'</span>: <span class="hljs-number">1</span>})
|
|
<span class="hljs-meta">>>> </span>counter.most_common()[<span class="hljs-number">0</span>]
|
|
(<span class="hljs-string">'blue'</span>, <span class="hljs-number">3</span>)
|
|
</code></pre></div>
|
|
|
|
<div><h2 id="set"><a href="#set" name="set">#</a>Set</h2><pre><code class="python language-python hljs"><set> = set()
|
|
</code></pre></div>
|
|
|
|
<pre><code class="python language-python hljs"><set>.add(<el>) <span class="hljs-comment"># Or: <set> |= {<el>}</span>
|
|
<set>.update(<collection>) <span class="hljs-comment"># Or: <set> |= <set></span>
|
|
</code></pre>
|
|
<pre><code class="python language-python hljs"><set> = <set>.union(<coll.>) <span class="hljs-comment"># Or: <set> | <set></span>
|
|
<set> = <set>.intersection(<coll.>) <span class="hljs-comment"># Or: <set> & <set></span>
|
|
<set> = <set>.difference(<coll.>) <span class="hljs-comment"># Or: <set> - <set></span>
|
|
<set> = <set>.symmetric_difference(<coll.>) <span class="hljs-comment"># Or: <set> ^ <set></span>
|
|
<bool> = <set>.issubset(<coll.>) <span class="hljs-comment"># Or: <set> <= <set></span>
|
|
<bool> = <set>.issuperset(<coll.>) <span class="hljs-comment"># Or: <set> >= <set></span>
|
|
</code></pre>
|
|
<pre><code class="python language-python hljs"><el> = <set>.pop() <span class="hljs-comment"># Raises KeyError if empty.</span>
|
|
<set>.remove(<el>) <span class="hljs-comment"># Raises KeyError if missing.</span>
|
|
<set>.discard(<el>) <span class="hljs-comment"># Doesn't raise an error.</span>
|
|
</code></pre>
|
|
<div><h3 id="frozenset">Frozen Set</h3><ul>
|
|
<li><strong>Is immutable and hashable.</strong></li>
|
|
<li><strong>That means it can be used as a key in a dictionary or as an element in a set.</strong></li>
|
|
</ul><pre><code class="python language-python hljs"><frozenset> = frozenset(<collection>)
|
|
</code></pre></div>
|
|
|
|
|
|
<div><h2 id="tuple"><a href="#tuple" name="tuple">#</a>Tuple</h2><p><strong>Tuple is an immutable and hashable list.</strong></p><pre><code class="python language-python hljs"><tuple> = ()
|
|
<tuple> = (<el>, )
|
|
<tuple> = (<el_1>, <el_2> [, ...])
|
|
</code></pre></div>
|
|
|
|
|
|
<div><h3 id="namedtuple">Named Tuple</h3><p><strong>Tuple's subclass with named elements.</strong></p><pre><code class="python language-python hljs"><span class="hljs-meta">>>> </span><span class="hljs-keyword">from</span> collections <span class="hljs-keyword">import</span> namedtuple
|
|
<span class="hljs-meta">>>> </span>Point = namedtuple(<span class="hljs-string">'Point'</span>, <span class="hljs-string">'x y'</span>)
|
|
<span class="hljs-meta">>>> </span>p = Point(<span class="hljs-number">1</span>, y=<span class="hljs-number">2</span>)
|
|
Point(x=<span class="hljs-number">1</span>, y=<span class="hljs-number">2</span>)
|
|
<span class="hljs-meta">>>> </span>p[<span class="hljs-number">0</span>]
|
|
<span class="hljs-number">1</span>
|
|
<span class="hljs-meta">>>> </span>p.x
|
|
<span class="hljs-number">1</span>
|
|
<span class="hljs-meta">>>> </span>getattr(p, <span class="hljs-string">'y'</span>)
|
|
<span class="hljs-number">2</span>
|
|
<span class="hljs-meta">>>> </span>p._fields <span class="hljs-comment"># Or: Point._fields</span>
|
|
(<span class="hljs-string">'x'</span>, <span class="hljs-string">'y'</span>)
|
|
</code></pre></div>
|
|
|
|
|
|
<div><h2 id="range"><a href="#range" name="range">#</a>Range</h2><pre><code class="python language-python hljs"><range> = range(to_exclusive)
|
|
<range> = range(from_inclusive, to_exclusive)
|
|
<range> = range(from_inclusive, to_exclusive, ±step_size)
|
|
</code></pre></div>
|
|
|
|
<pre><code class="python language-python hljs">from_inclusive = <range>.start
|
|
to_exclusive = <range>.stop
|
|
</code></pre>
|
|
<div><h2 id="enumerate"><a href="#enumerate" name="enumerate">#</a>Enumerate</h2><pre><code class="python language-python hljs"><span class="hljs-keyword">for</span> i, el <span class="hljs-keyword">in</span> enumerate(<collection> [, i_start]):
|
|
...
|
|
</code></pre></div>
|
|
|
|
<div><h2 id="iterator"><a href="#iterator" name="iterator">#</a>Iterator</h2><pre><code class="python language-python hljs"><iter> = iter(<collection>) <span class="hljs-comment"># `iter(<iter>)` returns unmodified iterator.</span>
|
|
<iter> = iter(<function>, to_exclusive) <span class="hljs-comment"># A sequence of return values until 'to_exclusive'.</span>
|
|
<el> = next(<iter> [, default]) <span class="hljs-comment"># Raises StopIteration or returns 'default' on end.</span>
|
|
<list> = list(<iter>) <span class="hljs-comment"># Returns a list of iterator's remaining elements.</span>
|
|
</code></pre></div>
|
|
|
|
<div><h3 id="itertools">Itertools</h3><pre><code class="python language-python hljs"><span class="hljs-keyword">from</span> itertools <span class="hljs-keyword">import</span> count, repeat, cycle, chain, islice
|
|
</code></pre></div>
|
|
|
|
<pre><code class="python language-python hljs"><iter> = count(start=<span class="hljs-number">0</span>, step=<span class="hljs-number">1</span>) <span class="hljs-comment"># Returns incremented value endlessly.</span>
|
|
<iter> = repeat(<el> [, times]) <span class="hljs-comment"># Returns element endlessly or 'times' times.</span>
|
|
<iter> = cycle(<collection>) <span class="hljs-comment"># Repeats the sequence endlessly.</span>
|
|
</code></pre>
|
|
<pre><code class="python language-python hljs"><iter> = chain(<coll_1>, <coll_2> [, ...]) <span class="hljs-comment"># Empties collections in order.</span>
|
|
<iter> = chain.from_iterable(<collection>) <span class="hljs-comment"># Empties collections inside a collection in order.</span>
|
|
</code></pre>
|
|
<pre><code class="python language-python hljs"><iter> = islice(<collection>, to_exclusive)
|
|
<iter> = islice(<collection>, from_inclusive, to_exclusive [, +step_size])
|
|
</code></pre>
|
|
<div><h2 id="generator"><a href="#generator" name="generator">#</a>Generator</h2><ul>
|
|
<li><strong>Any function that contains a yield statement returns a generator.</strong></li>
|
|
<li><strong>Generators and iterators are interchangeable.</strong></li>
|
|
</ul><pre><code class="python language-python hljs"><span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">count</span><span class="hljs-params">(start, step)</span>:</span>
|
|
<span class="hljs-keyword">while</span> <span class="hljs-keyword">True</span>:
|
|
<span class="hljs-keyword">yield</span> start
|
|
start += step
|
|
</code></pre></div>
|
|
|
|
|
|
<pre><code class="python language-python hljs"><span class="hljs-meta">>>> </span>counter = count(<span class="hljs-number">10</span>, <span class="hljs-number">2</span>)
|
|
<span class="hljs-meta">>>> </span>next(counter), next(counter), next(counter)
|
|
(<span class="hljs-number">10</span>, <span class="hljs-number">12</span>, <span class="hljs-number">14</span>)
|
|
</code></pre>
|
|
<div><h2 id="type"><a href="#type" name="type">#</a>Type</h2><ul>
|
|
<li><strong>Everything is an object.</strong></li>
|
|
<li><strong>Every object has a type.</strong></li>
|
|
<li><strong>Type and class are synonymous.</strong></li>
|
|
</ul><pre><code class="python language-python hljs"><type> = type(<el>) <span class="hljs-comment"># Or: <el>.__class__</span>
|
|
<bool> = isinstance(<el>, <type>) <span class="hljs-comment"># Or: issubclass(type(<el>), <type>)</span>
|
|
</code></pre></div>
|
|
|
|
|
|
<pre><code class="python language-python hljs"><span class="hljs-meta">>>> </span>type(<span class="hljs-string">'a'</span>), <span class="hljs-string">'a'</span>.__class__, str
|
|
(<<span class="hljs-class"><span class="hljs-title">class</span> '<span class="hljs-title">str</span>'>, <<span class="hljs-title">class</span> '<span class="hljs-title">str</span>'>, <<span class="hljs-title">class</span> '<span class="hljs-title">str</span>'>)
|
|
</span></code></pre>
|
|
<div><h4 id="sometypesdonothavebuiltinnamessotheymustbeimported">Some types do not have built-in names, so they must be imported:</h4><pre><code class="python language-python hljs"><span class="hljs-keyword">from</span> types <span class="hljs-keyword">import</span> FunctionType, MethodType, LambdaType, GeneratorType
|
|
</code></pre></div>
|
|
|
|
<div><h3 id="abc">ABC</h3><p><strong>An abstract base class introduces virtual subclasses that don’t inherit from it, but are still recognized by isinstance() and issubclass().</strong></p><pre><code class="python language-python hljs"><span class="hljs-meta">>>> </span><span class="hljs-keyword">from</span> collections.abc <span class="hljs-keyword">import</span> Sequence, Collection, Iterable
|
|
<span class="hljs-meta">>>> </span>isinstance([<span class="hljs-number">1</span>, <span class="hljs-number">2</span>, <span class="hljs-number">3</span>], Iterable)
|
|
<span class="hljs-keyword">True</span>
|
|
</code></pre></div>
|
|
|
|
|
|
<pre><code class="text language-text">+------------------+------------+------------+------------+
|
|
| | Sequence | Collection | Iterable |
|
|
+------------------+------------+------------+------------+
|
|
| list, range, str | yes | yes | yes |
|
|
| dict, set | | yes | yes |
|
|
| iter | | | yes |
|
|
+------------------+------------+------------+------------+
|
|
</code></pre>
|
|
<pre><code class="python language-python hljs"><span class="hljs-meta">>>> </span><span class="hljs-keyword">from</span> numbers <span class="hljs-keyword">import</span> Integral, Rational, Real, Complex, Number
|
|
<span class="hljs-meta">>>> </span>isinstance(<span class="hljs-number">123</span>, Number)
|
|
<span class="hljs-keyword">True</span>
|
|
</code></pre>
|
|
<pre><code class="text language-text">+--------------------+----------+----------+----------+----------+----------+
|
|
| | Integral | Rational | Real | Complex | Number |
|
|
+--------------------+----------+----------+----------+----------+----------+
|
|
| int | yes | yes | yes | yes | yes |
|
|
| fractions.Fraction | | yes | yes | yes | yes |
|
|
| float | | | yes | yes | yes |
|
|
| complex | | | | yes | yes |
|
|
| decimal.Decimal | | | | | yes |
|
|
+--------------------+----------+----------+----------+----------+----------+
|
|
</code></pre>
|
|
<div><h2 id="string"><a href="#string" name="string">#</a>String</h2><pre><code class="python language-python hljs"><str> = <str>.strip() <span class="hljs-comment"># Strips all whitespace characters from both ends.</span>
|
|
<str> = <str>.strip(<span class="hljs-string">'<chars>'</span>) <span class="hljs-comment"># Strips all passed characters from both ends.</span>
|
|
</code></pre></div>
|
|
|
|
<pre><code class="python language-python hljs"><list> = <str>.split() <span class="hljs-comment"># Splits on one or more whitespace characters.</span>
|
|
<list> = <str>.split(sep=<span class="hljs-keyword">None</span>, maxsplit=<span class="hljs-number">-1</span>) <span class="hljs-comment"># Splits on 'sep' str at most 'maxsplit' times.</span>
|
|
<list> = <str>.splitlines(keepends=<span class="hljs-keyword">False</span>) <span class="hljs-comment"># Splits on line breaks. Keeps them if 'keepends'.</span>
|
|
<str> = <str>.join(<coll_of_strings>) <span class="hljs-comment"># Joins elements using string as separator.</span>
|
|
</code></pre>
|
|
<pre><code class="python language-python hljs"><bool> = <sub_str> <span class="hljs-keyword">in</span> <str> <span class="hljs-comment"># Checks if string contains a substring.</span>
|
|
<bool> = <str>.startswith(<sub_str>) <span class="hljs-comment"># Pass tuple of strings for multiple options.</span>
|
|
<bool> = <str>.endswith(<sub_str>) <span class="hljs-comment"># Pass tuple of strings for multiple options.</span>
|
|
<int> = <str>.find(<sub_str>) <span class="hljs-comment"># Returns start index of first match or -1.</span>
|
|
<int> = <str>.index(<sub_str>) <span class="hljs-comment"># Same but raises ValueError if missing.</span>
|
|
</code></pre>
|
|
<pre><code class="python language-python hljs"><str> = <str>.replace(old, new [, count]) <span class="hljs-comment"># Replaces 'old' with 'new' at most 'count' times.</span>
|
|
<str> = <str>.translate(<table>) <span class="hljs-comment"># Use `str.maketrans(<dict>)` to generate table.</span>
|
|
</code></pre>
|
|
<pre><code class="python language-python hljs"><str> = chr(<int>) <span class="hljs-comment"># Converts int to Unicode char.</span>
|
|
<int> = ord(<str>) <span class="hljs-comment"># Converts Unicode char to int.</span>
|
|
</code></pre>
|
|
<ul>
|
|
<li><strong>Also: <code class="python hljs"><span class="hljs-string">'lstrip()'</span></code>, <code class="python hljs"><span class="hljs-string">'rstrip()'</span></code>.</strong></li>
|
|
<li><strong>Also: <code class="python hljs"><span class="hljs-string">'lower()'</span></code>, <code class="python hljs"><span class="hljs-string">'upper()'</span></code>, <code class="python hljs"><span class="hljs-string">'capitalize()'</span></code> and <code class="python hljs"><span class="hljs-string">'title()'</span></code>.</strong></li>
|
|
</ul>
|
|
<div><h3 id="propertymethods">Property Methods</h3><pre><code class="text language-text">+---------------+----------+----------+----------+----------+----------+
|
|
| | [ !#$%…] | [a-zA-Z] | [¼½¾] | [²³¹] | [0-9] |
|
|
+---------------+----------+----------+----------+----------+----------+
|
|
| isprintable() | yes | yes | yes | yes | yes |
|
|
| isalnum() | | yes | yes | yes | yes |
|
|
| isnumeric() | | | yes | yes | yes |
|
|
| isdigit() | | | | yes | yes |
|
|
| isdecimal() | | | | | yes |
|
|
+---------------+----------+----------+----------+----------+----------+
|
|
</code></pre></div>
|
|
|
|
<ul>
|
|
<li><strong>Also: <code class="python hljs"><span class="hljs-string">'isspace()'</span></code> checks for <code class="python hljs"><span class="hljs-string">'[ \t\n\r\f\v…]'</span></code>.</strong></li>
|
|
</ul>
|
|
<div><h2 id="regex"><a href="#regex" name="regex">#</a>Regex</h2><pre><code class="python language-python hljs"><span class="hljs-keyword">import</span> re
|
|
<str> = re.sub(<regex>, new, text, count=<span class="hljs-number">0</span>) <span class="hljs-comment"># Substitutes all occurrences with 'new'.</span>
|
|
<list> = re.findall(<regex>, text) <span class="hljs-comment"># Returns all occurrences as strings.</span>
|
|
<list> = re.split(<regex>, text, maxsplit=<span class="hljs-number">0</span>) <span class="hljs-comment"># Use brackets in regex to include the matches.</span>
|
|
<Match> = re.search(<regex>, text) <span class="hljs-comment"># Searches for first occurrence of the pattern.</span>
|
|
<Match> = re.match(<regex>, text) <span class="hljs-comment"># Searches only at the beginning of the text.</span>
|
|
<iter> = re.finditer(<regex>, text) <span class="hljs-comment"># Returns all occurrences as match objects.</span>
|
|
</code></pre></div>
|
|
|
|
<ul>
|
|
<li><strong>Search() and match() return None if they can't find a match.</strong></li>
|
|
<li><strong>Argument <code class="python hljs"><span class="hljs-string">'flags=re.IGNORECASE'</span></code> can be used with all functions.</strong></li>
|
|
<li><strong>Argument <code class="python hljs"><span class="hljs-string">'flags=re.MULTILINE'</span></code> makes <code class="python hljs"><span class="hljs-string">'^'</span></code> and <code class="python hljs"><span class="hljs-string">'$'</span></code> match the start/end of each line.</strong></li>
|
|
<li><strong>Argument <code class="python hljs"><span class="hljs-string">'flags=re.DOTALL'</span></code> makes dot also accept the <code class="python hljs"><span class="hljs-string">'\n'</span></code>.</strong></li>
|
|
<li><strong>Use <code class="python hljs"><span class="hljs-string">r'\1'</span></code> or <code class="python hljs"><span class="hljs-string">'\\1'</span></code> for backreference.</strong></li>
|
|
<li><strong>Add <code class="python hljs"><span class="hljs-string">'?'</span></code> after an operator to make it non-greedy.</strong></li>
|
|
</ul>
|
|
<div><h3 id="matchobject">Match Object</h3><pre><code class="python language-python hljs"><str> = <Match>.group() <span class="hljs-comment"># Returns the whole match. Also group(0).</span>
|
|
<str> = <Match>.group(<span class="hljs-number">1</span>) <span class="hljs-comment"># Returns part in the first bracket.</span>
|
|
<tuple> = <Match>.groups() <span class="hljs-comment"># Returns all bracketed parts.</span>
|
|
<int> = <Match>.start() <span class="hljs-comment"># Returns start index of the match.</span>
|
|
<int> = <Match>.end() <span class="hljs-comment"># Returns exclusive end index of the match.</span>
|
|
</code></pre></div>
|
|
|
|
<div><h3 id="specialsequences">Special Sequences</h3><ul>
|
|
<li><strong>By default digits, whitespaces and alphanumerics from all alphabets are matched, unless <code class="python hljs"><span class="hljs-string">'flags=re.ASCII'</span></code> argument is used.</strong></li>
|
|
<li><strong>Use a capital letter for negation.</strong></li>
|
|
</ul><pre><code class="python language-python hljs"><span class="hljs-string">'\d'</span> == <span class="hljs-string">'[0-9]'</span> <span class="hljs-comment"># Matches any digit.</span>
|
|
<span class="hljs-string">'\w'</span> == <span class="hljs-string">'[a-zA-Z0-9_]'</span> <span class="hljs-comment"># Matches any alphanumeric.</span>
|
|
<span class="hljs-string">'\s'</span> == <span class="hljs-string">'[ \t\n\r\f\v]'</span> <span class="hljs-comment"># Matches any whitespace.</span>
|
|
</code></pre></div>
|
|
|
|
|
|
<div><h2 id="format"><a href="#format" name="format">#</a>Format</h2><pre><code class="python language-python hljs"><str> = <span class="hljs-string">f'<span class="hljs-subst">{<el_1>}</span>, <span class="hljs-subst">{<el_2>}</span>'</span>
|
|
<str> = <span class="hljs-string">'{}, {}'</span>.format(<el_1>, <el_2>)
|
|
</code></pre></div>
|
|
|
|
<div><h3 id="attributes">Attributes</h3><pre><code class="python language-python hljs"><span class="hljs-meta">>>> </span><span class="hljs-keyword">from</span> collections <span class="hljs-keyword">import</span> namedtuple
|
|
<span class="hljs-meta">>>> </span>Person = namedtuple(<span class="hljs-string">'Person'</span>, <span class="hljs-string">'name height'</span>)
|
|
<span class="hljs-meta">>>> </span>person = Person(<span class="hljs-string">'Jean-Luc'</span>, <span class="hljs-number">187</span>)
|
|
<span class="hljs-meta">>>> </span><span class="hljs-string">f'<span class="hljs-subst">{person.height}</span>'</span>
|
|
<span class="hljs-string">'187'</span>
|
|
<span class="hljs-meta">>>> </span><span class="hljs-string">'{p.height}'</span>.format(p=person)
|
|
<span class="hljs-string">'187'</span>
|
|
</code></pre></div>
|
|
|
|
<div><h3 id="generaloptions">General Options</h3><pre><code class="python language-python hljs">{<el>:<<span class="hljs-number">10</span>} <span class="hljs-comment"># '<el> '</span>
|
|
{<el>:^<span class="hljs-number">10</span>} <span class="hljs-comment"># ' <el> '</span>
|
|
{<el>:><span class="hljs-number">10</span>} <span class="hljs-comment"># ' <el>'</span>
|
|
{<el>:.<<span class="hljs-number">10</span>} <span class="hljs-comment"># '<el>......'</span>
|
|
{<el>:<<span class="hljs-number">0</span>} <span class="hljs-comment"># '<el>'</span>
|
|
</code></pre></div>
|
|
|
|
<div><h3 id="strings">Strings</h3><p><strong><code class="python hljs"><span class="hljs-string">'!r'</span></code> calls object's <a href="#class">repr()</a> method, instead of <a href="#class">str()</a>, to get a string.</strong></p><pre><code class="python language-python hljs">{<span class="hljs-string">'abcde'</span>!r:<span class="hljs-number">10</span>} <span class="hljs-comment"># "'abcde' "</span>
|
|
{<span class="hljs-string">'abcde'</span>:<span class="hljs-number">10.3</span>} <span class="hljs-comment"># 'abc '</span>
|
|
{<span class="hljs-string">'abcde'</span>:<span class="hljs-number">.3</span>} <span class="hljs-comment"># 'abc'</span>
|
|
</code></pre></div>
|
|
|
|
|
|
<div><h3 id="numbers-1">Numbers</h3><pre><code class="python language-python hljs">{ <span class="hljs-number">123456</span>:<span class="hljs-number">10</span>,} <span class="hljs-comment"># ' 123,456'</span>
|
|
{ <span class="hljs-number">123456</span>:<span class="hljs-number">10</span>_} <span class="hljs-comment"># ' 123_456'</span>
|
|
{ <span class="hljs-number">123456</span>:+<span class="hljs-number">10</span>} <span class="hljs-comment"># ' +123456'</span>
|
|
{<span class="hljs-number">-123456</span>:=<span class="hljs-number">10</span>} <span class="hljs-comment"># '- 123456'</span>
|
|
{ <span class="hljs-number">123456</span>: } <span class="hljs-comment"># ' 123456'</span>
|
|
{<span class="hljs-number">-123456</span>: } <span class="hljs-comment"># '-123456'</span>
|
|
</code></pre></div>
|
|
|
|
<div><h3 id="floats">Floats</h3><pre><code class="python language-python hljs">{<span class="hljs-number">1.23456</span>:<span class="hljs-number">10.3</span>} <span class="hljs-comment"># ' 1.23'</span>
|
|
{<span class="hljs-number">1.23456</span>:<span class="hljs-number">10.3</span>f} <span class="hljs-comment"># ' 1.235'</span>
|
|
{<span class="hljs-number">1.23456</span>:<span class="hljs-number">10.3</span>e} <span class="hljs-comment"># ' 1.235e+00'</span>
|
|
{<span class="hljs-number">1.23456</span>:<span class="hljs-number">10.3</span>%} <span class="hljs-comment"># ' 123.456%'</span>
|
|
</code></pre></div>
|
|
|
|
<div><h4 id="comparisonofpresentationtypes">Comparison of presentation types:</h4><pre><code class="text language-text">+---------------+-----------------+-----------------+-----------------+-----------------+
|
|
| | {<real>} | {<real>:f} | {<real>:e} | {<real>:%} |
|
|
+---------------+-----------------+-----------------+-----------------+-----------------+
|
|
| 0.000056789 | '5.6789e-05' | '0.000057' | '5.678900e-05' | '0.005679%' |
|
|
| 0.00056789 | '0.00056789' | '0.000568' | '5.678900e-04' | '0.056789%' |
|
|
| 0.0056789 | '0.0056789' | '0.005679' | '5.678900e-03' | '0.567890%' |
|
|
| 0.056789 | '0.056789' | '0.056789' | '5.678900e-02' | '5.678900%' |
|
|
| 0.56789 | '0.56789' | '0.567890' | '5.678900e-01' | '56.789000%' |
|
|
| 5.6789 | '5.6789' | '5.678900' | '5.678900e+00' | '567.890000%' |
|
|
| 56.789 | '56.789' | '56.789000' | '5.678900e+01' | '5678.900000%' |
|
|
| 567.89 | '567.89' | '567.890000' | '5.678900e+02' | '56789.000000%' |
|
|
+---------------+-----------------+-----------------+-----------------+-----------------+
|
|
</code></pre></div>
|
|
|
|
<pre><code class="text language-text">+---------------+-----------------+-----------------+-----------------+-----------------+
|
|
| | {<float>:.2} | {<real>:.2f} | {<real>:.2e} | {<real>:.2%} |
|
|
+---------------+-----------------+-----------------+-----------------+-----------------+
|
|
| 0.000056789 | '5.7e-05' | '0.00' | '5.68e-05' | '0.01%' |
|
|
| 0.00056789 | '0.00057' | '0.00' | '5.68e-04' | '0.06%' |
|
|
| 0.0056789 | '0.0057' | '0.01' | '5.68e-03' | '0.57%' |
|
|
| 0.056789 | '0.057' | '0.06' | '5.68e-02' | '5.68%' |
|
|
| 0.56789 | '0.57' | '0.57' | '5.68e-01' | '56.79%' |
|
|
| 5.6789 | '5.7' | '5.68' | '5.68e+00' | '567.89%' |
|
|
| 56.789 | '5.7e+01' | '56.79' | '5.68e+01' | '5678.90%' |
|
|
| 567.89 | '5.7e+02' | '567.89' | '5.68e+02' | '56789.00%' |
|
|
+---------------+-----------------+-----------------+-----------------+-----------------+
|
|
</code></pre>
|
|
<div><h3 id="ints">Ints</h3><pre><code class="python language-python hljs">{<span class="hljs-number">90</span>:c} <span class="hljs-comment"># 'Z'</span>
|
|
{<span class="hljs-number">90</span>:b} <span class="hljs-comment"># '1011010'</span>
|
|
{<span class="hljs-number">90</span>:X} <span class="hljs-comment"># '5A'</span>
|
|
</code></pre></div>
|
|
|
|
<div><h2 id="numbers"><a href="#numbers" name="numbers">#</a>Numbers</h2><div><h3 id="types">Types</h3><pre><code class="python language-python hljs"><int> = int(<float/str/bool>) <span class="hljs-comment"># Or: math.floor(<float>)</span>
|
|
<float> = float(<int/str/bool>) <span class="hljs-comment"># Or: <real>e±<int></span>
|
|
<complex> = complex(real=<span class="hljs-number">0</span>, imag=<span class="hljs-number">0</span>) <span class="hljs-comment"># Or: <real> ± <real>j</span>
|
|
<Fraction> = fractions.Fraction(numerator=<span class="hljs-number">0</span>, denominator=<span class="hljs-number">1</span>)
|
|
<Decimal> = decimal.Decimal(<str/int/float>)
|
|
</code></pre></div></div>
|
|
|
|
|
|
<ul>
|
|
<li><strong><code class="python hljs"><span class="hljs-string">'int(<str>)'</span></code> and <code class="python hljs"><span class="hljs-string">'float(<str>)'</span></code> raise ValueError on malformed strings.</strong></li>
|
|
<li><strong>Decimal numbers can be represented exactly, unlike floats where <code class="python hljs"><span class="hljs-string">'1.1 + 2.2 != 3.3'</span></code>.</strong></li>
|
|
<li><strong>Precision of decimal operations is set with: <code class="python hljs"><span class="hljs-string">'decimal.getcontext().prec = <int>'</span></code>.</strong></li>
|
|
</ul>
|
|
<div><h3 id="basicfunctions">Basic Functions</h3><pre><code class="python language-python hljs"><num> = pow(<num>, <num>) <span class="hljs-comment"># Or: <num> ** <num></span>
|
|
<num> = abs(<num>) <span class="hljs-comment"># <float> = abs(<complex>)</span>
|
|
<num> = round(<num> [, ±ndigits]) <span class="hljs-comment"># `round(126, -1) == 130`</span>
|
|
</code></pre></div>
|
|
|
|
<div><h3 id="math">Math</h3><pre><code class="python language-python hljs"><span class="hljs-keyword">from</span> math <span class="hljs-keyword">import</span> e, pi, inf, nan
|
|
<span class="hljs-keyword">from</span> math <span class="hljs-keyword">import</span> cos, acos, sin, asin, tan, atan, degrees, radians
|
|
<span class="hljs-keyword">from</span> math <span class="hljs-keyword">import</span> log, log10, log2
|
|
</code></pre></div>
|
|
|
|
<div><h3 id="statistics">Statistics</h3><pre><code class="python language-python hljs"><span class="hljs-keyword">from</span> statistics <span class="hljs-keyword">import</span> mean, median, variance, pvariance, pstdev
|
|
</code></pre></div>
|
|
|
|
<div><h3 id="random">Random</h3><pre><code class="python language-python hljs"><span class="hljs-keyword">from</span> random <span class="hljs-keyword">import</span> random, randint, choice, shuffle
|
|
<float> = random()
|
|
<int> = randint(from_inclusive, to_inclusive)
|
|
<el> = choice(<list>)
|
|
shuffle(<list>)
|
|
</code></pre></div>
|
|
|
|
<div><h3 id="binhex">Bin, Hex</h3><pre><code class="python language-python hljs"><int> = <span class="hljs-number">0</span>b<bin> <span class="hljs-comment"># Or: 0x<hex></span>
|
|
<int> = int(<span class="hljs-string">'<bin>'</span>, <span class="hljs-number">2</span>) <span class="hljs-comment"># Or: int('<hex>', 16)</span>
|
|
<int> = int(<span class="hljs-string">'0b<bin>'</span>, <span class="hljs-number">0</span>) <span class="hljs-comment"># Or: int('0x<hex>', 0)</span>
|
|
<span class="hljs-string">'0b<bin>'</span> = bin(<int>) <span class="hljs-comment"># Or: hex(<int>)</span>
|
|
</code></pre></div>
|
|
|
|
<div><h3 id="bitwiseoperators">Bitwise Operators</h3><pre><code class="python language-python hljs"><int> = <int> & <int> <span class="hljs-comment"># And</span>
|
|
<int> = <int> | <int> <span class="hljs-comment"># Or</span>
|
|
<int> = <int> ^ <int> <span class="hljs-comment"># Xor (0 if both bits equal)</span>
|
|
<int> = <int> << n_bits <span class="hljs-comment"># Shift left</span>
|
|
<int> = <int> >> n_bits <span class="hljs-comment"># Shift right</span>
|
|
<int> = ~<int> <span class="hljs-comment"># Compliment (flips bits)</span>
|
|
</code></pre></div>
|
|
|
|
<div><h2 id="combinatorics"><a href="#combinatorics" name="combinatorics">#</a>Combinatorics</h2><ul>
|
|
<li><strong>Every function returns an iterator.</strong></li>
|
|
<li><strong>If you want to print the iterator, you need to pass it to the list() function!</strong></li>
|
|
</ul><pre><code class="python language-python hljs"><span class="hljs-keyword">from</span> itertools <span class="hljs-keyword">import</span> product, combinations, combinations_with_replacement, permutations
|
|
</code></pre></div>
|
|
|
|
|
|
<pre><code class="python language-python hljs"><span class="hljs-meta">>>> </span>product([<span class="hljs-number">0</span>, <span class="hljs-number">1</span>], repeat=<span class="hljs-number">3</span>)
|
|
[(<span class="hljs-number">0</span>, <span class="hljs-number">0</span>, <span class="hljs-number">0</span>), (<span class="hljs-number">0</span>, <span class="hljs-number">0</span>, <span class="hljs-number">1</span>), (<span class="hljs-number">0</span>, <span class="hljs-number">1</span>, <span class="hljs-number">0</span>), (<span class="hljs-number">0</span>, <span class="hljs-number">1</span>, <span class="hljs-number">1</span>),
|
|
(<span class="hljs-number">1</span>, <span class="hljs-number">0</span>, <span class="hljs-number">0</span>), (<span class="hljs-number">1</span>, <span class="hljs-number">0</span>, <span class="hljs-number">1</span>), (<span class="hljs-number">1</span>, <span class="hljs-number">1</span>, <span class="hljs-number">0</span>), (<span class="hljs-number">1</span>, <span class="hljs-number">1</span>, <span class="hljs-number">1</span>)]
|
|
</code></pre>
|
|
<pre><code class="python language-python hljs"><span class="hljs-meta">>>> </span>product(<span class="hljs-string">'ab'</span>, <span class="hljs-string">'12'</span>)
|
|
[(<span class="hljs-string">'a'</span>, <span class="hljs-string">'1'</span>), (<span class="hljs-string">'a'</span>, <span class="hljs-string">'2'</span>),
|
|
(<span class="hljs-string">'b'</span>, <span class="hljs-string">'1'</span>), (<span class="hljs-string">'b'</span>, <span class="hljs-string">'2'</span>)]
|
|
</code></pre>
|
|
<pre><code class="python language-python hljs"><span class="hljs-meta">>>> </span>combinations(<span class="hljs-string">'abc'</span>, <span class="hljs-number">2</span>)
|
|
[(<span class="hljs-string">'a'</span>, <span class="hljs-string">'b'</span>), (<span class="hljs-string">'a'</span>, <span class="hljs-string">'c'</span>), (<span class="hljs-string">'b'</span>, <span class="hljs-string">'c'</span>)]
|
|
</code></pre>
|
|
<pre><code class="python language-python hljs"><span class="hljs-meta">>>> </span>combinations_with_replacement(<span class="hljs-string">'abc'</span>, <span class="hljs-number">2</span>)
|
|
[(<span class="hljs-string">'a'</span>, <span class="hljs-string">'a'</span>), (<span class="hljs-string">'a'</span>, <span class="hljs-string">'b'</span>), (<span class="hljs-string">'a'</span>, <span class="hljs-string">'c'</span>),
|
|
(<span class="hljs-string">'b'</span>, <span class="hljs-string">'b'</span>), (<span class="hljs-string">'b'</span>, <span class="hljs-string">'c'</span>),
|
|
(<span class="hljs-string">'c'</span>, <span class="hljs-string">'c'</span>)]
|
|
</code></pre>
|
|
<pre><code class="python language-python hljs"><span class="hljs-meta">>>> </span>permutations(<span class="hljs-string">'abc'</span>, <span class="hljs-number">2</span>)
|
|
[(<span class="hljs-string">'a'</span>, <span class="hljs-string">'b'</span>), (<span class="hljs-string">'a'</span>, <span class="hljs-string">'c'</span>),
|
|
(<span class="hljs-string">'b'</span>, <span class="hljs-string">'a'</span>), (<span class="hljs-string">'b'</span>, <span class="hljs-string">'c'</span>),
|
|
(<span class="hljs-string">'c'</span>, <span class="hljs-string">'a'</span>), (<span class="hljs-string">'c'</span>, <span class="hljs-string">'b'</span>)]
|
|
</code></pre>
|
|
<div><h2 id="datetime"><a href="#datetime" name="datetime">#</a>Datetime</h2><ul>
|
|
<li><strong>Module 'datetime' provides 'date' <code class="apache hljs"><span class="hljs-section"><D></span></code>, 'time' <code class="apache hljs"><span class="hljs-section"><T></span></code>, 'datetime' <code class="apache hljs"><span class="hljs-section"><DT></span></code> and 'timedelta' <code class="apache hljs"><span class="hljs-section"><TD></span></code> classes. All are immutable and hashable.</strong></li>
|
|
<li><strong>Time and datetime objects can be 'aware' <code class="apache hljs"><span class="hljs-section"><a></span></code>, meaning they have defined timezone, or 'naive' <code class="apache hljs"><span class="hljs-section"><n></span></code>, meaning they don't.</strong></li>
|
|
<li><strong>If object is naive, it is presumed to be in the system's timezone.</strong></li>
|
|
</ul><pre><code class="python language-python hljs"><span class="hljs-keyword">from</span> datetime <span class="hljs-keyword">import</span> date, time, datetime, timedelta
|
|
<span class="hljs-keyword">from</span> dateutil.tz <span class="hljs-keyword">import</span> UTC, tzlocal, gettz, resolve_imaginary
|
|
</code></pre></div>
|
|
|
|
|
|
<div><h3 id="constructors">Constructors</h3><pre><code class="python language-python apache hljs"><D> = date(year, month, day)
|
|
<T> = time(hour=<span class="hljs-number">0</span>, minute=<span class="hljs-number">0</span>, second=<span class="hljs-number">0</span>, microsecond=<span class="hljs-number">0</span>, tzinfo=<span class="hljs-keyword">None</span>, fold=<span class="hljs-number">0</span>)
|
|
<DT> = datetime(year, month, day, hour=<span class="hljs-number">0</span>, minute=<span class="hljs-number">0</span>, second=<span class="hljs-number">0</span>, ...)
|
|
<TD> = timedelta(days=<span class="hljs-number">0</span>, seconds=<span class="hljs-number">0</span>, microseconds=<span class="hljs-number">0</span>, milliseconds=<span class="hljs-number">0</span>,
|
|
minutes=<span class="hljs-number">0</span>, hours=<span class="hljs-number">0</span>, weeks=<span class="hljs-number">0</span>)
|
|
</code></pre></div>
|
|
|
|
<ul>
|
|
<li><strong>Use <code class="python hljs"><span class="hljs-string">'<D/DT>.weekday()'</span></code> to get the day of the week (Mon == 0).</strong></li>
|
|
<li><strong><code class="python hljs"><span class="hljs-string">'fold=1'</span></code> means the second pass in case of time jumping back for one hour.</strong></li>
|
|
<li><strong><code class="python hljs"><span class="hljs-string">'<DTa> = resolve_imaginary(<DTa>)'</span></code> fixes DTs that fall into the missing hour.</strong></li>
|
|
</ul>
|
|
<div><h3 id="now">Now</h3><pre><code class="python language-python hljs"><D/DTn> = D/DT.today() <span class="hljs-comment"># Current local date or naive datetime.</span>
|
|
<DTn> = DT.utcnow() <span class="hljs-comment"># Naive datetime from current UTC time.</span>
|
|
<DTa> = DT.now(<tzinfo>) <span class="hljs-comment"># Aware datetime from current tz time.</span>
|
|
</code></pre></div>
|
|
|
|
<ul>
|
|
<li><strong>To extract time use <code class="python hljs"><span class="hljs-string">'<DTn>.time()'</span></code>, <code class="python hljs"><span class="hljs-string">'<DTa>.time()'</span></code> or <code class="python hljs"><span class="hljs-string">'<DTa>.timetz()'</span></code>.</strong></li>
|
|
</ul>
|
|
<div><h3 id="timezone">Timezone</h3><pre><code class="python language-python apache hljs"><tzinfo> = UTC <span class="hljs-comment"># UTC timezone. London without DST.</span>
|
|
<tzinfo> = tzlocal() <span class="hljs-comment"># Local timezone. Also gettz().</span>
|
|
<tzinfo> = gettz(<span class="hljs-string">'<Cont.>/<City>'</span>) <span class="hljs-comment"># 'Continent/City_Name' timezone or None.</span>
|
|
<DTa> = <DT>.astimezone(<tzinfo>) <span class="hljs-comment"># Datetime, converted to passed timezone.</span>
|
|
<Ta/DTa> = <T/DT>.replace(tzinfo=<tzinfo>) <span class="hljs-comment"># Unconverted object with new timezone.</span>
|
|
</code></pre></div>
|
|
|
|
<div><h3 id="encode">Encode</h3><pre><code class="python language-python apache hljs"><D/T/DT> = D/T/DT.fromisoformat(<span class="hljs-string">'<iso>'</span>) <span class="hljs-comment"># Object from ISO string. Raises ValueError.</span>
|
|
<DT> = DT.strptime(<str>, <span class="hljs-string">'<format>'</span>) <span class="hljs-comment"># Datetime from str, according to format.</span>
|
|
<D/DTn> = D/DT.fromordinal(<int>) <span class="hljs-comment"># D/DTn from days since Christ, at midnight.</span>
|
|
<DTn> = DT.fromtimestamp(<real>) <span class="hljs-comment"># Local time DTn from seconds since Epoch.</span>
|
|
<DTa> = DT.fromtimestamp(<real>, <tz.>) <span class="hljs-comment"># Aware datetime from seconds since Epoch.</span>
|
|
</code></pre></div>
|
|
|
|
<ul>
|
|
<li><strong>ISO strings come in following forms: <code class="python hljs"><span class="hljs-string">'YYYY-MM-DD'</span></code>, <code class="python hljs"><span class="hljs-string">'HH:MM:SS.ffffff[±<offset>]'</span></code>, or both separated by an arbitrary character. Offset is formatted as: <code class="python hljs"><span class="hljs-string">'HH:MM'</span></code>.</strong></li>
|
|
<li><strong>Epoch on Unix systems is: <code class="python hljs"><span class="hljs-string">'1970-01-01 00:00 UTC'</span></code>, <code class="python hljs"><span class="hljs-string">'1970-01-01 01:00 CET'</span></code>, …</strong></li>
|
|
</ul>
|
|
<div><h3 id="decode">Decode</h3><pre><code class="python language-python hljs"><str> = <D/T/DT>.isoformat(sep=<span class="hljs-string">'T'</span>) <span class="hljs-comment"># Also timespec='auto/hours/minutes/seconds'.</span>
|
|
<str> = <D/T/DT>.strftime(<span class="hljs-string">'<format>'</span>) <span class="hljs-comment"># Custom string representation.</span>
|
|
<int> = <D/DT>.toordinal() <span class="hljs-comment"># Days since Christ, ignoring time and tz.</span>
|
|
<float> = <DTn>.timestamp() <span class="hljs-comment"># Seconds since Epoch, from DTn in local tz.</span>
|
|
<float> = <DTa>.timestamp() <span class="hljs-comment"># Seconds since Epoch, from DTa.</span>
|
|
</code></pre></div>
|
|
|
|
<div><h3 id="format-1">Format</h3><pre><code class="python language-python hljs"><span class="hljs-meta">>>> </span><span class="hljs-keyword">from</span> datetime <span class="hljs-keyword">import</span> datetime
|
|
<span class="hljs-meta">>>> </span>dt = datetime.strptime(<span class="hljs-string">'2015-05-14 23:39:00.00 +0200'</span>, <span class="hljs-string">'%Y-%m-%d %H:%M:%S.%f %z'</span>)
|
|
<span class="hljs-meta">>>> </span>dt.strftime(<span class="hljs-string">"%A, %dth of %B '%y, %I:%M%p %Z"</span>)
|
|
<span class="hljs-string">"Thursday, 14th of May '15, 11:39PM UTC+02:00"</span>
|
|
</code></pre></div>
|
|
|
|
<ul>
|
|
<li><strong>When parsing, <code class="python hljs"><span class="hljs-string">'%z'</span></code> also accepts <code class="python hljs"><span class="hljs-string">'±HH:MM'</span></code>.</strong></li>
|
|
<li><strong>For abbreviated weekday and month use <code class="python hljs"><span class="hljs-string">'%a'</span></code> and <code class="python hljs"><span class="hljs-string">'%b'</span></code>.</strong></li>
|
|
</ul>
|
|
<div><h3 id="arithmetics">Arithmetics</h3><pre><code class="python language-python apache hljs"><D/DT> = <D/DT> ± <TD> <span class="hljs-comment"># Returned datetime can fall into missing hour.</span>
|
|
<TD> = <D/DTn> - <D/DTn> <span class="hljs-comment"># Returns the difference, ignoring time jumps.</span>
|
|
<TD> = <DTa> - <DTa> <span class="hljs-comment"># Ignores time jumps if they share tzinfo object.</span>
|
|
<TD> = <DT_UTC> - <DT_UTC> <span class="hljs-comment"># Convert DTs to UTC to get the actual delta.</span>
|
|
</code></pre></div>
|
|
|
|
<div><h2 id="arguments"><a href="#arguments" name="arguments">#</a>Arguments</h2><div><h3 id="insidefunctioncall">Inside Function Call</h3><pre><code class="python language-python hljs"><function>(<positional_args>) <span class="hljs-comment"># f(0, 0)</span>
|
|
<function>(<keyword_args>) <span class="hljs-comment"># f(x=0, y=0)</span>
|
|
<function>(<positional_args>, <keyword_args>) <span class="hljs-comment"># f(0, y=0)</span>
|
|
</code></pre></div></div>
|
|
|
|
|
|
<div><h3 id="insidefunctiondefinition">Inside Function Definition</h3><pre><code class="python language-python hljs"><span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">f</span><span class="hljs-params">(<nondefault_args>)</span>:</span> <span class="hljs-comment"># def f(x, y):</span>
|
|
<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">f</span><span class="hljs-params">(<default_args>)</span>:</span> <span class="hljs-comment"># def f(x=0, y=0):</span>
|
|
<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">f</span><span class="hljs-params">(<nondefault_args>, <default_args>)</span>:</span> <span class="hljs-comment"># def f(x, y=0):</span>
|
|
</code></pre></div>
|
|
|
|
<div><h2 id="splatoperator"><a href="#splatoperator" name="splatoperator">#</a>Splat Operator</h2><div><h3 id="insidefunctioncall-1">Inside Function Call</h3><p><strong>Splat expands a collection into positional arguments, while splatty-splat expands a dictionary into keyword arguments.</strong></p><pre><code class="python language-python hljs">args = (<span class="hljs-number">1</span>, <span class="hljs-number">2</span>)
|
|
kwargs = {<span class="hljs-string">'x'</span>: <span class="hljs-number">3</span>, <span class="hljs-string">'y'</span>: <span class="hljs-number">4</span>, <span class="hljs-string">'z'</span>: <span class="hljs-number">5</span>}
|
|
func(*args, **kwargs)
|
|
</code></pre></div></div>
|
|
|
|
|
|
|
|
<div><h4 id="isthesameas">Is the same as:</h4><pre><code class="python language-python hljs">func(<span class="hljs-number">1</span>, <span class="hljs-number">2</span>, x=<span class="hljs-number">3</span>, y=<span class="hljs-number">4</span>, z=<span class="hljs-number">5</span>)
|
|
</code></pre></div>
|
|
|
|
<div><h3 id="insidefunctiondefinition-1">Inside Function Definition</h3><p><strong>Splat combines zero or more positional arguments into a tuple, while splatty-splat combines zero or more keyword arguments into a dictionary.</strong></p><pre><code class="python language-python hljs"><span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">add</span><span class="hljs-params">(*a)</span>:</span>
|
|
<span class="hljs-keyword">return</span> sum(a)
|
|
</code></pre></div>
|
|
|
|
|
|
<pre><code class="python language-python hljs"><span class="hljs-meta">>>> </span>add(<span class="hljs-number">1</span>, <span class="hljs-number">2</span>, <span class="hljs-number">3</span>)
|
|
<span class="hljs-number">6</span>
|
|
</code></pre>
|
|
<div><h4 id="legalargumentcombinations">Legal argument combinations:</h4><pre><code class="python language-python hljs"><span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">f</span><span class="hljs-params">(x, y, z)</span>:</span> <span class="hljs-comment"># f(x=1, y=2, z=3) | f(1, y=2, z=3) | f(1, 2, z=3) | f(1, 2, 3)</span>
|
|
<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">f</span><span class="hljs-params">(*, x, y, z)</span>:</span> <span class="hljs-comment"># f(x=1, y=2, z=3)</span>
|
|
<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">f</span><span class="hljs-params">(x, *, y, z)</span>:</span> <span class="hljs-comment"># f(x=1, y=2, z=3) | f(1, y=2, z=3)</span>
|
|
<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">f</span><span class="hljs-params">(x, y, *, z)</span>:</span> <span class="hljs-comment"># f(x=1, y=2, z=3) | f(1, y=2, z=3) | f(1, 2, z=3)</span>
|
|
</code></pre></div>
|
|
|
|
<pre><code class="python language-python hljs"><span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">f</span><span class="hljs-params">(*args)</span>:</span> <span class="hljs-comment"># f(1, 2, 3)</span>
|
|
<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">f</span><span class="hljs-params">(x, *args)</span>:</span> <span class="hljs-comment"># f(1, 2, 3)</span>
|
|
<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">f</span><span class="hljs-params">(*args, z)</span>:</span> <span class="hljs-comment"># f(1, 2, z=3)</span>
|
|
<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">f</span><span class="hljs-params">(x, *args, z)</span>:</span> <span class="hljs-comment"># f(1, 2, z=3)</span>
|
|
</code></pre>
|
|
<pre><code class="python language-python hljs"><span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">f</span><span class="hljs-params">(**kwargs)</span>:</span> <span class="hljs-comment"># f(x=1, y=2, z=3)</span>
|
|
<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">f</span><span class="hljs-params">(x, **kwargs)</span>:</span> <span class="hljs-comment"># f(x=1, y=2, z=3) | f(1, y=2, z=3)</span>
|
|
<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">f</span><span class="hljs-params">(*, x, **kwargs)</span>:</span> <span class="hljs-comment"># f(x=1, y=2, z=3)</span>
|
|
</code></pre>
|
|
<pre><code class="python language-python hljs"><span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">f</span><span class="hljs-params">(*args, **kwargs)</span>:</span> <span class="hljs-comment"># f(x=1, y=2, z=3) | f(1, y=2, z=3) | f(1, 2, z=3) | f(1, 2, 3)</span>
|
|
<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">f</span><span class="hljs-params">(x, *args, **kwargs)</span>:</span> <span class="hljs-comment"># f(x=1, y=2, z=3) | f(1, y=2, z=3) | f(1, 2, z=3) | f(1, 2, 3)</span>
|
|
<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">f</span><span class="hljs-params">(*args, y, **kwargs)</span>:</span> <span class="hljs-comment"># f(x=1, y=2, z=3) | f(1, y=2, z=3)</span>
|
|
<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">f</span><span class="hljs-params">(x, *args, z, **kwargs)</span>:</span> <span class="hljs-comment"># f(x=1, y=2, z=3) | f(1, y=2, z=3) | f(1, 2, z=3)</span>
|
|
</code></pre>
|
|
<div><h3 id="otheruses">Other Uses</h3><pre><code class="python language-python hljs"><list> = [*<collection> [, ...]]
|
|
<set> = {*<collection> [, ...]}
|
|
<tuple> = (*<collection>, [...])
|
|
<dict> = {**<dict> [, ...]}
|
|
</code></pre></div>
|
|
|
|
<pre><code class="python language-python hljs">head, *body, tail = <collection>
|
|
</code></pre>
|
|
<div><h2 id="inline"><a href="#inline" name="inline">#</a>Inline</h2><div><h3 id="lambda">Lambda</h3><pre><code class="python language-python hljs"><function> = <span class="hljs-keyword">lambda</span>: <return_value>
|
|
<function> = <span class="hljs-keyword">lambda</span> <argument_1>, <argument_2>: <return_value>
|
|
</code></pre></div></div>
|
|
|
|
|
|
<div><h3 id="comprehension">Comprehension</h3><pre><code class="python language-python hljs"><list> = [i+<span class="hljs-number">1</span> <span class="hljs-keyword">for</span> i <span class="hljs-keyword">in</span> range(<span class="hljs-number">10</span>)] <span class="hljs-comment"># [1, 2, ..., 10]</span>
|
|
<set> = {i <span class="hljs-keyword">for</span> i <span class="hljs-keyword">in</span> range(<span class="hljs-number">10</span>) <span class="hljs-keyword">if</span> i > <span class="hljs-number">5</span>} <span class="hljs-comment"># {6, 7, 8, 9}</span>
|
|
<iter> = (i+<span class="hljs-number">5</span> <span class="hljs-keyword">for</span> i <span class="hljs-keyword">in</span> range(<span class="hljs-number">10</span>)) <span class="hljs-comment"># (5, 6, ..., 14)</span>
|
|
<dict> = {i: i*<span class="hljs-number">2</span> <span class="hljs-keyword">for</span> i <span class="hljs-keyword">in</span> range(<span class="hljs-number">10</span>)} <span class="hljs-comment"># {0: 0, 1: 2, ..., 9: 18}</span>
|
|
</code></pre></div>
|
|
|
|
<pre><code class="python language-python hljs">out = [i+j <span class="hljs-keyword">for</span> i <span class="hljs-keyword">in</span> range(<span class="hljs-number">10</span>) <span class="hljs-keyword">for</span> j <span class="hljs-keyword">in</span> range(<span class="hljs-number">10</span>)]
|
|
</code></pre>
|
|
<div><h4 id="isthesameas-1">Is the same as:</h4><pre><code class="python language-python hljs">out = []
|
|
<span class="hljs-keyword">for</span> i <span class="hljs-keyword">in</span> range(<span class="hljs-number">10</span>):
|
|
<span class="hljs-keyword">for</span> j <span class="hljs-keyword">in</span> range(<span class="hljs-number">10</span>):
|
|
out.append(i+j)
|
|
</code></pre></div>
|
|
|
|
<div><h3 id="mapfilterreduce">Map, Filter, Reduce</h3><pre><code class="python language-python hljs"><span class="hljs-keyword">from</span> functools <span class="hljs-keyword">import</span> reduce
|
|
<iter> = map(<span class="hljs-keyword">lambda</span> x: x + <span class="hljs-number">1</span>, range(<span class="hljs-number">10</span>)) <span class="hljs-comment"># (1, 2, ..., 10)</span>
|
|
<iter> = filter(<span class="hljs-keyword">lambda</span> x: x > <span class="hljs-number">5</span>, range(<span class="hljs-number">10</span>)) <span class="hljs-comment"># (6, 7, 8, 9)</span>
|
|
<obj> = reduce(<span class="hljs-keyword">lambda</span> out, x: out + x, range(<span class="hljs-number">10</span>)) <span class="hljs-comment"># 45</span>
|
|
</code></pre></div>
|
|
|
|
<div><h3 id="anyall">Any, All</h3><pre><code class="python language-python hljs"><bool> = any(<collection>) <span class="hljs-comment"># False if empty.</span>
|
|
<bool> = all(el[<span class="hljs-number">1</span>] <span class="hljs-keyword">for</span> el <span class="hljs-keyword">in</span> <collection>) <span class="hljs-comment"># True if empty.</span>
|
|
</code></pre></div>
|
|
|
|
<div><h3 id="ifelse">If - Else</h3><pre><code class="python language-python hljs"><obj> = <expression_if_true> <span class="hljs-keyword">if</span> <condition> <span class="hljs-keyword">else</span> <expression_if_false>
|
|
</code></pre></div>
|
|
|
|
<pre><code class="python language-python hljs"><span class="hljs-meta">>>> </span>[a <span class="hljs-keyword">if</span> a <span class="hljs-keyword">else</span> <span class="hljs-string">'zero'</span> <span class="hljs-keyword">for</span> a <span class="hljs-keyword">in</span> (<span class="hljs-number">0</span>, <span class="hljs-number">1</span>, <span class="hljs-number">2</span>, <span class="hljs-number">3</span>)]
|
|
[<span class="hljs-string">'zero'</span>, <span class="hljs-number">1</span>, <span class="hljs-number">2</span>, <span class="hljs-number">3</span>]
|
|
</code></pre>
|
|
<div><h3 id="namedtupleenumdataclass">Namedtuple, Enum, Dataclass</h3><pre><code class="python language-python hljs"><span class="hljs-keyword">from</span> collections <span class="hljs-keyword">import</span> namedtuple
|
|
Point = namedtuple(<span class="hljs-string">'Point'</span>, <span class="hljs-string">'x y'</span>)
|
|
point = Point(<span class="hljs-number">0</span>, <span class="hljs-number">0</span>)
|
|
</code></pre></div>
|
|
|
|
<pre><code class="python language-python hljs"><span class="hljs-keyword">from</span> enum <span class="hljs-keyword">import</span> Enum
|
|
Direction = Enum(<span class="hljs-string">'Direction'</span>, <span class="hljs-string">'n e s w'</span>)
|
|
direction = Direction.n
|
|
</code></pre>
|
|
<pre><code class="python language-python hljs"><span class="hljs-keyword">from</span> dataclasses <span class="hljs-keyword">import</span> make_dataclass
|
|
Creature = make_dataclass(<span class="hljs-string">'Creature'</span>, [<span class="hljs-string">'location'</span>, <span class="hljs-string">'direction'</span>])
|
|
creature = Creature(Point(<span class="hljs-number">0</span>, <span class="hljs-number">0</span>), Direction.n)
|
|
</code></pre>
|
|
<div><h2 id="closure"><a href="#closure" name="closure">#</a>Closure</h2><p><strong>We have a closure in Python when:</strong></p><ul>
|
|
<li><strong>A nested function references a value of its enclosing function and then</strong></li>
|
|
<li><strong>the enclosing function returns the nested function.</strong></li>
|
|
</ul><pre><code class="python language-python hljs"><span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">get_multiplier</span><span class="hljs-params">(a)</span>:</span>
|
|
<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">out</span><span class="hljs-params">(b)</span>:</span>
|
|
<span class="hljs-keyword">return</span> a * b
|
|
<span class="hljs-keyword">return</span> out
|
|
</code></pre></div>
|
|
|
|
|
|
|
|
<pre><code class="python language-python hljs"><span class="hljs-meta">>>> </span>multiply_by_3 = get_multiplier(<span class="hljs-number">3</span>)
|
|
<span class="hljs-meta">>>> </span>multiply_by_3(<span class="hljs-number">10</span>)
|
|
<span class="hljs-number">30</span>
|
|
</code></pre>
|
|
<ul>
|
|
<li><strong>If multiple nested functions within enclosing function reference the same value, that value gets shared.</strong></li>
|
|
<li><strong>To dynamically access function's first free variable use <code class="python hljs"><span class="hljs-string">'<function>.__closure__[0].cell_contents'</span></code>.</strong></li>
|
|
</ul>
|
|
<div><h3 id="partial">Partial</h3><pre><code class="python language-python hljs"><span class="hljs-keyword">from</span> functools <span class="hljs-keyword">import</span> partial
|
|
<function> = partial(<function> [, <arg_1>, <arg_2>, ...])
|
|
</code></pre></div>
|
|
|
|
<pre><code class="python language-python hljs"><span class="hljs-meta">>>> </span><span class="hljs-keyword">import</span> operator <span class="hljs-keyword">as</span> op
|
|
<span class="hljs-meta">>>> </span>multiply_by_3 = partial(op.mul, <span class="hljs-number">3</span>)
|
|
<span class="hljs-meta">>>> </span>multiply_by_3(<span class="hljs-number">10</span>)
|
|
<span class="hljs-number">30</span>
|
|
</code></pre>
|
|
<ul>
|
|
<li><strong>Partial is also useful in cases when function needs to be passed as an argument, because it enables us to set its arguments beforehand.</strong></li>
|
|
<li><strong>A few examples being: <code class="python hljs"><span class="hljs-string">'defaultdict(<function>)'</span></code>, <code class="python hljs"><span class="hljs-string">'iter(<function>, to_exclusive)'</span></code> and dataclass's <code class="python hljs"><span class="hljs-string">'field(default_factory=<function>)'</span></code>.</strong></li>
|
|
</ul>
|
|
<div><h3 id="nonlocal">Nonlocal</h3><p><strong>If variable is being assigned to anywhere in the scope, it is regarded as a local variable, unless it is declared as a 'global' or a 'nonlocal'.</strong></p><pre><code class="python language-python hljs"><span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">get_counter</span><span class="hljs-params">()</span>:</span>
|
|
i = <span class="hljs-number">0</span>
|
|
<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">out</span><span class="hljs-params">()</span>:</span>
|
|
<span class="hljs-keyword">nonlocal</span> i
|
|
i += <span class="hljs-number">1</span>
|
|
<span class="hljs-keyword">return</span> i
|
|
<span class="hljs-keyword">return</span> out
|
|
</code></pre></div>
|
|
|
|
|
|
<pre><code class="python language-python hljs"><span class="hljs-meta">>>> </span>counter = get_counter()
|
|
<span class="hljs-meta">>>> </span>counter(), counter(), counter()
|
|
(<span class="hljs-number">1</span>, <span class="hljs-number">2</span>, <span class="hljs-number">3</span>)
|
|
</code></pre>
|
|
<div><h2 id="decorator"><a href="#decorator" name="decorator">#</a>Decorator</h2><p><strong>A decorator takes a function, adds some functionality and returns it.</strong></p><pre><code class="python language-python hljs"><span class="hljs-meta">@decorator_name</span>
|
|
<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">function_that_gets_passed_to_decorator</span><span class="hljs-params">()</span>:</span>
|
|
...
|
|
</code></pre></div>
|
|
|
|
|
|
<div><h3 id="debuggerexample">Debugger Example</h3><p><strong>Decorator that prints function's name every time it gets called.</strong></p><pre><code class="python language-python hljs"><span class="hljs-keyword">from</span> functools <span class="hljs-keyword">import</span> wraps
|
|
|
|
<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">debug</span><span class="hljs-params">(func)</span>:</span>
|
|
<span class="hljs-meta"> @wraps(func)</span>
|
|
<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">out</span><span class="hljs-params">(*args, **kwargs)</span>:</span>
|
|
print(func.__name__)
|
|
<span class="hljs-keyword">return</span> func(*args, **kwargs)
|
|
<span class="hljs-keyword">return</span> out
|
|
|
|
<span class="hljs-meta">@debug</span>
|
|
<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">add</span><span class="hljs-params">(x, y)</span>:</span>
|
|
<span class="hljs-keyword">return</span> x + y
|
|
</code></pre></div>
|
|
|
|
|
|
<ul>
|
|
<li><strong>Wraps is a helper decorator that copies the metadata of the passed function (func) to the function it is wrapping (out).</strong></li>
|
|
<li><strong>Without it <code class="python hljs"><span class="hljs-string">'add.__name__'</span></code> would return <code class="python hljs"><span class="hljs-string">'out'</span></code>.</strong></li>
|
|
</ul>
|
|
<div><h3 id="lrucache">LRU Cache</h3><p><strong>Decorator that caches function's return values. All function's arguments must be hashable.</strong></p><pre><code class="python language-python hljs"><span class="hljs-keyword">from</span> functools <span class="hljs-keyword">import</span> lru_cache
|
|
|
|
<span class="hljs-meta">@lru_cache(maxsize=None)</span>
|
|
<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">fib</span><span class="hljs-params">(n)</span>:</span>
|
|
<span class="hljs-keyword">return</span> n <span class="hljs-keyword">if</span> n < <span class="hljs-number">2</span> <span class="hljs-keyword">else</span> fib(n-<span class="hljs-number">2</span>) + fib(n-<span class="hljs-number">1</span>)
|
|
</code></pre></div>
|
|
|
|
|
|
<ul>
|
|
<li><strong>CPython interpreter limits recursion depth to 1000 by default. To increase it use <code class="python hljs"><span class="hljs-string">'sys.setrecursionlimit(<depth>)'</span></code>.</strong></li>
|
|
</ul>
|
|
<div><h3 id="parametrizeddecorator">Parametrized Decorator</h3><p><strong>A decorator that accepts arguments and returns a normal decorator that accepts a function.</strong></p><pre><code class="python language-python hljs"><span class="hljs-keyword">from</span> functools <span class="hljs-keyword">import</span> wraps
|
|
|
|
<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">debug</span><span class="hljs-params">(print_result=False)</span>:</span>
|
|
<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">decorator</span><span class="hljs-params">(func)</span>:</span>
|
|
<span class="hljs-meta"> @wraps(func)</span>
|
|
<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">out</span><span class="hljs-params">(*args, **kwargs)</span>:</span>
|
|
result = func(*args, **kwargs)
|
|
print(func.__name__, result <span class="hljs-keyword">if</span> print_result <span class="hljs-keyword">else</span> <span class="hljs-string">''</span>)
|
|
<span class="hljs-keyword">return</span> result
|
|
<span class="hljs-keyword">return</span> out
|
|
<span class="hljs-keyword">return</span> decorator
|
|
|
|
<span class="hljs-meta">@debug(print_result=True)</span>
|
|
<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">add</span><span class="hljs-params">(x, y)</span>:</span>
|
|
<span class="hljs-keyword">return</span> x + y
|
|
</code></pre></div>
|
|
|
|
|
|
<div><h2 id="class"><a href="#class" name="class">#</a>Class</h2><pre><code class="python language-python hljs"><span class="hljs-class"><span class="hljs-keyword">class</span> <<span class="hljs-title">name</span>>:</span>
|
|
<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">__init__</span><span class="hljs-params">(self, a)</span>:</span>
|
|
self.a = a
|
|
<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">__repr__</span><span class="hljs-params">(self)</span>:</span>
|
|
class_name = self.__class__.__name__
|
|
<span class="hljs-keyword">return</span> <span class="hljs-string">f'<span class="hljs-subst">{class_name}</span>(<span class="hljs-subst">{self.a!r}</span>)'</span>
|
|
<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">__str__</span><span class="hljs-params">(self)</span>:</span>
|
|
<span class="hljs-keyword">return</span> str(self.a)
|
|
|
|
<span class="hljs-meta"> @classmethod</span>
|
|
<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">get_class_name</span><span class="hljs-params">(cls)</span>:</span>
|
|
<span class="hljs-keyword">return</span> cls.__name__
|
|
</code></pre></div>
|
|
|
|
<ul>
|
|
<li><strong>Return value of repr() should be unambiguous and of str() readable.</strong></li>
|
|
<li><strong>If only repr() is defined, it will also be used for str().</strong></li>
|
|
</ul>
|
|
<div><h4 id="strusecases">Str() use cases:</h4><pre><code class="python language-python hljs">print(<el>)
|
|
print(<span class="hljs-string">f'<span class="hljs-subst">{<el>}</span>'</span>)
|
|
<span class="hljs-keyword">raise</span> Exception(<el>)
|
|
loguru.logger.debug(<el>)
|
|
csv.writer(<file>).writerow([<el>])
|
|
</code></pre></div>
|
|
|
|
<div><h4 id="reprusecases">Repr() use cases:</h4><pre><code class="python language-python hljs">print([<el>])
|
|
print(<span class="hljs-string">f'<span class="hljs-subst">{<el>!r}</span>'</span>)
|
|
<span class="hljs-meta">>>> </span><el>
|
|
loguru.logger.exception()
|
|
Z = dataclasses.make_dataclass(<span class="hljs-string">'Z'</span>, [<span class="hljs-string">'a'</span>]); print(Z(<el>))
|
|
</code></pre></div>
|
|
|
|
<div><h3 id="constructoroverloading">Constructor Overloading</h3><pre><code class="python language-python hljs"><span class="hljs-class"><span class="hljs-keyword">class</span> <<span class="hljs-title">name</span>>:</span>
|
|
<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">__init__</span><span class="hljs-params">(self, a=None)</span>:</span>
|
|
self.a = a
|
|
</code></pre></div>
|
|
|
|
<div><h3 id="inheritance">Inheritance</h3><pre><code class="python language-python hljs"><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Person</span>:</span>
|
|
<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">__init__</span><span class="hljs-params">(self, name, age)</span>:</span>
|
|
self.name = name
|
|
self.age = age
|
|
|
|
<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Employee</span><span class="hljs-params">(Person)</span>:</span>
|
|
<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">__init__</span><span class="hljs-params">(self, name, age, staff_num)</span>:</span>
|
|
super().__init__(name, age)
|
|
self.staff_num = staff_num
|
|
</code></pre></div>
|
|
|
|
<div><h3 id="multipleinheritance">Multiple Inheritance</h3><pre><code class="python language-python hljs"><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">A</span>:</span> <span class="hljs-keyword">pass</span>
|
|
<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">B</span>:</span> <span class="hljs-keyword">pass</span>
|
|
<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">C</span><span class="hljs-params">(A, B)</span>:</span> <span class="hljs-keyword">pass</span>
|
|
</code></pre></div>
|
|
|
|
<p><strong>MRO determines the order in which parent classes are traversed when searching for a method:</strong></p>
|
|
<pre><code class="python language-python hljs"><span class="hljs-meta">>>> </span>C.mro()
|
|
[<<span class="hljs-class"><span class="hljs-title">class</span> '<span class="hljs-title">C</span>'>, <<span class="hljs-title">class</span> '<span class="hljs-title">A</span>'>, <<span class="hljs-title">class</span> '<span class="hljs-title">B</span>'>, <<span class="hljs-title">class</span> '<span class="hljs-title">object</span>'>]
|
|
</span></code></pre>
|
|
<div><h3 id="property">Property</h3><p><strong>Pythonic way of implementing getters and setters.</strong></p><pre><code class="python language-python hljs"><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">MyClass</span>:</span>
|
|
<span class="hljs-meta"> @property</span>
|
|
<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">a</span><span class="hljs-params">(self)</span>:</span>
|
|
<span class="hljs-keyword">return</span> self._a
|
|
|
|
<span class="hljs-meta"> @a.setter</span>
|
|
<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">a</span><span class="hljs-params">(self, value)</span>:</span>
|
|
self._a = value
|
|
</code></pre></div>
|
|
|
|
|
|
<pre><code class="python language-python hljs"><span class="hljs-meta">>>> </span>el = MyClass()
|
|
<span class="hljs-meta">>>> </span>el.a = <span class="hljs-number">123</span>
|
|
<span class="hljs-meta">>>> </span>el.a
|
|
<span class="hljs-number">123</span>
|
|
</code></pre>
|
|
<div><h3 id="dataclass">Dataclass</h3><p><strong>Decorator that automatically generates init(), repr() and eq() special methods.</strong></p><pre><code class="python language-python hljs"><span class="hljs-keyword">from</span> dataclasses <span class="hljs-keyword">import</span> dataclass, field
|
|
|
|
<span class="hljs-meta">@dataclass(order=False, frozen=False)</span>
|
|
<span class="hljs-class"><span class="hljs-keyword">class</span> <<span class="hljs-title">class_name</span>>:</span>
|
|
<attr_name_1>: <type>
|
|
<attr_name_2>: <type> = <default_value>
|
|
<attr_name_3>: list/dict/set = field(default_factory=list/dict/set)
|
|
</code></pre></div>
|
|
|
|
|
|
<ul>
|
|
<li><strong>Objects can be made sortable with <code class="python hljs"><span class="hljs-string">'order=True'</span></code> and/or immutable and hashable with <code class="python hljs"><span class="hljs-string">'frozen=True'</span></code>.</strong></li>
|
|
<li><strong>Function field() is needed because <code class="python hljs"><span class="hljs-string">'<attr_name>: list = []'</span></code> would make a list that is shared among all instances.</strong></li>
|
|
<li><strong>Default_factory can be any <a href="#callable">callable</a>.</strong></li>
|
|
</ul>
|
|
<div><h4 id="inline-1">Inline:</h4><pre><code class="python language-python hljs"><code class="python language-python hljs"><span class="hljs-keyword">from</span> dataclasses <span class="hljs-keyword">import</span> make_dataclass
|
|
<class> = make_dataclass(<span class="hljs-string">'<class_name>'</span>, <coll_of_attribute_names>)
|
|
<class> = make_dataclass(<span class="hljs-string">'<class_name>'</span>, <coll_of_tuples>)
|
|
<tuple> = (<span class="hljs-string">'<attr_name>'</span>, <type> [, <default_value>])</code></code></pre></div>
|
|
|
|
<div><h3 id="slots">Slots</h3><p><strong>Mechanism that restricts objects to attributes listed in 'slots' and significantly reduces their memory footprint.</strong></p><pre><code class="python language-python hljs"><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">MyClassWithSlots</span>:</span>
|
|
__slots__ = [<span class="hljs-string">'a'</span>]
|
|
<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">__init__</span><span class="hljs-params">(self)</span>:</span>
|
|
self.a = <span class="hljs-number">1</span>
|
|
</code></pre></div>
|
|
|
|
|
|
<div><h3 id="copy">Copy</h3><pre><code class="python language-python hljs"><span class="hljs-keyword">from</span> copy <span class="hljs-keyword">import</span> copy, deepcopy
|
|
<object> = copy(<object>)
|
|
<object> = deepcopy(<object>)
|
|
</code></pre></div>
|
|
|
|
<div><h2 id="ducktypes"><a href="#ducktypes" name="ducktypes">#</a>Duck Types</h2><p><strong>A duck type is an implicit type that prescribes a set of special methods. Any object that has those methods defined is considered a member of that duck type.</strong></p><div><h3 id="comparable">Comparable</h3><ul>
|
|
<li><strong>If eq() method is not overridden, it returns <code class="python hljs"><span class="hljs-string">'id(self) == id(other)'</span></code>, which is the same as <code class="python hljs"><span class="hljs-string">'self is other'</span></code>.</strong></li>
|
|
<li><strong>That means all objects compare not equal by default.</strong></li>
|
|
<li><strong>Only the left side object has eq() method called, unless it returns NotImplemented, in which case the right object is consulted.</strong></li>
|
|
</ul><pre><code class="python language-python hljs"><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">MyComparable</span>:</span>
|
|
<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">__init__</span><span class="hljs-params">(self, a)</span>:</span>
|
|
self.a = a
|
|
<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">__eq__</span><span class="hljs-params">(self, other)</span>:</span>
|
|
<span class="hljs-keyword">if</span> isinstance(other, type(self)):
|
|
<span class="hljs-keyword">return</span> self.a == other.a
|
|
<span class="hljs-keyword">return</span> <span class="hljs-built_in">NotImplemented</span>
|
|
</code></pre></div></div>
|
|
|
|
|
|
|
|
|
|
<div><h3 id="hashable">Hashable</h3><ul>
|
|
<li><strong>Hashable object needs both hash() and eq() methods and its hash value should never change.</strong></li>
|
|
<li><strong>Hashable objects that compare equal must have the same hash value, meaning default hash() that returns <code class="python hljs"><span class="hljs-string">'id(self)'</span></code> will not do.</strong></li>
|
|
<li><strong>That is why Python automatically makes classes unhashable if you only implement eq().</strong></li>
|
|
</ul><pre><code class="python language-python hljs"><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">MyHashable</span>:</span>
|
|
<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">__init__</span><span class="hljs-params">(self, a)</span>:</span>
|
|
self._a = copy.deepcopy(a)
|
|
<span class="hljs-meta"> @property</span>
|
|
<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">a</span><span class="hljs-params">(self)</span>:</span>
|
|
<span class="hljs-keyword">return</span> self._a
|
|
<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">__eq__</span><span class="hljs-params">(self, other)</span>:</span>
|
|
<span class="hljs-keyword">if</span> isinstance(other, type(self)):
|
|
<span class="hljs-keyword">return</span> self.a == other.a
|
|
<span class="hljs-keyword">return</span> <span class="hljs-built_in">NotImplemented</span>
|
|
<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">__hash__</span><span class="hljs-params">(self)</span>:</span>
|
|
<span class="hljs-keyword">return</span> hash(self.a)
|
|
</code></pre></div>
|
|
|
|
|
|
<div><h3 id="sortable">Sortable</h3><ul>
|
|
<li><strong>With total_ordering decorator you only need to provide eq() and one of lt(), gt(), le() or ge() special methods.</strong></li>
|
|
</ul><pre><code class="python language-python hljs"><span class="hljs-keyword">from</span> functools <span class="hljs-keyword">import</span> total_ordering
|
|
|
|
<span class="hljs-meta">@total_ordering</span>
|
|
<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">MySortable</span>:</span>
|
|
<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">__init__</span><span class="hljs-params">(self, a)</span>:</span>
|
|
self.a = a
|
|
<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">__eq__</span><span class="hljs-params">(self, other)</span>:</span>
|
|
<span class="hljs-keyword">if</span> isinstance(other, type(self)):
|
|
<span class="hljs-keyword">return</span> self.a == other.a
|
|
<span class="hljs-keyword">return</span> <span class="hljs-built_in">NotImplemented</span>
|
|
<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">__lt__</span><span class="hljs-params">(self, other)</span>:</span>
|
|
<span class="hljs-keyword">if</span> isinstance(other, type(self)):
|
|
<span class="hljs-keyword">return</span> self.a < other.a
|
|
<span class="hljs-keyword">return</span> <span class="hljs-built_in">NotImplemented</span>
|
|
</code></pre></div>
|
|
|
|
|
|
<div><h3 id="iterator-1">Iterator</h3><ul>
|
|
<li><strong>Any object that has methods next() and iter() is an iterator.</strong></li>
|
|
<li><strong>Next() should return next item or raise StopIteration.</strong></li>
|
|
<li><strong>Iter() should return 'self'.</strong></li>
|
|
</ul><pre><code class="python language-python hljs"><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Counter</span>:</span>
|
|
<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">__init__</span><span class="hljs-params">(self)</span>:</span>
|
|
self.i = <span class="hljs-number">0</span>
|
|
<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">__next__</span><span class="hljs-params">(self)</span>:</span>
|
|
self.i += <span class="hljs-number">1</span>
|
|
<span class="hljs-keyword">return</span> self.i
|
|
<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">__iter__</span><span class="hljs-params">(self)</span>:</span>
|
|
<span class="hljs-keyword">return</span> self
|
|
</code></pre></div>
|
|
|
|
|
|
<pre><code class="python language-python hljs"><span class="hljs-meta">>>> </span>counter = Counter()
|
|
<span class="hljs-meta">>>> </span>next(counter), next(counter), next(counter)
|
|
(<span class="hljs-number">1</span>, <span class="hljs-number">2</span>, <span class="hljs-number">3</span>)
|
|
</code></pre>
|
|
<div><h4 id="pythonhasmanydifferentiteratorobjects">Python has many different iterator objects:</h4><ul>
|
|
<li><strong>Iterators returned by the <a href="#iterator">iter()</a> function, such as list_iterator and set_iterator.</strong></li>
|
|
<li><strong>Objects returned by the <a href="#itertools">itertools</a> module, such as count, repeat and cycle.</strong></li>
|
|
<li><strong>Generators returned by the <a href="#generator">generator functions</a> and <a href="#comprehension">generator expressions</a>.</strong></li>
|
|
<li><strong>File objects returned by the <a href="#open">open()</a> function, etc.</strong></li>
|
|
</ul><div><h3 id="callable">Callable</h3><ul>
|
|
<li><strong>All functions and classes have a call() method, hence are callable.</strong></li>
|
|
<li><strong>When this cheatsheet uses <code class="python hljs"><span class="hljs-string">'<function>'</span></code> as an argument, it actually means <code class="python hljs"><span class="hljs-string">'<callable>'</span></code>.</strong></li>
|
|
</ul><pre><code class="python language-python hljs"><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Counter</span>:</span>
|
|
<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">__init__</span><span class="hljs-params">(self)</span>:</span>
|
|
self.i = <span class="hljs-number">0</span>
|
|
<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">__call__</span><span class="hljs-params">(self)</span>:</span>
|
|
self.i += <span class="hljs-number">1</span>
|
|
<span class="hljs-keyword">return</span> self.i
|
|
</code></pre></div></div>
|
|
|
|
|
|
|
|
|
|
<pre><code class="python language-python hljs"><span class="hljs-meta">>>> </span>counter = Counter()
|
|
<span class="hljs-meta">>>> </span>counter(), counter(), counter()
|
|
(<span class="hljs-number">1</span>, <span class="hljs-number">2</span>, <span class="hljs-number">3</span>)
|
|
</code></pre>
|
|
<div><h3 id="contextmanager">Context Manager</h3><ul>
|
|
<li><strong>Enter() should lock the resources and (optionally) return an object.</strong></li>
|
|
<li><strong>Exit() should release the resources.</strong></li>
|
|
<li><strong>Any exception that happens inside the with block is passed to the exit() method.</strong></li>
|
|
<li><strong>If it wishes to suppress the exception it must return a true value.</strong> </li>
|
|
</ul><pre><code class="python language-python hljs"><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">MyOpen</span><span class="hljs-params">()</span>:</span>
|
|
<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">__init__</span><span class="hljs-params">(self, filename)</span>:</span>
|
|
self.filename = filename
|
|
<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">__enter__</span><span class="hljs-params">(self)</span>:</span>
|
|
self.file = open(self.filename)
|
|
<span class="hljs-keyword">return</span> self.file
|
|
<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">__exit__</span><span class="hljs-params">(self, exc_type, exception, traceback)</span>:</span>
|
|
self.file.close()
|
|
</code></pre></div>
|
|
|
|
|
|
<pre><code class="python language-python hljs"><span class="hljs-meta">>>> </span><span class="hljs-keyword">with</span> open(<span class="hljs-string">'test.txt'</span>, <span class="hljs-string">'w'</span>) <span class="hljs-keyword">as</span> file:
|
|
<span class="hljs-meta">... </span> file.write(<span class="hljs-string">'Hello World!'</span>)
|
|
<span class="hljs-meta">>>> </span><span class="hljs-keyword">with</span> MyOpen(<span class="hljs-string">'test.txt'</span>) <span class="hljs-keyword">as</span> file:
|
|
<span class="hljs-meta">... </span> print(file.read())
|
|
Hello World!
|
|
</code></pre>
|
|
<div><h2 id="iterableducktypes"><a href="#iterableducktypes" name="iterableducktypes">#</a>Iterable Duck Types</h2><div><h3 id="iterable">Iterable</h3><ul>
|
|
<li><strong>Only required method is iter(). It should return an iterator of object's items.</strong></li>
|
|
<li><strong>Contains() automatically works on any object that has iter() defined.</strong></li>
|
|
</ul><pre><code class="python language-python hljs"><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">MyIterable</span>:</span>
|
|
<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">__init__</span><span class="hljs-params">(self, a)</span>:</span>
|
|
self.a = a
|
|
<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">__iter__</span><span class="hljs-params">(self)</span>:</span>
|
|
<span class="hljs-keyword">for</span> el <span class="hljs-keyword">in</span> self.a:
|
|
<span class="hljs-keyword">yield</span> el
|
|
</code></pre></div></div>
|
|
|
|
|
|
|
|
<pre><code class="python language-python hljs"><span class="hljs-meta">>>> </span>obj = MyIterable([<span class="hljs-number">1</span>, <span class="hljs-number">2</span>, <span class="hljs-number">3</span>])
|
|
<span class="hljs-meta">>>> </span>[el <span class="hljs-keyword">for</span> el <span class="hljs-keyword">in</span> obj]
|
|
[<span class="hljs-number">1</span>, <span class="hljs-number">2</span>, <span class="hljs-number">3</span>]
|
|
<span class="hljs-meta">>>> </span><span class="hljs-number">1</span> <span class="hljs-keyword">in</span> obj
|
|
<span class="hljs-keyword">True</span>
|
|
</code></pre>
|
|
<div><h3 id="collection">Collection</h3><ul>
|
|
<li><strong>Only required methods are iter() and len().</strong></li>
|
|
<li><strong>This cheatsheet actually means <code class="python hljs"><span class="hljs-string">'<iterable>'</span></code> when it uses <code class="python hljs"><span class="hljs-string">'<collection>'</span></code>.</strong></li>
|
|
<li><strong>I chose not to use the name 'iterable' because it sounds scarier and more vague than 'collection'.</strong></li>
|
|
</ul><pre><code class="python language-python hljs"><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">MyCollection</span>:</span>
|
|
<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">__init__</span><span class="hljs-params">(self, a)</span>:</span>
|
|
self.a = a
|
|
<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">__iter__</span><span class="hljs-params">(self)</span>:</span>
|
|
<span class="hljs-keyword">return</span> iter(self.a)
|
|
<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">__contains__</span><span class="hljs-params">(self, el)</span>:</span>
|
|
<span class="hljs-keyword">return</span> el <span class="hljs-keyword">in</span> self.a
|
|
<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">__len__</span><span class="hljs-params">(self)</span>:</span>
|
|
<span class="hljs-keyword">return</span> len(self.a)
|
|
</code></pre></div>
|
|
|
|
|
|
<div><h3 id="sequence">Sequence</h3><ul>
|
|
<li><strong>Only required methods are len() and getitem().</strong></li>
|
|
<li><strong>Getitem() should return an item at index or raise IndexError.</strong></li>
|
|
<li><strong>Iter() and contains() automatically work on any object that has getitem() defined.</strong></li>
|
|
<li><strong>Reversed() automatically works on any object that has getitem() and len() defined.</strong></li>
|
|
</ul><pre><code class="python language-python hljs"><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">MySequence</span>:</span>
|
|
<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">__init__</span><span class="hljs-params">(self, a)</span>:</span>
|
|
self.a = a
|
|
<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">__iter__</span><span class="hljs-params">(self)</span>:</span>
|
|
<span class="hljs-keyword">return</span> iter(self.a)
|
|
<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">__contains__</span><span class="hljs-params">(self, el)</span>:</span>
|
|
<span class="hljs-keyword">return</span> el <span class="hljs-keyword">in</span> self.a
|
|
<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">__len__</span><span class="hljs-params">(self)</span>:</span>
|
|
<span class="hljs-keyword">return</span> len(self.a)
|
|
<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">__getitem__</span><span class="hljs-params">(self, i)</span>:</span>
|
|
<span class="hljs-keyword">return</span> self.a[i]
|
|
<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">__reversed__</span><span class="hljs-params">(self)</span>:</span>
|
|
<span class="hljs-keyword">return</span> reversed(self.a)
|
|
</code></pre></div>
|
|
|
|
|
|
<div><h3 id="collectionsabcsequence">Collections.abc.Sequence</h3><ul>
|
|
<li><strong>It's a richer interface than the basic sequence.</strong></li>
|
|
<li><strong>Extending it generates iter(), contains(), reversed(), index() and count().</strong></li>
|
|
<li><strong>Unlike <code class="python hljs"><span class="hljs-string">'abc.Iterable'</span></code> and <code class="python hljs"><span class="hljs-string">'abc.Collection'</span></code>, it is not a duck type. That is why <code class="python hljs"><span class="hljs-string">'issubclass(MySequence, abc.Sequence)'</span></code> would return False even if MySequence had all the methods defined.</strong></li>
|
|
</ul><pre><code class="python language-python hljs"><span class="hljs-keyword">from</span> collections <span class="hljs-keyword">import</span> abc
|
|
|
|
<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">MyAbcSequence</span><span class="hljs-params">(abc.Sequence)</span>:</span>
|
|
<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">__init__</span><span class="hljs-params">(self, a)</span>:</span>
|
|
self.a = a
|
|
<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">__len__</span><span class="hljs-params">(self)</span>:</span>
|
|
<span class="hljs-keyword">return</span> len(self.a)
|
|
<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">__getitem__</span><span class="hljs-params">(self, i)</span>:</span>
|
|
<span class="hljs-keyword">return</span> self.a[i]
|
|
</code></pre></div>
|
|
|
|
|
|
<div><h4 id="tableofrequiredandautomaticallyavailablespecialmethods">Table of required and automatically available special methods:</h4><pre><code class="text language-text">+------------+------------+------------+------------+--------------+
|
|
| | Iterable | Collection | Sequence | abc.Sequence |
|
|
+------------+------------+------------+------------+--------------+
|
|
| iter() | REQ | REQ | Yes | Yes |
|
|
| contains() | Yes | Yes | Yes | Yes |
|
|
| len() | | REQ | REQ | REQ |
|
|
| getitem() | | | REQ | REQ |
|
|
| reversed() | | | Yes | Yes |
|
|
| index() | | | | Yes |
|
|
| count() | | | | Yes |
|
|
+------------+------------+------------+------------+--------------+
|
|
</code></pre></div>
|
|
|
|
<ul>
|
|
<li><strong>Other ABCs that generate missing methods are: MutableSequence, Set, MutableSet, Mapping and MutableMapping.</strong></li>
|
|
<li><strong>Names of their required methods are stored in <code class="python hljs"><span class="hljs-string">'<abc>.__abstractmethods__'</span></code>.</strong></li>
|
|
</ul>
|
|
<div><h2 id="enum"><a href="#enum" name="enum">#</a>Enum</h2><pre><code class="python language-python hljs"><span class="hljs-keyword">from</span> enum <span class="hljs-keyword">import</span> Enum, auto
|
|
|
|
<span class="hljs-class"><span class="hljs-keyword">class</span> <<span class="hljs-title">enum_name</span>><span class="hljs-params">(Enum)</span>:</span>
|
|
<member_name_1> = <value_1>
|
|
<member_name_2> = <value_2_a>, <value_2_b>
|
|
<member_name_3> = auto()
|
|
</code></pre></div>
|
|
|
|
<ul>
|
|
<li><strong>If there are no numeric values before auto(), it returns 1.</strong></li>
|
|
<li><strong>Otherwise it returns an increment of the last numeric value.</strong></li>
|
|
</ul>
|
|
<pre><code class="python language-python hljs"><member> = <enum>.<member_name> <span class="hljs-comment"># Returns a member.</span>
|
|
<member> = <enum>[<span class="hljs-string">'<member_name>'</span>] <span class="hljs-comment"># Returns a member or raises KeyError.</span>
|
|
<member> = <enum>(<value>) <span class="hljs-comment"># Returns a member or raises ValueError.</span>
|
|
<str> = <member>.name <span class="hljs-comment"># Returns member's name.</span>
|
|
<obj> = <member>.value <span class="hljs-comment"># Returns member's value.</span>
|
|
</code></pre>
|
|
<pre><code class="python language-python hljs">list_of_members = list(<enum>)
|
|
member_names = [a.name <span class="hljs-keyword">for</span> a <span class="hljs-keyword">in</span> <enum>]
|
|
member_values = [a.value <span class="hljs-keyword">for</span> a <span class="hljs-keyword">in</span> <enum>]
|
|
random_member = random.choice(list(<enum>))
|
|
</code></pre>
|
|
<pre><code class="python language-python hljs"><span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">get_next_member</span><span class="hljs-params">(member)</span>:</span>
|
|
members = list(member.__class__)
|
|
index = (members.index(member) + <span class="hljs-number">1</span>) % len(members)
|
|
<span class="hljs-keyword">return</span> members[index]
|
|
</code></pre>
|
|
<div><h3 id="inline-2">Inline</h3><pre><code class="python language-python hljs">Cutlery = Enum(<span class="hljs-string">'Cutlery'</span>, <span class="hljs-string">'fork knife spoon'</span>)
|
|
Cutlery = Enum(<span class="hljs-string">'Cutlery'</span>, [<span class="hljs-string">'fork'</span>, <span class="hljs-string">'knife'</span>, <span class="hljs-string">'spoon'</span>])
|
|
Cutlery = Enum(<span class="hljs-string">'Cutlery'</span>, {<span class="hljs-string">'fork'</span>: <span class="hljs-number">1</span>, <span class="hljs-string">'knife'</span>: <span class="hljs-number">2</span>, <span class="hljs-string">'spoon'</span>: <span class="hljs-number">3</span>})
|
|
</code></pre></div>
|
|
|
|
<div><h4 id="userdefinedfunctionscannotbevaluessotheymustbewrapped">User-defined functions cannot be values, so they must be wrapped:</h4><pre><code class="python language-python hljs"><span class="hljs-keyword">from</span> functools <span class="hljs-keyword">import</span> partial
|
|
LogicOp = Enum(<span class="hljs-string">'LogicOp'</span>, {<span class="hljs-string">'AND'</span>: partial(<span class="hljs-keyword">lambda</span> l, r: l <span class="hljs-keyword">and</span> r),
|
|
<span class="hljs-string">'OR'</span> : partial(<span class="hljs-keyword">lambda</span> l, r: l <span class="hljs-keyword">or</span> r)})
|
|
</code></pre></div>
|
|
|
|
<ul>
|
|
<li><strong>Another solution in this particular case is to use built-in functions <code class="python hljs"><span class="hljs-string">'and_'</span></code> and <code class="python hljs"><span class="hljs-string">'or_'</span></code> from the module <a href="#operator">operator</a>.</strong></li>
|
|
</ul>
|
|
<div><h2 id="exceptions"><a href="#exceptions" name="exceptions">#</a>Exceptions</h2><div><h3 id="basicexample">Basic Example</h3><pre><code class="python language-python hljs"><span class="hljs-keyword">try</span>:
|
|
<code>
|
|
<span class="hljs-keyword">except</span> <exception>:
|
|
<code>
|
|
</code></pre></div></div>
|
|
|
|
|
|
<div><h3 id="complexexample">Complex Example</h3><pre><code class="python language-python hljs"><span class="hljs-keyword">try</span>:
|
|
<code_1>
|
|
<span class="hljs-keyword">except</span> <exception_a>:
|
|
<code_2_a>
|
|
<span class="hljs-keyword">except</span> <exception_b>:
|
|
<code_2_b>
|
|
<span class="hljs-keyword">else</span>:
|
|
<code_2_c>
|
|
<span class="hljs-keyword">finally</span>:
|
|
<code_3>
|
|
</code></pre></div>
|
|
|
|
<div><h3 id="catchingexceptions">Catching Exceptions</h3><pre><code class="python language-python hljs"><span class="hljs-keyword">except</span> <exception>:
|
|
<span class="hljs-keyword">except</span> <exception> <span class="hljs-keyword">as</span> <name>:
|
|
<span class="hljs-keyword">except</span> (<exception>, ...):
|
|
<span class="hljs-keyword">except</span> (<exception>, ...) <span class="hljs-keyword">as</span> <name>:
|
|
</code></pre></div>
|
|
|
|
<ul>
|
|
<li><strong>Also catches subclasses of the exception.</strong></li>
|
|
<li><strong>Use <code class="python hljs"><span class="hljs-string">'traceback.print_exc()'</span></code> to print the error message.</strong></li>
|
|
</ul>
|
|
<div><h3 id="raisingexceptions">Raising Exceptions</h3><pre><code class="python language-python hljs"><span class="hljs-keyword">raise</span> <exception>
|
|
<span class="hljs-keyword">raise</span> <exception>()
|
|
<span class="hljs-keyword">raise</span> <exception>(<el> [, ...])
|
|
</code></pre></div>
|
|
|
|
<div><h4 id="reraisingcaughtexception">Re-raising caught exception:</h4><pre><code class="python language-python hljs"><span class="hljs-keyword">except</span> <exception> <span class="hljs-keyword">as</span> <name>:
|
|
...
|
|
<span class="hljs-keyword">raise</span>
|
|
</code></pre></div>
|
|
|
|
<div><h3 id="exceptionobject">Exception Object</h3><pre><code class="python language-python hljs">arguments = <name>.args
|
|
exc_type = <name>.__class__
|
|
filename = <name>.__traceback__.tb_frame.f_code.co_filename
|
|
func_name = <name>.__traceback__.tb_frame.f_code.co_name
|
|
line = linecache.getline(filename, <name>.__traceback__.tb_lineno)
|
|
error_msg = traceback.format_exception(exc_type, <name>, <name>.__traceback__)
|
|
</code></pre></div>
|
|
|
|
<div><h3 id="builtinexceptions">Built-in Exceptions</h3><pre><code class="text language-text">BaseException
|
|
+-- SystemExit # Raised by the sys.exit() function.
|
|
+-- KeyboardInterrupt # Raised when the user hits the interrupt key (ctrl-c).
|
|
+-- Exception # User-defined exceptions should be derived from this class.
|
|
+-- StopIteration # Raised by next() when run on an empty iterator.
|
|
+-- ArithmeticError # Base class for arithmetic errors.
|
|
| +-- ZeroDivisionError # Raised when dividing by zero.
|
|
+-- AttributeError # Raised when an attribute is missing.
|
|
+-- EOFError # Raised by input() when it hits end-of-file condition.
|
|
+-- LookupError # Raised when a look-up on a collection fails.
|
|
| +-- IndexError # Raised when a sequence index is out of range.
|
|
| +-- KeyError # Raised when a dictionary key or set element is not found.
|
|
+-- NameError # Raised when a variable name is not found.
|
|
+-- OSError # Failures such as “file not found” or “disk full”.
|
|
| +-- FileNotFoundError # When a file or directory is requested but doesn't exist.
|
|
+-- RuntimeError # Raised by errors that don't fall in other categories.
|
|
| +-- RecursionError # Raised when the maximum recursion depth is exceeded.
|
|
+-- TypeError # Raised when an argument is of wrong type.
|
|
+-- ValueError # When an argument is of right type but inappropriate value.
|
|
+-- UnicodeError # Raised when encoding/decoding strings from/to bytes fails.
|
|
</code></pre></div>
|
|
|
|
<div><h4 id="collectionsandtheirexceptions">Collections and their exceptions:</h4><pre><code class="text language-text">+-----------+------------+------------+------------+
|
|
| | list | dict | set |
|
|
+-----------+------------+------------+------------+
|
|
| getitem() | IndexError | KeyError | |
|
|
| pop() | IndexError | KeyError | KeyError |
|
|
| remove() | ValueError | | KeyError |
|
|
| index() | ValueError | | |
|
|
+-----------+------------+------------+------------+
|
|
</code></pre></div>
|
|
|
|
<div><h4 id="usefulbuiltinexceptions">Useful built-in exceptions:</h4><pre><code class="python language-python hljs"><span class="hljs-keyword">raise</span> TypeError(<span class="hljs-string">'Argument is of wrong type!'</span>)
|
|
<span class="hljs-keyword">raise</span> ValueError(<span class="hljs-string">'Argument is of right type but inappropriate value!'</span>)
|
|
<span class="hljs-keyword">raise</span> RuntimeError(<span class="hljs-string">'None of above!'</span>)
|
|
</code></pre></div>
|
|
|
|
<div><h3 id="userdefinedexceptions">User-defined Exceptions</h3><pre><code class="python language-python hljs"><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">MyError</span><span class="hljs-params">(Exception)</span>:</span>
|
|
<span class="hljs-keyword">pass</span>
|
|
|
|
<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">MyInputError</span><span class="hljs-params">(MyError)</span>:</span>
|
|
<span class="hljs-keyword">pass</span>
|
|
</code></pre></div>
|
|
|
|
<div><h2 id="exit"><a href="#exit" name="exit">#</a>Exit</h2><p><strong>Exits the interpreter by raising SystemExit exception.</strong></p><pre><code class="python language-python hljs"><span class="hljs-keyword">import</span> sys
|
|
sys.exit() <span class="hljs-comment"># Exits with exit code 0 (success).</span>
|
|
sys.exit(<int>) <span class="hljs-comment"># Exits with passed exit code.</span>
|
|
sys.exit(<obj>) <span class="hljs-comment"># Prints the object and exits with 1 (failure).</span>
|
|
</code></pre></div>
|
|
|
|
|
|
<div class="pagebreak"></div><div><h2 id="print"><a href="#print" name="print">#</a>Print</h2><pre><code class="python language-python hljs">print(<el_1>, ..., sep=<span class="hljs-string">' '</span>, end=<span class="hljs-string">'\n'</span>, file=sys.stdout, flush=<span class="hljs-keyword">False</span>)
|
|
</code></pre></div>
|
|
|
|
<ul>
|
|
<li><strong>Use <code class="python hljs"><span class="hljs-string">'file=sys.stderr'</span></code> for messages about errors.</strong></li>
|
|
<li><strong>Use <code class="python hljs"><span class="hljs-string">'flush=True'</span></code> to forcibly flush the stream.</strong></li>
|
|
</ul>
|
|
<div><h3 id="prettyprint">Pretty Print</h3><pre><code class="python language-python hljs"><span class="hljs-keyword">from</span> pprint <span class="hljs-keyword">import</span> pprint
|
|
pprint(<collection>, width=<span class="hljs-number">80</span>, depth=<span class="hljs-keyword">None</span>, compact=<span class="hljs-keyword">False</span>, sort_dicts=<span class="hljs-keyword">True</span>)
|
|
</code></pre></div>
|
|
|
|
<ul>
|
|
<li><strong>Levels deeper than 'depth' get replaced by '…'.</strong></li>
|
|
</ul>
|
|
<div><h2 id="input"><a href="#input" name="input">#</a>Input</h2><p><strong>Reads a line from user input or pipe if present.</strong></p><pre><code class="python language-python hljs"><str> = input(prompt=<span class="hljs-keyword">None</span>)
|
|
</code></pre></div>
|
|
|
|
|
|
<ul>
|
|
<li><strong>Trailing newline gets stripped.</strong></li>
|
|
<li><strong>Prompt string is printed to the standard output before reading input.</strong></li>
|
|
<li><strong>Raises EOFError when user hits EOF (ctrl-d) or input stream gets exhausted.</strong></li>
|
|
</ul>
|
|
<div><h2 id="commandlinearguments"><a href="#commandlinearguments" name="commandlinearguments">#</a>Command Line Arguments</h2><pre><code class="python language-python hljs"><span class="hljs-keyword">import</span> sys
|
|
script_name = sys.argv[<span class="hljs-number">0</span>]
|
|
arguments = sys.argv[<span class="hljs-number">1</span>:]
|
|
</code></pre></div>
|
|
|
|
<div><h3 id="argparse">Argparse</h3><pre><code class="python language-python hljs"><span class="hljs-keyword">from</span> argparse <span class="hljs-keyword">import</span> ArgumentParser, FileType
|
|
p = ArgumentParser(description=<str>)
|
|
p.add_argument(<span class="hljs-string">'-<short_name>'</span>, <span class="hljs-string">'--<name>'</span>, action=<span class="hljs-string">'store_true'</span>) <span class="hljs-comment"># Flag</span>
|
|
p.add_argument(<span class="hljs-string">'-<short_name>'</span>, <span class="hljs-string">'--<name>'</span>, type=<type>) <span class="hljs-comment"># Option</span>
|
|
p.add_argument(<span class="hljs-string">'<name>'</span>, type=<type>, nargs=<span class="hljs-number">1</span>) <span class="hljs-comment"># First argument</span>
|
|
p.add_argument(<span class="hljs-string">'<name>'</span>, type=<type>, nargs=<span class="hljs-string">'+'</span>) <span class="hljs-comment"># Remaining arguments</span>
|
|
p.add_argument(<span class="hljs-string">'<name>'</span>, type=<type>, nargs=<span class="hljs-string">'*'</span>) <span class="hljs-comment"># Optional arguments</span>
|
|
args = p.parse_args() <span class="hljs-comment"># Exits on error.</span>
|
|
value = args.<name>
|
|
</code></pre></div>
|
|
|
|
<ul>
|
|
<li><strong>Use <code class="python hljs"><span class="hljs-string">'help=<str>'</span></code> to set argument description.</strong></li>
|
|
<li><strong>Use <code class="python hljs"><span class="hljs-string">'default=<el>'</span></code> to set the default value.</strong></li>
|
|
<li><strong>Use <code class="python hljs"><span class="hljs-string">'type=FileType(<mode>)'</span></code> for files.</strong></li>
|
|
</ul>
|
|
<div><h2 id="open"><a href="#open" name="open">#</a>Open</h2><p><strong>Opens the file and returns a corresponding file object.</strong></p><pre><code class="python language-python hljs"><file> = open(<span class="hljs-string">'<path>'</span>, mode=<span class="hljs-string">'r'</span>, encoding=<span class="hljs-keyword">None</span>, newline=<span class="hljs-keyword">None</span>)
|
|
</code></pre></div>
|
|
|
|
|
|
<ul>
|
|
<li><strong><code class="python hljs"><span class="hljs-string">'encoding=None'</span></code> means that the default encoding is used, which is platform dependent. Best practice is to use <code class="python hljs"><span class="hljs-string">'encoding="utf-8"'</span></code> whenever possible.</strong></li>
|
|
<li><strong><code class="python hljs"><span class="hljs-string">'newline=None'</span></code> means all different end of line combinations are converted to '\n' on read, while on write all '\n' characters are converted to system's default line separator.</strong></li>
|
|
<li><strong><code class="python hljs"><span class="hljs-string">'newline=""'</span></code> means no conversions take place, but input is still broken into chunks by readline() and readlines() on either '\n', '\r' or '\r\n'.</strong></li>
|
|
</ul>
|
|
<div><h3 id="modes">Modes</h3><ul>
|
|
<li><strong><code class="python hljs"><span class="hljs-string">'r'</span></code> - Read (default).</strong></li>
|
|
<li><strong><code class="python hljs"><span class="hljs-string">'w'</span></code> - Write (truncate).</strong></li>
|
|
<li><strong><code class="python hljs"><span class="hljs-string">'x'</span></code> - Write or fail if the file already exists.</strong></li>
|
|
<li><strong><code class="python hljs"><span class="hljs-string">'a'</span></code> - Append.</strong></li>
|
|
<li><strong><code class="python hljs"><span class="hljs-string">'w+'</span></code> - Read and write (truncate).</strong></li>
|
|
<li><strong><code class="python hljs"><span class="hljs-string">'r+'</span></code> - Read and write from the start.</strong></li>
|
|
<li><strong><code class="python hljs"><span class="hljs-string">'a+'</span></code> - Read and write from the end.</strong></li>
|
|
<li><strong><code class="python hljs"><span class="hljs-string">'t'</span></code> - Text mode (default).</strong></li>
|
|
<li><strong><code class="python hljs"><span class="hljs-string">'b'</span></code> - Binary mode.</strong></li>
|
|
</ul><div><h3 id="exceptions-1">Exceptions</h3><ul>
|
|
<li><strong><code class="python hljs"><span class="hljs-string">'FileNotFoundError'</span></code> can be raised when reading with <code class="python hljs"><span class="hljs-string">'r'</span></code> or <code class="python hljs"><span class="hljs-string">'r+'</span></code>.</strong></li>
|
|
<li><strong><code class="python hljs"><span class="hljs-string">'FileExistsError'</span></code> can be raised when writing with <code class="python hljs"><span class="hljs-string">'x'</span></code>.</strong></li>
|
|
<li><strong><code class="python hljs"><span class="hljs-string">'IsADirectoryError'</span></code> and <code class="python hljs"><span class="hljs-string">'PermissionError'</span></code> can be raised by any.</strong></li>
|
|
<li><strong><code class="python hljs"><span class="hljs-string">'OSError'</span></code> is the parent class of all listed exceptions.</strong></li>
|
|
</ul><div><h3 id="fileobject">File Object</h3><pre><code class="python language-python hljs"><file>.seek(<span class="hljs-number">0</span>) <span class="hljs-comment"># Moves to the start of the file.</span>
|
|
<file>.seek(offset) <span class="hljs-comment"># Moves 'offset' chars/bytes from the start.</span>
|
|
<file>.seek(<span class="hljs-number">0</span>, <span class="hljs-number">2</span>) <span class="hljs-comment"># Moves to the end of the file.</span>
|
|
<bin_file>.seek(±offset, <anchor>) <span class="hljs-comment"># Anchor: 0 start, 1 current pos., 2 end.</span>
|
|
</code></pre></div></div></div>
|
|
|
|
|
|
|
|
|
|
|
|
<pre><code class="python language-python hljs"><str/bytes> = <file>.read(size=<span class="hljs-number">-1</span>) <span class="hljs-comment"># Reads 'size' chars/bytes or until EOF.</span>
|
|
<str/bytes> = <file>.readline() <span class="hljs-comment"># Returns a line or empty string/bytes on EOF.</span>
|
|
<list> = <file>.readlines() <span class="hljs-comment"># Returns a list of remaining lines.</span>
|
|
<str/bytes> = next(<file>) <span class="hljs-comment"># Returns a line using buffer. Do not mix.</span>
|
|
</code></pre>
|
|
<pre><code class="python language-python hljs"><file>.write(<str/bytes>) <span class="hljs-comment"># Writes a string or bytes object.</span>
|
|
<file>.writelines(<collection>) <span class="hljs-comment"># Writes a coll. of strings or bytes objects.</span>
|
|
<file>.flush() <span class="hljs-comment"># Flushes write buffer.</span>
|
|
</code></pre>
|
|
<ul>
|
|
<li><strong>Methods do not add or strip trailing newlines, even writelines().</strong></li>
|
|
</ul>
|
|
<div><h3 id="readtextfromfile">Read Text from File</h3><pre><code class="python language-python hljs"><span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">read_file</span><span class="hljs-params">(filename)</span>:</span>
|
|
<span class="hljs-keyword">with</span> open(filename, encoding=<span class="hljs-string">'utf-8'</span>) <span class="hljs-keyword">as</span> file:
|
|
<span class="hljs-keyword">return</span> file.readlines()
|
|
</code></pre></div>
|
|
|
|
<div><h3 id="writetexttofile">Write Text to File</h3><pre><code class="python language-python hljs"><span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">write_to_file</span><span class="hljs-params">(filename, text)</span>:</span>
|
|
<span class="hljs-keyword">with</span> open(filename, <span class="hljs-string">'w'</span>, encoding=<span class="hljs-string">'utf-8'</span>) <span class="hljs-keyword">as</span> file:
|
|
file.write(text)
|
|
</code></pre></div>
|
|
|
|
<div><h2 id="path"><a href="#path" name="path">#</a>Path</h2><pre><code class="python language-python hljs"><span class="hljs-keyword">from</span> os <span class="hljs-keyword">import</span> getcwd, path, listdir
|
|
<span class="hljs-keyword">from</span> glob <span class="hljs-keyword">import</span> glob
|
|
</code></pre></div>
|
|
|
|
<pre><code class="python language-python hljs"><str> = getcwd() <span class="hljs-comment"># Returns current working directory.</span>
|
|
<str> = path.join(<path>, ...) <span class="hljs-comment"># Joins two or more pathname components.</span>
|
|
<str> = path.abspath(<path>) <span class="hljs-comment"># Returns absolute path.</span>
|
|
</code></pre>
|
|
<pre><code class="python language-python hljs"><str> = path.basename(<path>) <span class="hljs-comment"># Returns final component of the path.</span>
|
|
<str> = path.dirname(<path>) <span class="hljs-comment"># Returns path without the final component.</span>
|
|
<tup.> = path.splitext(<path>) <span class="hljs-comment"># Splits on last period of the final component.</span>
|
|
</code></pre>
|
|
<pre><code class="python language-python hljs"><list> = listdir(path=<span class="hljs-string">'.'</span>) <span class="hljs-comment"># Returns filenames located at path.</span>
|
|
<list> = glob(<span class="hljs-string">'<pattern>'</span>) <span class="hljs-comment"># Returns paths matching the wildcard pattern.</span>
|
|
</code></pre>
|
|
<pre><code class="python language-python hljs"><bool> = path.exists(<path>) <span class="hljs-comment"># Or: <Path>.exists()</span>
|
|
<bool> = path.isfile(<path>) <span class="hljs-comment"># Or: <DirEntry/Path>.is_file()</span>
|
|
<bool> = path.isdir(<path>) <span class="hljs-comment"># Or: <DirEntry/Path>.is_dir()</span>
|
|
</code></pre>
|
|
<div><h3 id="direntry">DirEntry</h3><p><strong>Using scandir() instead of listdir() can significantly increase the performance of code that also needs file type information.</strong></p><pre><code class="python language-python hljs"><span class="hljs-keyword">from</span> os <span class="hljs-keyword">import</span> scandir
|
|
</code></pre></div>
|
|
|
|
|
|
<pre><code class="python language-python hljs"><iter> = scandir(path=<span class="hljs-string">'.'</span>) <span class="hljs-comment"># Returns DirEntry objects located at path.</span>
|
|
<str> = <DirEntry>.path <span class="hljs-comment"># Returns path as a string.</span>
|
|
<str> = <DirEntry>.name <span class="hljs-comment"># Returns final component as a string.</span>
|
|
<file> = open(<DirEntry>) <span class="hljs-comment"># Opens the file and returns file object.</span>
|
|
</code></pre>
|
|
<div><h3 id="pathobject">Path Object</h3><pre><code class="python language-python hljs"><span class="hljs-keyword">from</span> pathlib <span class="hljs-keyword">import</span> Path
|
|
</code></pre></div>
|
|
|
|
<pre><code class="python language-python hljs"><Path> = Path(<path> [, ...]) <span class="hljs-comment"># Accepts strings, Paths and DirEntry objects.</span>
|
|
<Path> = <path> / <path> [/ ...] <span class="hljs-comment"># One of the paths must be a Path object.</span>
|
|
</code></pre>
|
|
<pre><code class="python language-python hljs"><Path> = Path() <span class="hljs-comment"># Returns relative cwd. Also Path('.').</span>
|
|
<Path> = Path.cwd() <span class="hljs-comment"># Returns absolute cwd. Also Path().resolve().</span>
|
|
<Path> = <Path>.resolve() <span class="hljs-comment"># Returns absolute Path without symlinks.</span>
|
|
</code></pre>
|
|
<pre><code class="python language-python hljs"><Path> = <Path>.parent <span class="hljs-comment"># Returns Path without final component.</span>
|
|
<str> = <Path>.name <span class="hljs-comment"># Returns final component as a string.</span>
|
|
<str> = <Path>.stem <span class="hljs-comment"># Returns final component without extension.</span>
|
|
<str> = <Path>.suffix <span class="hljs-comment"># Returns final component's extension.</span>
|
|
<tup.> = <Path>.parts <span class="hljs-comment"># Returns all components as strings.</span>
|
|
</code></pre>
|
|
<pre><code class="python language-python hljs"><iter> = <Path>.iterdir() <span class="hljs-comment"># Returns dir contents as Path objects.</span>
|
|
<iter> = <Path>.glob(<span class="hljs-string">'<pattern>'</span>) <span class="hljs-comment"># Returns Paths matching the wildcard pattern.</span>
|
|
</code></pre>
|
|
<pre><code class="python language-python hljs"><str> = str(<Path>) <span class="hljs-comment"># Returns path as a string.</span>
|
|
<file> = open(<Path>) <span class="hljs-comment"># Opens the file and returns file object.</span>
|
|
</code></pre>
|
|
<div><h2 id="oscommands"><a href="#oscommands" name="oscommands">#</a>OS Commands</h2><div><h3 id="filesanddirectories">Files and Directories</h3><ul>
|
|
<li><strong>Paths can be either strings, Paths, or DirEntry objects.</strong></li>
|
|
<li><strong>Functions report OS related errors by raising either OSError or one of its <a href="#exceptions-1">subclasses</a>.</strong></li>
|
|
</ul><pre><code class="python language-python hljs"><span class="hljs-keyword">import</span> os, shutil
|
|
</code></pre></div></div>
|
|
|
|
|
|
|
|
<pre><code class="python language-python hljs">os.chdir(<path>) <span class="hljs-comment"># Changes current working directory.</span>
|
|
os.mkdir(<path>, mode=<span class="hljs-number">0o777</span>) <span class="hljs-comment"># Creates a directory. Mode is in octal.</span>
|
|
</code></pre>
|
|
<pre><code class="python language-python hljs">shutil.copy(from, to) <span class="hljs-comment"># Copies the file.</span>
|
|
shutil.copytree(from, to) <span class="hljs-comment"># Copies the directory.</span>
|
|
</code></pre>
|
|
<pre><code class="python language-python hljs">os.rename(from, to) <span class="hljs-comment"># Renames or moves the file or directory.</span>
|
|
os.replace(from, to) <span class="hljs-comment"># Same, but overwrites 'to' if it exists.</span>
|
|
</code></pre>
|
|
<pre><code class="python language-python hljs">os.remove(<path>) <span class="hljs-comment"># Deletes the file.</span>
|
|
os.rmdir(<path>) <span class="hljs-comment"># Deletes the empty directory.</span>
|
|
shutil.rmtree(<path>) <span class="hljs-comment"># Deletes the non-empty directory.</span>
|
|
</code></pre>
|
|
<div><h3 id="shellcommands">Shell Commands</h3><pre><code class="python language-python hljs"><span class="hljs-keyword">import</span> os
|
|
<str> = os.popen(<span class="hljs-string">'<shell_command>'</span>).read()
|
|
</code></pre></div>
|
|
|
|
<div><h4 id="sends11tothecalculatorandcapturesitsoutput">Sends '1 + 1' to the calculator and captures its output:</h4><pre><code class="python language-python hljs"><span class="hljs-meta">>>> </span><span class="hljs-keyword">from</span> subprocess <span class="hljs-keyword">import</span> run
|
|
<span class="hljs-meta">>>> </span>run(<span class="hljs-string">'bc'</span>, input=<span class="hljs-string">'1 + 1\n'</span>, capture_output=<span class="hljs-keyword">True</span>, encoding=<span class="hljs-string">'utf-8'</span>)
|
|
CompletedProcess(args=<span class="hljs-string">'bc'</span>, returncode=<span class="hljs-number">0</span>, stdout=<span class="hljs-string">'2\n'</span>, stderr=<span class="hljs-string">''</span>)
|
|
</code></pre></div>
|
|
|
|
<div><h4 id="sendstestintothecalculatorrunninginstandardmodeandsavesitsoutputtotestout">Sends test.in to the calculator running in standard mode and saves its output to test.out:</h4><pre><code class="python language-python hljs"><span class="hljs-meta">>>> </span><span class="hljs-keyword">from</span> shlex <span class="hljs-keyword">import</span> split
|
|
<span class="hljs-meta">>>> </span>os.popen(<span class="hljs-string">'echo 1 + 1 > test.in'</span>)
|
|
<span class="hljs-meta">>>> </span>run(split(<span class="hljs-string">'bc -s'</span>), stdin=open(<span class="hljs-string">'test.in'</span>), stdout=open(<span class="hljs-string">'test.out'</span>, <span class="hljs-string">'w'</span>))
|
|
CompletedProcess(args=[<span class="hljs-string">'bc'</span>, <span class="hljs-string">'-s'</span>], returncode=<span class="hljs-number">0</span>)
|
|
<span class="hljs-meta">>>> </span>open(<span class="hljs-string">'test.out'</span>).read()
|
|
<span class="hljs-string">'2\n'</span>
|
|
</code></pre></div>
|
|
|
|
<div><h2 id="json"><a href="#json" name="json">#</a>JSON</h2><p><strong>Text file format for storing collections of strings and numbers.</strong></p><pre><code class="python language-python hljs"><span class="hljs-keyword">import</span> json
|
|
<str> = json.dumps(<object>, ensure_ascii=<span class="hljs-keyword">True</span>, indent=<span class="hljs-keyword">None</span>)
|
|
<object> = json.loads(<str>)
|
|
</code></pre></div>
|
|
|
|
|
|
<div><h3 id="readobjectfromjsonfile">Read Object from JSON File</h3><pre><code class="python language-python hljs"><span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">read_json_file</span><span class="hljs-params">(filename)</span>:</span>
|
|
<span class="hljs-keyword">with</span> open(filename, encoding=<span class="hljs-string">'utf-8'</span>) <span class="hljs-keyword">as</span> file:
|
|
<span class="hljs-keyword">return</span> json.load(file)
|
|
</code></pre></div>
|
|
|
|
<div><h3 id="writeobjecttojsonfile">Write Object to JSON File</h3><pre><code class="python language-python hljs"><span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">write_to_json_file</span><span class="hljs-params">(filename, an_object)</span>:</span>
|
|
<span class="hljs-keyword">with</span> open(filename, <span class="hljs-string">'w'</span>, encoding=<span class="hljs-string">'utf-8'</span>) <span class="hljs-keyword">as</span> file:
|
|
json.dump(an_object, file, ensure_ascii=<span class="hljs-keyword">False</span>, indent=<span class="hljs-number">2</span>)
|
|
</code></pre></div>
|
|
|
|
<div><h2 id="pickle"><a href="#pickle" name="pickle">#</a>Pickle</h2><p><strong>Binary file format for storing objects.</strong></p><pre><code class="python language-python hljs"><span class="hljs-keyword">import</span> pickle
|
|
<bytes> = pickle.dumps(<object>)
|
|
<object> = pickle.loads(<bytes>)
|
|
</code></pre></div>
|
|
|
|
|
|
<div><h3 id="readobjectfromfile">Read Object from File</h3><pre><code class="python language-python hljs"><span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">read_pickle_file</span><span class="hljs-params">(filename)</span>:</span>
|
|
<span class="hljs-keyword">with</span> open(filename, <span class="hljs-string">'rb'</span>) <span class="hljs-keyword">as</span> file:
|
|
<span class="hljs-keyword">return</span> pickle.load(file)
|
|
</code></pre></div>
|
|
|
|
<div><h3 id="writeobjecttofile">Write Object to File</h3><pre><code class="python language-python hljs"><span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">write_to_pickle_file</span><span class="hljs-params">(filename, an_object)</span>:</span>
|
|
<span class="hljs-keyword">with</span> open(filename, <span class="hljs-string">'wb'</span>) <span class="hljs-keyword">as</span> file:
|
|
pickle.dump(an_object, file)
|
|
</code></pre></div>
|
|
|
|
<div><h2 id="csv"><a href="#csv" name="csv">#</a>CSV</h2><p><strong>Text file format for storing spreadsheets.</strong></p><pre><code class="python language-python hljs"><span class="hljs-keyword">import</span> csv
|
|
</code></pre></div>
|
|
|
|
|
|
<div><h3 id="read">Read</h3><pre><code class="python language-python hljs"><reader> = csv.reader(<file>, dialect=<span class="hljs-string">'excel'</span>, delimiter=<span class="hljs-string">','</span>)
|
|
<list> = next(<reader>) <span class="hljs-comment"># Returns next row as a list of strings.</span>
|
|
<list> = list(<reader>) <span class="hljs-comment"># Returns list of remaining rows.</span>
|
|
</code></pre></div>
|
|
|
|
<ul>
|
|
<li><strong>File must be opened with <code class="python hljs"><span class="hljs-string">'newline=""'</span></code> argument, or newlines embedded inside quoted fields will not be interpreted correctly!</strong></li>
|
|
</ul>
|
|
<div><h3 id="write">Write</h3><pre><code class="python language-python hljs"><writer> = csv.writer(<file>, dialect=<span class="hljs-string">'excel'</span>, delimiter=<span class="hljs-string">','</span>)
|
|
<writer>.writerow(<collection>) <span class="hljs-comment"># Encodes objects using `str(<el>)`.</span>
|
|
<writer>.writerows(<coll_of_coll>) <span class="hljs-comment"># Appends multiple rows.</span>
|
|
</code></pre></div>
|
|
|
|
<ul>
|
|
<li><strong>File must be opened with <code class="python hljs"><span class="hljs-string">'newline=""'</span></code> argument, or an extra '\r' will be added to every '\n' on platforms that use '\r\n' linendings!</strong></li>
|
|
</ul>
|
|
<div><h3 id="parameters">Parameters</h3><ul>
|
|
<li><strong><code class="python hljs"><span class="hljs-string">'dialect'</span></code> - Master parameter that sets the default values.</strong></li>
|
|
<li><strong><code class="python hljs"><span class="hljs-string">'delimiter'</span></code> - A one-character string used to separate fields.</strong></li>
|
|
<li><strong><code class="python hljs"><span class="hljs-string">'quotechar'</span></code> - Character for quoting fields that contain special characters.</strong></li>
|
|
<li><strong><code class="python hljs"><span class="hljs-string">'doublequote'</span></code> - Whether quotechars inside fields get doubled or escaped.</strong></li>
|
|
<li><strong><code class="python hljs"><span class="hljs-string">'skipinitialspace'</span></code> - Whether whitespace after delimiter gets stripped.</strong></li>
|
|
<li><strong><code class="python hljs"><span class="hljs-string">'lineterminator'</span></code> - Specifies how writer terminates rows.</strong></li>
|
|
<li><strong><code class="python hljs"><span class="hljs-string">'quoting'</span></code> - Controls the amount of quoting: 0 - as necessary, 1 - all.</strong></li>
|
|
<li><strong><code class="python hljs"><span class="hljs-string">'escapechar'</span></code> - Character for escaping 'quotechar' if 'doublequote' is False.</strong></li>
|
|
</ul><div><h3 id="dialects">Dialects</h3><pre><code class="text language-text">+------------------+--------------+--------------+--------------+
|
|
| | excel | excel-tab | unix |
|
|
+------------------+--------------+--------------+--------------+
|
|
| delimiter | ',' | '\t' | ',' |
|
|
| quotechar | '"' | '"' | '"' |
|
|
| doublequote | True | True | True |
|
|
| skipinitialspace | False | False | False |
|
|
| lineterminator | '\r\n' | '\r\n' | '\n' |
|
|
| quoting | 0 | 0 | 1 |
|
|
| escapechar | None | None | None |
|
|
+------------------+--------------+--------------+--------------+
|
|
</code></pre></div></div>
|
|
|
|
|
|
|
|
<div><h3 id="readrowsfromcsvfile">Read Rows from CSV File</h3><pre><code class="python language-python hljs"><span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">read_csv_file</span><span class="hljs-params">(filename)</span>:</span>
|
|
<span class="hljs-keyword">with</span> open(filename, encoding=<span class="hljs-string">'utf-8'</span>, newline=<span class="hljs-string">''</span>) <span class="hljs-keyword">as</span> file:
|
|
<span class="hljs-keyword">return</span> list(csv.reader(file))
|
|
</code></pre></div>
|
|
|
|
<div><h3 id="writerowstocsvfile">Write Rows to CSV File</h3><pre><code class="python language-python hljs"><span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">write_to_csv_file</span><span class="hljs-params">(filename, rows)</span>:</span>
|
|
<span class="hljs-keyword">with</span> open(filename, <span class="hljs-string">'w'</span>, encoding=<span class="hljs-string">'utf-8'</span>, newline=<span class="hljs-string">''</span>) <span class="hljs-keyword">as</span> file:
|
|
writer = csv.writer(file)
|
|
writer.writerows(rows)
|
|
</code></pre></div>
|
|
|
|
<div><h2 id="sqlite"><a href="#sqlite" name="sqlite">#</a>SQLite</h2><p><strong>Server-less database engine that stores each database into a separate file.</strong></p><div><h3 id="connect">Connect</h3><p><strong>Opens a connection to the database file. Creates a new file if path doesn't exist.</strong></p><pre><code class="python language-python hljs"><span class="hljs-keyword">import</span> sqlite3
|
|
db = sqlite3.connect(<span class="hljs-string">'<path>'</span>) <span class="hljs-comment"># Also ':memory:'.</span>
|
|
...
|
|
db.close()
|
|
</code></pre></div></div>
|
|
|
|
|
|
|
|
|
|
<div><h3 id="read-1">Read</h3><p><strong>Returned values can be of type str, int, float, bytes or None.</strong></p><pre><code class="python language-python hljs"><cursor> = db.execute(<span class="hljs-string">'<query>'</span>) <span class="hljs-comment"># Can raise sqlite3.OperationalError.</span>
|
|
<tuple> = <cursor>.fetchone() <span class="hljs-comment"># Returns next row. Also next(<cursor>).</span>
|
|
<list> = <cursor>.fetchall() <span class="hljs-comment"># Returns remaining rows.</span>
|
|
</code></pre></div>
|
|
|
|
|
|
<div><h3 id="write-1">Write</h3><pre><code class="python language-python hljs">db.execute(<span class="hljs-string">'<query>'</span>)
|
|
db.commit()
|
|
</code></pre></div>
|
|
|
|
<div><h4 id="or">Or:</h4><pre><code class="python language-python hljs"><span class="hljs-keyword">with</span> db:
|
|
db.execute(<span class="hljs-string">'<query>'</span>)
|
|
</code></pre></div>
|
|
|
|
<div><h3 id="placeholders">Placeholders</h3><ul>
|
|
<li><strong>Passed values can be of type str, int, float, bytes, None, bool, datetime.date or datetime.datetme.</strong></li>
|
|
<li><strong>Bools will be stored and returned as ints and dates as <a href="#encode">ISO formatted strings</a>.</strong></li>
|
|
</ul><pre><code class="python language-python hljs">db.execute(<span class="hljs-string">'<query>'</span>, <list/tuple>) <span class="hljs-comment"># Replaces '?'s in query with values.</span>
|
|
db.execute(<span class="hljs-string">'<query>'</span>, <dict/namedtuple>) <span class="hljs-comment"># Replaces ':<key>'s with values.</span>
|
|
db.executemany(<span class="hljs-string">'<query>'</span>, <coll_of_above>) <span class="hljs-comment"># Runs execute() many times.</span>
|
|
</code></pre></div>
|
|
|
|
|
|
<div><h3 id="example">Example</h3><p><strong>In this example values are not actually saved because <code class="python hljs"><span class="hljs-string">'db.commit()'</span></code> is omitted!</strong></p><pre><code class="python language-python hljs"><span class="hljs-meta">>>> </span>db = sqlite3.connect(<span class="hljs-string">'test.db'</span>)
|
|
<span class="hljs-meta">>>> </span>db.execute(<span class="hljs-string">'create table t (a, b, c)'</span>)
|
|
<span class="hljs-meta">>>> </span>db.execute(<span class="hljs-string">'insert into t values (1, 2, 3)'</span>)
|
|
<span class="hljs-meta">>>> </span>db.execute(<span class="hljs-string">'select * from t'</span>).fetchall()
|
|
[(<span class="hljs-number">1</span>, <span class="hljs-number">2</span>, <span class="hljs-number">3</span>)]
|
|
</code></pre></div>
|
|
|
|
|
|
<div><h3 id="mysql">MySQL</h3><p><strong>Has a very similar interface, with differences listed below.</strong></p><pre><code class="python language-python hljs"><span class="hljs-comment"># $ pip3 install mysql-connector</span>
|
|
<span class="hljs-keyword">from</span> mysql <span class="hljs-keyword">import</span> connector
|
|
db = connector.connect(host=<str>, user=<str>, password=<str>, database=<str>)
|
|
<cursor> = db.cursor()
|
|
<cursor>.execute(<span class="hljs-string">'<query>'</span>) <span class="hljs-comment"># Only cursor has execute method.</span>
|
|
<cursor>.execute(<span class="hljs-string">'<query>'</span>, <list/tuple>) <span class="hljs-comment"># Replaces '%s's in query with values.</span>
|
|
<cursor>.execute(<span class="hljs-string">'<query>'</span>, <dict/namedtuple>) <span class="hljs-comment"># Replaces '%(<key>)s's with values.</span>
|
|
</code></pre></div>
|
|
|
|
|
|
<div><h2 id="bytes"><a href="#bytes" name="bytes">#</a>Bytes</h2><p><strong>Bytes object is an immutable sequence of single bytes. Mutable version is called bytearray.</strong></p><pre><code class="python language-python hljs"><bytes> = <span class="hljs-string">b'<str>'</span> <span class="hljs-comment"># Only accepts ASCII characters and \x00 - \xff.</span>
|
|
<int> = <bytes>[<index>] <span class="hljs-comment"># Returns int in range from 0 to 255.</span>
|
|
<bytes> = <bytes>[<slice>] <span class="hljs-comment"># Returns bytes even if it has only one element.</span>
|
|
<bytes> = <bytes>.join(<coll_of_bytes>) <span class="hljs-comment"># Joins elements using bytes object as separator.</span>
|
|
</code></pre></div>
|
|
|
|
|
|
<div><h3 id="encode-1">Encode</h3><pre><code class="python language-python hljs"><bytes> = bytes(<coll_of_ints>) <span class="hljs-comment"># Ints must be in range from 0 to 255.</span>
|
|
<bytes> = bytes(<str>, <span class="hljs-string">'utf-8'</span>) <span class="hljs-comment"># Or: <str>.encode('utf-8')</span>
|
|
<bytes> = <int>.to_bytes(n_bytes, byteorder=<span class="hljs-string">'big/little'</span>, signed=<span class="hljs-keyword">False</span>)
|
|
<bytes> = bytes.fromhex(<span class="hljs-string">'<hex>'</span>)
|
|
</code></pre></div>
|
|
|
|
<div><h3 id="decode-1">Decode</h3><pre><code class="python language-python hljs"><list> = list(<bytes>) <span class="hljs-comment"># Returns ints in range from 0 to 255.</span>
|
|
<str> = str(<bytes>, <span class="hljs-string">'utf-8'</span>) <span class="hljs-comment"># Or: <bytes>.decode('utf-8')</span>
|
|
<int> = int.from_bytes(<bytes>, byteorder=<span class="hljs-string">'big/little'</span>, signed=<span class="hljs-keyword">False</span>)
|
|
<span class="hljs-string">'<hex>'</span> = <bytes>.hex()
|
|
</code></pre></div>
|
|
|
|
<div><h3 id="readbytesfromfile">Read Bytes from File</h3><pre><code class="python language-python hljs"><span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">read_bytes</span><span class="hljs-params">(filename)</span>:</span>
|
|
<span class="hljs-keyword">with</span> open(filename, <span class="hljs-string">'rb'</span>) <span class="hljs-keyword">as</span> file:
|
|
<span class="hljs-keyword">return</span> file.read()
|
|
</code></pre></div>
|
|
|
|
<div><h3 id="writebytestofile">Write Bytes to File</h3><pre><code class="python language-python hljs"><span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">write_bytes</span><span class="hljs-params">(filename, bytes_obj)</span>:</span>
|
|
<span class="hljs-keyword">with</span> open(filename, <span class="hljs-string">'wb'</span>) <span class="hljs-keyword">as</span> file:
|
|
file.write(bytes_obj)
|
|
</code></pre></div>
|
|
|
|
<div><h2 id="struct"><a href="#struct" name="struct">#</a>Struct</h2><ul>
|
|
<li><strong>Module that performs conversions between a sequence of numbers and a bytes object.</strong></li>
|
|
<li><strong>Machine’s native type sizes and byte order are used by default.</strong></li>
|
|
</ul><pre><code class="python language-python hljs"><span class="hljs-keyword">from</span> struct <span class="hljs-keyword">import</span> pack, unpack, iter_unpack
|
|
<bytes> = pack(<span class="hljs-string">'<format>'</span>, <num_1> [, <num_2>, ...])
|
|
<tuple> = unpack(<span class="hljs-string">'<format>'</span>, <bytes>)
|
|
<tuples> = iter_unpack(<span class="hljs-string">'<format>'</span>, <bytes>)
|
|
</code></pre></div>
|
|
|
|
|
|
<div><h3 id="example-1">Example</h3><pre><code class="python language-python hljs"><span class="hljs-meta">>>> </span>pack(<span class="hljs-string">'>hhl'</span>, <span class="hljs-number">1</span>, <span class="hljs-number">2</span>, <span class="hljs-number">3</span>)
|
|
<span class="hljs-string">b'\x00\x01\x00\x02\x00\x00\x00\x03'</span>
|
|
<span class="hljs-meta">>>> </span>unpack(<span class="hljs-string">'>hhl'</span>, <span class="hljs-string">b'\x00\x01\x00\x02\x00\x00\x00\x03'</span>)
|
|
(<span class="hljs-number">1</span>, <span class="hljs-number">2</span>, <span class="hljs-number">3</span>)
|
|
</code></pre></div>
|
|
|
|
<div><h3 id="format-2">Format</h3></div><div><h4 id="forstandardsizesstartformatstringwith">For standard sizes start format string with:</h4><ul>
|
|
<li><strong><code class="python hljs"><span class="hljs-string">'='</span></code> - native byte order</strong></li>
|
|
<li><strong><code class="python hljs"><span class="hljs-string">'<'</span></code> - little-endian</strong></li>
|
|
<li><strong><code class="python hljs"><span class="hljs-string">'>'</span></code> - big-endian (also <code class="python hljs"><span class="hljs-string">'!'</span></code>)</strong></li>
|
|
</ul></div><div><h4 id="integertypesuseacapitalletterforunsignedtypestandardsizesareinbrackets">Integer types. Use a capital letter for unsigned type. Standard sizes are in brackets:</h4><ul>
|
|
<li><strong><code class="python hljs"><span class="hljs-string">'x'</span></code> - pad byte</strong></li>
|
|
<li><strong><code class="python hljs"><span class="hljs-string">'b'</span></code> - char (1)</strong></li>
|
|
<li><strong><code class="python hljs"><span class="hljs-string">'h'</span></code> - short (2)</strong></li>
|
|
<li><strong><code class="python hljs"><span class="hljs-string">'i'</span></code> - int (4)</strong></li>
|
|
<li><strong><code class="python hljs"><span class="hljs-string">'l'</span></code> - long (4)</strong></li>
|
|
<li><strong><code class="python hljs"><span class="hljs-string">'q'</span></code> - long long (8)</strong></li>
|
|
</ul></div><div><h4 id="floatingpointtypes">Floating point types:</h4><ul>
|
|
<li><strong><code class="python hljs"><span class="hljs-string">'f'</span></code> - float (4)</strong></li>
|
|
<li><strong><code class="python hljs"><span class="hljs-string">'d'</span></code> - double (8)</strong></li>
|
|
</ul></div>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<div><h2 id="array"><a href="#array" name="array">#</a>Array</h2><p><strong>List that can only hold numbers of a predefined type. Available types and their sizes in bytes are listed above.</strong></p><pre><code class="python language-python hljs"><span class="hljs-keyword">from</span> array <span class="hljs-keyword">import</span> array
|
|
<array> = array(<span class="hljs-string">'<typecode>'</span>, <collection>) <span class="hljs-comment"># Array from coll. of numbers.</span>
|
|
<array> = array(<span class="hljs-string">'<typecode>'</span>, <bytes>) <span class="hljs-comment"># Array from bytes object.</span>
|
|
<bytes> = bytes(<array>) <span class="hljs-comment"># Or: <array>.tobytes()</span>
|
|
</code></pre></div>
|
|
|
|
|
|
<div><h2 id="memoryview"><a href="#memoryview" name="memoryview">#</a>Memory View</h2><ul>
|
|
<li><strong>A sequence object that points to the memory of another object.</strong></li>
|
|
<li><strong>Each element can reference a single or multiple consecutive bytes, depending on format.</strong></li>
|
|
<li><strong>Order and number of elements can be changed with slicing.</strong></li>
|
|
</ul><pre><code class="python language-python hljs"><mview> = memoryview(<bytes/bytearray/array>) <span class="hljs-comment"># Immutable if bytes, else mutable.</span>
|
|
<real> = <mview>[<index>] <span class="hljs-comment"># Returns an int or a float.</span>
|
|
<mview> = <mview>[<slice>] <span class="hljs-comment"># Mview with rearranged elements.</span>
|
|
<mview> = <mview>.cast(<span class="hljs-string">'<typecode>'</span>) <span class="hljs-comment"># Casts memoryview to the new format.</span>
|
|
<mview>.release() <span class="hljs-comment"># Releases the object's memory buffer.</span>
|
|
</code></pre></div>
|
|
|
|
|
|
<div><h3 id="decode-2">Decode</h3><pre><code class="python language-python hljs"><bin_file>.write(<mview>) <span class="hljs-comment"># Writes mview to the binary file.</span>
|
|
<bytes> = bytes(<mview>) <span class="hljs-comment"># Creates a new bytes object.</span>
|
|
<bytes> = <bytes>.join(<coll_of_mviews>) <span class="hljs-comment"># Joins mviews using bytes object as sep.</span>
|
|
<list> = list(<mview>) <span class="hljs-comment"># Returns list of ints or floats.</span>
|
|
<str> = str(<mview>, <span class="hljs-string">'utf-8'</span>) <span class="hljs-comment"># Treats mview as a bytes object.</span>
|
|
<int> = int.from_bytes(<mview>, byteorder=<span class="hljs-string">'big/little'</span>, signed=<span class="hljs-keyword">False</span>)
|
|
<span class="hljs-string">'<hex>'</span> = <mview>.hex()
|
|
</code></pre></div>
|
|
|
|
<div><h2 id="deque"><a href="#deque" name="deque">#</a>Deque</h2><p><strong>A thread-safe list with efficient appends and pops from either side. Pronounced "deck".</strong></p><pre><code class="python language-python hljs"><span class="hljs-keyword">from</span> collections <span class="hljs-keyword">import</span> deque
|
|
<deque> = deque(<collection>, maxlen=<span class="hljs-keyword">None</span>)
|
|
</code></pre></div>
|
|
|
|
|
|
<pre><code class="python language-python hljs"><deque>.appendleft(<el>) <span class="hljs-comment"># Opposite element is dropped if full.</span>
|
|
<deque>.extendleft(<collection>) <span class="hljs-comment"># Collection gets reversed.</span>
|
|
<el> = <deque>.popleft() <span class="hljs-comment"># Raises IndexError if empty.</span>
|
|
<deque>.rotate(n=<span class="hljs-number">1</span>) <span class="hljs-comment"># Rotates elements to the right.</span>
|
|
</code></pre>
|
|
<div><h2 id="threading"><a href="#threading" name="threading">#</a>Threading</h2><ul>
|
|
<li><strong>CPython interpreter can only run a single thread at a time.</strong></li>
|
|
<li><strong>That is why using multiple threads won't result in a faster execution, unless at least one of the threads contains an I/O operation.</strong></li>
|
|
</ul><pre><code class="python language-python hljs"><span class="hljs-keyword">from</span> threading <span class="hljs-keyword">import</span> Thread, RLock, Semaphore, Event, Barrier
|
|
</code></pre></div>
|
|
|
|
|
|
<div><h3 id="thread">Thread</h3><pre><code class="python language-python hljs">thread = Thread(target=<function>, args=(<first_arg>, ))
|
|
thread.start()
|
|
...
|
|
<bool> = thread.is_alive() <span class="hljs-comment"># Checks if thread has finished executing.</span>
|
|
thread.join() <span class="hljs-comment"># Waits for thread to finish.</span>
|
|
</code></pre></div>
|
|
|
|
<ul>
|
|
<li><strong>Use <code class="python hljs"><span class="hljs-string">'kwargs=<dict>'</span></code> to pass keyword arguments to the function.</strong></li>
|
|
<li><strong>Use <code class="python hljs"><span class="hljs-string">'daemon=True'</span></code>, or the program will not be able to exit while the thread is alive.</strong></li>
|
|
</ul>
|
|
<div><h3 id="lock">Lock</h3><pre><code class="python language-python hljs">lock = RLock()
|
|
lock.acquire() <span class="hljs-comment"># Waits for lock to be available.</span>
|
|
...
|
|
lock.release()
|
|
</code></pre></div>
|
|
|
|
<div><h4 id="or-1">Or:</h4><pre><code class="python language-python hljs">lock = RLock()
|
|
<span class="hljs-keyword">with</span> lock:
|
|
...
|
|
</code></pre></div>
|
|
|
|
<div><h3 id="semaphoreeventbarrier">Semaphore, Event, Barrier</h3><pre><code class="python language-python hljs"><Semaphore> = Semaphore(value=<span class="hljs-number">1</span>) <span class="hljs-comment"># Lock that can be acquired 'value' times.</span>
|
|
<Event> = Event() <span class="hljs-comment"># Method wait() blocks until set() is called.</span>
|
|
<Barrier> = Barrier(n_times) <span class="hljs-comment"># Method wait() blocks until it's called n_times.</span>
|
|
</code></pre></div>
|
|
|
|
<div><h3 id="threadpoolexecutor">Thread Pool Executor</h3><pre><code class="python language-python hljs"><span class="hljs-keyword">from</span> concurrent.futures <span class="hljs-keyword">import</span> ThreadPoolExecutor
|
|
<span class="hljs-keyword">with</span> ThreadPoolExecutor(max_workers=<span class="hljs-keyword">None</span>) <span class="hljs-keyword">as</span> executor:
|
|
<iter> = executor.map(<span class="hljs-keyword">lambda</span> x: x + <span class="hljs-number">1</span>, range(<span class="hljs-number">3</span>)) <span class="hljs-comment"># (1, 2, 3)</span>
|
|
<iter> = executor.map(<span class="hljs-keyword">lambda</span> x, y: x + y, <span class="hljs-string">'abc'</span>, <span class="hljs-string">'123'</span>) <span class="hljs-comment"># ('a1', 'b2', 'c3')</span>
|
|
<Future> = executor.submit(<function> [, <arg_1>, ...])
|
|
</code></pre></div>
|
|
|
|
<div><h4 id="future">Future:</h4><pre><code class="python language-python hljs"><bool> = <Future>.done() <span class="hljs-comment"># Checks if thread has finished executing.</span>
|
|
<obj> = <Future>.result() <span class="hljs-comment"># Waits for thread to finish and returns result.</span>
|
|
</code></pre></div>
|
|
|
|
<div><h3 id="queue">Queue</h3><p><strong>A thread-safe FIFO queue. For LIFO queue use LifoQueue.</strong></p><pre><code class="python language-python hljs"><span class="hljs-keyword">from</span> queue <span class="hljs-keyword">import</span> Queue
|
|
<Queue> = Queue(maxsize=<span class="hljs-number">0</span>)
|
|
</code></pre></div>
|
|
|
|
|
|
<pre><code class="python language-python hljs"><Queue>.put(<el>) <span class="hljs-comment"># Blocks until queue stops being full.</span>
|
|
<Queue>.put_nowait(<el>) <span class="hljs-comment"># Raises queue.Full exception if full.</span>
|
|
<el> = <Queue>.get() <span class="hljs-comment"># Blocks until queue stops being empty.</span>
|
|
<el> = <Queue>.get_nowait() <span class="hljs-comment"># Raises queue.Empty exception if empty.</span>
|
|
</code></pre>
|
|
<div><h2 id="operator"><a href="#operator" name="operator">#</a>Operator</h2><p><strong>Module of functions that provide the functionality of operators.</strong></p><pre><code class="python language-python hljs"><span class="hljs-keyword">from</span> operator <span class="hljs-keyword">import</span> add, sub, mul, truediv, floordiv, mod, pow, neg, abs
|
|
<span class="hljs-keyword">from</span> operator <span class="hljs-keyword">import</span> eq, ne, lt, le, gt, ge
|
|
<span class="hljs-keyword">from</span> operator <span class="hljs-keyword">import</span> and_, or_, not_
|
|
<span class="hljs-keyword">from</span> operator <span class="hljs-keyword">import</span> itemgetter, attrgetter, methodcaller
|
|
</code></pre></div>
|
|
|
|
|
|
<pre><code class="python language-python hljs"><span class="hljs-keyword">import</span> operator <span class="hljs-keyword">as</span> op
|
|
elementwise_sum = map(op.add, list_a, list_b)
|
|
sorted_by_second = sorted(<collection>, key=op.itemgetter(<span class="hljs-number">1</span>))
|
|
sorted_by_both = sorted(<collection>, key=op.itemgetter(<span class="hljs-number">1</span>, <span class="hljs-number">0</span>))
|
|
product_of_elems = functools.reduce(op.mul, <collection>)
|
|
LogicOp = enum.Enum(<span class="hljs-string">'LogicOp'</span>, {<span class="hljs-string">'AND'</span>: op.and_, <span class="hljs-string">'OR'</span> : op.or_})
|
|
last_el = op.methodcaller(<span class="hljs-string">'pop'</span>)(<list>)
|
|
</code></pre>
|
|
<div><h2 id="introspection"><a href="#introspection" name="introspection">#</a>Introspection</h2><p><strong>Inspecting code at runtime.</strong></p><div><h3 id="variables">Variables</h3><pre><code class="python language-python hljs"><list> = dir() <span class="hljs-comment"># Returns names of local variables (incl. functions).</span>
|
|
<dict> = vars() <span class="hljs-comment"># Returns dict of local variables. Also locals().</span>
|
|
<dict> = globals() <span class="hljs-comment"># Returns dict of global variables.</span>
|
|
</code></pre></div></div>
|
|
|
|
|
|
|
|
<div><h3 id="attributes-1">Attributes</h3><pre><code class="python language-python hljs"><list> = dir(<object>) <span class="hljs-comment"># Returns names of object's attributes (incl. methods).</span>
|
|
<dict> = vars(<object>) <span class="hljs-comment"># Returns dict of object's fields. Also <obj>.__dict__.</span>
|
|
</code></pre></div>
|
|
|
|
<pre><code class="python language-python hljs"><bool> = hasattr(<object>, <span class="hljs-string">'<attr_name>'</span>)
|
|
value = getattr(<object>, <span class="hljs-string">'<attr_name>'</span>)
|
|
setattr(<object>, <span class="hljs-string">'<attr_name>'</span>, value)
|
|
delattr(<object>, <span class="hljs-string">'<attr_name>'</span>)
|
|
</code></pre>
|
|
<div><h3 id="parameters-1">Parameters</h3><pre><code class="python language-python hljs"><span class="hljs-keyword">from</span> inspect <span class="hljs-keyword">import</span> signature
|
|
<sig> = signature(<function>)
|
|
no_of_params = len(<sig>.parameters)
|
|
param_names = list(<sig>.parameters.keys())
|
|
param_kinds = [a.kind <span class="hljs-keyword">for</span> a <span class="hljs-keyword">in</span> <sig>.parameters.values()]
|
|
</code></pre></div>
|
|
|
|
<div><h2 id="metaprograming"><a href="#metaprograming" name="metaprograming">#</a>Metaprograming</h2><p><strong>Code that generates code.</strong></p><div><h3 id="type-1">Type</h3><p><strong>Type is the root class. If only passed an object it returns its type (class). Otherwise it creates a new class.</strong></p><pre><code class="python language-python hljs"><code class="python language-python hljs"><class> = type(<span class="hljs-string">'<class_name>'</span>, <parents_tuple>, <attributes_dict>)</code></code></pre></div></div>
|
|
|
|
|
|
|
|
|
|
<pre><code class="python language-python hljs"><span class="hljs-meta">>>> </span>Z = type(<span class="hljs-string">'Z'</span>, (), {<span class="hljs-string">'a'</span>: <span class="hljs-string">'abcde'</span>, <span class="hljs-string">'b'</span>: <span class="hljs-number">12345</span>})
|
|
<span class="hljs-meta">>>> </span>z = Z()
|
|
</code></pre>
|
|
<div><h3 id="metaclass">Meta Class</h3><p><strong>A class that creates classes.</strong></p><pre><code class="python language-python hljs"><span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">my_meta_class</span><span class="hljs-params">(name, parents, attrs)</span>:</span>
|
|
attrs[<span class="hljs-string">'a'</span>] = <span class="hljs-string">'abcde'</span>
|
|
<span class="hljs-keyword">return</span> type(name, parents, attrs)
|
|
</code></pre></div>
|
|
|
|
|
|
<div><h4 id="or-2">Or:</h4><pre><code class="python language-python hljs"><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">MyMetaClass</span><span class="hljs-params">(type)</span>:</span>
|
|
<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">__new__</span><span class="hljs-params">(cls, name, parents, attrs)</span>:</span>
|
|
attrs[<span class="hljs-string">'a'</span>] = <span class="hljs-string">'abcde'</span>
|
|
<span class="hljs-keyword">return</span> type.__new__(cls, name, parents, attrs)
|
|
</code></pre></div>
|
|
|
|
<ul>
|
|
<li><strong>New() is a class method that gets called before init(). If it returns an instance of its class, then that instance gets passed to init() as a 'self' argument.</strong></li>
|
|
<li><strong>It receives the same arguments as init(), except for the first one that specifies the desired type of the returned instance (MyMetaClass in our case).</strong></li>
|
|
<li><strong>Like in our case, new() can also be called directly, usually from a new() method of a child class (</strong><code class="python hljs"><span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">__new__</span><span class="hljs-params">(cls)</span>:</span> <span class="hljs-keyword">return</span> super().__new__(cls)</code><strong>).</strong></li>
|
|
<li><strong>The only difference between the examples above is that my_meta_class() returns a class of type type, while MyMetaClass() returns a class of type MyMetaClass.</strong></li>
|
|
</ul>
|
|
<div><h3 id="metaclassattribute">Metaclass Attribute</h3><p><strong>Right before a class is created it checks if it has a 'metaclass' attribute defined. If not, it recursively checks if any of his parents has it defined and eventually comes to type().</strong></p><pre><code class="python language-python hljs"><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">MyClass</span><span class="hljs-params">(metaclass=MyMetaClass)</span>:</span>
|
|
b = <span class="hljs-number">12345</span>
|
|
</code></pre></div>
|
|
|
|
|
|
<pre><code class="python language-python hljs"><span class="hljs-meta">>>> </span>MyClass.a, MyClass.b
|
|
(<span class="hljs-string">'abcde'</span>, <span class="hljs-number">12345</span>)
|
|
</code></pre>
|
|
<div><h3 id="typediagram">Type Diagram</h3><pre><code class="python language-python hljs">type(MyClass) == MyMetaClass <span class="hljs-comment"># MyClass is an instance of MyMetaClass.</span>
|
|
type(MyMetaClass) == type <span class="hljs-comment"># MyMetaClass is an instance of type.</span>
|
|
</code></pre></div>
|
|
|
|
<pre><code class="text language-text">+-------------+-------------+
|
|
| Classes | Metaclasses |
|
|
+-------------+-------------|
|
|
| MyClass --> MyMetaClass |
|
|
| | v |
|
|
| object -----> type <+ |
|
|
| | ^ +---+ |
|
|
| str ---------+ |
|
|
+-------------+-------------+
|
|
</code></pre>
|
|
<div><h3 id="inheritancediagram">Inheritance Diagram</h3><pre><code class="python language-python hljs">MyClass.__base__ == object <span class="hljs-comment"># MyClass is a subclass of object.</span>
|
|
MyMetaClass.__base__ == type <span class="hljs-comment"># MyMetaClass is a subclass of type.</span>
|
|
</code></pre></div>
|
|
|
|
<pre><code class="text language-text">+-------------+-------------+
|
|
| Classes | Metaclasses |
|
|
+-------------+-------------|
|
|
| MyClass | MyMetaClass |
|
|
| v | v |
|
|
| object <----- type |
|
|
| ^ | |
|
|
| str | |
|
|
+-------------+-------------+
|
|
</code></pre>
|
|
<div><h2 id="eval"><a href="#eval" name="eval">#</a>Eval</h2><pre><code class="python language-python hljs"><span class="hljs-meta">>>> </span><span class="hljs-keyword">from</span> ast <span class="hljs-keyword">import</span> literal_eval
|
|
<span class="hljs-meta">>>> </span>literal_eval(<span class="hljs-string">'1 + 2'</span>)
|
|
<span class="hljs-number">3</span>
|
|
<span class="hljs-meta">>>> </span>literal_eval(<span class="hljs-string">'[1, 2, 3]'</span>)
|
|
[<span class="hljs-number">1</span>, <span class="hljs-number">2</span>, <span class="hljs-number">3</span>]
|
|
<span class="hljs-meta">>>> </span>literal_eval(<span class="hljs-string">'abs(1)'</span>)
|
|
ValueError: malformed node or string
|
|
</code></pre></div>
|
|
|
|
<div><h2 id="coroutines"><a href="#coroutines" name="coroutines">#</a>Coroutines</h2><ul>
|
|
<li><strong>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.</strong></li>
|
|
<li><strong>Coroutine definition starts with <code class="python hljs"><span class="hljs-string">'async'</span></code> and its call with <code class="python hljs"><span class="hljs-string">'await'</span></code>.</strong></li>
|
|
<li><strong><code class="python hljs"><span class="hljs-string">'asyncio.run(<coroutine>)'</span></code> is the main entry point for asynchronous programs.</strong></li>
|
|
<li><strong>Functions wait(), gather() and as_completed() can be used when multiple coroutines need to be started at the same time.</strong></li>
|
|
<li><strong>Asyncio module also provides it's own <a href="#queue">Queue</a>, <a href="#semaphoreeventbarrier">Event</a>, <a href="#lock">Lock</a> and <a href="#semaphoreeventbarrier">Semaphore</a> classes.</strong></li>
|
|
</ul><div><h4 id="runsaterminalgamewhereyoucontrolanasteriskthatmustavoidnumbers">Runs a terminal game where you control an asterisk that must avoid numbers:</h4><pre><code class="python language-python hljs"><span class="hljs-keyword">import</span> asyncio, collections, curses, enum, random
|
|
|
|
P = collections.namedtuple(<span class="hljs-string">'P'</span>, <span class="hljs-string">'x y'</span>) <span class="hljs-comment"># Position</span>
|
|
D = enum.Enum(<span class="hljs-string">'D'</span>, <span class="hljs-string">'n e s w'</span>) <span class="hljs-comment"># Direction</span>
|
|
|
|
<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">main</span><span class="hljs-params">(screen)</span>:</span>
|
|
curses.curs_set(<span class="hljs-number">0</span>) <span class="hljs-comment"># Makes cursor invisible.</span>
|
|
screen.nodelay(<span class="hljs-keyword">True</span>) <span class="hljs-comment"># Makes getch() non-blocking.</span>
|
|
asyncio.run(main_coroutine(screen)) <span class="hljs-comment"># Starts running asyncio code.</span>
|
|
|
|
<span class="hljs-keyword">async</span> <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">main_coroutine</span><span class="hljs-params">(screen)</span>:</span>
|
|
state = {<span class="hljs-string">'*'</span>: P(<span class="hljs-number">0</span>, <span class="hljs-number">0</span>), **{id_: P(<span class="hljs-number">30</span>, <span class="hljs-number">10</span>) <span class="hljs-keyword">for</span> id_ <span class="hljs-keyword">in</span> range(<span class="hljs-number">10</span>)}}
|
|
moves = asyncio.Queue()
|
|
coros = (*(random_controller(id_, moves) <span class="hljs-keyword">for</span> id_ <span class="hljs-keyword">in</span> range(<span class="hljs-number">10</span>)),
|
|
human_controller(screen, moves),
|
|
model(moves, state, *screen.getmaxyx()),
|
|
view(state, screen))
|
|
<span class="hljs-keyword">await</span> asyncio.wait(coros, return_when=asyncio.FIRST_COMPLETED)
|
|
|
|
<span class="hljs-keyword">async</span> <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">random_controller</span><span class="hljs-params">(id_, moves)</span>:</span>
|
|
<span class="hljs-keyword">while</span> <span class="hljs-keyword">True</span>:
|
|
moves.put_nowait((id_, random.choice(list(D))))
|
|
<span class="hljs-keyword">await</span> asyncio.sleep(random.random() / <span class="hljs-number">2</span>)
|
|
|
|
<span class="hljs-keyword">async</span> <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">human_controller</span><span class="hljs-params">(screen, moves)</span>:</span>
|
|
<span class="hljs-keyword">while</span> (ch := screen.getch()) != <span class="hljs-number">27</span>:
|
|
key_mappings = {<span class="hljs-number">259</span>: D.n, <span class="hljs-number">261</span>: D.e, <span class="hljs-number">258</span>: D.s, <span class="hljs-number">260</span>: D.w}
|
|
<span class="hljs-keyword">if</span> ch <span class="hljs-keyword">in</span> key_mappings:
|
|
moves.put_nowait((<span class="hljs-string">'*'</span>, key_mappings[ch]))
|
|
<span class="hljs-keyword">await</span> asyncio.sleep(<span class="hljs-number">0.01</span>)
|
|
|
|
<span class="hljs-keyword">async</span> <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">model</span><span class="hljs-params">(moves, state, height, width)</span>:</span>
|
|
<span class="hljs-keyword">while</span> state[<span class="hljs-string">'*'</span>] <span class="hljs-keyword">not</span> <span class="hljs-keyword">in</span> {p <span class="hljs-keyword">for</span> id_, p <span class="hljs-keyword">in</span> state.items() <span class="hljs-keyword">if</span> id_ != <span class="hljs-string">'*'</span>}:
|
|
id_, d = <span class="hljs-keyword">await</span> moves.get()
|
|
p = state[id_]
|
|
deltas = {D.n: P(<span class="hljs-number">0</span>, <span class="hljs-number">-1</span>), D.e: P(<span class="hljs-number">1</span>, <span class="hljs-number">0</span>), D.s: P(<span class="hljs-number">0</span>, <span class="hljs-number">1</span>), D.w: P(<span class="hljs-number">-1</span>, <span class="hljs-number">0</span>)}
|
|
new_p = P(*[sum(a) <span class="hljs-keyword">for</span> a <span class="hljs-keyword">in</span> zip(p, deltas[d])])
|
|
<span class="hljs-keyword">if</span> <span class="hljs-number">0</span> <= new_p.x < width<span class="hljs-number">-1</span> <span class="hljs-keyword">and</span> <span class="hljs-number">0</span> <= new_p.y < height:
|
|
state[id_] = new_p
|
|
|
|
<span class="hljs-keyword">async</span> <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">view</span><span class="hljs-params">(state, screen)</span>:</span>
|
|
<span class="hljs-keyword">while</span> <span class="hljs-keyword">True</span>:
|
|
screen.clear()
|
|
<span class="hljs-keyword">for</span> id_, p <span class="hljs-keyword">in</span> state.items():
|
|
screen.addstr(p.y, p.x, str(id_))
|
|
<span class="hljs-keyword">await</span> asyncio.sleep(<span class="hljs-number">0.01</span>)
|
|
|
|
curses.wrapper(main)
|
|
</code></pre></div></div>
|
|
|
|
|
|
|
|
<p><br></p>
|
|
<div><h1 id="libraries">Libraries</h1><div><h2 id="progressbar"><a href="#progressbar" name="progressbar">#</a>Progress Bar</h2><pre><code class="python language-python hljs"><span class="hljs-comment"># $ pip3 install tqdm</span>
|
|
<span class="hljs-keyword">from</span> tqdm <span class="hljs-keyword">import</span> tqdm
|
|
<span class="hljs-keyword">from</span> time <span class="hljs-keyword">import</span> sleep
|
|
<span class="hljs-keyword">for</span> el <span class="hljs-keyword">in</span> tqdm([<span class="hljs-number">1</span>, <span class="hljs-number">2</span>, <span class="hljs-number">3</span>]):
|
|
sleep(<span class="hljs-number">0.2</span>)
|
|
</code></pre></div></div>
|
|
|
|
|
|
<div><h2 id="plot"><a href="#plot" name="plot">#</a>Plot</h2><pre><code class="python language-python hljs"><span class="hljs-comment"># $ pip3 install matplotlib</span>
|
|
<span class="hljs-keyword">from</span> matplotlib <span class="hljs-keyword">import</span> pyplot
|
|
pyplot.plot(<y_data> [, label=<str>])
|
|
pyplot.plot(<x_data>, <y_data>)
|
|
pyplot.legend() <span class="hljs-comment"># Adds a legend.</span>
|
|
pyplot.savefig(<filename>) <span class="hljs-comment"># Saves the figure.</span>
|
|
pyplot.show() <span class="hljs-comment"># Displays the figure.</span>
|
|
pyplot.clf() <span class="hljs-comment"># Clears the figure.</span>
|
|
</code></pre></div>
|
|
|
|
<div><h2 id="table"><a href="#table" name="table">#</a>Table</h2><div><h4 id="printsacsvfileasanasciitable">Prints a CSV file as an ASCII table:</h4><pre><code class="python language-python hljs"><span class="hljs-comment"># $ pip3 install tabulate</span>
|
|
<span class="hljs-keyword">import</span> csv, tabulate
|
|
<span class="hljs-keyword">with</span> open(<span class="hljs-string">'test.csv'</span>, encoding=<span class="hljs-string">'utf-8'</span>, newline=<span class="hljs-string">''</span>) <span class="hljs-keyword">as</span> file:
|
|
rows = csv.reader(file)
|
|
header = [a.title() <span class="hljs-keyword">for</span> a <span class="hljs-keyword">in</span> next(rows)]
|
|
table = tabulate.tabulate(rows, header)
|
|
print(table)
|
|
</code></pre></div></div>
|
|
|
|
|
|
<div><h2 id="curses"><a href="#curses" name="curses">#</a>Curses</h2><div><h4 id="clearstheterminalprintsamessageandwaitsfortheesckeypress">Clears the terminal, prints a message and waits for the ESC key press:</h4><pre><code class="python language-python hljs"><span class="hljs-keyword">from</span> curses <span class="hljs-keyword">import</span> wrapper, curs_set, ascii
|
|
<span class="hljs-keyword">from</span> curses <span class="hljs-keyword">import</span> KEY_UP, KEY_RIGHT, KEY_DOWN, KEY_LEFT
|
|
|
|
<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">main</span><span class="hljs-params">()</span>:</span>
|
|
wrapper(draw)
|
|
|
|
<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">draw</span><span class="hljs-params">(screen)</span>:</span>
|
|
curs_set(<span class="hljs-number">0</span>) <span class="hljs-comment"># Makes cursor invisible.</span>
|
|
screen.nodelay(<span class="hljs-keyword">True</span>) <span class="hljs-comment"># Makes getch() non-blocking.</span>
|
|
screen.clear()
|
|
screen.addstr(<span class="hljs-number">0</span>, <span class="hljs-number">0</span>, <span class="hljs-string">'Press ESC to quit.'</span>)
|
|
<span class="hljs-keyword">while</span> screen.getch() != ascii.ESC:
|
|
<span class="hljs-keyword">pass</span>
|
|
|
|
<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">get_border</span><span class="hljs-params">(screen)</span>:</span>
|
|
<span class="hljs-keyword">from</span> collections <span class="hljs-keyword">import</span> namedtuple
|
|
P = namedtuple(<span class="hljs-string">'P'</span>, <span class="hljs-string">'x y'</span>)
|
|
height, width = screen.getmaxyx()
|
|
<span class="hljs-keyword">return</span> P(width - <span class="hljs-number">1</span>, height - <span class="hljs-number">1</span>)
|
|
|
|
<span class="hljs-keyword">if</span> __name__ == <span class="hljs-string">'__main__'</span>:
|
|
main()
|
|
</code></pre></div></div>
|
|
|
|
|
|
<div><h2 id="logging"><a href="#logging" name="logging">#</a>Logging</h2><pre><code class="python language-python hljs"><span class="hljs-comment"># $ pip3 install loguru</span>
|
|
<span class="hljs-keyword">from</span> loguru <span class="hljs-keyword">import</span> logger
|
|
</code></pre></div>
|
|
|
|
<pre><code class="python language-python hljs">logger.add(<span class="hljs-string">'debug_{time}.log'</span>, colorize=<span class="hljs-keyword">True</span>) <span class="hljs-comment"># Connects a log file.</span>
|
|
logger.add(<span class="hljs-string">'error_{time}.log'</span>, level=<span class="hljs-string">'ERROR'</span>) <span class="hljs-comment"># Another file for errors or higher.</span>
|
|
logger.<level>(<span class="hljs-string">'A logging message.'</span>)
|
|
</code></pre>
|
|
<ul>
|
|
<li><strong>Levels: <code class="python hljs"><span class="hljs-string">'debug'</span></code>, <code class="python hljs"><span class="hljs-string">'info'</span></code>, <code class="python hljs"><span class="hljs-string">'success'</span></code>, <code class="python hljs"><span class="hljs-string">'warning'</span></code>, <code class="python hljs"><span class="hljs-string">'error'</span></code>, <code class="python hljs"><span class="hljs-string">'critical'</span></code>.</strong></li>
|
|
</ul>
|
|
<div><h3 id="exceptions-2">Exceptions</h3><p><strong>Exception description, stack trace and values of variables are appended automatically.</strong></p><pre><code class="python language-python hljs"><span class="hljs-keyword">try</span>:
|
|
...
|
|
<span class="hljs-keyword">except</span> <exception>:
|
|
logger.exception(<span class="hljs-string">'An error happened.'</span>)
|
|
</code></pre></div>
|
|
|
|
|
|
<div><h3 id="rotation">Rotation</h3><p><strong>Argument that sets a condition when a new log file is created.</strong></p><pre><code class="python language-python hljs">rotation=<int>|<datetime.timedelta>|<datetime.time>|<str>
|
|
</code></pre></div>
|
|
|
|
|
|
<ul>
|
|
<li><strong><code class="python hljs"><span class="hljs-string">'<int>'</span></code> - Max file size in bytes.</strong></li>
|
|
<li><strong><code class="python hljs"><span class="hljs-string">'<timedelta>'</span></code> - Max age of a file.</strong></li>
|
|
<li><strong><code class="python hljs"><span class="hljs-string">'<time>'</span></code> - Time of day.</strong></li>
|
|
<li><strong><code class="python hljs"><span class="hljs-string">'<str>'</span></code> - Any of above as a string: <code class="python hljs"><span class="hljs-string">'100 MB'</span></code>, <code class="python hljs"><span class="hljs-string">'1 month'</span></code>, <code class="python hljs"><span class="hljs-string">'monday at 12:00'</span></code>, …</strong></li>
|
|
</ul>
|
|
<div><h3 id="retention">Retention</h3><p><strong>Sets a condition which old log files get deleted.</strong></p><pre><code class="python language-python hljs">retention=<int>|<datetime.timedelta>|<str>
|
|
</code></pre></div>
|
|
|
|
|
|
<ul>
|
|
<li><strong><code class="python hljs"><span class="hljs-string">'<int>'</span></code> - Max number of files.</strong></li>
|
|
<li><strong><code class="python hljs"><span class="hljs-string">'<timedelta>'</span></code> - Max age of a file.</strong></li>
|
|
<li><strong><code class="python hljs"><span class="hljs-string">'<str>'</span></code> - Max age as a string: <code class="python hljs"><span class="hljs-string">'1 week, 3 days'</span></code>, <code class="python hljs"><span class="hljs-string">'2 months'</span></code>, …</strong></li>
|
|
</ul>
|
|
<div><h2 id="scraping"><a href="#scraping" name="scraping">#</a>Scraping</h2><div><h4 id="scrapespythonsurlversionnumberandlogofromwikipediapage">Scrapes Python's URL, version number and logo from Wikipedia page:</h4><pre><code class="python language-python hljs"><span class="hljs-comment"># $ pip3 install requests beautifulsoup4</span>
|
|
<span class="hljs-keyword">import</span> requests
|
|
<span class="hljs-keyword">from</span> bs4 <span class="hljs-keyword">import</span> BeautifulSoup
|
|
URL = <span class="hljs-string">'https://en.wikipedia.org/wiki/Python_(programming_language)'</span>
|
|
<span class="hljs-keyword">try</span>:
|
|
html = requests.get(URL).text
|
|
doc = BeautifulSoup(html, <span class="hljs-string">'html.parser'</span>)
|
|
table = doc.find(<span class="hljs-string">'table'</span>, class_=<span class="hljs-string">'infobox vevent'</span>)
|
|
rows = table.find_all(<span class="hljs-string">'tr'</span>)
|
|
link = rows[<span class="hljs-number">11</span>].find(<span class="hljs-string">'a'</span>)[<span class="hljs-string">'href'</span>]
|
|
ver = rows[<span class="hljs-number">6</span>].find(<span class="hljs-string">'div'</span>).text.split()[<span class="hljs-number">0</span>]
|
|
url_i = rows[<span class="hljs-number">0</span>].find(<span class="hljs-string">'img'</span>)[<span class="hljs-string">'src'</span>]
|
|
image = requests.get(<span class="hljs-string">f'https:<span class="hljs-subst">{url_i}</span>'</span>).content
|
|
<span class="hljs-keyword">with</span> open(<span class="hljs-string">'test.png'</span>, <span class="hljs-string">'wb'</span>) <span class="hljs-keyword">as</span> file:
|
|
file.write(image)
|
|
print(link, ver)
|
|
<span class="hljs-keyword">except</span> requests.exceptions.ConnectionError:
|
|
print(<span class="hljs-string">"You've got problems with connection."</span>)
|
|
</code></pre></div></div>
|
|
|
|
|
|
<div><h2 id="web"><a href="#web" name="web">#</a>Web</h2><pre><code class="python language-python hljs"><span class="hljs-comment"># $ pip3 install bottle</span>
|
|
<span class="hljs-keyword">from</span> bottle <span class="hljs-keyword">import</span> run, route, static_file, template, post, request, response
|
|
<span class="hljs-keyword">import</span> json
|
|
</code></pre></div>
|
|
|
|
<div><h3 id="run">Run</h3><pre><code class="python language-python hljs">run(host=<span class="hljs-string">'localhost'</span>, port=<span class="hljs-number">8080</span>) <span class="hljs-comment"># Runs locally.</span>
|
|
run(host=<span class="hljs-string">'0.0.0.0'</span>, port=<span class="hljs-number">80</span>) <span class="hljs-comment"># Runs globally.</span>
|
|
</code></pre></div>
|
|
|
|
<div><h3 id="staticrequest">Static Request</h3><pre><code class="python language-python hljs"><span class="hljs-meta">@route('/img/<image>')</span>
|
|
<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">send_image</span><span class="hljs-params">(image)</span>:</span>
|
|
<span class="hljs-keyword">return</span> static_file(image, <span class="hljs-string">'img_dir/'</span>, mimetype=<span class="hljs-string">'image/png'</span>)
|
|
</code></pre></div>
|
|
|
|
<div><h3 id="dynamicrequest">Dynamic Request</h3><pre><code class="python language-python hljs"><span class="hljs-meta">@route('/<sport>')</span>
|
|
<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">send_page</span><span class="hljs-params">(sport)</span>:</span>
|
|
<span class="hljs-keyword">return</span> template(<span class="hljs-string">'<h1>{{title}}</h1>'</span>, title=sport)
|
|
</code></pre></div>
|
|
|
|
<div><h3 id="restrequest">REST Request</h3><pre><code class="python language-python hljs"><span class="hljs-meta">@post('/odds/<sport>')</span>
|
|
<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">odds_handler</span><span class="hljs-params">(sport)</span>:</span>
|
|
team = request.forms.get(<span class="hljs-string">'team'</span>)
|
|
home_odds, away_odds = <span class="hljs-number">2.44</span>, <span class="hljs-number">3.29</span>
|
|
response.headers[<span class="hljs-string">'Content-Type'</span>] = <span class="hljs-string">'application/json'</span>
|
|
response.headers[<span class="hljs-string">'Cache-Control'</span>] = <span class="hljs-string">'no-cache'</span>
|
|
<span class="hljs-keyword">return</span> json.dumps([team, home_odds, away_odds])
|
|
</code></pre></div>
|
|
|
|
<div><h4 id="test">Test:</h4><pre><code class="python language-python hljs"><span class="hljs-comment"># $ pip3 install requests</span>
|
|
<span class="hljs-meta">>>> </span><span class="hljs-keyword">import</span> requests
|
|
<span class="hljs-meta">>>> </span>url = <span class="hljs-string">'http://localhost:8080/odds/football'</span>
|
|
<span class="hljs-meta">>>> </span>data = {<span class="hljs-string">'team'</span>: <span class="hljs-string">'arsenal f.c.'</span>}
|
|
<span class="hljs-meta">>>> </span>response = requests.post(url, data=data)
|
|
<span class="hljs-meta">>>> </span>response.json()
|
|
[<span class="hljs-string">'arsenal f.c.'</span>, <span class="hljs-number">2.44</span>, <span class="hljs-number">3.29</span>]
|
|
</code></pre></div>
|
|
|
|
<div><h2 id="profiling"><a href="#profiling" name="profiling">#</a>Profiling</h2><div><h3 id="stopwatch">Stopwatch</h3><pre><code class="python language-python hljs"><span class="hljs-keyword">from</span> time <span class="hljs-keyword">import</span> time
|
|
start_time = time() <span class="hljs-comment"># Seconds since the Epoch.</span>
|
|
...
|
|
duration = time() - start_time
|
|
</code></pre></div></div>
|
|
|
|
|
|
<div><h4 id="highperformance">High performance:</h4><pre><code class="python language-python hljs"><span class="hljs-keyword">from</span> time <span class="hljs-keyword">import</span> perf_counter
|
|
start_time = perf_counter() <span class="hljs-comment"># Seconds since restart.</span>
|
|
...
|
|
duration = perf_counter() - start_time
|
|
</code></pre></div>
|
|
|
|
<div><h3 id="timingasnippet">Timing a Snippet</h3><pre><code class="python language-python hljs"><span class="hljs-meta">>>> </span><span class="hljs-keyword">from</span> timeit <span class="hljs-keyword">import</span> timeit
|
|
<span class="hljs-meta">>>> </span>timeit(<span class="hljs-string">'"-".join(str(a) for a in range(100))'</span>,
|
|
<span class="hljs-meta">... </span> number=<span class="hljs-number">10000</span>, globals=globals(), setup=<span class="hljs-string">'pass'</span>)
|
|
<span class="hljs-number">0.34986</span>
|
|
</code></pre></div>
|
|
|
|
<div><h3 id="profilingbyline">Profiling by Line</h3><pre><code class="python language-python hljs"><span class="hljs-comment"># $ pip3 install line_profiler memory_profiler</span>
|
|
<span class="hljs-meta">@profile</span>
|
|
<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">main</span><span class="hljs-params">()</span>:</span>
|
|
a = [*range(<span class="hljs-number">10000</span>)]
|
|
b = {*range(<span class="hljs-number">10000</span>)}
|
|
main()
|
|
</code></pre></div>
|
|
|
|
<pre><code class="text language-text">$ kernprof -lv test.py
|
|
Line # Hits Time Per Hit % Time Line Contents
|
|
=======================================================
|
|
1 @profile
|
|
2 def main():
|
|
3 1 1128.0 1128.0 27.4 a = [*range(10000)]
|
|
4 1 2994.0 2994.0 72.6 b = {*range(10000)}
|
|
</code></pre>
|
|
<pre><code class="text language-text">$ python3 -m memory_profiler test.py
|
|
Line # Mem usage Increment Line Contents
|
|
=======================================================
|
|
1 35.387 MiB 35.387 MiB @profile
|
|
2 def main():
|
|
3 35.734 MiB 0.348 MiB a = [*range(10000)]
|
|
4 36.160 MiB 0.426 MiB b = {*range(10000)}
|
|
</code></pre>
|
|
<div><h3 id="callgraph">Call Graph</h3><div><h4 id="generatesapngimageofacallgraphwithhighlightedbottlenecks">Generates a PNG image of a call graph with highlighted bottlenecks:</h4><pre><code class="python language-python hljs"><span class="hljs-comment"># $ pip3 install pycallgraph</span>
|
|
<span class="hljs-keyword">from</span> pycallgraph <span class="hljs-keyword">import</span> output, PyCallGraph
|
|
<span class="hljs-keyword">from</span> datetime <span class="hljs-keyword">import</span> datetime
|
|
time_str = datetime.now().strftime(<span class="hljs-string">'%Y%m%d%H%M%S'</span>)
|
|
filename = <span class="hljs-string">f'profile-<span class="hljs-subst">{time_str}</span>.png'</span>
|
|
drawer = output.GraphvizOutput(output_file=filename)
|
|
<span class="hljs-keyword">with</span> PyCallGraph(drawer):
|
|
<code_to_be_profiled>
|
|
</code></pre></div></div>
|
|
|
|
|
|
<div><h2 id="numpy"><a href="#numpy" name="numpy">#</a>NumPy</h2><p><strong>Array manipulation mini-language. It can run up to one hundred times faster than the equivalent Python code.</strong></p><pre><code class="python language-python hljs"><span class="hljs-comment"># $ pip3 install numpy</span>
|
|
<span class="hljs-keyword">import</span> numpy <span class="hljs-keyword">as</span> np
|
|
</code></pre></div>
|
|
|
|
|
|
<pre><code class="python language-python hljs"><array> = np.array(<list>)
|
|
<array> = np.arange(from_inclusive, to_exclusive, ±step_size)
|
|
<array> = np.ones(<shape>)
|
|
<array> = np.random.randint(from_inclusive, to_exclusive, <shape>)
|
|
</code></pre>
|
|
<pre><code class="python language-python hljs"><array>.shape = <shape>
|
|
<view> = <array>.reshape(<shape>)
|
|
<view> = np.broadcast_to(<array>, <shape>)
|
|
</code></pre>
|
|
<pre><code class="python language-python hljs"><array> = <array>.sum(axis)
|
|
indexes = <array>.argmin(axis)
|
|
</code></pre>
|
|
<ul>
|
|
<li><strong>Shape is a tuple of dimension sizes.</strong></li>
|
|
<li><strong>Axis is the index of a dimension that gets collapsed. The leftmost dimension has index 0.</strong></li>
|
|
</ul>
|
|
<div><h3 id="indexing">Indexing</h3><pre><code class="bash language-bash hljs"><el> = <2d_array>[0, 0] <span class="hljs-comment"># First element.</span>
|
|
<1d_view> = <2d_array>[0] <span class="hljs-comment"># First row.</span>
|
|
<1d_view> = <2d_array>[:, 0] <span class="hljs-comment"># First column. Also [..., 0].</span>
|
|
<3d_view> = <2d_array>[None, :, :] <span class="hljs-comment"># Expanded by dimension of size 1.</span>
|
|
</code></pre></div>
|
|
|
|
<pre><code class="bash language-bash hljs"><1d_array> = <2d_array>[<1d_row_indexes>, <1d_column_indexes>]
|
|
<2d_array> = <2d_array>[<2d_row_indexes>, <2d_column_indexes>]
|
|
</code></pre>
|
|
<pre><code class="bash language-bash hljs"><2d_bools> = <2d_array> > 0
|
|
<1d_array> = <2d_array>[<2d_bools>]
|
|
</code></pre>
|
|
<ul>
|
|
<li><strong>If row and column indexes differ in shape, they are combined with broadcasting.</strong></li>
|
|
</ul>
|
|
<div><h3 id="broadcasting">Broadcasting</h3><p><strong>Broadcasting is a set of rules by which NumPy functions operate on arrays of different sizes and/or dimensions.</strong></p><pre><code class="python language-python hljs">left = [[<span class="hljs-number">0.1</span>], [<span class="hljs-number">0.6</span>], [<span class="hljs-number">0.8</span>]] <span class="hljs-comment"># Shape: (3, 1)</span>
|
|
right = [ <span class="hljs-number">0.1</span> , <span class="hljs-number">0.6</span> , <span class="hljs-number">0.8</span> ] <span class="hljs-comment"># Shape: (3)</span>
|
|
</code></pre></div>
|
|
|
|
|
|
<div><h4 id="1ifarrayshapesdifferinlengthleftpadtheshortershapewithones">1. If array shapes differ in length, left-pad the shorter shape with ones:</h4><pre><code class="python language-python hljs">left = [[<span class="hljs-number">0.1</span>], [<span class="hljs-number">0.6</span>], [<span class="hljs-number">0.8</span>]] <span class="hljs-comment"># Shape: (3, 1)</span>
|
|
right = [[<span class="hljs-number">0.1</span> , <span class="hljs-number">0.6</span> , <span class="hljs-number">0.8</span>]] <span class="hljs-comment"># Shape: (1, 3) <- !</span>
|
|
</code></pre></div>
|
|
|
|
<div><h4 id="2ifanydimensionsdifferinsizeexpandtheonesthathavesize1byduplicatingtheirelements">2. If any dimensions differ in size, expand the ones that have size 1 by duplicating their elements:</h4><pre><code class="python language-python hljs">left = [[<span class="hljs-number">0.1</span>, <span class="hljs-number">0.1</span>, <span class="hljs-number">0.1</span>], [<span class="hljs-number">0.6</span>, <span class="hljs-number">0.6</span>, <span class="hljs-number">0.6</span>], [<span class="hljs-number">0.8</span>, <span class="hljs-number">0.8</span>, <span class="hljs-number">0.8</span>]] <span class="hljs-comment"># Shape: (3, 3) <- !</span>
|
|
right = [[<span class="hljs-number">0.1</span>, <span class="hljs-number">0.6</span>, <span class="hljs-number">0.8</span>], [<span class="hljs-number">0.1</span>, <span class="hljs-number">0.6</span>, <span class="hljs-number">0.8</span>], [<span class="hljs-number">0.1</span>, <span class="hljs-number">0.6</span>, <span class="hljs-number">0.8</span>]] <span class="hljs-comment"># Shape: (3, 3) <- !</span>
|
|
</code></pre></div>
|
|
|
|
<div><h4 id="3ifneithernonmatchingdimensionhassize1raiseanerror">3. If neither non-matching dimension has size 1, raise an error.</h4><div><h3 id="example-2">Example</h3><div><h4 id="foreachpointreturnsindexofitsnearestpoint010608121">For each point returns index of its nearest point (<code class="python hljs">[<span class="hljs-number">0.1</span>, <span class="hljs-number">0.6</span>, <span class="hljs-number">0.8</span>] => [<span class="hljs-number">1</span>, <span class="hljs-number">2</span>, <span class="hljs-number">1</span>]</code>):</h4><pre><code class="python language-python hljs"><span class="hljs-meta">>>> </span>points = np.array([<span class="hljs-number">0.1</span>, <span class="hljs-number">0.6</span>, <span class="hljs-number">0.8</span>])
|
|
[ <span class="hljs-number">0.1</span>, <span class="hljs-number">0.6</span>, <span class="hljs-number">0.8</span>]
|
|
<span class="hljs-meta">>>> </span>wrapped_points = points.reshape(<span class="hljs-number">3</span>, <span class="hljs-number">1</span>)
|
|
[[ <span class="hljs-number">0.1</span>],
|
|
[ <span class="hljs-number">0.6</span>],
|
|
[ <span class="hljs-number">0.8</span>]]
|
|
<span class="hljs-meta">>>> </span>distances = wrapped_points - points
|
|
[[ <span class="hljs-number">0.</span> , <span class="hljs-number">-0.5</span>, <span class="hljs-number">-0.7</span>],
|
|
[ <span class="hljs-number">0.5</span>, <span class="hljs-number">0.</span> , <span class="hljs-number">-0.2</span>],
|
|
[ <span class="hljs-number">0.7</span>, <span class="hljs-number">0.2</span>, <span class="hljs-number">0.</span> ]]
|
|
<span class="hljs-meta">>>> </span>distances = np.abs(distances)
|
|
[[ <span class="hljs-number">0.</span> , <span class="hljs-number">0.5</span>, <span class="hljs-number">0.7</span>],
|
|
[ <span class="hljs-number">0.5</span>, <span class="hljs-number">0.</span> , <span class="hljs-number">0.2</span>],
|
|
[ <span class="hljs-number">0.7</span>, <span class="hljs-number">0.2</span>, <span class="hljs-number">0.</span> ]]
|
|
<span class="hljs-meta">>>> </span>i = np.arange(<span class="hljs-number">3</span>)
|
|
[<span class="hljs-number">0</span>, <span class="hljs-number">1</span>, <span class="hljs-number">2</span>]
|
|
<span class="hljs-meta">>>> </span>distances[i, i] = np.inf
|
|
[[ inf, <span class="hljs-number">0.5</span>, <span class="hljs-number">0.7</span>],
|
|
[ <span class="hljs-number">0.5</span>, inf, <span class="hljs-number">0.2</span>],
|
|
[ <span class="hljs-number">0.7</span>, <span class="hljs-number">0.2</span>, inf]]
|
|
<span class="hljs-meta">>>> </span>distances.argmin(<span class="hljs-number">1</span>)
|
|
[<span class="hljs-number">1</span>, <span class="hljs-number">2</span>, <span class="hljs-number">1</span>]
|
|
</code></pre></div></div></div>
|
|
|
|
|
|
|
|
<div><h2 id="image"><a href="#image" name="image">#</a>Image</h2><pre><code class="python language-python hljs"><span class="hljs-comment"># $ pip3 install pillow</span>
|
|
<span class="hljs-keyword">from</span> PIL <span class="hljs-keyword">import</span> Image
|
|
</code></pre></div>
|
|
|
|
<pre><code class="python language-python hljs"><Image> = Image.new(<span class="hljs-string">'<mode>'</span>, (width, height))
|
|
<Image> = Image.open(<span class="hljs-string">'<path>'</span>)
|
|
<Image> = <Image>.convert(<span class="hljs-string">'<mode>'</span>)
|
|
<Image>.save(<span class="hljs-string">'<path>'</span>)
|
|
<Image>.show()
|
|
</code></pre>
|
|
<pre><code class="python language-python hljs"><tuple/int> = <Image>.getpixel((x, y)) <span class="hljs-comment"># Returns a pixel.</span>
|
|
<Image>.putpixel((x, y), <tuple/int>) <span class="hljs-comment"># Writes a pixel to the image.</span>
|
|
<ImagingCore> = <Image>.getdata() <span class="hljs-comment"># Returns a sequence of pixels.</span>
|
|
<Image>.putdata(<list/ImagingCore>) <span class="hljs-comment"># Writes a sequence of pixels.</span>
|
|
<Image>.paste(<Image>, (x, y)) <span class="hljs-comment"># Writes an image to the image.</span>
|
|
</code></pre>
|
|
<pre><code class="bash language-bash hljs"><2d_array> = np.array(<Image>) <span class="hljs-comment"># Creates NumPy array from greyscale image.</span>
|
|
<3d_array> = np.array(<Image>) <span class="hljs-comment"># Creates NumPy array from color image.</span>
|
|
<Image> = Image.fromarray(<array>) <span class="hljs-comment"># Creates image from NumPy array of floats.</span>
|
|
</code></pre>
|
|
<div><h3 id="modes-1">Modes</h3><ul>
|
|
<li><strong><code class="python hljs"><span class="hljs-string">'1'</span></code> - 1-bit pixels, black and white, stored with one pixel per byte.</strong></li>
|
|
<li><strong><code class="python hljs"><span class="hljs-string">'L'</span></code> - 8-bit pixels, greyscale.</strong></li>
|
|
<li><strong><code class="python hljs"><span class="hljs-string">'RGB'</span></code> - 3x8-bit pixels, true color.</strong></li>
|
|
<li><strong><code class="python hljs"><span class="hljs-string">'RGBA'</span></code> - 4x8-bit pixels, true color with transparency mask.</strong></li>
|
|
<li><strong><code class="python hljs"><span class="hljs-string">'HSV'</span></code> - 3x8-bit pixels, Hue, Saturation, Value color space.</strong></li>
|
|
</ul><div><h3 id="examples">Examples</h3><div><h4 id="createsapngimageofarainbowgradient">Creates a PNG image of a rainbow gradient:</h4><pre><code class="python language-python hljs">WIDTH, HEIGHT = <span class="hljs-number">100</span>, <span class="hljs-number">100</span>
|
|
size = WIDTH * HEIGHT
|
|
hues = [<span class="hljs-number">255</span> * i/size <span class="hljs-keyword">for</span> i <span class="hljs-keyword">in</span> range(size)]
|
|
img = Image.new(<span class="hljs-string">'HSV'</span>, (WIDTH, HEIGHT))
|
|
img.putdata([(int(h), <span class="hljs-number">255</span>, <span class="hljs-number">255</span>) <span class="hljs-keyword">for</span> h <span class="hljs-keyword">in</span> hues])
|
|
img.convert(<span class="hljs-string">'RGB'</span>).save(<span class="hljs-string">'test.png'</span>)
|
|
</code></pre></div></div></div>
|
|
|
|
|
|
|
|
|
|
<div><h4 id="addsnoisetoapngimage">Adds noise to a PNG image:</h4><pre><code class="python language-python hljs"><span class="hljs-keyword">from</span> random <span class="hljs-keyword">import</span> randint
|
|
add_noise = <span class="hljs-keyword">lambda</span> value: max(<span class="hljs-number">0</span>, min(<span class="hljs-number">255</span>, value + randint(<span class="hljs-number">-20</span>, <span class="hljs-number">20</span>)))
|
|
img = Image.open(<span class="hljs-string">'test.png'</span>).convert(<span class="hljs-string">'HSV'</span>)
|
|
img.putdata([(add_noise(h), s, v) <span class="hljs-keyword">for</span> h, s, v <span class="hljs-keyword">in</span> img.getdata()])
|
|
img.convert(<span class="hljs-string">'RGB'</span>).save(<span class="hljs-string">'test.png'</span>)
|
|
</code></pre></div>
|
|
|
|
<div><h3 id="drawing">Drawing</h3><pre><code class="python language-python hljs"><span class="hljs-keyword">from</span> PIL <span class="hljs-keyword">import</span> ImageDraw
|
|
</code></pre></div>
|
|
|
|
<pre><code class="python language-python hljs"><ImageDraw> = ImageDraw.Draw(<Image>)
|
|
<ImageDraw>.point((x, y), fill=<span class="hljs-keyword">None</span>)
|
|
<ImageDraw>.line((x1, y1, x2, y2 [, ...]), fill=<span class="hljs-keyword">None</span>, width=<span class="hljs-number">0</span>, joint=<span class="hljs-keyword">None</span>)
|
|
<ImageDraw>.arc((x1, y1, x2, y2), from_deg, to_deg, fill=<span class="hljs-keyword">None</span>, width=<span class="hljs-number">0</span>)
|
|
<ImageDraw>.rectangle((x1, y1, x2, y2), fill=<span class="hljs-keyword">None</span>, outline=<span class="hljs-keyword">None</span>, width=<span class="hljs-number">0</span>)
|
|
<ImageDraw>.polygon((x1, y1, x2, y2 [, ...]), fill=<span class="hljs-keyword">None</span>, outline=<span class="hljs-keyword">None</span>)
|
|
<ImageDraw>.ellipse((x1, y1, x2, y2), fill=<span class="hljs-keyword">None</span>, outline=<span class="hljs-keyword">None</span>, width=<span class="hljs-number">0</span>)
|
|
</code></pre>
|
|
<ul>
|
|
<li><strong>Use <code class="python hljs"><span class="hljs-string">'fill=<color>'</span></code> to set the primary color.</strong></li>
|
|
<li><strong>Use <code class="python hljs"><span class="hljs-string">'outline=<color>'</span></code> to set the secondary color.</strong></li>
|
|
<li><strong>Color can be specified as a tuple, int, <code class="python hljs"><span class="hljs-string">'#rrggbb'</span></code> string or a color name.</strong></li>
|
|
</ul>
|
|
<div><h2 id="animation"><a href="#animation" name="animation">#</a>Animation</h2><div><h4 id="createsagifofabouncingball">Creates a GIF of a bouncing ball:</h4><pre><code class="python language-python hljs"><span class="hljs-comment"># $ pip3 install pillow imageio</span>
|
|
<span class="hljs-keyword">from</span> PIL <span class="hljs-keyword">import</span> Image, ImageDraw
|
|
<span class="hljs-keyword">import</span> imageio
|
|
WIDTH, R = <span class="hljs-number">126</span>, <span class="hljs-number">10</span>
|
|
frames = []
|
|
<span class="hljs-keyword">for</span> velocity <span class="hljs-keyword">in</span> range(<span class="hljs-number">15</span>):
|
|
y = sum(range(velocity+<span class="hljs-number">1</span>))
|
|
frame = Image.new(<span class="hljs-string">'L'</span>, (WIDTH, WIDTH))
|
|
draw = ImageDraw.Draw(frame)
|
|
draw.ellipse((WIDTH/<span class="hljs-number">2</span>-R, y, WIDTH/<span class="hljs-number">2</span>+R, y+<span class="hljs-number">2</span>*R), fill=<span class="hljs-string">'white'</span>)
|
|
frames.append(frame)
|
|
frames += reversed(frames[<span class="hljs-number">1</span>:<span class="hljs-number">-1</span>])
|
|
imageio.mimsave(<span class="hljs-string">'test.gif'</span>, frames, duration=<span class="hljs-number">0.03</span>)
|
|
</code></pre></div></div>
|
|
|
|
|
|
<div><h2 id="audio"><a href="#audio" name="audio">#</a>Audio</h2><pre><code class="python language-python hljs"><span class="hljs-keyword">import</span> wave
|
|
</code></pre></div>
|
|
|
|
<pre><code class="python language-python hljs"><Wave_read> = wave.open(<span class="hljs-string">'<path>'</span>, <span class="hljs-string">'rb'</span>) <span class="hljs-comment"># Opens the WAV file.</span>
|
|
framerate = <Wave_read>.getframerate() <span class="hljs-comment"># Number of frames per second.</span>
|
|
nchannels = <Wave_read>.getnchannels() <span class="hljs-comment"># Number of samples per frame.</span>
|
|
sampwidth = <Wave_read>.getsampwidth() <span class="hljs-comment"># Sample size in bytes.</span>
|
|
nframes = <Wave_read>.getnframes() <span class="hljs-comment"># Number of frames.</span>
|
|
<params> = <Wave_read>.getparams() <span class="hljs-comment"># Immutable collection of above.</span>
|
|
<bytes> = <Wave_read>.readframes(nframes) <span class="hljs-comment"># Returns next 'nframes' frames.</span>
|
|
</code></pre>
|
|
<pre><code class="python language-python hljs"><Wave_write> = wave.open(<span class="hljs-string">'<path>'</span>, <span class="hljs-string">'wb'</span>) <span class="hljs-comment"># Truncates existing file.</span>
|
|
<Wave_write>.setframerate(<int>) <span class="hljs-comment"># 44100 for CD, 48000 for video.</span>
|
|
<Wave_write>.setnchannels(<int>) <span class="hljs-comment"># 1 for mono, 2 for stereo.</span>
|
|
<Wave_write>.setsampwidth(<int>) <span class="hljs-comment"># 2 for CD quality sound.</span>
|
|
<Wave_write>.setparams(<params>) <span class="hljs-comment"># Sets all parameters.</span>
|
|
<Wave_write>.writeframes(<bytes>) <span class="hljs-comment"># Appends frames to file.</span>
|
|
</code></pre>
|
|
<ul>
|
|
<li><strong>Bytes object contains a sequence of frames, each consisting of one or more samples.</strong></li>
|
|
<li><strong>In a stereo signal, the first sample of a frame belongs to the left channel.</strong></li>
|
|
<li><strong>Each sample consists of one or more bytes that, when converted to an integer, indicate the displacement of a speaker membrane at a given moment.</strong></li>
|
|
<li><strong>If sample width is one, then the integer should be encoded unsigned.</strong></li>
|
|
<li><strong>For all other sizes, the integer should be encoded signed with little-endian byte order.</strong></li>
|
|
</ul>
|
|
<div><h3 id="samplevalues">Sample Values</h3><pre><code class="text language-text">+-----------+-------------+------+-------------+
|
|
| sampwidth | min | zero | max |
|
|
+-----------+-------------+------+-------------+
|
|
| 1 | 0 | 128 | 255 |
|
|
| 2 | -32768 | 0 | 32767 |
|
|
| 3 | -8388608 | 0 | 8388607 |
|
|
| 4 | -2147483648 | 0 | 2147483647 |
|
|
+-----------+-------------+------+-------------+
|
|
</code></pre></div>
|
|
|
|
<div><h3 id="readfloatsamplesfromwavfile">Read Float Samples from WAV File</h3><pre><code class="python language-python hljs"><span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">read_wav_file</span><span class="hljs-params">(filename)</span>:</span>
|
|
<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">get_int</span><span class="hljs-params">(a_bytes)</span>:</span>
|
|
an_int = int.from_bytes(a_bytes, <span class="hljs-string">'little'</span>, signed=width!=<span class="hljs-number">1</span>)
|
|
<span class="hljs-keyword">return</span> an_int - <span class="hljs-number">128</span> * (width == <span class="hljs-number">1</span>)
|
|
<span class="hljs-keyword">with</span> wave.open(filename, <span class="hljs-string">'rb'</span>) <span class="hljs-keyword">as</span> file:
|
|
width = file.getsampwidth()
|
|
frames = file.readframes(file.getnframes())
|
|
byte_samples = (frames[i: i + width] <span class="hljs-keyword">for</span> i <span class="hljs-keyword">in</span> range(<span class="hljs-number">0</span>, len(frames), width))
|
|
<span class="hljs-keyword">return</span> [get_int(b) / pow(<span class="hljs-number">2</span>, width * <span class="hljs-number">8</span> - <span class="hljs-number">1</span>) <span class="hljs-keyword">for</span> b <span class="hljs-keyword">in</span> byte_samples]
|
|
</code></pre></div>
|
|
|
|
<div><h3 id="writefloatsamplestowavfile">Write Float Samples to WAV File</h3><pre><code class="python language-python hljs"><span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">write_to_wav_file</span><span class="hljs-params">(filename, float_samples, nchannels=<span class="hljs-number">1</span>, sampwidth=<span class="hljs-number">2</span>, framerate=<span class="hljs-number">44100</span>)</span>:</span>
|
|
<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">get_bytes</span><span class="hljs-params">(a_float)</span>:</span>
|
|
a_float = max(<span class="hljs-number">-1</span>, min(<span class="hljs-number">1</span> - <span class="hljs-number">2e-16</span>, a_float))
|
|
a_float += sampwidth == <span class="hljs-number">1</span>
|
|
a_float *= pow(<span class="hljs-number">2</span>, sampwidth * <span class="hljs-number">8</span> - <span class="hljs-number">1</span>)
|
|
<span class="hljs-keyword">return</span> int(a_float).to_bytes(sampwidth, <span class="hljs-string">'little'</span>, signed=sampwidth!=<span class="hljs-number">1</span>)
|
|
<span class="hljs-keyword">with</span> wave.open(filename, <span class="hljs-string">'wb'</span>) <span class="hljs-keyword">as</span> file:
|
|
file.setnchannels(nchannels)
|
|
file.setsampwidth(sampwidth)
|
|
file.setframerate(framerate)
|
|
file.writeframes(<span class="hljs-string">b''</span>.join(get_bytes(f) <span class="hljs-keyword">for</span> f <span class="hljs-keyword">in</span> float_samples))
|
|
</code></pre></div>
|
|
|
|
<div><h3 id="examples-1">Examples</h3><div><h4 id="savesasinewavetoamonowavfile">Saves a sine wave to a mono WAV file:</h4><pre><code class="python language-python hljs"><span class="hljs-keyword">from</span> math <span class="hljs-keyword">import</span> pi, sin
|
|
samples_f = (sin(i * <span class="hljs-number">2</span> * pi * <span class="hljs-number">440</span> / <span class="hljs-number">44100</span>) <span class="hljs-keyword">for</span> i <span class="hljs-keyword">in</span> range(<span class="hljs-number">100000</span>))
|
|
write_to_wav_file(<span class="hljs-string">'test.wav'</span>, samples_f)
|
|
</code></pre></div></div>
|
|
|
|
|
|
<div><h4 id="addsnoisetoamonowavfile">Adds noise to a mono WAV file:</h4><pre><code class="python language-python hljs"><span class="hljs-keyword">from</span> random <span class="hljs-keyword">import</span> random
|
|
add_noise = <span class="hljs-keyword">lambda</span> value: value + (random() - <span class="hljs-number">0.5</span>) * <span class="hljs-number">0.03</span>
|
|
samples_f = (add_noise(f) <span class="hljs-keyword">for</span> f <span class="hljs-keyword">in</span> read_wav_file(<span class="hljs-string">'test.wav'</span>))
|
|
write_to_wav_file(<span class="hljs-string">'test.wav'</span>, samples_f)
|
|
</code></pre></div>
|
|
|
|
<div><h4 id="playsawavfile">Plays a WAV file:</h4><pre><code class="python language-python hljs"><span class="hljs-comment"># $ pip3 install simpleaudio</span>
|
|
<span class="hljs-keyword">from</span> simpleaudio <span class="hljs-keyword">import</span> play_buffer
|
|
<span class="hljs-keyword">with</span> wave.open(<span class="hljs-string">'test.wav'</span>, <span class="hljs-string">'rb'</span>) <span class="hljs-keyword">as</span> file:
|
|
p = file.getparams()
|
|
frames = file.readframes(p.nframes)
|
|
play_buffer(frames, p.nchannels, p.sampwidth, p.framerate)
|
|
</code></pre></div>
|
|
|
|
<div><h3 id="texttospeech">Text to Speech</h3><pre><code class="python language-python hljs"><span class="hljs-comment"># $ pip3 install pyttsx3</span>
|
|
<span class="hljs-keyword">import</span> pyttsx3
|
|
engine = pyttsx3.init()
|
|
engine.say(<span class="hljs-string">'Sally sells seashells by the seashore.'</span>)
|
|
engine.runAndWait()
|
|
</code></pre></div>
|
|
|
|
<div><h2 id="synthesizer"><a href="#synthesizer" name="synthesizer">#</a>Synthesizer</h2><div><h4 id="playspopcornbygershonkingsley">Plays Popcorn by Gershon Kingsley:</h4><pre><code class="python language-python hljs"><span class="hljs-comment"># $ pip3 install simpleaudio</span>
|
|
<span class="hljs-keyword">import</span> simpleaudio, math, struct
|
|
<span class="hljs-keyword">from</span> itertools <span class="hljs-keyword">import</span> chain, repeat
|
|
F = <span class="hljs-number">44100</span>
|
|
P1 = <span class="hljs-string">'71♪,69,,71♪,66,,62♪,66,,59♪,,,'</span>
|
|
P2 = <span class="hljs-string">'71♪,73,,74♪,73,,74,,71,,73♪,71,,73,,69,,71♪,69,,71,,67,,71♪,,,'</span>
|
|
get_pause = <span class="hljs-keyword">lambda</span> seconds: repeat(<span class="hljs-number">0</span>, int(seconds * F))
|
|
sin_f = <span class="hljs-keyword">lambda</span> i, hz: math.sin(i * <span class="hljs-number">2</span> * math.pi * hz / F)
|
|
get_wave = <span class="hljs-keyword">lambda</span> hz, seconds: (sin_f(i, hz) <span class="hljs-keyword">for</span> i <span class="hljs-keyword">in</span> range(int(seconds * F)))
|
|
get_hz = <span class="hljs-keyword">lambda</span> key: <span class="hljs-number">8.176</span> * <span class="hljs-number">2</span> ** (int(key) / <span class="hljs-number">12</span>)
|
|
parse_note = <span class="hljs-keyword">lambda</span> note: (get_hz(note[:<span class="hljs-number">2</span>]), <span class="hljs-number">0.25</span> <span class="hljs-keyword">if</span> <span class="hljs-string">'♪'</span> <span class="hljs-keyword">in</span> note <span class="hljs-keyword">else</span> <span class="hljs-number">0.125</span>)
|
|
get_samples = <span class="hljs-keyword">lambda</span> note: get_wave(*parse_note(note)) <span class="hljs-keyword">if</span> note <span class="hljs-keyword">else</span> get_pause(<span class="hljs-number">0.125</span>)
|
|
samples_f = chain.from_iterable(get_samples(n) <span class="hljs-keyword">for</span> n <span class="hljs-keyword">in</span> <span class="hljs-string">f'<span class="hljs-subst">{P1}</span><span class="hljs-subst">{P1}</span><span class="hljs-subst">{P2}</span>'</span>.split(<span class="hljs-string">','</span>))
|
|
samples_b = <span class="hljs-string">b''</span>.join(struct.pack(<span class="hljs-string">'<h'</span>, int(f * <span class="hljs-number">30000</span>)) <span class="hljs-keyword">for</span> f <span class="hljs-keyword">in</span> samples_f)
|
|
simpleaudio.play_buffer(samples_b, <span class="hljs-number">1</span>, <span class="hljs-number">2</span>, F)
|
|
</code></pre></div></div>
|
|
|
|
|
|
<div><h2 id="basicscripttemplate"><a href="#basicscripttemplate" name="basicscripttemplate">#</a>Basic Script Template</h2><pre><code class="python language-python hljs"><span class="hljs-comment">#!/usr/bin/env python3</span>
|
|
<span class="hljs-comment">#</span>
|
|
<span class="hljs-comment"># Usage: .py</span>
|
|
<span class="hljs-comment">#</span>
|
|
|
|
<span class="hljs-keyword">from</span> collections <span class="hljs-keyword">import</span> namedtuple
|
|
<span class="hljs-keyword">from</span> dataclasses <span class="hljs-keyword">import</span> make_dataclass
|
|
<span class="hljs-keyword">from</span> enum <span class="hljs-keyword">import</span> Enum
|
|
<span class="hljs-keyword">from</span> sys <span class="hljs-keyword">import</span> argv
|
|
<span class="hljs-keyword">import</span> re
|
|
|
|
|
|
<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">main</span><span class="hljs-params">()</span>:</span>
|
|
<span class="hljs-keyword">pass</span>
|
|
|
|
|
|
<span class="hljs-comment">###</span>
|
|
<span class="hljs-comment">## UTIL</span>
|
|
<span class="hljs-comment">#</span>
|
|
|
|
<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">read_file</span><span class="hljs-params">(filename)</span>:</span>
|
|
<span class="hljs-keyword">with</span> open(filename, encoding=<span class="hljs-string">'utf-8'</span>) <span class="hljs-keyword">as</span> file:
|
|
<span class="hljs-keyword">return</span> file.readlines()
|
|
|
|
|
|
<span class="hljs-keyword">if</span> __name__ == <span class="hljs-string">'__main__'</span>:
|
|
main()
|
|
</code></pre></div>
|
|
|
|
|
|
<footer>
|
|
<aside>December 15, 2019</aside>
|
|
<a href="../" rel="author">Jure Šorn</a>
|
|
</footer>
|
|
|
|
<br>
|
|
<br>
|
|
<br>
|
|
<script src="web/jquery-3.4.0.min.js"></script>
|
|
<script src="web/script_2.js"></script>
|
|
<script type="text/javascript" src="https://transactions.sendowl.com/assets/sendowl.js" ></script>
|
|
</body>
|
|
</html>
|