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.

2421 lines
64 KiB

6 years ago
7 years ago
5 years ago
7 years ago
6 years ago
6 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
6 years ago
6 years ago
5 years ago
5 years ago
5 years ago
5 years ago
6 years ago
6 years ago
5 years ago
5 years ago
5 years ago
6 years ago
5 years ago
5 years ago
6 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
6 years ago
6 years ago
6 years ago
5 years ago
6 years ago
5 years ago
5 years ago
6 years ago
7 years ago
6 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
6 years ago
6 years ago
6 years ago
7 years ago
6 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
6 years ago
5 years ago
6 years ago
5 years ago
6 years ago
5 years ago
5 years ago
6 years ago
7 years ago
6 years ago
6 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
6 years ago
6 years ago
5 years ago
6 years ago
6 years ago
5 years ago
6 years ago
5 years ago
6 years ago
5 years ago
6 years ago
5 years ago
6 years ago
6 years ago
7 years ago
6 years ago
7 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
6 years ago
5 years ago
6 years ago
6 years ago
5 years ago
5 years ago
5 years ago
6 years ago
5 years ago
5 years ago
5 years ago
5 years ago
6 years ago
5 years ago
6 years ago
6 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
6 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
6 years ago
6 years ago
5 years ago
5 years ago
5 years ago
6 years ago
5 years ago
6 years ago
5 years ago
6 years ago
6 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
6 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
6 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
5 years ago
5 years ago
6 years ago
6 years ago
6 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
6 years ago
6 years ago
5 years ago
6 years ago
5 years ago
5 years ago
5 years ago
6 years ago
5 years ago
6 years ago
5 years ago
6 years ago
6 years ago
6 years ago
6 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
5 years ago
6 years ago
5 years ago
5 years ago
5 years ago
5 years ago
6 years ago
5 years ago
6 years ago
6 years ago
5 years ago
5 years ago
6 years ago
5 years ago
5 years ago
6 years ago
6 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
6 years ago
5 years ago
5 years ago
5 years ago
6 years ago
5 years ago
5 years ago
5 years ago
5 years ago
6 years ago
6 years ago
5 years ago
5 years ago
5 years ago
5 years ago
6 years ago
6 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
6 years ago
6 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
6 years ago
6 years ago
5 years ago
5 years ago
6 years ago
5 years ago
6 years ago
6 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
6 years ago
5 years ago
6 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
6 years ago
6 years ago
6 years ago
6 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
6 years ago
6 years ago
5 years ago
6 years ago
5 years ago
5 years ago
6 years ago
5 years ago
6 years ago
5 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
5 years ago
5 years ago
5 years ago
6 years ago
6 years ago
6 years ago
5 years ago
5 years ago
6 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
6 years ago
6 years ago
5 years ago
6 years ago
6 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
6 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
6 years ago
6 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
6 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
6 years ago
6 years ago
5 years ago
5 years ago
6 years ago
5 years ago
5 years ago
6 years ago
5 years ago
5 years ago
6 years ago
6 years ago
5 years ago
6 years ago
6 years ago
6 years ago
5 years ago
6 years ago
5 years ago
5 years ago
6 years ago
5 years ago
5 years ago
6 years ago
6 years ago
6 years ago
5 years ago
5 years ago
6 years ago
6 years ago
5 years ago
6 years ago
6 years ago
5 years ago
5 years ago
6 years ago
5 years ago
5 years ago
5 years ago
6 years ago
6 years ago
5 years ago
5 years ago
5 years ago
5 years ago
6 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
6 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
6 years ago
5 years ago
5 years ago
5 years ago
6 years ago
5 years ago
5 years ago
6 years ago
6 years ago
6 years ago
5 years ago
6 years ago
6 years ago
6 years ago
5 years ago
6 years ago
5 years ago
6 years ago
5 years ago
6 years ago
5 years ago
6 years ago
5 years ago
6 years ago
6 years ago
6 years ago
5 years ago
5 years ago
5 years ago
6 years ago
6 years ago
6 years ago
5 years ago
5 years ago
5 years ago
6 years ago
5 years ago
5 years ago
5 years ago
6 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
6 years ago
5 years ago
6 years ago
5 years ago
6 years ago
5 years ago
6 years ago
5 years ago
6 years ago
5 years ago
6 years ago
5 years ago
6 years ago
5 years ago
5 years ago
5 years ago
5 years ago
6 years ago
5 years ago
6 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
6 years ago
5 years ago
5 years ago
5 years ago
6 years ago
6 years ago
5 years ago
5 years ago
6 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
6 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
6 years ago
5 years ago
6 years ago
5 years ago
  1. Comprehensive Python Cheatsheet
  2. ===============================
  3. <sup>[Download text file](https://raw.githubusercontent.com/gto76/python-cheatsheet/master/README.md), [Fork me on GitHub](https://github.com/gto76/python-cheatsheet) or [Check out FAQ](https://github.com/gto76/python-cheatsheet/wiki/Frequently-Asked-Questions).
  4. </sup>
  5. ![Monty Python](web/image_888.jpeg)
  6. Contents
  7. --------
  8. **&nbsp;&nbsp;&nbsp;** **1. Collections:** **&nbsp;** **[`List`](#list)**__,__ **[`Dictionary `](#dictionary)**__,__ **[`Set`](#set)**__,__ **[`Tuple`](#tuple)**__,__ **[`Range`](#range)**__,__ **[`Enumerate`](#enumerate)**__,__ **[`Iterator`](#iterator)**__,__ **[`Generator`](#generator)**__.__
  9. **&nbsp;&nbsp;&nbsp;** **2. Types:** **&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;** **[`Type`](#type)**__,__ **[`String`](#string)**__,__ **[`Regular_Exp`](#regex)**__,__ **[`Format`](#format)**__,__ **[`Numbers`](#numbers)**__,__ **[`Combinatorics`](#combinatorics)**__,__ **[`Datetime`](#datetime)**__.__
  10. **&nbsp;&nbsp;&nbsp;** **3. Syntax:** **&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;** **[`Args`](#arguments)**__,__ **[`Inline`](#inline)**__,__ **[`Closure`](#closure)**__,__ **[`Decorator`](#decorator)**__,__ **[`Class`](#class)**__,__ **[`Duck_Types`](#duck-types)**__,__ **[`Enum`](#enum)**__,__ **[`Exceptions`](#exceptions)**__.__
  11. **&nbsp;&nbsp;&nbsp;** **4. System:** **&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;** **[`Print`](#print)**__,__ **[`Input`](#input)**__,__ **[`Command_Line_Arguments`](#command-line-arguments)**__,__ **[`Open`](#open)**__,__ **[`Path`](#path)**__,__ **[`Command_Execution`](#command-execution)**__.__
  12. **&nbsp;&nbsp;&nbsp;** **5. Data:** **&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;** **[`CSV`](#csv)**__,__ **[`JSON`](#json)**__,__ **[`Pickle`](#pickle)**__,__ **[`SQLite`](#sqlite)**__,__ **[`Bytes`](#bytes)**__,__ **[`Struct`](#struct)**__,__ **[`Array`](#array)**__,__ **[`MemoryView`](#memory-view)**__,__ **[`Deque`](#deque)**__.__
  13. **&nbsp;&nbsp;&nbsp;** **6. Advanced:** **&nbsp;&nbsp;&nbsp;** **[`Threading`](#threading)**__,__ **[`Introspection`](#introspection)**__,__ **[`Metaprograming`](#metaprograming)**__,__ **[`Operator`](#operator)**__,__ **[`Eval`](#eval)**__,__ **[`Coroutine`](#coroutine)**__.__
  14. **&nbsp;&nbsp;&nbsp;** **7. Libraries:** **&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;** **[`Progress_Bar`](#progress-bar)**__,__ **[`Plot`](#plot)**__,__ **[`Table`](#table)**__,__ **[`Curses`](#curses)**__,__ **[`Logging`](#logging)**__,__ **[`Scraping`](#scraping)**__,__ **[`Web`](#web)**__,__ **[`Profile`](#profile)**__,__
  15. **&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;** **[`NumPy`](#numpy)**__,__ **[`Image`](#image)**__,__ **[`Audio`](#audio)**__.__
  16. Main
  17. ----
  18. ```python
  19. if __name__ == '__main__': # Runs main() if file wasn't imported.
  20. main()
  21. ```
  22. List
  23. ----
  24. ```python
  25. <list> = <list>[from_inclusive : to_exclusive : ±step_size]
  26. ```
  27. ```python
  28. <list>.append(<el>) # Or: <list> += [<el>]
  29. <list>.extend(<collection>) # Or: <list> += <collection>
  30. ```
  31. ```python
  32. <list>.sort()
  33. <list>.reverse()
  34. <list> = sorted(<collection>)
  35. <iter> = reversed(<list>)
  36. ```
  37. ```python
  38. sum_of_elements = sum(<collection>)
  39. elementwise_sum = [sum(pair) for pair in zip(list_a, list_b)]
  40. sorted_by_second = sorted(<collection>, key=lambda el: el[1])
  41. sorted_by_both = sorted(<collection>, key=lambda el: (el[1], el[0]))
  42. flatter_list = list(itertools.chain.from_iterable(<list>))
  43. product_of_elems = functools.reduce(lambda out, x: out * x, <collection>)
  44. list_of_chars = list(<str>)
  45. ```
  46. ```python
  47. index = <list>.index(<el>) # Returns index of first occurrence or raises ValueError.
  48. <list>.insert(index, <el>) # Inserts item at index and moves the rest to the right.
  49. <el> = <list>.pop([index]) # Removes and returns item at index or from the end.
  50. <list>.remove(<el>) # Removes first occurrence of item or raises ValueError.
  51. <list>.clear() # Removes all items. Also works on dict and set.
  52. ```
  53. Dictionary
  54. ----------
  55. ```python
  56. <view> = <dict>.keys() # Coll. of keys that reflects changes.
  57. <view> = <dict>.values() # Coll. of values that reflects changes.
  58. <view> = <dict>.items() # Coll. of key-value tuples.
  59. ```
  60. ```python
  61. value = <dict>.get(key, default=None) # Returns default if key does not exist.
  62. value = <dict>.setdefault(key, default=None) # Same, but also adds default to dict.
  63. <dict> = collections.defaultdict(<type>) # Creates a dict with default value of type.
  64. <dict> = collections.defaultdict(lambda: 1) # Creates a dict with default value 1.
  65. ```
  66. ```python
  67. <dict>.update(<dict>)
  68. <dict> = dict(<collection>) # Creates a dict from coll. of key-value pairs.
  69. <dict> = dict(zip(keys, values)) # Creates a dict from two collections.
  70. <dict> = dict.fromkeys(keys [, value]) # Creates a dict from collection of keys.
  71. ```
  72. ```python
  73. value = <dict>.pop(key) # Removes item from dictionary.
  74. {k: v for k, v in <dict>.items() if k in keys} # Filters dictionary by keys.
  75. ```
  76. ### Counter
  77. ```python
  78. >>> from collections import Counter
  79. >>> colors = ['red', 'blue', 'yellow', 'blue', 'red', 'blue']
  80. >>> counter = Counter(colors)
  81. Counter({'blue': 3, 'red': 2, 'yellow': 1})
  82. >>> counter.most_common()[0]
  83. ('blue', 3)
  84. ```
  85. Set
  86. ---
  87. ```python
  88. <set> = set()
  89. ```
  90. ```python
  91. <set>.add(<el>) # Or: <set> |= {<el>}
  92. <set>.update(<collection>) # Or: <set> |= <set>
  93. ```
  94. ```python
  95. <set> = <set>.union(<coll.>) # Or: <set> | <set>
  96. <set> = <set>.intersection(<coll.>) # Or: <set> & <set>
  97. <set> = <set>.difference(<coll.>) # Or: <set> - <set>
  98. <set> = <set>.symmetric_difference(<coll.>) # Or: <set> ^ <set>
  99. <bool> = <set>.issubset(<coll.>) # Or: <set> <= <set>
  100. <bool> = <set>.issuperset(<coll.>) # Or: <set> >= <set>
  101. ```
  102. ```python
  103. <set>.remove(<el>) # Raises KeyError.
  104. <set>.discard(<el>) # Doesn't raise an error.
  105. ```
  106. ### Frozen Set
  107. * **Is immutable and hashable.**
  108. * **That means it can be used as a key in a dictionary or as an element in a set.**
  109. ```python
  110. <frozenset> = frozenset(<collection>)
  111. ```
  112. Tuple
  113. -----
  114. **Tuple is an immutable and hashable list.**
  115. ```python
  116. <tuple> = ()
  117. <tuple> = (<el>, )
  118. <tuple> = (<el_1>, <el_2>, ...)
  119. ```
  120. ### Named Tuple
  121. **Tuple's subclass with named elements.**
  122. ```python
  123. >>> from collections import namedtuple
  124. >>> Point = namedtuple('Point', 'x y')
  125. >>> p = Point(1, y=2)
  126. Point(x=1, y=2)
  127. >>> p[0]
  128. 1
  129. >>> p.x
  130. 1
  131. >>> getattr(p, 'y')
  132. 2
  133. >>> p._fields # Or: Point._fields
  134. ('x', 'y')
  135. ```
  136. Range
  137. -----
  138. ```python
  139. <range> = range(to_exclusive)
  140. <range> = range(from_inclusive, to_exclusive)
  141. <range> = range(from_inclusive, to_exclusive, ±step_size)
  142. ```
  143. ```python
  144. from_inclusive = <range>.start
  145. to_exclusive = <range>.stop
  146. ```
  147. Enumerate
  148. ---------
  149. ```python
  150. for i, el in enumerate(<collection> [, i_start]):
  151. ...
  152. ```
  153. Iterator
  154. --------
  155. ```python
  156. <iter> = iter(<collection>) # Calling `iter(<iter>)` returns unmodified iterator.
  157. <iter> = iter(<function>, to_exclusive) # Sequence of return values until 'to_exclusive'.
  158. <el> = next(<iter> [, default]) # Raises StopIteration or returns 'default' on end.
  159. ```
  160. ### Itertools
  161. ```python
  162. from itertools import count, repeat, cycle, chain, islice
  163. ```
  164. ```python
  165. <iter> = count(start=0, step=1) # Returns incremented value endlessly.
  166. <iter> = repeat(<el> [, times]) # Returns element endlessly or 'times' times.
  167. <iter> = cycle(<collection>) # Repeats the sequence indefinitely.
  168. ```
  169. ```python
  170. <iter> = chain(<coll.>, <coll.> [, ...]) # Empties collections in order.
  171. <iter> = chain.from_iterable(<collection>) # Empties collections inside a collection in order.
  172. ```
  173. ```python
  174. <iter> = islice(<collection>, to_exclusive)
  175. <iter> = islice(<collection>, from_inclusive, to_exclusive)
  176. <iter> = islice(<collection>, from_inclusive, to_exclusive, +step_size)
  177. ```
  178. Generator
  179. ---------
  180. * **Convenient way to implement the iterator protocol.**
  181. * **Any function that contains a yield statement returns a generator object.**
  182. * **Generators and iterators are interchangeable.**
  183. ```python
  184. def count(start, step):
  185. while True:
  186. yield start
  187. start += step
  188. ```
  189. ```python
  190. >>> counter = count(10, 2)
  191. >>> next(counter), next(counter), next(counter)
  192. (10, 12, 14)
  193. ```
  194. Type
  195. ----
  196. * **Everything is an object.**
  197. * **Every object has a type.**
  198. * **Type and class are synonymous.**
  199. ```python
  200. <type> = type(<el>) # Or: <el>.__class__
  201. <bool> = isinstance(<el>, <type>) # Or: issubclass(type(<el>), <type>)
  202. ```
  203. ```python
  204. >>> type('a'), 'a'.__class__, str
  205. (<class 'str'>, <class 'str'>, <class 'str'>)
  206. ```
  207. #### Some types do not have builtin names, so they must be imported:
  208. ```python
  209. from types import FunctionType, MethodType, LambdaType, GeneratorType
  210. ```
  211. ### ABC
  212. **An abstract base class introduces virtual subclasses, that don’t inherit from it but are still recognized by isinstance() and issubclass().**
  213. ```python
  214. >>> from collections.abc import Sequence, Collection, Iterable
  215. >>> isinstance([1, 2, 3], Iterable)
  216. True
  217. ```
  218. ```text
  219. +------------------+----------+------------+----------+
  220. | | Sequence | Collection | Iterable |
  221. +------------------+----------+------------+----------+
  222. | list, range, str | yes | yes | yes |
  223. | dict, set | | yes | yes |
  224. | iter | | | yes |
  225. +------------------+----------+------------+----------+
  226. ```
  227. ```python
  228. >>> from numbers import Integral, Rational, Real, Complex, Number
  229. >>> isinstance(123, Number)
  230. True
  231. ```
  232. ```text
  233. +--------------------+----------+----------+------+---------+--------+
  234. | | Integral | Rational | Real | Complex | Number |
  235. +--------------------+----------+----------+------+---------+--------+
  236. | int | yes | yes | yes | yes | yes |
  237. | fractions.Fraction | | yes | yes | yes | yes |
  238. | float | | | yes | yes | yes |
  239. | complex | | | | yes | yes |
  240. +--------------------+----------+----------+------+---------+--------+
  241. ```
  242. String
  243. ------
  244. ```python
  245. <str> = <str>.strip() # Strips all whitespace characters from both ends.
  246. <str> = <str>.strip('<chars>') # Strips all passed characters from both ends.
  247. ```
  248. ```python
  249. <list> = <str>.split() # Splits on one or more whitespace characters.
  250. <list> = <str>.split(sep=None, maxsplit=-1) # Splits on 'sep' str at most 'maxsplit' times.
  251. <list> = <str>.splitlines(keepends=False) # Splits on line breaks. Keeps them if 'keepends'.
  252. <str> = <str>.join(<coll_of_strings>) # Joins elements using string as separator.
  253. ```
  254. ```python
  255. <bool> = <sub_str> in <str> # Checks if string contains a substring.
  256. <bool> = <str>.startswith(<sub_str>) # Pass tuple of strings for multiple options.
  257. <bool> = <str>.endswith(<sub_str>) # Pass tuple of strings for multiple options.
  258. <int> = <str>.find(<sub_str>) # Returns start index of first match or -1.
  259. <int> = <str>.index(<sub_str>) # Same but raises ValueError.
  260. ```
  261. ```python
  262. <str> = <str>.replace(old, new [, count]) # Replaces 'old' with 'new' at most 'count' times.
  263. <bool> = <str>.isnumeric() # True if str contains only numeric characters.
  264. <list> = textwrap.wrap(<str>, width) # Nicely breaks string into lines.
  265. ```
  266. * **Also: `'lstrip()'`, `'rstrip()'`.**
  267. * **Also: `'lower()'`, `'upper()'`, `'capitalize()'` and `'title()'`.**
  268. ### Char
  269. ```python
  270. <str> = chr(<int>) # Converts int to unicode char.
  271. <int> = ord(<str>) # Converts unicode char to int.
  272. ```
  273. ```python
  274. >>> ord('0'), ord('9')
  275. (48, 57)
  276. >>> ord('A'), ord('Z')
  277. (65, 90)
  278. >>> ord('a'), ord('z')
  279. (97, 122)
  280. ```
  281. Regex
  282. -----
  283. ```python
  284. import re
  285. <str> = re.sub(<regex>, new, text, count=0) # Substitutes all occurrences.
  286. <list> = re.findall(<regex>, text) # Returns all occurrences.
  287. <list> = re.split(<regex>, text, maxsplit=0) # Use brackets in regex to keep the matches.
  288. <Match> = re.search(<regex>, text) # Searches for first occurrence of pattern.
  289. <Match> = re.match(<regex>, text) # Searches only at the beginning of the text.
  290. <iter> = re.finditer(<regex>, text) # Returns all occurrences as match objects.
  291. ```
  292. * **Argument `'flags=re.IGNORECASE'` can be used with all functions.**
  293. * **Argument `'flags=re.DOTALL'` makes dot also accept newline.**
  294. * **Use `r'\1'` or `'\\1'` for backreference.**
  295. * **Use `'?'` to make an operator non-greedy.**
  296. ### Match Object
  297. ```python
  298. <str> = <Match>.group() # Whole match. Also group(0).
  299. <str> = <Match>.group(1) # Part in first bracket.
  300. <tuple> = <Match>.groups() # All bracketed parts.
  301. <int> = <Match>.start() # Start index of a match.
  302. <int> = <Match>.end() # Exclusive end index of a match.
  303. ```
  304. ### Special Sequences
  305. * **By default digits, whitespaces and alphanumerics from all alphabets are matched, unless `'flags=re.ASCII'` argument is used.**
  306. * **Use capital letters for negation.**
  307. ```python
  308. '\d' == '[0-9]' # Digit
  309. '\s' == '[ \t\n\r\f\v]' # Whitespace
  310. '\w' == '[a-zA-Z0-9_]' # Alphanumeric
  311. ```
  312. Format
  313. ------
  314. ```python
  315. <str> = f'{<el_1>}, {<el_2>}'
  316. <str> = '{}, {}'.format(<el_1>, <el_2>)
  317. ```
  318. ### Attributes
  319. ```python
  320. >>> from collections import namedtuple
  321. >>> Person = namedtuple('Person', 'name height')
  322. >>> person = Person('Jean-Luc', 187)
  323. >>> f'{person.height}'
  324. '187'
  325. >>> '{p.height}'.format(p=person)
  326. '187'
  327. ```
  328. ### General Options
  329. ```python
  330. {<el>:<10} # '<el> '
  331. {<el>:^10} # ' <el> '
  332. {<el>:>10} # ' <el>'
  333. ```
  334. ```python
  335. {<el>:.<10} # '<el>......'
  336. {<el>:>0} # '<el>'
  337. ```
  338. ### Strings
  339. **`'!r'` calls object's repr() method, instead of format(), to get a string.**
  340. ```python
  341. {'abcde'!r:<10} # "'abcde' "
  342. {'abcde':.3} # 'abc'
  343. {'abcde':10.3} # 'abc '
  344. ```
  345. ### Numbers
  346. ```python
  347. { 123456:10,} # ' 123,456'
  348. { 123456:10_} # ' 123_456'
  349. { 123456:+10} # ' +123456'
  350. {-123456:=10} # '- 123456'
  351. { 123456: } # ' 123456'
  352. {-123456: } # '-123456'
  353. ```
  354. ### Floats
  355. ```python
  356. {1.23456:10.3} # ' 1.23'
  357. {1.23456:10.3f} # ' 1.235'
  358. {1.23456:10.3e} # ' 1.235e+00'
  359. {1.23456:10.3%} # ' 123.456%'
  360. ```
  361. #### Comparison of float presentation types:
  362. ```text
  363. +----------------+--------------+---------------+---------------+---------------+
  364. | | {<float>:.2} | {<float>:.2f} | {<float>:.2e} | {<float>:.2%} |
  365. +----------------+--------------+---------------+---------------+---------------+
  366. | 0.000056789 | '5.7e-05' | '0.00' | '5.68e-05' | '0.01%' |
  367. | 0.00056789 | '0.00057' | '0.00' | '5.68e-04' | '0.06%' |
  368. | 0.0056789 | '0.0057' | '0.01' | '5.68e-03' | '0.57%' |
  369. | 0.056789 | '0.057' | '0.06' | '5.68e-02' | '5.68%' |
  370. | 0.56789 | '0.57' | '0.57' | '5.68e-01' | '56.79%' |
  371. | 5.6789 | '5.7' | '5.68' | '5.68e+00' | '567.89%' |
  372. | 56.789 | '5.7e+01' | '56.79' | '5.68e+01' | '5678.90%' |
  373. | 567.89 | '5.7e+02' | '567.89' | '5.68e+02' | '56789.00%' |
  374. +----------------+--------------+---------------+---------------+---------------+
  375. ```
  376. ### Ints
  377. ```python
  378. {90:c} # 'Z'
  379. {90:X} # '5A'
  380. {90:b} # '1011010'
  381. ```
  382. Numbers
  383. -------
  384. ```python
  385. <int> = int(<float/str/bool>) # Or: math.floor(<float>)
  386. <float> = float(<int/str/bool>)
  387. <complex> = complex(real=0, imag=0) # Or: <real> + <real>j
  388. <Fraction> = fractions.Fraction(numerator=0, denominator=1)
  389. ```
  390. * **`'int(<str>)'` and `'float(<str>)'` raise ValueError on malformed strings.**
  391. ### Basic Functions
  392. ```python
  393. <num> = pow(<num>, <num>) # Or: <num> ** <num>
  394. <real> = abs(<num>)
  395. <int> = round(<real>)
  396. <real> = round(<real>, ±ndigits) # `round(126, -1) == 130`
  397. ```
  398. ### Math
  399. ```python
  400. from math import e, pi, inf, nan
  401. from math import cos, acos, sin, asin, tan, atan, degrees, radians
  402. from math import log, log10, log2
  403. ```
  404. ### Statistics
  405. ```python
  406. from statistics import mean, median, variance, pvariance, pstdev
  407. ```
  408. ### Random
  409. ```python
  410. from random import random, randint, choice, shuffle
  411. <float> = random()
  412. <int> = randint(from_inclusive, to_inclusive)
  413. <el> = choice(<list>)
  414. shuffle(<list>)
  415. ```
  416. ### Bin, Hex
  417. ```python
  418. <int> = 0b<bin> # Or: 0x<hex>
  419. <int> = int('0b<bin>', 0) # Or: int('0x<hex>', 0)
  420. <int> = int('<bin>', 2) # Or: int('<hex>', 16)
  421. '0b<bin>' = bin(<int>) # Or: '0x<hex>' = hex(<int>)
  422. ```
  423. ### Bitwise Operators
  424. ```python
  425. <int> = <int> & <int> # And
  426. <int> = <int> | <int> # Or
  427. <int> = <int> ^ <int> # Xor (0 if both bits equal)
  428. <int> = <int> << n_bits # Shift left
  429. <int> = <int> >> n_bits # Shift right
  430. <int> = ~<int> # Compliment (flips bits)
  431. ```
  432. Combinatorics
  433. -------------
  434. * **Every function returns an iterator.**
  435. * **If you want to print the iterator, you need to pass it to the list() function!**
  436. ```python
  437. from itertools import product, combinations, combinations_with_replacement, permutations
  438. ```
  439. ```python
  440. >>> product([0, 1], repeat=3)
  441. [(0, 0, 0), (0, 0, 1), (0, 1, 0), (0, 1, 1),
  442. (1, 0, 0), (1, 0, 1), (1, 1, 0), (1, 1, 1)]
  443. ```
  444. ```python
  445. >>> product('ab', '12')
  446. [('a', '1'), ('a', '2'),
  447. ('b', '1'), ('b', '2')]
  448. ```
  449. ```python
  450. >>> combinations('abc', 2)
  451. [('a', 'b'), ('a', 'c'), ('b', 'c')]
  452. ```
  453. ```python
  454. >>> combinations_with_replacement('abc', 2)
  455. [('a', 'a'), ('a', 'b'), ('a', 'c'),
  456. ('b', 'b'), ('b', 'c'),
  457. ('c', 'c')]
  458. ```
  459. ```python
  460. >>> permutations('abc', 2)
  461. [('a', 'b'), ('a', 'c'),
  462. ('b', 'a'), ('b', 'c'),
  463. ('c', 'a'), ('c', 'b')]
  464. ```
  465. Datetime
  466. --------
  467. * **Module 'datetime' provides 'date' `<D>`, 'time' `<T>`, 'datetime' `<DT>` and 'timedelta' `<TD>` classes. All are immutable and hashable.**
  468. * **Time and datetime can be 'aware' `<a>`, meaning they have defined timezone, or 'naive' `<n>`, meaning they don't.**
  469. * **If object is naive it is presumed to be in system's timezone.**
  470. ```python
  471. from datetime import date, time, datetime, timedelta
  472. from dateutil.tz import UTC, tzlocal, gettz
  473. ```
  474. ### Constructors
  475. ```python
  476. <D> = date(year, month, day)
  477. <T> = time(hour=0, minute=0, second=0, microsecond=0, tzinfo=None, fold=0)
  478. <DT> = datetime(year, month, day, hour=0, minute=0, second=0, ...)
  479. <TD> = timedelta(days=0, seconds=0, microseconds=0, milliseconds=0,
  480. minutes=0, hours=0, weeks=0)
  481. ```
  482. * **Use `'<D/DT>.weekday()'` to get the day of the week (Mon == 0).**
  483. * **`'fold=1'` means second pass in case of time jumping back for one hour.**
  484. ### Now
  485. ```python
  486. <D/DTn> = D/DT.today() # Current local date or naive datetime.
  487. <DTn> = DT.utcnow() # Naive datetime from current UTC time.
  488. <DTa> = DT.now(<tzinfo>) # Aware datetime from current tz time.
  489. ```
  490. * **To extract time use `'<DTn>.time()'`, `'<DTa>.time()'` or `'<DTa>.timetz()'`.**
  491. ### Timezone
  492. ```python
  493. <tzinfo> = UTC # UTC timezone. London without DST.
  494. <tzinfo> = tzlocal() # Local timezone. Also gettz().
  495. <tzinfo> = gettz('<Cont.>/<City>') # Timezone from 'Continent/City_Name' str.
  496. ```
  497. ```python
  498. <DTa> = <DT>.astimezone(<tzinfo>) # Datetime, converted to passed timezone.
  499. <Ta/DTa> = <T/DT>.replace(tzinfo=<tzinfo>) # Unconverted object with new timezone.
  500. ```
  501. ### Encode
  502. ```python
  503. <D/T/DT> = D/T/DT.fromisoformat('<iso>') # Object from ISO string.
  504. <DT> = DT.strptime(<str>, '<format>') # Datetime from str, according to format.
  505. <D/DTn> = D/DT.fromordinal(<int>) # D/DTn from days since Christ, at midnight.
  506. <DTn> = DT.fromtimestamp(<real>) # Local time DTn from seconds since Epoch.
  507. <DTa> = DT.fromtimestamp(<real>, <tz.>) # Aware datetime from seconds since Epoch.
  508. ```
  509. * **ISO strings come in following forms: `'YYYY-MM-DD'`, `'HH:MM:SS.ffffff[±<offset>]'`, or both separated by `'T'`. Offset is formatted as: `'HH:MM'`.**
  510. * **On Unix systems Epoch is `'1970-01-01 00:00 UTC'`, `'1970-01-01 01:00 CET'`, ...**
  511. ### Decode
  512. ```python
  513. <str> = <D/T/DT>.isoformat() # ISO string representation.
  514. <str> = <D/T/DT>.strftime('<format>') # Custom string representation.
  515. <int> = <D/DT>.toordinal() # Days since Christ, ignoring time and tz.
  516. <float> = <DTn>.timestamp() # Seconds since Epoch from DTn in local time.
  517. <float> = <DTa>.timestamp() # Seconds since Epoch from DTa.
  518. ```
  519. ### Format
  520. ```python
  521. >>> from datetime import datetime
  522. >>> dt = datetime.strptime('2015-05-14 23:39:00.00 +0200', '%Y-%m-%d %H:%M:%S.%f %z')
  523. >>> dt.strftime("%A, %dth of %B '%y, %I:%M%p %Z")
  524. "Thursday, 14th of May '15, 11:39PM UTC+02:00"
  525. ```
  526. * **For abbreviated weekday and month use `'%a'` and `'%b'`.**
  527. * **When parsing, `'%z'` also accepts `'±HH:MM'`.**
  528. ### Arithmetics
  529. ```python
  530. <D/DT> = <D/DT> ± <TD>
  531. <TD> = <TD> ± <TD>
  532. <TD> = <TD> */ <real>
  533. <float> = <TD> / <TD>
  534. ```
  535. Arguments
  536. ---------
  537. ### Inside Function Call
  538. ```python
  539. <function>(<positional_args>) # f(0, 0)
  540. <function>(<keyword_args>) # f(x=0, y=0)
  541. <function>(<positional_args>, <keyword_args>) # f(0, y=0)
  542. ```
  543. ### Inside Function Definition
  544. ```python
  545. def f(<nondefault_args>): # def f(x, y):
  546. def f(<default_args>): # def f(x=0, y=0):
  547. def f(<nondefault_args>, <default_args>): # def f(x, y=0):
  548. ```
  549. Splat Operator
  550. --------------
  551. ### Inside Function Call
  552. **Splat expands a collection into positional arguments, while splatty-splat expands a dictionary into keyword arguments.**
  553. ```python
  554. args = (1, 2)
  555. kwargs = {'x': 3, 'y': 4, 'z': 5}
  556. func(*args, **kwargs)
  557. ```
  558. #### Is the same as:
  559. ```python
  560. func(1, 2, x=3, y=4, z=5)
  561. ```
  562. ### Inside Function Definition
  563. **Splat combines zero or more positional arguments into a tuple, while splatty-splat combines zero or more keyword arguments into a dictionary.**
  564. ```python
  565. def add(*a):
  566. return sum(a)
  567. ```
  568. ```python
  569. >>> add(1, 2, 3)
  570. 6
  571. ```
  572. #### Legal argument combinations:
  573. ```python
  574. def f(x, y, z): # f(x=1, y=2, z=3) | f(1, y=2, z=3) | f(1, 2, z=3) | f(1, 2, 3)
  575. def f(*, x, y, z): # f(x=1, y=2, z=3)
  576. def f(x, *, y, z): # f(x=1, y=2, z=3) | f(1, y=2, z=3)
  577. def f(x, y, *, z): # f(x=1, y=2, z=3) | f(1, y=2, z=3) | f(1, 2, z=3)
  578. ```
  579. ```python
  580. def f(*args): # f(1, 2, 3)
  581. def f(x, *args): # f(1, 2, 3)
  582. def f(*args, z): # f(1, 2, z=3)
  583. def f(x, *args, z): # f(1, 2, z=3)
  584. ```
  585. ```python
  586. def f(**kwargs): # f(x=1, y=2, z=3)
  587. def f(x, **kwargs): # f(x=1, y=2, z=3) | f(1, y=2, z=3)
  588. def f(*, x, **kwargs): # f(x=1, y=2, z=3)
  589. ```
  590. ```python
  591. def f(*args, **kwargs): # f(x=1, y=2, z=3) | f(1, y=2, z=3) | f(1, 2, z=3) | f(1, 2, 3)
  592. def f(x, *args, **kwargs): # f(x=1, y=2, z=3) | f(1, y=2, z=3) | f(1, 2, z=3) | f(1, 2, 3)
  593. def f(*args, y, **kwargs): # f(x=1, y=2, z=3) | f(1, y=2, z=3)
  594. def f(x, *args, z, **kwargs): # f(x=1, y=2, z=3) | f(1, y=2, z=3) | f(1, 2, z=3)
  595. ```
  596. ### Other Uses
  597. ```python
  598. <list> = [*<collection> [, ...]]
  599. <set> = {*<collection> [, ...]}
  600. <tuple> = (*<collection>, [...])
  601. <dict> = {**<dict> [, ...]}
  602. ```
  603. ```python
  604. head, *body, tail = <collection>
  605. ```
  606. Inline
  607. ------
  608. ### Lambda
  609. ```python
  610. <function> = lambda: <return_value>
  611. <function> = lambda <argument_1>, <argument_2>: <return_value>
  612. ```
  613. ### Comprehension
  614. ```python
  615. <list> = [i+1 for i in range(10)] # [1, 2, ..., 10]
  616. <set> = {i for i in range(10) if i > 5} # {6, 7, 8, 9}
  617. <iter> = (i+5 for i in range(10)) # (5, 6, ..., 14)
  618. <dict> = {i: i*2 for i in range(10)} # {0: 0, 1: 2, ..., 9: 18}
  619. ```
  620. ```python
  621. out = [i+j for i in range(10) for j in range(10)]
  622. ```
  623. #### Is the same as:
  624. ```python
  625. out = []
  626. for i in range(10):
  627. for j in range(10):
  628. out.append(i+j)
  629. ```
  630. ### Map, Filter, Reduce
  631. ```python
  632. from functools import reduce
  633. <iter> = map(lambda x: x + 1, range(10)) # (1, 2, ..., 10)
  634. <iter> = filter(lambda x: x > 5, range(10)) # (6, 7, 8, 9)
  635. <int> = reduce(lambda out, x: out + x, range(10)) # 45
  636. ```
  637. ### Any, All
  638. ```python
  639. <bool> = any(<collection>) # False if empty.
  640. <bool> = all(el[1] for el in <collection>) # True if empty.
  641. ```
  642. ### If - Else
  643. ```python
  644. <expression_if_true> if <condition> else <expression_if_false>
  645. ```
  646. ```python
  647. >>> [a if a else 'zero' for a in (0, 1, 0, 3)]
  648. ['zero', 1, 'zero', 3]
  649. ```
  650. ### Namedtuple, Enum, Dataclass
  651. ```python
  652. from collections import namedtuple
  653. Point = namedtuple('Point', 'x y')
  654. point = Point(0, 0)
  655. ```
  656. ```python
  657. from enum import Enum
  658. Direction = Enum('Direction', 'n e s w')
  659. direction = Direction.n
  660. ```
  661. ```python
  662. from dataclasses import make_dataclass
  663. Creature = make_dataclass('Creature', ['location', 'direction'])
  664. creature = Creature(Point(0, 0), Direction.n)
  665. ```
  666. Closure
  667. -------
  668. **We have a closure in Python when:**
  669. * **A nested function references a value of its enclosing function and then**
  670. * **the enclosing function returns the nested function.**
  671. ```python
  672. def get_multiplier(a):
  673. def out(b):
  674. return a * b
  675. return out
  676. ```
  677. ```python
  678. >>> multiply_by_3 = get_multiplier(3)
  679. >>> multiply_by_3(10)
  680. 30
  681. ```
  682. * **If multiple nested functions within enclosing function reference the same value, that value gets shared.**
  683. * **To dynamically access function's first free variable use `'<function>.__closure__[0].cell_contents'`.**
  684. ### Partial
  685. ```python
  686. from functools import partial
  687. <function> = partial(<function> [, <arg_1>, <arg_2>, ...])
  688. ```
  689. ```python
  690. >>> import operator as op
  691. >>> multiply_by_3 = partial(op.mul, 3)
  692. >>> multiply_by_3(10)
  693. 30
  694. ```
  695. ### Nonlocal
  696. **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'.**
  697. ```python
  698. def get_counter():
  699. i = 0
  700. def out():
  701. nonlocal i
  702. i += 1
  703. return i
  704. return out
  705. ```
  706. ```python
  707. >>> counter = get_counter()
  708. >>> counter(), counter(), counter()
  709. (1, 2, 3)
  710. ```
  711. Decorator
  712. ---------
  713. **A decorator takes a function, adds some functionality and returns it.**
  714. ```python
  715. @decorator_name
  716. def function_that_gets_passed_to_decorator():
  717. ...
  718. ```
  719. ### Debugger Example
  720. **Decorator that prints function's name every time it gets called.**
  721. ```python
  722. from functools import wraps
  723. def debug(func):
  724. @wraps(func)
  725. def out(*args, **kwargs):
  726. print(func.__name__)
  727. return func(*args, **kwargs)
  728. return out
  729. @debug
  730. def add(x, y):
  731. return x + y
  732. ```
  733. * **Wraps is a helper decorator that copies metadata of function add() to function out().**
  734. * **Without it `'add.__name__'` would return `'out'`.**
  735. ### LRU Cache
  736. **Decorator that caches function's return values. All function's arguments must be hashable.**
  737. ```python
  738. from functools import lru_cache
  739. @lru_cache(maxsize=None)
  740. def fib(n):
  741. return n if n < 2 else fib(n-2) + fib(n-1)
  742. ```
  743. * **Recursion depth is limited to 1000 by default. To increase it use `'sys.setrecursionlimit(<depth>)'`.**
  744. ### Parametrized Decorator
  745. **A decorator that accepts arguments and returns a normal decorator that accepts a function.**
  746. ```python
  747. from functools import wraps
  748. def debug(print_result=False):
  749. def decorator(func):
  750. @wraps(func)
  751. def out(*args, **kwargs):
  752. result = func(*args, **kwargs)
  753. print(func.__name__, result if print_result else '')
  754. return result
  755. return out
  756. return decorator
  757. @debug(print_result=True)
  758. def add(x, y):
  759. return x + y
  760. ```
  761. Class
  762. -----
  763. ```python
  764. class <name>:
  765. def __init__(self, a):
  766. self.a = a
  767. def __repr__(self):
  768. class_name = self.__class__.__name__
  769. return f'{class_name}({self.a!r})'
  770. def __str__(self):
  771. return str(self.a)
  772. @classmethod
  773. def get_class_name(cls):
  774. return cls.__name__
  775. ```
  776. * **Return value of repr() should be unambiguous and of str() readable.**
  777. * **If only repr() is defined, it will also be used for str().**
  778. #### Str() use cases:
  779. ```python
  780. print(<el>)
  781. print(f'{<el>}')
  782. raise Exception(<el>)
  783. logging.debug(<el>)
  784. csv.writer(<file>).writerow([<el>])
  785. ```
  786. #### Repr() use cases:
  787. ```python
  788. print([<el>])
  789. print(f'{<el>!r}')
  790. >>> <el>
  791. loguru.logger.exception()
  792. Z = dataclasses.make_dataclass('Z', ['a']); print(Z(<el>))
  793. ```
  794. ### Constructor Overloading
  795. ```python
  796. class <name>:
  797. def __init__(self, a=None):
  798. self.a = a
  799. ```
  800. ### Inheritance
  801. ```python
  802. class Person:
  803. def __init__(self, name, age):
  804. self.name = name
  805. self.age = age
  806. class Employee(Person):
  807. def __init__(self, name, age, staff_num):
  808. super().__init__(name, age)
  809. self.staff_num = staff_num
  810. ```
  811. ### Multiple Inheritance
  812. ```python
  813. class A: pass
  814. class B: pass
  815. class C(A, B): pass
  816. ```
  817. **MRO determines the order in which parent classes are traversed when searching for a method:**
  818. ```python
  819. >>> C.mro()
  820. [<class 'C'>, <class 'A'>, <class 'B'>, <class 'object'>]
  821. ```
  822. ### Property
  823. ```python
  824. class MyClass:
  825. @property
  826. def a(self):
  827. return self._a
  828. @a.setter
  829. def a(self, value):
  830. self._a = value
  831. ```
  832. ```python
  833. >>> el = MyClass()
  834. >>> el.a = 123
  835. >>> el.a
  836. 123
  837. ```
  838. ### Dataclass
  839. **Decorator that automatically generates init(), repr() and eq() special methods.**
  840. ```python
  841. from dataclasses import dataclass, field
  842. @dataclass(order=False, frozen=False)
  843. class <class_name>:
  844. <attr_name_1>: <type>
  845. <attr_name_2>: <type> = <default_value>
  846. <attr_name_3>: list/dict/set = field(default_factory=list/dict/set)
  847. ```
  848. * **An object can be made sortable with `'order=True'` or immutable with `'frozen=True'`.**
  849. * **Function field() is needed because `'<attr_name>: list = []'` would make a list that is shared among all instances.**
  850. * **Default_factory can be any callable.**
  851. ### Copy
  852. ```python
  853. from copy import copy, deepcopy
  854. <object> = copy(<object>)
  855. <object> = deepcopy(<object>)
  856. ```
  857. Duck Types
  858. ----------
  859. **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.**
  860. ### Comparable
  861. * **If eq() method is not overridden, it returns `'id(self) == id(other)'`, which is the same as `'self is other'`.**
  862. * **That means all objects compare not equal by default.**
  863. * **Only left side object has eq() method called, unless it returns 'NotImplemented', in which case the right object is consulted.**
  864. ```python
  865. class MyComparable:
  866. def __init__(self, a):
  867. self.a = a
  868. def __eq__(self, other):
  869. if isinstance(other, type(self)):
  870. return self.a == other.a
  871. return NotImplemented
  872. ```
  873. ### Hashable
  874. * **Hashable object needs both hash() and eq() methods and its hash value should never change.**
  875. * **Hashable objects that compare equal must have the same hash value, meaning default hash() that returns `'id(self)'` will not do.**
  876. * **That is why Python automatically makes classes unhashable if you only implement eq().**
  877. ```python
  878. class MyHashable:
  879. def __init__(self, a):
  880. self._a = copy.deepcopy(a)
  881. @property
  882. def a(self):
  883. return self._a
  884. def __eq__(self, other):
  885. if isinstance(other, type(self)):
  886. return self.a == other.a
  887. return NotImplemented
  888. def __hash__(self):
  889. return hash(self.a)
  890. ```
  891. ### Sortable
  892. * **With 'total_ordering' decorator you only need to provide one of lt(), gt(), le() or ge() special methods.**
  893. ```python
  894. from functools import total_ordering
  895. @total_ordering
  896. class MySortable:
  897. def __init__(self, a):
  898. self.a = a
  899. def __eq__(self, other):
  900. if isinstance(other, type(self)):
  901. return self.a == other.a
  902. return NotImplemented
  903. def __lt__(self, other):
  904. if isinstance(other, type(self)):
  905. return self.a < other.a
  906. return NotImplemented
  907. ```
  908. ### Iterable
  909. * **Only required method for iterable is iter(), that should return an iterator of its contents.**
  910. ```python
  911. class MyIterable:
  912. def __init__(self, a):
  913. self.a = a
  914. def __iter__(self):
  915. for el in self.a:
  916. yield el
  917. ```
  918. ### Collection
  919. * **Every collection is also an iterable.**
  920. * **This cheatsheet actually means `'<iterable>'` when it uses `'<collection>'`.**
  921. * **I chose not to use the name iterable because it sounds scarier and more vague than collection.**
  922. ```python
  923. class MyCollection:
  924. def __init__(self, a):
  925. self.a = a
  926. def __iter__(self):
  927. for el in self.a:
  928. yield el
  929. def __len__(self):
  930. return len(self.a)
  931. def __contains__(self, el):
  932. return el in self.a
  933. ```
  934. ### Sequence
  935. * **Every sequence is also an iterable.**
  936. * **That is because iter() is automatically generated if getitem() is defined.**
  937. ```python
  938. class MySequence:
  939. def __init__(self, a):
  940. self.a = a
  941. def __len__(self):
  942. return len(self.a)
  943. def __getitem__(self, i):
  944. return self.a[i]
  945. ```
  946. ### Collections.abc.Sequence
  947. * **A much richer interface than the basic sequence.**
  948. * **Extending it generates contains(), iter(), reversed(), index(), and count().**
  949. * **It is not a duck type, so `'issubclass(MySequence, collections.abc.Sequence)'` would return 'False' even if it had all the methods defined.**
  950. ```python
  951. class MyAbcSequence(collections.abc.Sequence):
  952. def __init__(self, a):
  953. self.a = a
  954. def __len__(self):
  955. return len(self.a)
  956. def __getitem__(self, i):
  957. return self.a[i]
  958. ```
  959. #### Table of provided methods:
  960. ```text
  961. +------------+----------+------------+----------+--------------+
  962. | | iterable | collection | sequence | abc.Sequence |
  963. +------------+----------+------------+----------+--------------+
  964. | iter() | yes | yes | yes | yes |
  965. | len() | | yes | yes | yes |
  966. | getitem() | | | yes | yes |
  967. | contains() | | yes | | yes |
  968. +------------+----------+------------+----------+--------------+
  969. ```
  970. ### Iterator
  971. ```python
  972. class Counter:
  973. def __init__(self):
  974. self.i = 0
  975. def __next__(self):
  976. self.i += 1
  977. return self.i
  978. def __iter__(self):
  979. return self
  980. ```
  981. ```python
  982. >>> counter = Counter()
  983. >>> next(counter), next(counter), next(counter)
  984. (1, 2, 3)
  985. ```
  986. ### Callable
  987. ```python
  988. class Counter:
  989. def __init__(self):
  990. self.i = 0
  991. def __call__(self):
  992. self.i += 1
  993. return self.i
  994. ```
  995. ```python
  996. >>> counter = Counter()
  997. >>> counter(), counter(), counter()
  998. (1, 2, 3)
  999. ```
  1000. ### Context Manager
  1001. ```python
  1002. class MyOpen():
  1003. def __init__(self, filename):
  1004. self.filename = filename
  1005. def __enter__(self):
  1006. self.file = open(self.filename)
  1007. return self.file
  1008. def __exit__(self, *args):
  1009. self.file.close()
  1010. ```
  1011. ```python
  1012. >>> with open('test.txt', 'w') as file:
  1013. ... file.write('Hello World!')
  1014. >>> with MyOpen('test.txt') as file:
  1015. ... print(file.read())
  1016. Hello World!
  1017. ```
  1018. Enum
  1019. ----
  1020. ```python
  1021. from enum import Enum, auto
  1022. class <enum_name>(Enum):
  1023. <member_name_1> = <value_1>
  1024. <member_name_2> = <value_2_a>, <value_2_b>
  1025. <member_name_3> = auto()
  1026. @classmethod
  1027. def get_member_names(cls):
  1028. return [a.name for a in cls.__members__.values()]
  1029. ```
  1030. * **If there are no numeric values before auto(), it returns 1.**
  1031. * **Otherwise it returns an increment of last numeric value.**
  1032. ```python
  1033. <member> = <enum>.<member_name>
  1034. <member> = <enum>['<member_name>']
  1035. <member> = <enum>(<value>)
  1036. name = <member>.name
  1037. value = <member>.value
  1038. ```
  1039. ```python
  1040. list_of_members = list(<enum>)
  1041. member_names = [a.name for a in <enum>]
  1042. member_values = [a.value for a in <enum>]
  1043. random_member = random.choice(list(<enum>))
  1044. ```
  1045. ### Inline
  1046. ```python
  1047. Cutlery = Enum('Cutlery', ['fork', 'knife', 'spoon'])
  1048. Cutlery = Enum('Cutlery', 'fork knife spoon')
  1049. Cutlery = Enum('Cutlery', {'fork': 1, 'knife': 2, 'spoon': 3})
  1050. ```
  1051. #### Functions can not be values, so they must be wrapped:
  1052. ```python
  1053. from functools import partial
  1054. LogicOp = Enum('LogicOp', {'AND': partial(lambda l, r: l and r),
  1055. 'OR' : partial(lambda l, r: l or r)})
  1056. ```
  1057. Exceptions
  1058. ----------
  1059. ```python
  1060. while True:
  1061. try:
  1062. x = int(input('Please enter a number: '))
  1063. except ValueError:
  1064. print('Oops! That was no valid number. Try again...')
  1065. else:
  1066. print('Thank you.')
  1067. break
  1068. ```
  1069. ### Raising Exception
  1070. ```python
  1071. raise ValueError('A very specific message!')
  1072. ```
  1073. ### Finally
  1074. ```python
  1075. >>> try:
  1076. ... raise KeyboardInterrupt
  1077. ... finally:
  1078. ... print('Goodbye, world!')
  1079. Goodbye, world!
  1080. Traceback (most recent call last):
  1081. File "<stdin>", line 2, in <module>
  1082. KeyboardInterrupt
  1083. ```
  1084. Print
  1085. -----
  1086. ```python
  1087. print(<el_1>, ..., sep=' ', end='\n', file=sys.stdout, flush=False)
  1088. ```
  1089. * **Use `'file=sys.stderr'` for errors.**
  1090. * **Use `'flush=True'` to forcibly flush the stream.**
  1091. ### Pretty Print
  1092. ```python
  1093. >>> from pprint import pprint
  1094. >>> pprint(dir())
  1095. ['__annotations__',
  1096. '__builtins__',
  1097. '__doc__', ...]
  1098. ```
  1099. Input
  1100. -----
  1101. * **Reads a line from user input or pipe if present.**
  1102. * **Trailing newline gets stripped.**
  1103. * **Prompt string is printed to the standard output before reading input.**
  1104. ```python
  1105. <str> = input(prompt=None)
  1106. ```
  1107. #### Prints lines until EOF:
  1108. ```python
  1109. while True:
  1110. try:
  1111. print(input())
  1112. except EOFError:
  1113. break
  1114. ```
  1115. Command Line Arguments
  1116. ----------------------
  1117. ```python
  1118. import sys
  1119. script_name = sys.argv[0]
  1120. arguments = sys.argv[1:]
  1121. ```
  1122. ### Argparse
  1123. ```python
  1124. from argparse import ArgumentParser, FileType
  1125. p = ArgumentParser(description=<str>)
  1126. p.add_argument('-<short_name>', '--<name>', action='store_true') # Flag
  1127. p.add_argument('-<short_name>', '--<name>', type=<type>) # Option
  1128. p.add_argument('<name>', type=<type>, nargs=1) # Argument
  1129. p.add_argument('<name>', type=<type>, nargs='+') # Arguments
  1130. args = p.parse_args()
  1131. value = args.<name>
  1132. ```
  1133. * **Use `'help=<str>'` for argument description.**
  1134. * **Use `'type=FileType(<mode>)'` for files.**
  1135. Open
  1136. ----
  1137. **Opens a file and returns a corresponding file object.**
  1138. ```python
  1139. <file> = open('<path>', mode='r', encoding=None, newline=None)
  1140. ```
  1141. * **`'encoding=None'` means default encoding is used, which is platform dependent. Best practice is to use `'encoding="utf-8"'` whenever possible.**
  1142. * **`'newline=None'` 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.**
  1143. * **`'newline=""'` means no conversions take place, but lines are still broken by readline() on either '\n', '\r' or '\r\n'.**
  1144. ### Modes
  1145. * **`'r'` - Read (default).**
  1146. * **`'w'` - Write (truncate).**
  1147. * **`'x'` - Write or fail if the file already exists.**
  1148. * **`'a'` - Append.**
  1149. * **`'w+'` - Read and write (truncate).**
  1150. * **`'r+'` - Read and write from the start.**
  1151. * **`'a+'` - Read and write from the end.**
  1152. * **`'t'` - Text mode (default).**
  1153. * **`'b'` - Binary mode.**
  1154. ### File
  1155. ```python
  1156. <file>.seek(0) # Moves to the start of the file.
  1157. <file>.seek(offset) # Moves 'offset' chars/bytes from the start.
  1158. <file>.seek(0, 2) # Moves to the end of the file.
  1159. <bin_file>.seek(±offset, <anchor>) # Anchor: 0 start, 1 current pos., 2 end.
  1160. ```
  1161. ```python
  1162. <str/bytes> = <file>.read(size=-1) # Reads 'size' chars/bytes or until EOF.
  1163. <str/bytes> = <file>.readline() # Returns a line.
  1164. <list> = <file>.readlines() # Returns a list of lines.
  1165. <str/bytes> = next(<file>) # Returns a line using buffer. Do not mix.
  1166. ```
  1167. ```python
  1168. <file>.write(<str/bytes>) # Writes a string or bytes object.
  1169. <file>.writelines(<coll.>) # Writes a coll. of strings or bytes objects.
  1170. <file>.flush() # Flushes write buffer.
  1171. ```
  1172. * **Methods do not add or strip trailing newlines, even writelines().**
  1173. ### Read Text from File
  1174. ```python
  1175. def read_file(filename):
  1176. with open(filename, encoding='utf-8') as file:
  1177. return file.readlines()
  1178. ```
  1179. ### Write Text to File
  1180. ```python
  1181. def write_to_file(filename, text):
  1182. with open(filename, 'w', encoding='utf-8') as file:
  1183. file.write(text)
  1184. ```
  1185. Path
  1186. ----
  1187. ```python
  1188. from os import path, listdir
  1189. from glob import glob
  1190. ```
  1191. ```python
  1192. <bool> = path.exists('<path>')
  1193. <bool> = path.isfile('<path>')
  1194. <bool> = path.isdir('<path>')
  1195. ```
  1196. ```python
  1197. <list> = listdir('<path>') # List of filenames located at 'path'.
  1198. <list> = glob('<pattern>') # Filenames matching the wildcard pattern.
  1199. ```
  1200. ### Pathlib
  1201. ```python
  1202. from pathlib import Path
  1203. ```
  1204. ```python
  1205. cwd = Path()
  1206. <Path> = Path('<path>' [, '<path>', <Path>, ...])
  1207. <Path> = <Path> / '<dir>' / '<file>'
  1208. ```
  1209. ```python
  1210. <bool> = <Path>.exists()
  1211. <bool> = <Path>.is_file()
  1212. <bool> = <Path>.is_dir()
  1213. ```
  1214. ```python
  1215. <iter> = <Path>.iterdir() # Iterator of filenames located at path.
  1216. <iter> = <Path>.glob('<pattern>') # Filenames matching the wildcard pattern.
  1217. ```
  1218. ```python
  1219. <str> = str(<Path>) # Returns path as a string.
  1220. <tup.> = <Path>.parts # Returns all components as strings.
  1221. <Path> = <Path>.resolve() # Returns absolute Path without symlinks.
  1222. ```
  1223. ```python
  1224. <str> = <Path>.name # Final component.
  1225. <str> = <Path>.stem # Final component without extension.
  1226. <str> = <Path>.suffix # Final component's extension.
  1227. <Path> = <Path>.parent # Path without final component.
  1228. ```
  1229. Command Execution
  1230. -----------------
  1231. ```python
  1232. import os
  1233. <str> = os.popen(<command>).read()
  1234. ```
  1235. ### Subprocess
  1236. ```python
  1237. >>> import subprocess, shlex
  1238. >>> a = subprocess.run(shlex.split('ls -a'), stdout=subprocess.PIPE)
  1239. >>> a.stdout
  1240. b'.\n..\nfile1.txt\nfile2.txt\n'
  1241. >>> a.returncode
  1242. 0
  1243. ```
  1244. CSV
  1245. ---
  1246. ```python
  1247. import csv
  1248. ```
  1249. ### Read Rows from CSV File
  1250. ```python
  1251. def read_csv_file(filename):
  1252. with open(filename, encoding='utf-8', newline='') as file:
  1253. return csv.reader(file, delimiter=';')
  1254. ```
  1255. * **If `'newline=""'` is not specified, then newlines embedded inside quoted fields will not be interpreted correctly.**
  1256. ### Write Rows to CSV File
  1257. ```python
  1258. def write_to_csv_file(filename, rows):
  1259. with open(filename, 'w', encoding='utf-8', newline='') as file:
  1260. writer = csv.writer(file, delimiter=';')
  1261. writer.writerows(rows)
  1262. ```
  1263. JSON
  1264. ----
  1265. ```python
  1266. import json
  1267. <str> = json.dumps(<object>, ensure_ascii=True, indent=None)
  1268. <object> = json.loads(<str>)
  1269. ```
  1270. ### Read Object from JSON File
  1271. ```python
  1272. def read_json_file(filename):
  1273. with open(filename, encoding='utf-8') as file:
  1274. return json.load(file)
  1275. ```
  1276. ### Write Object to JSON File
  1277. ```python
  1278. def write_to_json_file(filename, an_object):
  1279. with open(filename, 'w', encoding='utf-8') as file:
  1280. json.dump(an_object, file, ensure_ascii=False, indent=2)
  1281. ```
  1282. Pickle
  1283. ------
  1284. ```python
  1285. import pickle
  1286. <bytes> = pickle.dumps(<object>)
  1287. <object> = pickle.loads(<bytes>)
  1288. ```
  1289. ### Read Object from File
  1290. ```python
  1291. def read_pickle_file(filename):
  1292. with open(filename, 'rb') as file:
  1293. return pickle.load(file)
  1294. ```
  1295. ### Write Object to File
  1296. ```python
  1297. def write_to_pickle_file(filename, an_object):
  1298. with open(filename, 'wb') as file:
  1299. pickle.dump(an_object, file)
  1300. ```
  1301. SQLite
  1302. ------
  1303. **Server-less database engine that stores each database into separate file.**
  1304. ```python
  1305. import sqlite3
  1306. db = sqlite3.connect('<path>') # Also ':memory:'.
  1307. ...
  1308. db.close()
  1309. ```
  1310. * **New database will be created if path doesn't exist.**
  1311. ### Read
  1312. ```python
  1313. cursor = db.execute('<query>')
  1314. if cursor:
  1315. <tuple> = cursor.fetchone() # First row.
  1316. <list> = cursor.fetchall() # Remaining rows.
  1317. ```
  1318. * **Returned values can be of type str, int, float, bytes or None.**
  1319. ### Write
  1320. ```python
  1321. db.execute('<query>')
  1322. db.commit()
  1323. ```
  1324. ### Placeholders
  1325. ```python
  1326. db.execute('<query>', <list/tuple>) # Replaces '?'s in query with values.
  1327. db.execute('<query>', <dict/namedtuple>) # Replaces ':<key>'s with values.
  1328. db.executemany('<query>', <coll_of_above>) # Runs execute() many times.
  1329. ```
  1330. * **Passed values can be of type str, int, float, bytes, None, bool, datetime.date or datetime.datetme.**
  1331. ### MySQL
  1332. **Has a very similar interface, with differences listed below.**
  1333. ```python
  1334. # $ pip3 install mysql-connector
  1335. from mysql import connector
  1336. db = connector.connect(host=<str>, user=<str>, password=<str>, database=<str>)
  1337. cursor = db.cursor()
  1338. cursor.execute('<query>') # Connector doesn't have execute method.
  1339. cursor.execute('<query>', <list/tuple>) # Replaces '%s's in query with values.
  1340. cursor.execute('<query>', <dict/namedtuple>) # Replaces '%(<key>)s's with values.
  1341. ```
  1342. Bytes
  1343. -----
  1344. **Bytes object is an immutable sequence of single bytes. Mutable version is called 'bytearray'.**
  1345. ```python
  1346. <bytes> = b'<str>' # Only accepts ASCII characters and \x00 - \xff.
  1347. <int> = <bytes>[<index>] # Returns int in range from 0 to 255.
  1348. <bytes> = <bytes>[<slice>] # Returns bytes even if it has only one element.
  1349. <bytes> = <bytes>.join(<coll_of_bytes>) # Joins elements using bytes object as separator.
  1350. ```
  1351. ### Encode
  1352. ```python
  1353. <bytes> = <str>.encode('utf-8') # Or: bytes(<str>, 'utf-8')
  1354. <bytes> = bytes(<coll_of_ints>) # Ints must be in range from 0 to 255.
  1355. <bytes> = <int>.to_bytes(<length>, byteorder='big|little', signed=False)
  1356. <bytes> = bytes.fromhex('<hex>')
  1357. ```
  1358. ### Decode
  1359. ```python
  1360. <str> = <bytes>.decode('utf-8') # Or: str(<bytes>, 'utf-8')
  1361. <list> = list(<bytes>) # Returns ints in range from 0 to 255.
  1362. <int> = int.from_bytes(<bytes>, byteorder='big|little', signed=False)
  1363. '<hex>' = <bytes>.hex()
  1364. ```
  1365. ### Read Bytes from File
  1366. ```python
  1367. def read_bytes(filename):
  1368. with open(filename, 'rb') as file:
  1369. return file.read()
  1370. ```
  1371. ### Write Bytes to File
  1372. ```python
  1373. def write_bytes(filename, bytes_obj):
  1374. with open(filename, 'wb') as file:
  1375. file.write(bytes_obj)
  1376. ```
  1377. Struct
  1378. ------
  1379. * **Module that performs conversions between a sequence of numbers and a C struct, represented as a Python bytes object.**
  1380. * **Machine’s native type sizes and byte order are used by default.**
  1381. ```python
  1382. from struct import pack, unpack, iter_unpack, calcsize
  1383. <bytes> = pack('<format>', <num_1> [, <num_2>, ...])
  1384. <tuple> = unpack('<format>', <bytes>)
  1385. <tuples> = iter_unpack('<format>', <bytes>)
  1386. ```
  1387. ### Example
  1388. ```python
  1389. >>> pack('>hhl', 1, 2, 3)
  1390. b'\x00\x01\x00\x02\x00\x00\x00\x03'
  1391. >>> unpack('>hhl', b'\x00\x01\x00\x02\x00\x00\x00\x03')
  1392. (1, 2, 3)
  1393. >>> calcsize('>hhl')
  1394. 8
  1395. ```
  1396. ### Format
  1397. #### For standard sizes start format string with:
  1398. * **`'='` - native byte order**
  1399. * **`'<'` - little-endian**
  1400. * **`'>'` - big-endian**
  1401. #### Integer types. Use capital letter for unsigned type. Standard sizes are in brackets:
  1402. * **`'x'` - pad byte**
  1403. * **`'b'` - char (1)**
  1404. * **`'h'` - short (2)**
  1405. * **`'i'` - int (4)**
  1406. * **`'l'` - long (4)**
  1407. * **`'q'` - long long (8)**
  1408. #### Floating point types:
  1409. * **`'f'` - float (4)**
  1410. * **`'d'` - double (8)**
  1411. Array
  1412. -----
  1413. **List that can only hold numbers of predefined type. Available types and their sizes in bytes are listed above.**
  1414. ```python
  1415. from array import array
  1416. <array> = array('<typecode>' [, <collection>])
  1417. ```
  1418. Memory View
  1419. -----------
  1420. **Used for accessing the internal data of an object that supports the buffer protocol.**
  1421. ```python
  1422. <memoryview> = memoryview(<bytes> / <bytearray> / <array>)
  1423. <memoryview>.release()
  1424. ```
  1425. Deque
  1426. -----
  1427. **A thread-safe list with efficient appends and pops from either side. Pronounced "deck".**
  1428. ```python
  1429. from collections import deque
  1430. <deque> = deque(<collection>, maxlen=None)
  1431. ```
  1432. ```python
  1433. <deque>.appendleft(<el>)
  1434. <el> = <deque>.popleft()
  1435. <deque>.extendleft(<collection>) # Collection gets reversed.
  1436. <deque>.rotate(n=1) # Rotates elements to the right.
  1437. ```
  1438. ```python
  1439. >>> a = deque([1, 2, 3], maxlen=3)
  1440. >>> a.append(4)
  1441. [2, 3, 4]
  1442. >>> a.appendleft(5)
  1443. [5, 2, 3]
  1444. >>> a.insert(1, 6)
  1445. IndexError: deque already at its maximum size
  1446. ```
  1447. Threading
  1448. ---------
  1449. ```python
  1450. from threading import Thread, RLock
  1451. ```
  1452. ### Thread
  1453. ```python
  1454. thread = Thread(target=<function>, args=(<first_arg>, ))
  1455. thread.start()
  1456. ...
  1457. thread.join()
  1458. ```
  1459. ### Lock
  1460. ```python
  1461. lock = RLock()
  1462. lock.acquire()
  1463. ...
  1464. lock.release()
  1465. ```
  1466. #### Or:
  1467. ```python
  1468. lock = RLock()
  1469. with lock:
  1470. ...
  1471. ```
  1472. Introspection
  1473. -------------
  1474. **Inspecting code at runtime.**
  1475. ### Variables
  1476. ```python
  1477. <list> = dir() # Names of variables in current scope.
  1478. <dict> = locals() # Dict of local variables. Also vars().
  1479. <dict> = globals() # Dict of global variables.
  1480. ```
  1481. ### Attributes
  1482. ```python
  1483. <dict> = vars(<object>)
  1484. <bool> = hasattr(<object>, '<attr_name>')
  1485. value = getattr(<object>, '<attr_name>')
  1486. setattr(<object>, '<attr_name>', value)
  1487. ```
  1488. ### Parameters
  1489. ```python
  1490. from inspect import signature
  1491. <sig> = signature(<function>)
  1492. no_of_params = len(<sig>.parameters)
  1493. param_names = list(<sig>.parameters.keys())
  1494. ```
  1495. Metaprograming
  1496. --------------
  1497. **Code that generates code.**
  1498. ### Type
  1499. **Type is the root class. If only passed an object it returns its type (class). Otherwise it creates a new class.**
  1500. ```python
  1501. <class> = type(<class_name>, <parents_tuple>, <attributes_dict>)
  1502. ```
  1503. ```python
  1504. >>> Z = type('Z', (), {'a': 'abcde', 'b': 12345})
  1505. >>> z = Z()
  1506. ```
  1507. ### Meta Class
  1508. **Class that creates class.**
  1509. ```python
  1510. def my_meta_class(name, parents, attrs):
  1511. attrs['a'] = 'abcde'
  1512. return type(name, parents, attrs)
  1513. ```
  1514. #### Or:
  1515. ```python
  1516. class MyMetaClass(type):
  1517. def __new__(cls, name, parents, attrs):
  1518. attrs['a'] = 'abcde'
  1519. return type.__new__(cls, name, parents, attrs)
  1520. ```
  1521. * **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.**
  1522. * **It receives the same arguments as init(), except for the first one that specifies the desired class of returned instance (**`'MyMetaClass'` **in our case).**
  1523. * **New() can also be called directly, usually from a new() method of a child class (**`def __new__(cls): return super().__new__(cls)`**), in which case init() is not called.**
  1524. ### Metaclass Attribute
  1525. **Right before a class is created it checks if it has metaclass defined. If not, it recursively checks if any of his parents has it defined and eventually comes to type().**
  1526. ```python
  1527. class MyClass(metaclass=MyMetaClass):
  1528. b = 12345
  1529. ```
  1530. ```python
  1531. >>> MyClass.a, MyClass.b
  1532. ('abcde', 12345)
  1533. ```
  1534. ### Type Diagram
  1535. ```python
  1536. type(MyClass) == MyMetaClass # MyClass is an instance of MyMetaClass.
  1537. type(MyMetaClass) == type # MyMetaClass is an instance of type.
  1538. ```
  1539. ```text
  1540. +---------+-------------+
  1541. | Classes | Metaclasses |
  1542. +---------+-------------|
  1543. | MyClass > MyMetaClass |
  1544. | | v |
  1545. | object ---> type <+ |
  1546. | | ^ +---+ |
  1547. | str -------+ |
  1548. +---------+-------------+
  1549. ```
  1550. ### Inheritance Diagram
  1551. ```python
  1552. MyClass.__base__ == object # MyClass is a subclass of object.
  1553. MyMetaClass.__base__ == type # MyMetaClass is a subclass of type.
  1554. ```
  1555. ```text
  1556. +---------+-------------+
  1557. | Classes | Metaclasses |
  1558. +---------+-------------|
  1559. | MyClass | MyMetaClass |
  1560. | v | v |
  1561. | object <--- type |
  1562. | ^ | |
  1563. | str | |
  1564. +---------+-------------+
  1565. ```
  1566. Operator
  1567. --------
  1568. ```python
  1569. from operator import add, sub, mul, truediv, floordiv, mod, pow, neg, abs
  1570. from operator import eq, ne, lt, le, gt, ge
  1571. from operator import not_, and_, or_
  1572. from operator import itemgetter, attrgetter, methodcaller
  1573. ```
  1574. ```python
  1575. import operator as op
  1576. product_of_elems = functools.reduce(op.mul, <collection>)
  1577. sorted_by_second = sorted(<collection>, key=op.itemgetter(1))
  1578. sorted_by_both = sorted(<collection>, key=op.itemgetter(1, 0))
  1579. LogicOp = enum.Enum('LogicOp', {'AND': op.and_, 'OR' : op.or_})
  1580. last_el = op.methodcaller('pop')(<list>)
  1581. ```
  1582. Eval
  1583. ----
  1584. ```python
  1585. >>> from ast import literal_eval
  1586. >>> literal_eval('1 + 2')
  1587. 3
  1588. >>> literal_eval('[1, 2, 3]')
  1589. [1, 2, 3]
  1590. >>> literal_eval('abs(1)')
  1591. ValueError: malformed node or string
  1592. ```
  1593. Coroutine
  1594. ---------
  1595. * **Similar to generator, but generator pulls data through the pipe with iteration, while coroutine pushes data into the pipeline with send().**
  1596. * **Coroutines provide more powerful data routing possibilities than iterators.**
  1597. * **If you build a collection of simple data processing components, you can glue them together into complex arrangements of pipes, branches, merging, etc.**
  1598. ### Helper Decorator
  1599. * **All coroutines must be "primed" by first calling next().**
  1600. * **Remembering to call next() is easy to forget.**
  1601. * **Solved by wrapping coroutines with a decorator:**
  1602. ```python
  1603. def coroutine(func):
  1604. def out(*args, **kwargs):
  1605. cr = func(*args, **kwargs)
  1606. next(cr)
  1607. return cr
  1608. return out
  1609. ```
  1610. ### Pipeline Example
  1611. ```python
  1612. def reader(target):
  1613. for i in range(10):
  1614. target.send(i)
  1615. target.close()
  1616. @coroutine
  1617. def adder(target):
  1618. while True:
  1619. value = (yield)
  1620. target.send(value + 100)
  1621. @coroutine
  1622. def printer():
  1623. while True:
  1624. value = (yield)
  1625. print(value)
  1626. reader(adder(printer())) # 100, 101, ..., 109
  1627. ```
  1628. <br><br>
  1629. Libraries
  1630. =========
  1631. Progress Bar
  1632. ------------
  1633. ```python
  1634. # $ pip3 install tqdm
  1635. from tqdm import tqdm
  1636. from time import sleep
  1637. for i in tqdm([1, 2, 3]):
  1638. sleep(0.2)
  1639. for i in tqdm(range(100)):
  1640. sleep(0.02)
  1641. ```
  1642. Plot
  1643. ----
  1644. ```python
  1645. # $ pip3 install matplotlib
  1646. from matplotlib import pyplot
  1647. pyplot.plot(<data_1> [, <data_2>, ...])
  1648. pyplot.savefig(<filename>)
  1649. pyplot.show()
  1650. ```
  1651. Table
  1652. -----
  1653. #### Prints a CSV file as an ASCII table:
  1654. ```python
  1655. # $ pip3 install tabulate
  1656. from tabulate import tabulate
  1657. import csv
  1658. with open(<filename>, encoding='utf-8', newline='') as file:
  1659. lines = csv.reader(file, delimiter=';')
  1660. headers = [header.title() for header in next(lines)]
  1661. table = tabulate(lines, headers)
  1662. print(table)
  1663. ```
  1664. Curses
  1665. ------
  1666. ```python
  1667. from curses import wrapper, ascii
  1668. def main():
  1669. wrapper(draw)
  1670. def draw(screen):
  1671. screen.clear()
  1672. screen.addstr(0, 0, 'Press ESC to quit.')
  1673. while screen.getch() != ascii.ESC:
  1674. pass
  1675. def get_border(screen):
  1676. from collections import namedtuple
  1677. P = namedtuple('P', 'y x')
  1678. height, width = screen.getmaxyx()
  1679. return P(height-1, width-1)
  1680. if __name__ == '__main__':
  1681. main()
  1682. ```
  1683. Logging
  1684. -------
  1685. ```python
  1686. # $ pip3 install loguru
  1687. from loguru import logger
  1688. ```
  1689. ```python
  1690. logger.add('debug_{time}.log', colorize=True) # Connects a log file.
  1691. logger.add('error_{time}.log', level='ERROR') # Another file for errors or higher.
  1692. logger.<level>('A logging message.')
  1693. ```
  1694. * **Levels: `'debug'`, `'info'`, `'success'`, `'warning'`, `'error'`, `'critical'`.**
  1695. ### Exceptions
  1696. **Error description, stack trace and values of variables are appended automatically.**
  1697. ```python
  1698. try:
  1699. ...
  1700. except <exception>:
  1701. logger.exception('An error happened.')
  1702. ```
  1703. ### Rotation
  1704. **Argument that sets a condition when a new log file is created.**
  1705. ```python
  1706. rotation=<int>|<datetime.timedelta>|<datetime.time>|<str>
  1707. ```
  1708. * **`'<int>'` - Max file size in bytes.**
  1709. * **`'<timedelta>'` - Max age of a file.**
  1710. * **`'<time>'` - Time of day.**
  1711. * **`'<str>'` - Any of above as a string: `'100 MB'`, `'1 month'`, `'monday at 12:00'`, ...**
  1712. ### Retention
  1713. **Sets a condition which old log files are deleted.**
  1714. ```python
  1715. retention=<int>|<datetime.timedelta>|<str>
  1716. ```
  1717. * **`'<int>'` - Max number of files.**
  1718. * **`'<timedelta>'` - Max age of a file.**
  1719. * **`'<str>'` - Max age as a string: `'1 week, 3 days'`, `'2 months'`, ...**
  1720. Scraping
  1721. --------
  1722. #### Scrapes and prints Python's URL and version number from Wikipedia:
  1723. ```python
  1724. # $ pip3 install requests beautifulsoup4
  1725. import requests
  1726. from bs4 import BeautifulSoup
  1727. url = 'https://en.wikipedia.org/wiki/Python_(programming_language)'
  1728. page = requests.get(url)
  1729. doc = BeautifulSoup(page.text, 'html.parser')
  1730. table = doc.find('table', class_='infobox vevent')
  1731. rows = table.find_all('tr')
  1732. link = rows[11].find('a')['href']
  1733. ver = rows[6].find('div').text.split()[0]
  1734. print(link, ver)
  1735. ```
  1736. Web
  1737. ---
  1738. ```python
  1739. # $ pip3 install bottle
  1740. from bottle import run, route, post, template, request, response
  1741. import json
  1742. ```
  1743. ### Run
  1744. ```python
  1745. run(host='localhost', port=8080)
  1746. run(host='0.0.0.0', port=80, server='cherrypy')
  1747. ```
  1748. ### Static Request
  1749. ```python
  1750. @route('/img/<image>')
  1751. def send_image(image):
  1752. return static_file(image, 'images/', mimetype='image/png')
  1753. ```
  1754. ### Dynamic Request
  1755. ```python
  1756. @route('/<sport>')
  1757. def send_page(sport):
  1758. return template('<h1>{{title}}</h1>', title=sport)
  1759. ```
  1760. ### REST Request
  1761. ```python
  1762. @post('/odds/<sport>')
  1763. def odds_handler(sport):
  1764. team = request.forms.get('team')
  1765. home_odds, away_odds = 2.44, 3.29
  1766. response.headers['Content-Type'] = 'application/json'
  1767. response.headers['Cache-Control'] = 'no-cache'
  1768. return json.dumps([team, home_odds, away_odds])
  1769. ```
  1770. #### Test:
  1771. ```python
  1772. # $ pip3 install requests
  1773. >>> import requests
  1774. >>> url = 'http://localhost:8080/odds/football'
  1775. >>> data = {'team': 'arsenal f.c.'}
  1776. >>> response = requests.post(url, data=data)
  1777. >>> response.json()
  1778. ['arsenal f.c.', 2.44, 3.29]
  1779. ```
  1780. Profile
  1781. -------
  1782. ### Basic
  1783. ```python
  1784. from time import time
  1785. start_time = time() # Seconds since Epoch.
  1786. ...
  1787. duration = time() - start_time
  1788. ```
  1789. ### High Performance
  1790. ```python
  1791. from time import perf_counter as pc
  1792. start_time = pc() # Seconds since restart.
  1793. ...
  1794. duration = pc() - start_time
  1795. ```
  1796. ### Timing a Snippet
  1797. ```python
  1798. >>> from timeit import timeit
  1799. >>> timeit('"-".join(str(a) for a in range(100))',
  1800. ... number=10000, globals=globals(), setup='pass')
  1801. 0.34986
  1802. ```
  1803. ### Line Profiler
  1804. ```python
  1805. # $ pip3 install line_profiler
  1806. @profile
  1807. def main():
  1808. a = [*range(10000)]
  1809. b = {*range(10000)}
  1810. main()
  1811. ```
  1812. #### Usage:
  1813. ```text
  1814. $ kernprof -lv test.py
  1815. Line # Hits Time Per Hit % Time Line Contents
  1816. ==============================================================
  1817. 1 @profile
  1818. 2 def main():
  1819. 3 1 1128.0 1128.0 27.4 a = [*range(10000)]
  1820. 4 1 2994.0 2994.0 72.6 b = {*range(10000)}
  1821. ```
  1822. ### Call Graph
  1823. #### Generates a PNG image of a call graph with highlighted bottlenecks:
  1824. ```python
  1825. # $ pip3 install pycallgraph
  1826. from pycallgraph import output, PyCallGraph
  1827. from datetime import datetime
  1828. time_str = datetime.now().strftime('%Y%m%d%H%M%S')
  1829. filename = f'profile-{time_str}.png'
  1830. drawer = output.GraphvizOutput(output_file=filename)
  1831. with PyCallGraph(drawer):
  1832. <code_to_be_profiled>
  1833. ```
  1834. NumPy
  1835. -----
  1836. **Array manipulation mini language. Can run up to one hundred times faster than equivalent Python code.**
  1837. ```python
  1838. # $ pip3 install numpy
  1839. import numpy as np
  1840. ```
  1841. ```python
  1842. <array> = np.array(<list>)
  1843. <array> = np.arange(from_inclusive, to_exclusive, ±step_size)
  1844. <array> = np.ones(<shape>)
  1845. <array> = np.random.randint(from_inclusive, to_exclusive, <shape>)
  1846. ```
  1847. ```python
  1848. <array>.shape = <shape>
  1849. <view> = <array>.reshape(<shape>)
  1850. <view> = np.broadcast_to(<array>, <shape>)
  1851. ```
  1852. ```python
  1853. <array> = <array>.sum(axis)
  1854. indexes = <array>.argmin(axis)
  1855. ```
  1856. * **Shape is a tuple of dimension sizes.**
  1857. * **Axis is an index of dimension that gets collapsed. Leftmost dimension has index 0.**
  1858. ### Indexing
  1859. ```bash
  1860. <el> = <2d_array>[0, 0] # First element.
  1861. <1d_view> = <2d_array>[0] # First row.
  1862. <1d_view> = <2d_array>[:, 0] # First column. Also [..., 0].
  1863. <3d_view> = <2d_array>[None, :, :] # Expanded by dimension of size 1.
  1864. ```
  1865. ```bash
  1866. <1d_array> = <2d_array>[<1d_row_indexes>, <1d_column_indexes>]
  1867. <2d_array> = <2d_array>[<2d_row_indexes>, <2d_column_indexes>]
  1868. ```
  1869. ```bash
  1870. <2d_bools> = <2d_array> > 0
  1871. <1d_array> = <2d_array>[<2d_bools>]
  1872. ```
  1873. * **If row and column indexes differ in shape, they are combined with broadcasting.**
  1874. ### Broadcasting
  1875. **Broadcasting is a set of rules by which NumPy functions operate on arrays of different sizes and/or dimensions.**
  1876. ```python
  1877. left = [[0.1], [0.6], [0.8]] # Shape: (3, 1)
  1878. right = [ 0.1 , 0.6 , 0.8 ] # Shape: (3)
  1879. ```
  1880. #### 1. If array shapes differ in length, left-pad the shorter shape with ones:
  1881. ```python
  1882. left = [[0.1], [0.6], [0.8]] # Shape: (3, 1)
  1883. right = [[0.1 , 0.6 , 0.8]] # Shape: (1, 3) <- !
  1884. ```
  1885. #### 2. If any dimensions differ in size, expand the ones that have size 1 by duplicating their elements:
  1886. ```python
  1887. left = [[0.1, 0.1, 0.1], [0.6, 0.6, 0.6], [0.8, 0.8, 0.8]] # Shape: (3, 3) <- !
  1888. right = [[0.1, 0.6, 0.8], [0.1, 0.6, 0.8], [0.1, 0.6, 0.8]] # Shape: (3, 3) <- !
  1889. ```
  1890. #### 3. If neither non-matching dimension has size 1, rise an error.
  1891. ### Example
  1892. #### For each point returns index of its nearest point (`[0.1, 0.6, 0.8] => [1, 2, 1]`):
  1893. ```python
  1894. >>> points = np.array([0.1, 0.6, 0.8])
  1895. [ 0.1, 0.6, 0.8]
  1896. >>> wrapped_points = points.reshape(3, 1)
  1897. [[ 0.1],
  1898. [ 0.6],
  1899. [ 0.8]]
  1900. >>> distances = wrapped_points - points
  1901. [[ 0. , -0.5, -0.7],
  1902. [ 0.5, 0. , -0.2],
  1903. [ 0.7, 0.2, 0. ]]
  1904. >>> distances = np.abs(distances)
  1905. [[ 0. , 0.5, 0.7],
  1906. [ 0.5, 0. , 0.2],
  1907. [ 0.7, 0.2, 0. ]]
  1908. >>> i = np.arange(3)
  1909. [0, 1, 2]
  1910. >>> distances[i, i] = np.inf
  1911. [[ inf, 0.5, 0.7],
  1912. [ 0.5, inf, 0.2],
  1913. [ 0.7, 0.2, inf]]
  1914. >>> distances.argmin(1)
  1915. [1, 2, 1]
  1916. ```
  1917. Image
  1918. -----
  1919. ```python
  1920. # $ pip3 install pillow
  1921. from PIL import Image
  1922. ```
  1923. #### Creates a PNG image of a rainbow gradient:
  1924. ```python
  1925. width = 100
  1926. height = 100
  1927. size = width * height
  1928. pixels = [255 * i/size for i in range(size)]
  1929. img = Image.new('HSV', (width, height))
  1930. img.putdata([(int(a), 255, 255) for a in pixels])
  1931. img.convert(mode='RGB').save('test.png')
  1932. ```
  1933. #### Adds noise to a PNG image:
  1934. ```python
  1935. from random import randint
  1936. add_noise = lambda value: max(0, min(255, value + randint(-20, 20)))
  1937. img = Image.open('test.png').convert(mode='HSV')
  1938. img.putdata([(add_noise(h), s, v) for h, s, v in img.getdata()])
  1939. img.convert(mode='RGB').save('test.png')
  1940. ```
  1941. ### Modes
  1942. * **`'1'` - 1-bit pixels, black and white, stored with one pixel per byte.**
  1943. * **`'L'` - 8-bit pixels, greyscale.**
  1944. * **`'RGB'` - 3x8-bit pixels, true color.**
  1945. * **`'RGBA'` - 4x8-bit pixels, true color with transparency mask.**
  1946. * **`'HSV'` - 3x8-bit pixels, Hue, Saturation, Value color space.**
  1947. Audio
  1948. -----
  1949. ```python
  1950. import wave
  1951. from struct import pack, iter_unpack
  1952. ```
  1953. ### Read Frames from WAV File
  1954. ```python
  1955. def read_wav_file(filename):
  1956. with wave.open(filename, 'rb') as wf:
  1957. frames = wf.readframes(wf.getnframes())
  1958. return [a[0] for a in iter_unpack('<h', frames)]
  1959. ```
  1960. ### Write Frames to WAV File
  1961. ```python
  1962. def write_to_wav_file(filename, frames_int, mono=True):
  1963. frames_short = (pack('<h', a) for a in frames_int)
  1964. with wave.open(filename, 'wb') as wf:
  1965. wf.setnchannels(1 if mono else 2)
  1966. wf.setsampwidth(2)
  1967. wf.setframerate(44100)
  1968. wf.writeframes(b''.join(frames_short))
  1969. ```
  1970. ### Examples
  1971. #### Saves a sine wave to a mono WAV file:
  1972. ```python
  1973. from math import pi, sin
  1974. frames_f = (sin(i * 2 * pi * 440 / 44100) for i in range(100000))
  1975. frames_i = (int(a * 30000) for a in frames_f)
  1976. write_to_wav_file('test.wav', frames_i)
  1977. ```
  1978. #### Adds noise to a mono WAV file:
  1979. ```python
  1980. from random import randint
  1981. add_noise = lambda value: max(-32768, min(32767, value + randint(-500, 500)))
  1982. frames_i = (add_noise(a) for a in read_wav_file('test.wav'))
  1983. write_to_wav_file('test.wav', frames_i)
  1984. ```
  1985. ### Synthesizer
  1986. ```python
  1987. # $ pip3 install simpleaudio
  1988. import simpleaudio, math, struct
  1989. from itertools import chain, repeat
  1990. F = 44100
  1991. P1 = '71♪,69,,71♪,66,,62♪,66,,59♪,,,'
  1992. P2 = '71♪,73,,74♪,73,,74,,71,,73♪,71,,73,,69,,71♪,69,,71,,67,,71♪,,,'
  1993. get_pause = lambda seconds: repeat(0, int(seconds * F))
  1994. sin_f = lambda i, hz: math.sin(i * 2 * math.pi * hz / F)
  1995. get_wave = lambda hz, seconds: (sin_f(i, hz) for i in range(int(seconds * F)))
  1996. get_hz = lambda key: 8.176 * 2 ** (int(key) / 12)
  1997. parse_note = lambda note: (get_hz(note[:2]), 0.25 if '♪' in note else 0.125)
  1998. get_frames = lambda note: get_wave(*parse_note(note)) if note else get_pause(0.125)
  1999. frames_f = chain.from_iterable(get_frames(n) for n in f'{P1}{P1}{P2}'.split(','))
  2000. frames_b = b''.join(struct.pack('<h', int(f * 30000)) for f in frames_f)
  2001. simpleaudio.play_buffer(frames_b, 1, 2, F)
  2002. ```
  2003. Basic Script Template
  2004. ---------------------
  2005. ```python
  2006. #!/usr/bin/env python3
  2007. #
  2008. # Usage: .py
  2009. #
  2010. from collections import namedtuple
  2011. from dataclasses import make_dataclass
  2012. from enum import Enum
  2013. import re
  2014. import sys
  2015. def main():
  2016. pass
  2017. ###
  2018. ## UTIL
  2019. #
  2020. def read_file(filename):
  2021. with open(filename, encoding='utf-8') as file:
  2022. return file.readlines()
  2023. if __name__ == '__main__':
  2024. main()
  2025. ```