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.

827 lines
15 KiB

6 years ago
7 years ago
6 years ago
6 years ago
7 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
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
7 years ago
6 years ago
6 years ago
7 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
7 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
6 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
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
7 years ago
6 years ago
7 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
6 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
6 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
6 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
6 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
6 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
6 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
6 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
6 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
6 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
6 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
6 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
6 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
6 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
6 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
6 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
6 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
6 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
6 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
6 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
6 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
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
7 years ago
  1. Comprehensive Python Cheatsheet
  2. ===============================
  3. ![Monty Python](web/image_888.jpeg)
  4. Main
  5. ----
  6. ```python
  7. if __name__ == '__main__':
  8. main()
  9. ```
  10. List
  11. ----
  12. ```python
  13. <list>[from_inclusive : to_exclusive : step_size]
  14. <list>.append(<el>)
  15. <list>.extend(<list>)
  16. <list>.sort()
  17. <list>.reverse()
  18. ```
  19. ```python
  20. sum(<list>)
  21. sorted_by_second = sorted(<list>, key=lambda tup: tup[1])
  22. flattened_list = [item for sublist in <list> for item in sublist]
  23. ```
  24. Dictionary
  25. ----------
  26. ```python
  27. <dict>.items()
  28. <dict>.get(key, default)
  29. <dict>.setdefault(key, default)
  30. <dict>.update(<dict>)
  31. ```
  32. ```python
  33. collections.defaultdict(<type>) # Creates a dictionary with default values.
  34. dict(zip(keys, values)) # Initiates a dict from two lists.
  35. {k: v for k, v in <dict>.iteritems() if k in <list>} # Filters a dict by keys.
  36. ```
  37. ### Counter
  38. ```python
  39. >>> from collections import Counter
  40. >>> z = ['blue', 'red', 'blue', 'yellow', 'blue', 'red']
  41. >>> Counter(z)
  42. Counter({'blue': 3, 'red': 2, 'yellow': 1})
  43. ```
  44. Set
  45. ---
  46. ```python
  47. <set> = set()
  48. <set>.add(<el>)
  49. <set>.update(<set>)
  50. <set>.union(<set>)
  51. <set>.intersection(<set>)
  52. <set>.difference(<set>)
  53. ```
  54. ### Frozenset
  55. #### Is hashable and can be used as a key in dictionary:
  56. ```python
  57. <set> = frozenset()
  58. ```
  59. Range
  60. -----
  61. ```python
  62. range(to_exclusive)
  63. range(from_inclusive, to_exclusive)
  64. range(from_inclusive, to_exclusive, step_size)
  65. range(from_inclusive, to_exclusive, -step_size)
  66. ```
  67. Enumerate
  68. ---------
  69. ```python
  70. for i, <el> in enumerate(<collection> [, i_start])
  71. ```
  72. Named Tuple
  73. -----------
  74. ```python
  75. >>> TestResults = collections.namedtuple('TestResults', ['filed', 'attempted'])
  76. >>> a = TestResults(1, attempted=2)
  77. TestResults(filed=1, attempted=2)
  78. >>> a.filed
  79. 1
  80. >>> getattr(a, 'attempted')
  81. 2
  82. ```
  83. Iterator
  84. --------
  85. #### Skips first element:
  86. ```python
  87. next(<iter>)
  88. for element in <iter>:
  89. ...
  90. ```
  91. #### Reads input until it reaches an empty line:
  92. ```python
  93. for line in iter(input, ''):
  94. ...
  95. ```
  96. #### Same, but prints a message every time:
  97. ```python
  98. from functools import partial
  99. for line in iter(partial(input, 'Please enter value'), ''):
  100. ...
  101. ```
  102. Generator
  103. ---------
  104. ```python
  105. def step(start, step):
  106. while True:
  107. yield start
  108. start += step
  109. ```
  110. ```python
  111. stepper = step(10, 2)
  112. next(stepper) # 10 (, 12, 14, ...)
  113. ```
  114. Type
  115. ----
  116. ```python
  117. type(<el>) # <class 'int'>/<class 'str'>/...
  118. ```
  119. ```python
  120. import numbers
  121. isinstance(<el>, numbers.Number)
  122. ```
  123. String
  124. ------
  125. ```python
  126. str.replace(text, old, new)
  127. <str>.isnumeric()
  128. <str>.split(sep=None, maxsplit=-1)
  129. <str>.strip()
  130. <str>.join(<list>)
  131. <str>.startswith(<str>)
  132. ```
  133. ### Print
  134. ```python
  135. print(<el> [, <el>, end='', sep='', file=<file>])
  136. ```
  137. ### Regex
  138. ```python
  139. import re
  140. re.sub(<regex>, new, text, count=0)
  141. re.search(<regex>, text) # Searches for first occurrence of pattern.
  142. re.match(<regex>, text) # Searches only at the beginning of the string.
  143. re.findall(<regex>, text)
  144. re.split(<regex>, text, maxsplit=0) # Use brackets in regex to keep the matches.
  145. ```
  146. **'Search' and 'match' functions return a 'Match' object. Use '.group()' method on it to get the match.**
  147. **Parameter 'flags=re.IGNORECASE' can be used with all functions.**
  148. **Parameter 'flags=re.DOTALL' makes dot also accept newline.**
  149. **Use '\\1' or r'\1' for backreference.**
  150. #### Special Sequences:
  151. ```python
  152. # Use capital letter for negation.
  153. '\d' == '[0-9]' # Digit
  154. '\s' == '[ \t\n\r\f\v]' # Whitespace
  155. '\w' == '[a-zA-Z0-9_]' # Alphanumeric
  156. ```
  157. ### Format
  158. ```python
  159. '{}'.format(<el> [, <el>, ...])
  160. ```
  161. ```python
  162. {:min_width} # '<el> '
  163. {:>min_width} # ' <el>'
  164. {:^min_width} # ' <el> '
  165. {:_min_width} # '<el>____'
  166. {:.max_width} # '<e>'
  167. ```
  168. ```python
  169. {:max_width.min_width} # ' <e>'
  170. {:max_width.no_of_decimalsf} # ' 3.14'
  171. ```
  172. ```python
  173. >>> person = {'name': 'Jean-Luc', 'height': 187.1}
  174. >>> '{p[height]:.0f}'.format(p=person)
  175. '187'
  176. ```
  177. #### Or:
  178. ```python
  179. >>> f"{person['height']:.0f}"
  180. '187'
  181. ```
  182. ### Text Wrap
  183. ```python
  184. import textwrap
  185. textwrap.wrap(text, width)
  186. ```
  187. Random
  188. ------
  189. ```python
  190. import random
  191. random.random()
  192. random.randint(from_inclusive, to_inclusive)
  193. random.shuffle(<list>)
  194. ```
  195. Infinity
  196. --------
  197. ```python
  198. float("inf")
  199. ```
  200. Datetime
  201. --------
  202. ```python
  203. import datetime
  204. now = datetime.datetime.now()
  205. now.month # 3
  206. now.strftime('%Y%m%d') # 20180315
  207. now.strftime('%Y%m%d%H%M%S') # 20180315002834
  208. ```
  209. Arguments
  210. ---------
  211. **"*" is the splat operator, that takes a list as input, and expands it into actual positional arguments in the function call:**
  212. ```python
  213. args = (1, 2)
  214. kwargs = {'x': 3, 'y': 4, 'z': 5}
  215. func(*args, **kwargs)
  216. ```
  217. #### Is the same as:
  218. ```python
  219. func(1, 2, x=3, y=4, z=5)
  220. ```
  221. Inline
  222. ------
  223. ### Lambda
  224. ```python
  225. lambda: <return_value>
  226. lambda <argument1>, <argument2>: <return_value>
  227. ```
  228. ### Comprehension
  229. ```python
  230. [i+1 for i in range(10)] # [1, 2, ..., 10]
  231. [i for i in range(10) if i>5] # [6, 7, ..., 9]
  232. {i: i*2 for i in range(10)} # {0: 0, 1: 2, ..., 9: 18}
  233. (x+5 for x in range(0, 10)) # (5, 6, ..., 14) -> Generator
  234. ```
  235. ```python
  236. [i+j for i in range(10) for j in range(10)]
  237. ```
  238. #### Is the same as:
  239. ```python
  240. out = []
  241. for i in range(10):
  242. for j in range(10):
  243. out.append(i+j)
  244. ```
  245. ### Map, Filter, Reduce
  246. ```python
  247. map(lambda x: x+1, range(10)) # [1, 2, ..., 10]
  248. filter(lambda x: x>5, range(10)) # [6, 7, ..., 9]
  249. functools.reduce(lambda sum, x: sum+x, range(10)) # 45
  250. ```
  251. ### Any, All
  252. ```python
  253. any(el[1] for el in <collection>)
  254. ```
  255. ### If - Else
  256. ```python
  257. <expression_if_true> if <condition> else <expression_if_false>
  258. ```
  259. Closure
  260. -------
  261. ```python
  262. def multiply_closure(x):
  263. def wrapped(y):
  264. return x * y
  265. return wrapped
  266. multiply_by_3 = multiply_closure(3)
  267. ```
  268. #### Or:
  269. ```python
  270. from functools import partial
  271. partial(<function>, <argument>)
  272. ```
  273. Decorator
  274. ---------
  275. ```python
  276. @closure_name
  277. def function_that_gets_passed_to_closure():
  278. pass
  279. ```
  280. #### Debugger example:
  281. ```python
  282. from functools import wraps
  283. def debug(func):
  284. @wraps(func) # Needed for metadata copying (func name, ...).
  285. def wrapper(*args, **kwargs):
  286. print(func.__name__)
  287. return func(*args, **kwargs)
  288. return wrapper
  289. @debug
  290. def add(x, y):
  291. return x + y
  292. ```
  293. Class
  294. -----
  295. ```python
  296. class <name>:
  297. def __init__(self, a):
  298. self.a = a
  299. def __repr__(self):
  300. return str({'a': self.a})
  301. def __str__(self):
  302. return str(self.a)
  303. ```
  304. ### Enum
  305. ```python
  306. import enum
  307. class <enum_name>(enum.Enum):
  308. <name1> = <value1>
  309. <name2> = <value2>
  310. <name3> = enum.auto() # Can be used for automatic indexing.
  311. ...
  312. ```
  313. ```python
  314. <enum_name>.<name> # == <enum>
  315. <enum_name>(value) # == <enum>
  316. <enum>.name # == <name>
  317. <enum>.value # == <value>
  318. ```
  319. ```python
  320. Cutlery = Enum('Cutlery', ['knife', 'fork', 'spoon'])
  321. list(<enum_name>) # == [<enum1>, <enum2>, ...]
  322. random.choice(list(<enum_name>)) # == random <enum>
  323. ```
  324. ### Copy
  325. ```python
  326. import copy
  327. copy.copy(<object>)
  328. copy.deepcopy(<object>)
  329. ```
  330. System
  331. ------
  332. ### Arguments
  333. ```python
  334. import sys
  335. sys.argv
  336. ```
  337. ### Read File
  338. ```python
  339. def read_file(filename):
  340. with open(filename, encoding='utf-8') as file:
  341. return file.readlines()
  342. ```
  343. ### Write to File
  344. ```python
  345. def write_to_file(filename, text):
  346. with open(filename, 'w', enconding='utf-8') as file:
  347. file.write(text)
  348. ```
  349. ### Execute Command
  350. ```python
  351. import os
  352. os.popen(<command>).read()
  353. ```
  354. #### Or:
  355. ```python
  356. >>> import subprocess
  357. >>> a = subprocess.run(['ls', '-a'], stdout=subprocess.PIPE)
  358. >>> a.stdout
  359. b'.\n..\nfile1.txt\nfile2.txt\n'
  360. >>> a.returncode
  361. 0
  362. ```
  363. ### Input
  364. ```python
  365. filename = input('Enter a file name: ')
  366. ```
  367. #### Prints lines until EOF:
  368. ```python
  369. while True:
  370. try:
  371. print(input())
  372. except EOFError:
  373. break
  374. ```
  375. JSON
  376. ----
  377. ```python
  378. import json
  379. ```
  380. ### Serialization
  381. ```python
  382. <str> = json.dumps(<object>, ensure_ascii=True, indent=None)
  383. <object> = json.loads(<str>)
  384. ```
  385. ### Read File
  386. ```python
  387. def read_json_file(filename):
  388. with open(filename, encoding='utf-8') as file:
  389. return json.load(file)
  390. ```
  391. ### Write to File
  392. ```python
  393. def write_to_json_file(filename, an_object):
  394. with open(filename, 'w', encoding='utf-8') as file:
  395. json.dump(an_object, file, ensure_ascii=False, indent=2)
  396. ```
  397. SQLite
  398. ------
  399. ```python
  400. import sqlite3
  401. db = sqlite3.connect(filename)
  402. ```
  403. ### Read
  404. ```python
  405. cursor = db.execute(<query>)
  406. if cursor:
  407. cursor.fetchall() # Or cursor.fetchone()
  408. db.close()
  409. ```
  410. ### Write
  411. ```python
  412. db.execute(<query>)
  413. db.commit()
  414. ```
  415. Exceptions
  416. ----------
  417. ```python
  418. while True:
  419. try:
  420. x = int(input("Please enter a number: "))
  421. break
  422. except ValueError:
  423. print("Oops! That was no valid number. Try again...")
  424. ```
  425. Threading
  426. ---------
  427. ```python
  428. import threading
  429. ```
  430. ### Thread
  431. ```python
  432. thread = threading.Thread(target=<function>, args=(<first_arg>, ))
  433. thread.start()
  434. thread.join()
  435. ```
  436. ### Lock
  437. ```python
  438. lock = threading.Rlock()
  439. lock.acquire()
  440. lock.release()
  441. ```
  442. Itertools
  443. ---------
  444. **Every function returns a generator and can accept any collection. If you want to print an output of generator, as in examples, you need to pass it to the list() function.**
  445. ```python
  446. from itertools import *
  447. ```
  448. ### Chain
  449. ```python
  450. >>> chain([1, 2], range(3, 5))
  451. [1, 2, 3, 4]
  452. ```
  453. ### Combinations
  454. ```python
  455. >>> combinations("abc", 2)
  456. [('a', 'b'), ('a', 'c'), ('b', 'c')]
  457. ```
  458. ### Permutations
  459. ```python
  460. >>> permutations("abc", 2)
  461. [('a', 'b'), ('a', 'c'), ('b', 'a'), ('b', 'c'), ('c', 'a'), ('c', 'b')]
  462. ```
  463. ### Product
  464. ```python
  465. >>> list(product('ab', [1, 2]))
  466. [('a', 1), ('a', 2), ('b', 1), ('b', 2)]
  467. ```
  468. ### Compress
  469. ```python
  470. >>> compress("abc", [True, 0, 23])
  471. ['a', 'c']
  472. ```
  473. ### Count
  474. ```python
  475. >>> a = count(5, 2)
  476. >>> next(a), next(a)
  477. (5, 7)
  478. ```
  479. ### Cycle
  480. ```python
  481. >>> a = cycle("abc")
  482. >>> [next(a) for _ in range(10)]
  483. ['a', 'b', 'c', 'a', 'b', 'c', 'a', 'b', 'c', 'a']
  484. ```
  485. ### Groupby
  486. ```python
  487. >>> a = [{"id": 1, "name": "bob"},
  488. {"id": 2, "name": "bob"},
  489. {"id": 3, "name": "peter"}]
  490. >>> {k: list(v) for k, v in groupby(a, key=lambda x: x["name"])}
  491. {'bob': [{'id': 1, 'name': 'bob'},
  492. {'id': 2, 'name': 'bob'}],
  493. 'peter': [{'id': 3, 'name': 'peter'}]}
  494. ```
  495. ### Islice
  496. ```python
  497. islice([1, 2, 3], 1, None)
  498. [2, 3]
  499. ```
  500. ### Ifilter, imap and izip
  501. #### Filter, map and zip functions that return generators instead of iterators.
  502. Introspection and Metaprograming
  503. --------------------------------
  504. **Inspecting code at runtime and code that generates code. You can:**
  505. * **Look at the attributes**
  506. * **Set new attributes**
  507. * **Create functions dynamically**
  508. * **Traverse the parent classes**
  509. * **Change values in the class**
  510. ```python
  511. >>> class B:
  512. ... def __init__(self):
  513. ... self.a= 'sdfsd'
  514. ... self.b = 123324
  515. >>> b = B()
  516. ```
  517. ### Getattr
  518. ```python
  519. >>> getattr(b, 'a')
  520. 'sdfsd'
  521. ```
  522. #### Is the same as:
  523. ```python
  524. B.__getattribute__(b, 'a')
  525. ```
  526. ### Hasattr
  527. ```python
  528. >>> hasattr(b, 'c')
  529. False
  530. ```
  531. ### Setattr
  532. ```python
  533. >>> setattr(b, 'c', 10)
  534. ```
  535. ### Type
  536. **Type is the root class. If only passed the object it returns it's type. Otherwise it creates a new class (and not the instance!):**
  537. ```python
  538. type(class_name, parents<tuple>, attributes<dict>)
  539. ```
  540. ```python
  541. >>> BB = type('B', (), {'a': 'sdfsd', 'b': 123324}
  542. >>> b = BB()
  543. ```
  544. ### MetaClass
  545. #### Class that creates class:
  546. ```python
  547. def my_meta_class(name, parents, attrs):
  548. ...
  549. return type(name, parents, attrs)
  550. ```
  551. #### Or:
  552. ```python
  553. class MyMetaClass(type):
  554. def __new__(klass, name, parents, attrs):
  555. ...
  556. return type.__new__(klass, name, parents, attrs)
  557. ```
  558. ### Metaclass Attr
  559. **When 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:**
  560. ```python
  561. class BlaBla:
  562. __metaclass__ = Bla
  563. ```
  564. Eval
  565. ----
  566. ```python
  567. import ast
  568. import operator as op
  569. # Supported operators
  570. operators = {ast.Add: op.add, ast.Sub: op.sub, ast.Mult: op.mul,
  571. ast.Div: op.truediv, ast.Pow: op.pow, ast.BitXor: op.xor,
  572. ast.USub: op.neg}
  573. def eval_expr(expr):
  574. return eval_(ast.parse(expr, mode='eval').body)
  575. def eval_(node):
  576. if isinstance(node, ast.Num): # <number>
  577. return node.n
  578. elif isinstance(node, ast.BinOp): # <left> <operator> <right>
  579. return operators[type(node.op)](eval_(node.left), eval_(node.right))
  580. elif isinstance(node, ast.UnaryOp): # <operator> <operand> e.g., -1
  581. return operators[type(node.op)](eval_(node.operand))
  582. else:
  583. raise TypeError(node)
  584. ```
  585. ```python
  586. >>> eval_expr('2^6')
  587. 4
  588. >>> eval_expr('2**6')
  589. 64
  590. >>> eval_expr('1 + 2*3**(4^5) / (6 + -7)')
  591. -5.0
  592. ```
  593. Libraries
  594. =========
  595. Plot
  596. ----
  597. ```python
  598. from matplotlib import pyplot
  599. pyplot.plot(<data> [, <data>])
  600. pyplot.show()
  601. pyplot.savefig(filename)
  602. ```
  603. Web
  604. ---
  605. ```python
  606. import bottle
  607. import urllib
  608. ```
  609. ### Run
  610. ```python
  611. bottle.run(host='localhost', port=8080)
  612. bottle.run(host='0.0.0.0', port=80, server='cherrypy')
  613. ```
  614. ### Static request
  615. ```python
  616. @route('/img/<image>')
  617. def send_image(image):
  618. return static_file(image, 'images/', mimetype='image/png')
  619. ```
  620. ### Dynamic request
  621. ```python
  622. @route('/<sport>')
  623. def send_page(sport):
  624. sport = urllib.parse.unquote(sport).lower()
  625. page = read_file(sport)
  626. return template(page)
  627. ```
  628. ### REST request
  629. ```python
  630. @post('/p/<sport>')
  631. def p_handler(sport):
  632. team = request.forms.get('team')
  633. team = urllib.parse.unquote(team).lower()
  634. db = sqlite3.connect(conf.DB_PATH)
  635. p_h, p_a = get_p(db, sport, team)
  636. db.close()
  637. response.headers['Content-Type'] = 'application/json'
  638. response.headers['Cache-Control'] = 'no-cache'
  639. return json.dumps([p_h, p_a])
  640. ```
  641. Curses
  642. ------
  643. ```python
  644. import curses
  645. def main():
  646. curses.wrapper(draw)
  647. def draw(screen):
  648. screen.clear()
  649. screen.addstr(0, 0, "Press ESC to quit.")
  650. while screen.getch() != 27:
  651. pass
  652. ```
  653. #### Gets char from int:
  654. ```python
  655. chr(<int>)
  656. ```
  657. Profile
  658. -------
  659. #### Times execution of the passed code:
  660. ```python
  661. import timeit
  662. timeit.timeit('"-".join(str(n) for n in range(100))', number=10000)
  663. ```
  664. #### Generates a PNG image of call graph and highlights the bottlenecks:
  665. ```python
  666. import pycallgraph
  667. graph = pycallgraph.output.GraphvizOutput()
  668. graph.output_file = get_filename()
  669. with pycallgraph.PyCallGraph(output=graph):
  670. <code_to_be_profiled>
  671. ```
  672. #### Utility code for unique PNG filenames:
  673. ```python
  674. def get_filename():
  675. return "{}-{}.png".format("profile", get_current_datetime_string())
  676. def get_current_datetime_string():
  677. now = datetime.datetime.now()
  678. return get_datetime_string(now)
  679. def get_datetime_string(a_datetime):
  680. return a_datetime.strftime('%Y%m%d%H%M%S')
  681. ```
  682. Audio
  683. -----
  684. #### Saves list of floats of size 0 to 1 to a WAV file:
  685. ```python
  686. import wave, struct
  687. frames = [struct.pack("%dh"%(1), int((a-0.5)*60000)) for a in <list>]
  688. wf = wave.open(filename, 'wb')
  689. wf.setnchannels(1)
  690. wf.setsampwidth(4)
  691. wf.setframerate(44100)
  692. wf.writeframes(b''.join(frames))
  693. wf.close()
  694. ```