├── .gitignore ├── .travis.yml ├── CONTRIBUTING.md ├── README.md ├── argparse_cheat.py ├── bibliography.md ├── bisect_cheat.py ├── builtin_functions.py ├── c_from_py ├── Makefile ├── README.md ├── ctypes_cheat.c ├── ctypes_cheat.py ├── ctypes_cheat_relative.py ├── import_cheat.c ├── import_cheat.py └── test ├── class.py ├── class_attribute.py ├── collections_cheat.py ├── concurrent_map.py ├── concurrent_map_exception.py ├── concurrent_submit.py ├── configure ├── csv_cheat.py ├── curses_cheat └── collision.py ├── datetime_cheat.py ├── decorator_cheat.py ├── dict_cheat.py ├── distutils_cheat ├── README.md ├── min │ ├── package │ │ ├── README.md │ │ ├── python_cheat_min.py │ │ └── setup.py │ └── test.py └── script │ ├── package │ ├── README.md │ ├── python_cheat_min.py │ ├── python_cheat_script.py │ ├── python_cheat_script_script.py │ └── setup.py │ └── test.py ├── doctest_cheat.py ├── environ.py ├── exception.py ├── expat_cheat.py ├── fileinput ├── README.md ├── a ├── b ├── main.py └── test_main.py ├── format_method.py ├── format_operator.py ├── frozenset.py ├── function.py ├── getopt_cheat.py ├── getting-started.md ├── h5py_cheat.py ├── how-to-hack-python-projects.md ├── implementations.md ├── import_cheat ├── README.md ├── __init__.py ├── d │ ├── __init__.py │ ├── notmain.py │ └── notmain2.py ├── main.py ├── notmain.py └── test ├── interactive-friendly.md ├── ipython.ipy ├── issubclass.py ├── iterator_cheat.py ├── jupyter ├── .gitignore ├── README.md ├── clear_output ├── get_html ├── inc.ipynb ├── inc.nbconvert.ipynb ├── ipywidgets_cheat.ipynb └── plotly.ipynb ├── keyword_only.py ├── lambda.py ├── list.py ├── logging_cheat.py ├── logo.png ├── main.py ├── math_cheat.py ├── matplotlib.md ├── multifile ├── README.md ├── a ├── a.py ├── aln.py ├── contains_list.py ├── d │ ├── __init__.py │ ├── a.py │ ├── a2.py │ ├── aln.py │ ├── d2 │ │ ├── __init__.py │ │ ├── a3.py │ │ └── d3 │ │ │ ├── __init__.py │ │ │ └── a4.py │ └── os.py ├── dict_cheat.py ├── execed.py ├── imported_from_a.py ├── imported_from_main.py ├── main.py └── raise_exception.py ├── net.py ├── networkx_cheat.py ├── nltk_cheat.py ├── number.py ├── numpy_cheat.py ├── operators.py ├── optparse_cheat.py ├── os_cheat.py ├── pandas_cheat.py ├── path_cheat.py ├── pexpect └── python_test.py ├── pickle_cheat.py ├── pip.md ├── pros-and-cons.md ├── py_from_c ├── Makefile ├── README.md ├── eval.c ├── pure.c ├── pure.py ├── pure_cpp.cpp └── test ├── pysocks_cheat └── tor.py ├── python-utility.md ├── python3 ├── README.md ├── enum_cheat.py ├── main.py └── pip.md ├── random_cheat.py ├── re_cheat.py ├── requirements.txt ├── scipy_cheat.py ├── set.py ├── simplehttpserver_cheat.md ├── slots.py ├── smtplib_cheat.py ├── smtplib_cheat_local.py.sample ├── special_methods.py ├── sphinx ├── Makefile ├── README.md ├── doc │ ├── Makefile │ ├── conf.py │ ├── index.rst │ ├── mod.rst │ ├── mod2.rst │ ├── modules.rst │ └── toctree_include.rst ├── mod │ ├── __init__.py │ ├── a.py │ ├── b.py │ └── main.py └── mod2 │ └── __init__.py ├── sqlite3_cheat.py ├── string_cheat.py ├── style-guides.md ├── subprocess_cheat ├── check_output.py ├── count.py ├── false.py ├── popen_background.py ├── stdout_stderr.py ├── stdout_stderr_test.py └── test ├── sympy_cheat.py ├── sys_cheat.py ├── tempfile_cheat.py ├── termcolor_cheat.py ├── test ├── thread_add.py ├── thread_cpu_bound.gnuplot ├── thread_cpu_bound.py ├── thread_cpu_bound.sh ├── thread_hello.py ├── thread_limit.py ├── time_cheat.py ├── tk ├── README.md ├── hello_world.py └── main.py ├── trac.md ├── tuple.py ├── unittest_cheat.py ├── urllib2_cheat ├── README.md ├── http_proxy.py └── post.py ├── virtualenv ├── .gitignore ├── Makefile ├── README.md └── main.py ├── waf ├── .gitignore ├── README.md ├── d │ └── wscript ├── test.sh └── wscript └── wsgi.py /.gitignore: -------------------------------------------------------------------------------- 1 | *.py[cod] 2 | *.tmp 3 | tmp.* 4 | *.tmp.* 5 | *_local.py 6 | 7 | # Extensions 8 | *.o 9 | *.a 10 | *.so 11 | 12 | # Packages 13 | *.egg 14 | *.egg-info 15 | dist 16 | build 17 | eggs 18 | parts 19 | var 20 | sdist 21 | develop-eggs 22 | .installed.cfg 23 | lib 24 | lib64 25 | pip-log.txt 26 | files.txt 27 | 28 | # Tests 29 | .coverage 30 | .tox 31 | nosetests.xml 32 | 33 | # Translations 34 | *.mo 35 | 36 | # MR developer 37 | .mr.developer.cfg 38 | .project 39 | .pydevproject 40 | 41 | # Sphinx 42 | _build 43 | _static 44 | _templates 45 | 46 | _out 47 | 48 | # Virtualenvs. 49 | .venv/ 50 | 51 | # Data files. 52 | /thread_cpu_bound.dat 53 | 54 | # Jupyter 55 | .ipynb_checkpoints 56 | 57 | # C compilation outputs. 58 | *.o 59 | *.out 60 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: python 2 | python: 3 | - "2.7" 4 | script: python test.py 5 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # CONTRIBUTING 2 | 3 | Style: follow PEP 8 and the Google Style Guide. 4 | 5 | Use single quotes for string literals. 6 | 7 | Cheats are runnable and full of assertions wherever possible: only unpredictable outputs are printed. 8 | 9 | Watch out for not naming a module with the same as in the stdlib, or you will import the module from current dir instead! This is why some files are named `something_cheat.py` instead of simply `cheat.py`. 10 | 11 | The cheats use the following "literate Python" style that mixes prose with runnable code: 12 | 13 | ## Markdown 14 | 15 | Prose is written mostly in markdown, except that code blocks are not indented. 16 | 17 | Never use indented lists with runnable code blocks in them as that breaks Python which is indentation based. 18 | 19 | ## Commented out code 20 | 21 | Commented out code, e.g. code that would break the examples or take drastic actions like filesystem writing, has no space after the `#`, prose has one space: 22 | 23 | ```py 24 | # Look at the following code: 25 | 26 | #shtuil.rmtree('') 27 | 28 | # But don't run it. 29 | ``` 30 | 31 | ## Large comments with triple double quoted strings 32 | 33 | We leave it to your discretion what consists of a "large" comment block, but as a rule of thumb we consider 4 lines large. 34 | 35 | ```py 36 | """ 37 | This explanation: 38 | 39 | - spans 40 | - more 41 | - than 42 | - four lines 43 | """ 44 | ``` 45 | 46 | ## Headers with if 47 | 48 | Headers are replaced by `if` blocks so as to give visual indentation. 49 | 50 | Important terms in the headers are prefixed with double hashes `##` so they can be easily searched for later. 51 | 52 | E.g.: 53 | 54 | ```py 55 | if '##string': 56 | 57 | # Strings are useful! 58 | 59 | s = 'Hello world!' 60 | 61 | if '##unicode': 62 | 63 | # Unicode is a pain! 64 | 65 | u = u'Hello world!' 66 | 67 | pass 68 | ``` 69 | 70 | If there is no non-comment line inside and `if` "header", add a `pass` statement to to it right after the `if`: 71 | 72 | ```py 73 | if '##unicode': 74 | 75 | pass 76 | 77 | # TODO this is too hard, so this section is empty. 78 | ``` 79 | 80 | But note that triple quoted string comments work, so don't add `pass` in that case: 81 | 82 | ```py 83 | if '##unicode': 84 | 85 | """ 86 | This is too hard. 87 | 88 | This is why this section is empty. 89 | """ 90 | ``` 91 | 92 | Multiple related terms can be hashed in a single `if` to make searching easier: 93 | 94 | ```py 95 | if '##import ##module': 96 | ``` 97 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Python Cheat ![logo](logo.png) 2 | 3 | This repo is in the process of moving to: https://cirosantilli.com/linux-kernel-module-cheat#python 4 | 5 | The move will be done progressively as examples are needed there, and no new content will be added here. 6 | 7 | [![Build Status](https://travis-ci.org/cirosantilli/python-cheat.svg?branch=master)](https://travis-ci.org/cirosantilli/python-cheat) 8 | 9 | Python minimal examples. Asserts used wherever possible. Tested in Ubuntu 18.04. 10 | 11 | 1. [Getting started](getting-started.md) 12 | 1. Introduction 13 | 1. [Implementations](implementations.md) 14 | 1. [python utility](python-utility.md) 15 | 1. [Style guides](style-guides.md) 16 | 1. [Pros and cons](pros-and-cons.md) 17 | 1. [How to hack Python projects](how-to-hack-python-projects.md) 18 | 1. Meta 19 | 1. [test](test) 20 | 1. Language 21 | 1. [Functions](function.py) 22 | 1. [lambda](lambda.py) 23 | 1. [keyword-only argument](keyword_only.py) 24 | 1. [Built-in functions](builtin_functions.py) 25 | 1. [class](class.py) 26 | 1. [Special methods](special_methods.py) 27 | 1. [__slots__](slots.py) 28 | 1. [issubclass](issubclass.py) 29 | 1. [__class__](class_attribute.py) 30 | 1. [Exception](exception.py) 31 | 1. [Decorator](decorator.py) 32 | 1. [Exception](exception.py) 33 | 1. [Iterator](iterator.py) 34 | 1. Data types 35 | 1. Built-in types 36 | 1. [Number](number.py) 37 | 1. [dict](dict_cheat.py) 38 | 1. [frozenset](frozenset.py) 39 | 1. [list](list.py) 40 | 1. [set](set.py) 41 | 1. [String](string_cheat.py) 42 | 1. [format()](format_method.py) 43 | 1. [Format operator %](format_operator.py) 44 | 1. [tuple](tuple.py) 45 | 1. [Multi-file operations](multifile/): `import`, modules, `imp` 46 | 1. [import_cheat](import_cheat/) 47 | 1. [Operators](operators.py) 48 | 1. [Python 3](python3/) 49 | 1. Cross-language 50 | 1. [C from Python](c_from_py/) 51 | 1. [Python from C](py_from_c/) 52 | 1. [py_from_c/eval.c](py_from_c/eval.c) 53 | 1. Pure embedding 54 | 1. [pure.py](pure.py) 55 | 1. [pure.c](pure.c) 56 | 1. [py_from_c/test](py_from_c/test) 57 | 1. Standard library 58 | 1. [argparse](argparse_cheat.py) 59 | 1. [bisect](bisect_cheat.py) 60 | 1. [collections](collections_cheat.py) 61 | 1. curses 62 | 1. [curses/collision.py](curses/collision.py) 63 | 1. [datetime](datetime_cheat.py) 64 | 1. [expat](expat_cheat.py) 65 | 1. [fileinput](fileinput/) 66 | 1. [logging](logging_cheat.py) 67 | 1. [math](math_cheat.py) 68 | 1. [optparse](optparse_cheat.py) 69 | 1. [os](os_cheat.py) 70 | 1. [environ](environ.py) 71 | 1. [path](path_cheat.py) 72 | 1. [pickle](pickle_cheat.py) 73 | 1. [random](random_cheat.py) 74 | 1. [re](re_cheat.py) 75 | 1. [sqlite3](sqlite3.py) 76 | 1. [sys](sys_cheat.py) 77 | 1. [tempfile](tempfile_cheat.py) 78 | 1. [termcolor](termcolor_cheat.py) 79 | 1. [time](time_cheat.py) 80 | 1. [tk](tk.py) 81 | 1. [unittest](unittest_cheat.py) 82 | 1. Networking 83 | 1. [SimpleHTTPServer](simplehttpserver_cheat.py) 84 | 1. [smtplib](smtplib_cheat.py) 85 | 1. [urllib2](urllib2_cheat.py) 86 | 1. [wsgi](wsgi.py) 87 | 1. Multi-thread 88 | 1. [subprocess](subprocess_cheat/) 89 | 1. [Multi threading hello world](thread_hello.py) 90 | 1. [Multi threading adder](thread_add.py) 91 | 1. [Thread CPU bound vs IO bound](thread_cpu_bound.py) 92 | 1. [Limit the number of threads](thread_limit.py) 93 | 1. concurrent 94 | 1. [concurrent map](concurrent_map.py) 95 | 1. [concurrent map exception](concurrent_map_exception.py) 96 | 1. [concurrent submit](concurrent_submit.py) 97 | 98 | 1. Third party 99 | 1. Pexpect 100 | 1. [pexpect/python_test.py](pexpect/python_test.py) 101 | 1. [pip](pip.md) 102 | 1. [sphinx](sphinx/) 103 | 1. [trac](trac.md) 104 | 1. [urllib2](urllib2_cheat.py) 105 | 1. [virtualenv](virtualenv/) 106 | 1. [waf](waf/) 107 | 1. [wsgi](wsgi.py) 108 | 1. Scientific 109 | 1. [NumPy](numpy_cheat.py) 110 | 1. [SciPy](scipy_cheat.py) 111 | 1. [SimPy](simpy_cheat.py) 112 | 1. [matplotlib](matplotlib.md). Moving to https://cirosantilli.com#matplotlib 113 | 1. [jupyter](jupyter/) 114 | 1. [pandas](pandas_cheat.py) 115 | 1. [h5py](h5py_cheat.py) HDF5 116 | 1. [Interactive friendly](interactive-friendly.md) 117 | 1. [ipython](ipython.ipy) 118 | 1. Packaging 119 | 1. [distutils](distutils_cheat/) 120 | 1. [setuptools](setuptools_cheat/) 121 | 1. [Bibliography](bibliography.md) 122 | 1. [CONTRIBUTING](CONTRIBUTING.md) 123 | -------------------------------------------------------------------------------- /bibliography.md: -------------------------------------------------------------------------------- 1 | # Bibliography 2 | 3 | - 4 | 5 | Good beginners tutorial. 6 | 7 | - 8 | 9 | Explains Python types in detail. 10 | -------------------------------------------------------------------------------- /bisect_cheat.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | import bisect 4 | 5 | # Insert into sorted list. 6 | # https://stackoverflow.com/questions/8024571/insert-an-item-into-sorted-list-in-python 7 | 8 | l = [0, 2, 4] 9 | bisect.insort_left(l, 1) 10 | assert l == [0, 1, 2, 4] 11 | 12 | # Find in sorted list. 13 | # bisect_left gives the position at which insertion would keep the list sorted. 14 | 15 | l = [0, 0, 2] 16 | assert bisect.bisect_left(l, -1) == 0 17 | assert bisect.bisect_left(l, 0) == 0 18 | assert bisect.bisect_left(l, 1) == 2 19 | assert bisect.bisect_left(l, 2) == 2 20 | assert bisect.bisect_left(l, 3) == 3 21 | 22 | assert bisect.bisect_right(l, -1) == 0 23 | assert bisect.bisect_right(l, 0) == 2 24 | assert bisect.bisect_right(l, 1) == 2 25 | assert bisect.bisect_right(l, 2) == 3 26 | 27 | # Slice sorted list. 28 | # https://stackoverflow.com/questions/13631720/python-optimized-method-of-cutting-slicing-sorted-lists/47477642#47477642 29 | 30 | def get_slice(list_, left, right): 31 | return list_[bisect.bisect_left(list_, left):bisect.bisect_left(list_, right)] 32 | assert get_slice([0, 1, 1, 3, 4, 4, 5, 6], 1, 5) == [1, 1, 3, 4, 4] 33 | -------------------------------------------------------------------------------- /builtin_functions.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | # https://docs.python.org/3/library/functions.html#sorted 4 | 5 | if 'sorted': 6 | strings = ['b.2', 'a.12', 'c.1'] 7 | assert sorted(['b.2', 'a.12', 'c.1'], key=lambda x: int(x.split('.')[1])) \ 8 | == ['c.1', 'b.2', 'a.12'] 9 | -------------------------------------------------------------------------------- /c_from_py/Makefile: -------------------------------------------------------------------------------- 1 | .POSIX: 2 | 3 | CFLGS := -Wall 4 | CNAME := ctypes_cheat 5 | 6 | .PHONY: clean 7 | 8 | lib$(CNAME).so: $(CNAME).c 9 | gcc $(CFLGS) -fPIC -c "$<" -o $(CNAME).o 10 | gcc $(CFLGS) -shared '$(CNAME).o' -o "$@" 11 | 12 | clean: 13 | rm -rf *.o *.so 14 | -------------------------------------------------------------------------------- /c_from_py/README.md: -------------------------------------------------------------------------------- 1 | # C from Python 2 | 3 | This dir shows how to call C functions from Python on Linux. 4 | 5 | This is called "extending Python with C", and is documented at: 6 | 7 | * https://stackoverflow.com/questions/145270/calling-c-c-from-python 8 | * https://docs.python.org/2/extending/extending.html 9 | 10 | Examples: 11 | 12 | - [cpython_cheat.c](cpython_cheat.c) and [cpython_cheat.py](cpython_cheat.py) demonstrate the usage of the Python standard library's `cpython` module. 13 | 14 | Notice how that module allows importing completely unmodified C functionality from a `.so` shared library into Python without any Python specifics to it. 15 | 16 | [cpython_cheat_relative.py](cpython_cheat_relative.py) imports the library with a relative path, and can be used to see that `LD_LIBRARY_PATH` is used to find the `.so`. 17 | 18 | - TODO [import_cheat.c](import_cheat.c) and [import_cheat.py](import_cheat.py) show that `.so` libraries can also be imported directly with the `import` statement. 19 | 20 | However, those libraries must contain Python specifics such as defining the init module function. 21 | 22 | The `PYTHONPATH` is used when searching for the `.so` files with `import` instead of `LD_LIBRARY_PATH`. 23 | 24 | See also: 25 | -------------------------------------------------------------------------------- /c_from_py/ctypes_cheat.c: -------------------------------------------------------------------------------- 1 | int f(int i, float f) { 2 | return i + f; 3 | } 4 | -------------------------------------------------------------------------------- /c_from_py/ctypes_cheat.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | import ctypes 4 | import os 5 | 6 | libctypes_cheat = ctypes.CDLL(os.path.join(os.path.split(os.path.realpath(__file__))[0], 'libctypes_cheat.so')) 7 | # Knows how to convert integers, but not floats. 8 | assert libctypes_cheat.f(1, ctypes.c_float(1.0)) == 2 9 | # Same as above, but more explicit. 10 | assert libctypes_cheat.f(ctypes.c_int(1), ctypes.c_float(1.0)) == 2 11 | 12 | # Standard library test. 13 | libc = ctypes.CDLL('libc.so.6') 14 | assert libc.strlen('abcde') == 5 15 | -------------------------------------------------------------------------------- /c_from_py/ctypes_cheat_relative.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | import ctypes 3 | libctypes_cheat = ctypes.CDLL('libctypes_cheat.so') 4 | assert libctypes_cheat.f(ctypes.c_int(1), ctypes.c_float(1.0)) == 2 5 | -------------------------------------------------------------------------------- /c_from_py/import_cheat.c: -------------------------------------------------------------------------------- 1 | /* TODO */ 2 | -------------------------------------------------------------------------------- /c_from_py/import_cheat.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | try: 4 | # ImportError: dynamic module does not define init function (initlibctypes_cheat) 5 | import libctypes_cheat 6 | except: 7 | pass 8 | else: 9 | assert False 10 | 11 | # TODO 12 | #import libimport_cheat 13 | # assert libimport_cheat.f(1, ctypes.c_float(1.0)) == 2 14 | -------------------------------------------------------------------------------- /c_from_py/test: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | set -eu 3 | ./ctypes_cheat.py 4 | LD_LIBRARY_PATH=. ./ctypes_cheat_relative.py 5 | ./import_cheat.py 6 | -------------------------------------------------------------------------------- /class_attribute.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | ''' 4 | # __class__ 5 | 6 | The only difference from `type()` seems to be for old style classes: 7 | http://stackoverflow.com/questions/1060499/difference-between-typeobj-and-obj-class 8 | Therefore, there is no difference in Python 3. 9 | ''' 10 | 11 | assert object.__class__ == type 12 | assert (1).__class__ == int 13 | 14 | ''' 15 | `__class__` can be set to something else however. 16 | 17 | This seems to have no special effect. 18 | ''' 19 | 20 | class D(): pass 21 | 22 | class C(): 23 | __class__ = D 24 | 25 | assert type(C()) == C 26 | assert C().__class__ == D 27 | 28 | ''' 29 | __class__ and inheritance: self determines class. 30 | ''' 31 | 32 | class C: 33 | def get_class(self): 34 | return self.__class__ 35 | 36 | class D(C): 37 | def get_class_2(self): 38 | return self.get_class() 39 | 40 | assert C().get_class() == C 41 | assert D().get_class() == D 42 | assert D().get_class_2() == D 43 | -------------------------------------------------------------------------------- /collections_cheat.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | import collections 4 | 5 | if 'OrderedDict': 6 | 7 | # Ordered by insertion order, not natural key order. 8 | 9 | d = collections.OrderedDict() 10 | d[1] = 2 11 | d[0] = 0 12 | d[2] = 1 13 | 14 | # Iteration. 15 | i = iter(d) 16 | assert(next(i) == 1) 17 | assert(next(i) == 0) 18 | assert(next(i) == 2) 19 | 20 | # Other built-in methods. 21 | assert d.keys() == [1, 0, 2] 22 | assert d.items() == [(1, 2), (0, 0), (2, 1)] 23 | -------------------------------------------------------------------------------- /concurrent_map.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | ''' 4 | Extremely likely outcome: 5 | 6 | [sleep 1] 7 | 1 8 | 1 2 9 | [sleep 1] 10 | 2 11 | [sleep 2] 12 | 4 13 | 4 5 14 | 2 3 15 | 16 | Interpretation: 17 | 18 | - like map(), the return order is fixed and matches the input 19 | 20 | - threads run in parallel, runtime is just 4 seconds 21 | 22 | All threads started running immediately from beginning. 23 | 24 | - threads return immediately when done, but only in order. 25 | 26 | If something slow comes up, e.g. the 4s wait, the following 27 | ones only return when that is done. 28 | ''' 29 | 30 | import concurrent.futures 31 | import time 32 | 33 | ints = [1, 4, 2] 34 | 35 | def myfunc(i): 36 | time.sleep(i) 37 | print(i) 38 | return i + 1 39 | 40 | with concurrent.futures.ProcessPoolExecutor() as executor: 41 | for input, output in zip(ints, executor.map(myfunc, ints)): 42 | print('{} {}'.format(input, output)) 43 | -------------------------------------------------------------------------------- /concurrent_map_exception.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | ''' 4 | https://stackoverflow.com/questions/19369724/the-right-way-to-limit-maximum-number-of-threads-running-at-once/55263676#55263676 5 | 6 | Usage: 7 | 8 | ./concurrent_map_exception.py [nproc [min [max]] 9 | 10 | e.g.: 11 | 12 | ./concurrent_map_exception.py 2 -10 100 13 | 14 | Outcome: 15 | 16 | - all input is read immediately 17 | - iteration stops on exception 18 | ''' 19 | 20 | import concurrent.futures 21 | import sys 22 | import time 23 | 24 | def my_func(i): 25 | time.sleep((abs(i) % 4) / 10.0) 26 | return 10.0 / i 27 | 28 | def my_get_work(min_, max_): 29 | for i in range(min_, max_): 30 | print('my_get_work: {}'.format(i)) 31 | yield i 32 | 33 | # CLI. 34 | argv_len = len(sys.argv) 35 | if argv_len > 1: 36 | nthreads = int(sys.argv[1]) 37 | if nthreads == 0: 38 | nthreads = None 39 | else: 40 | nthreads = None 41 | if argv_len > 2: 42 | min_ = int(sys.argv[2]) 43 | else: 44 | min_ = 1 45 | if argv_len > 3: 46 | max_ = int(sys.argv[3]) 47 | else: 48 | max_ = 100 49 | 50 | # Action. 51 | with concurrent.futures.ProcessPoolExecutor(max_workers=nthreads) as executor: 52 | for input, output in zip( 53 | my_get_work(min_, max_), 54 | executor.map(my_func, my_get_work(min_, max_)) 55 | ): 56 | print('result: {} {}'.format(input, output)) 57 | -------------------------------------------------------------------------------- /concurrent_submit.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | ''' 4 | Outcome: 5 | 6 | [sleep 1] 7 | 1 8 | [sleep 1] 9 | 2 10 | [sleep 2] 11 | 4 12 | 2 13 | 5 14 | 3 15 | ''' 16 | 17 | import concurrent.futures 18 | import time 19 | 20 | ints = [1, 4, 2] 21 | 22 | def myfunc(i): 23 | time.sleep(i) 24 | print(i) 25 | return i + 1 26 | 27 | futures = [] 28 | with concurrent.futures.ProcessPoolExecutor() as executor: 29 | for i in ints: 30 | futures.append(executor.submit(myfunc, i)) 31 | for future in futures: 32 | print(future.result()) 33 | -------------------------------------------------------------------------------- /configure: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | set -ex 3 | sudo apt-get update 4 | sudo apt-get install -y \ 5 | gfortran \ 6 | libblas-dev \ 7 | libfreetype6-dev \ 8 | liblapack-dev \ 9 | libpng-dev \ 10 | python-dev \ 11 | virtualenv \ 12 | ; 13 | # --distribute: http://stackoverflow.com/questions/35780537/error-no-module-named-markerlib-when-installing-some-packages-on-virtualenv 14 | virtualenv -p python2.7 .venv --distribute 15 | . .venv/bin/activate 16 | python -m pip install -r requirements.txt 17 | 18 | # TODO Last case resort if you can't install something with pip. 19 | #sudo apt-get install -y python-pip 20 | #sudo apt-get install -y python-scipy 21 | #sudo apt-get install -y python-matplotlib 22 | #sudo apt-get install -y python-sip 23 | ## Update NumPy version 24 | #sudo pip install -y numpy 25 | -------------------------------------------------------------------------------- /csv_cheat.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | import StringIO 4 | import csv 5 | import itertools 6 | 7 | if '## reader basic example': 8 | 9 | """ 10 | Takes anything that can be iterated linewise, e.g. file. 11 | But here we use arrays to mimize. 12 | 13 | Returns another iterator, but over lists. 14 | """ 15 | 16 | assert list(csv.reader(['1,2', '3,4'])) == [['1', '2'], ['3', '4']] 17 | 18 | if '## writer': 19 | 20 | """ 21 | No, not the inverse of the reader. 22 | First argument must have the write() method. 23 | """ 24 | 25 | rows = [['1', '2'], ['3', '4']] 26 | sio = StringIO.StringIO() 27 | csv_writer = csv.writer(sio, lineterminator='\n') 28 | for row in rows: 29 | csv_writer.writerow(row) 30 | assert sio.getvalue() == '1,2\n3,4\n' 31 | sio.close() 32 | 33 | if '## Escaping': 34 | # Escape the comma. 35 | assert list(csv.reader(['","'])) == [[',']] 36 | # Escape the quote. 37 | assert list(csv.reader(['"\""'])) == [['"']] 38 | # Escaped quotes must be quoted. 39 | assert list(csv.reader(['\"'])) == [['']] 40 | 41 | if '## DictReader': 42 | 43 | assert (list(csv.DictReader(['a,b', '1,2', '3,4'])) == 44 | [{'a': '1', 'b': '2'}, {'a': '3', 'b': '4'}]) 45 | assert (list(csv.DictReader(['1,2', '3,4'], fieldnames=['a', 'b'])) == 46 | [{'a': '1', 'b': '2'}, {'a': '3', 'b': '4'}]) 47 | 48 | if '## Ignore comment lines starting with #': 49 | 50 | # http://stackoverflow.com/questions/14158868/python-skip-comment-lines-marked-with-in-csv-dictreader 51 | 52 | assert (list(csv.reader(itertools.ifilter( 53 | lambda row: row[0] != '#', 54 | ['1,2', '#3,4', '5,6']))) == 55 | [['1', '2'], ['5', '6']]) 56 | assert (list(csv.reader(itertools.ifilter( 57 | lambda row: row[0] != '#', 58 | ['1,2', '"#3",4', '5,6']))) == 59 | [['1', '2'], ['#3', '4'], ['5', '6']]) 60 | -------------------------------------------------------------------------------- /curses_cheat/collision.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | 4 | """ 5 | Simple collision detection curses game. 6 | """ 7 | 8 | import curses 9 | import math 10 | import random 11 | 12 | debug = True 13 | #debug = False 14 | exit_msg = '' 15 | 16 | # Global model params: 17 | width = 70 18 | height = 20 19 | # Fraction of the screen that will be occupied by obstacles: 20 | obstacle_frac = 0.3 21 | 22 | # Initial state: 23 | posx = 1 24 | posy = 1 25 | obstacles = set() 26 | obstacles.add((posx,posy)) 27 | for x in xrange(0, width): 28 | obstacles.add((x,0)) 29 | obstacles.add((x,height)) 30 | for y in xrange(0, height): 31 | obstacles.add((0,y)) 32 | obstacles.add((width,y)) 33 | # Add random obstacles: 34 | n_obstacles = math.floor(width * height * obstacle_frac) 35 | while len (obstacles) < n_obstacles: 36 | randx = random.randint(0, width) 37 | randy = random.randint(0, height) 38 | obstacles.add((randx, randy)) 39 | 40 | def init(screen): 41 | """ 42 | Startup functions that make the terminal work like a GUI app. 43 | """ 44 | screen.border(0) 45 | screen.clear() 46 | curses.noecho() 47 | curses.cbreak() 48 | screen.keypad(1) 49 | curses.curs_set(0) 50 | 51 | def cleanup(screen): 52 | """ 53 | Cleanup actions in case of an exception (e.g. KeyboardInterrupt), 54 | or terminal may be left in a messy state. 55 | """ 56 | curses.nocbreak() 57 | screen.keypad(0) 58 | curses.echo() 59 | curses.endwin() 60 | curses.curs_set(1) 61 | 62 | def can_move(posx,posy,newposx,newposy): 63 | global obstacles 64 | if not (newposx,newposy) in obstacles: 65 | return True 66 | else: 67 | return False 68 | 69 | def main(screen): 70 | global posx, posy, width, height, obstacles, exit_msg, debug 71 | newposx = posx 72 | newposy = posy 73 | while 1: 74 | # Get window width and height: 75 | maxy, maxx = screen.getmaxyx() 76 | maxy = maxy - 1 77 | maxx = maxx - 1 78 | if width > maxx or height > maxy: 79 | exit_msg = "your terminal is too small\nrequired size: %d x %d\nactual size: %d %d" % (width, height, maxx, maxy) 80 | break 81 | 82 | # Clear screen: 83 | for y in xrange(maxy): 84 | screen.addstr(y, 0, maxx * ' ', curses.color_pair(1)) 85 | 86 | # Draw scene: 87 | for obs in obstacles: 88 | screen.addstr(obs[1], obs[0], '#', curses.color_pair(4)) 89 | screen.addstr(posy, posx, '@', curses.color_pair(3)) 90 | 91 | # Print messages; 92 | screen.addstr(height + 2, 0, "You: '@', obstacles: '#'. Move: 'ASDW'. Quit: 'Q'", curses.color_pair(2)) 93 | if debug: 94 | screen.addstr(height + 4, 0, "pos: {} {} newpos: {} {}".format(posx,posy,newposx,newposy), curses.color_pair(2)) 95 | 96 | # Wait for user to input a character: 97 | c = screen.getch() 98 | if c == ord('a'): 99 | # Left 100 | newposx = posx - 1 101 | newposy = posy 102 | elif c == ord('d'): 103 | # Right 104 | newposx = posx + 1 105 | newposy = posy 106 | elif c == ord('q'): 107 | # Quit 108 | exit_msg = 'quit' 109 | break 110 | elif c == ord('s'): 111 | # Down 112 | newposx = posx 113 | newposy = posy + 1 114 | elif c == ord('w'): 115 | # Up 116 | newposx = posx 117 | newposy = posy - 1 118 | elif c == curses.KEY_HOME: 119 | newposx = 0 120 | newposy = 0 121 | if can_move(posx, posy, newposx, newposy): 122 | posx = newposx 123 | posy = newposy 124 | 125 | if __name__ == "__main__": 126 | try: 127 | screen = curses.initscr() 128 | curses.start_color() 129 | curses.init_pair(1, curses.COLOR_BLACK, curses.COLOR_BLACK) 130 | curses.init_pair(2, curses.COLOR_WHITE, curses.COLOR_BLACK) 131 | curses.init_pair(3, curses.COLOR_RED, curses.COLOR_BLACK) 132 | curses.init_pair(4, curses.COLOR_YELLOW, curses.COLOR_BLACK) 133 | init(screen) 134 | curses.wrapper(main) 135 | except KeyboardInterrupt: 136 | print "interrupt" 137 | except Exception, e: 138 | print e 139 | finally: 140 | cleanup(screen) 141 | if exit_msg: 142 | print exit_msg 143 | -------------------------------------------------------------------------------- /datetime_cheat.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | """ 4 | ## datetime 5 | 6 | Year month day minute sec milisec oriented time operations. 7 | """ 8 | 9 | import datetime 10 | 11 | if '## datetime': 12 | 13 | now = datetime.datetime.now() 14 | print('now = ' + str(now)) 15 | print('now.tzinfor = ' + str(now.tzinfo)) 16 | 17 | # Get a datetime from a seconds since Epoch. 18 | # This is first passed to your timezone by default, 19 | # since timestamps are usually absolute, but datetimes are relative. 20 | # So it is likely to be 1970-01-01 offset by a few hours. 21 | print('fromtimestamp(0) = ' + str(datetime.datetime.fromtimestamp(0))) 22 | 23 | # This is guaranteed to be 1970-01-01 24 | print('utcfromtimestamp(0) = ' + str(datetime.datetime.utcfromtimestamp(0))) 25 | 26 | if 'Applications': 27 | 28 | if '# Midnight': 29 | 30 | # http://stackoverflow.com/questions/8361099/django-python-date-time-set-to-midnight 31 | 32 | today_midnight = datetime.datetime(year=now.year, month=now.month, day=now.day) 33 | tomorrow_midnight = today_midnight + datetime.timedelta(days=1) 34 | print('today midnight = ' + str(today_midnight)) 35 | print('tomorrow midnight = ' + str(tomorrow_midnight)) 36 | 37 | if 'UTC': 38 | 39 | print('utcnow = ' + str(datetime.datetime.utcnow())) 40 | assert type(datetime.datetime.utcnow()) == datetime.datetime 41 | 42 | if '## date': 43 | 44 | # Only up to day precision. 45 | 46 | print('today = ' + str(datetime.date.today())) 47 | 48 | # From datetime (OK, this assert *could* fail 49 | # if you're into learning Python at midnight): 50 | 51 | assert datetime.date.today() == datetime.datetime.now().date() 52 | 53 | # UTC today: 54 | # http://stackoverflow.com/questions/27587127/convert-datetime-date-today-to-utc-time 55 | # convert from utcnow. 56 | 57 | # How many days between two dates: 58 | 59 | assert (datetime.date(2000, 2, 1) - datetime.date(2000, 1, 1,)).days == 31 60 | 61 | if '## timedelta': 62 | 63 | # Time differences are of timedelta class. 64 | 65 | diff = now - now 66 | assert type(diff) == datetime.timedelta 67 | assert diff == datetime.timedelta() 68 | 69 | # One day. 70 | 71 | date = datetime.datetime(2000, 1, 2) 72 | assert date + datetime.timedelta(1) == datetime.datetime(2000, 1, 3) 73 | 74 | print('timedelta full costructor = ' + str(datetime.timedelta( 75 | # Not possible: 76 | #years = 1, 77 | #months = 1, 78 | weeks = 2, 79 | days = 3, 80 | hours = 4, 81 | minutes = 5, 82 | seconds = 6, 83 | milliseconds = 7, 84 | microseconds = 8 85 | ))) 86 | 87 | if '## naive ## offset': 88 | 89 | """ 90 | TODO. create one of each. 91 | """ 92 | -------------------------------------------------------------------------------- /decorator_cheat.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | """ 4 | ## decorator 5 | 6 | Decorators are syntaxical sugar syntax that allows to write functions or classes in the forms: 7 | 8 | @decorator 9 | def f(): 10 | pass 11 | 12 | @decorator 13 | class C: 14 | pass 15 | 16 | Where `decorator` is any callable such as a function of a class that implements `__call__`. 17 | 18 | They are documented together with function and class definition syntax. 19 | """ 20 | 21 | if 'Create a function based function decorator': 22 | 23 | def decorator(func): 24 | def wrapper(i, *args, **kwargs): 25 | return func(i, *args, **kwargs) + 1 26 | return wrapper 27 | 28 | # Decorator sugar 29 | 30 | @decorator 31 | def f(i): 32 | return i 33 | 34 | assert f(1) == 2 35 | 36 | # Exact same but without decorator sugar: 37 | 38 | def f(i): 39 | return i 40 | 41 | decorated = decorator(f) 42 | assert decorated(1) == 2 43 | 44 | if 'Multiple decorators': 45 | 46 | def decorator(func): 47 | def wrapped(i): 48 | return func(i) + 2 49 | return wrapped 50 | 51 | def decorator2(func): 52 | def wrapped(i): 53 | return func(i) * 2 54 | return wrapped 55 | 56 | @decorator 57 | @decorator2 58 | def f(i): 59 | return i 60 | 61 | assert f(0) == 2 62 | 63 | if 'Create a callable class based function decorator': 64 | 65 | class Decorator: 66 | def __init__(self, j): 67 | self.j = j 68 | 69 | def __call__(self, func): 70 | def wrapper(i, *args, **kwargs): 71 | return func(i, *args, **kwargs) + self.j 72 | return wrapper 73 | 74 | # Decorator sugar 75 | 76 | @Decorator(2) 77 | def f(i): 78 | return i 79 | 80 | assert f(1) == 3 81 | 82 | if 'Create a function based ## class decorator': 83 | 84 | def decorator(cls): 85 | def f(self): 86 | return 1 87 | cls.f = f 88 | return cls 89 | 90 | @decorator 91 | class C(object): 92 | pass 93 | 94 | assert C().f() == 1 95 | 96 | if 'It is only possible to decorate functions or classes, not variables.': 97 | 98 | def d(): 99 | pass 100 | #@d #SyntaxError 101 | a = 1 102 | 103 | if 'Decorators can take multiple arguments.': 104 | 105 | def decorator(func, j): 106 | def wrapper(i, *args, **kwargs): 107 | return func(i, *args, **kwargs) + j 108 | return wrapper 109 | 110 | # Decorator sugar 111 | 112 | #@decorator 113 | def f(i): 114 | return i 115 | 116 | # TODO get working 117 | #assert f(1) == 3 118 | 119 | if 'Decorator must take at least one argument to not raise a TypeError.': 120 | 121 | def d(): 122 | pass 123 | try: 124 | @d 125 | def f(): 126 | pass 127 | except TypeError: 128 | pass 129 | else: 130 | assert False 131 | 132 | if 'Decorator functions of __call__ methods must take at exactly one argument.': 133 | 134 | """ 135 | If you want to pass parameters to a decorator, make a class based decorator 136 | and use its __init__ method for the arguments. 137 | """ 138 | 139 | # Direct function approach fails. 140 | 141 | def decorator(func, j): 142 | def wrapper(i, *args, **kwargs): 143 | return func(i, *args, **kwargs) + j 144 | return wrapper 145 | 146 | try: 147 | @decorator(2) 148 | def f(i): 149 | return i 150 | except TypeError: 151 | pass 152 | else: 153 | assert False 154 | 155 | if 'The decorator call is only made at function / class definition.': 156 | 157 | def decorator(func): 158 | global i 159 | i += 1 160 | def wrapper(*args, **kwargs): 161 | pass 162 | return wrapper 163 | 164 | i = 0 165 | @decorator 166 | def f(): 167 | pass 168 | assert i == 1 169 | f() 170 | assert i == 1 171 | 172 | if 'Decorators can return anything.': 173 | 174 | def d(g): 175 | return 1 176 | 177 | @d 178 | def f(): 179 | pass 180 | 181 | assert f == 1 182 | 183 | -------------------------------------------------------------------------------- /dict_cheat.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | """ 4 | ## dict 5 | 6 | ## Map 7 | 8 | Unordered map of hashable keys and to values of any type. 9 | """ 10 | 11 | if '## create': 12 | 13 | # Built-in constructor syntax: 14 | 15 | d = {1: 'a', 'b': 2, 1.1: 2} 16 | 17 | # Global factory function. 18 | 19 | # From list of pairs: 20 | 21 | assert dict([(0, 'zero'), (1, 'one')]) == {0: 'zero', 1: 'one'} 22 | 23 | # From kwargs (keys can only be strings): 24 | 25 | assert dict(zero=0, one=1) == {'zero': 0, 'one': 1} 26 | 27 | # dict comprehension: 28 | 29 | assert {key: value for (key, value) in [(1, 2), (3, 4)]} == {1: 2, 3: 4} 30 | 31 | # Keys must be hashable. This excludes all mutable built-in types like lists. 32 | 33 | try: 34 | d = {[1]: 2} 35 | except TypeError: 36 | pass 37 | else: 38 | assert False 39 | 40 | if '## fromkeys': 41 | 42 | # 43 | 44 | # Create a dictionary with keys from a list, and a single value. 45 | 46 | # `dict` here is the `dict` type. 47 | 48 | assert dict.fromkeys([1, 2, 3]) == {1: None, 2: None, 3: None} 49 | assert dict.fromkeys([1, 2, 3], 0) == {1: 0, 2: 0, 3: 0} 50 | 51 | # Note however that this is not usually what you want for mutable objects: 52 | # http://stackoverflow.com/questions/8174723/dictionary-creation-with-fromkeys-and-mutable-objects-a-surprise 53 | 54 | # To list of pairs: 55 | 56 | d = {1: 'one', 2: 'two'} 57 | assert set(d.items()) == set([(1, 'one'), (2, 'two')]) 58 | 59 | # Get list of keys (undefined order) 60 | 61 | d = {1: 'one', 2: 'two'} 62 | assert set(d.keys()) == set([1, 2]) 63 | 64 | # Why a list is returned by keys() instead of set(): 65 | # http://stackoverflow.com/questions/13886129/why-does-pythons-dict-keys-return-a-list-and-not-a-set 66 | # set() didn't exist yet! 67 | 68 | # Get value of key: 69 | 70 | d = {1: 'one', 2: 'two'} 71 | assert d[1] == 'one' 72 | 73 | # Access one arbitrary element from dict. 74 | # https://stackoverflow.com/questions/3097866/access-an-arbitrary-element-in-a-dictionary-in-python 75 | d = {1:2} 76 | assert next(iter(d)) == 1 77 | assert next(iter(d.values())) == 2 78 | 79 | # If not in dict, `KeyError` exception: 80 | 81 | d = {} 82 | try: 83 | d['not-a-key'] 84 | except KeyError: 85 | pass 86 | else: 87 | assert False 88 | 89 | # Check if key is in dict: 90 | 91 | d = {1: 2} 92 | 93 | if 1 in d: 94 | pass 95 | else: 96 | assert False 97 | 98 | if 2 in d: 99 | assert False 100 | 101 | # Get default value if not present: 102 | 103 | assert d.get('not-a-key', 'default value') == 'default value' 104 | 105 | # Add new pair: 106 | 107 | d= {} 108 | d[0] = 'zero' 109 | assert d == {0: 'zero'} 110 | 111 | # Remove pair: 112 | 113 | d= {0: 'zero'} 114 | del d[0] 115 | 116 | # If key not present, KeyError: 117 | 118 | try: 119 | del d[0] 120 | except KeyError: 121 | pass 122 | else: 123 | assert False 124 | 125 | # Add new pair if key not present: 126 | 127 | d = {1: 2} 128 | assert d.setdefault(1, 3) == 2 129 | assert d == {1: 2} 130 | 131 | d = {} 132 | assert d.setdefault(1, 3) == 3 133 | assert d == {1: 3} 134 | 135 | if '## update': 136 | 137 | # https://stackoverflow.com/questions/577234/python-extend-for-a-dictionary 138 | 139 | # Add update all keys on d0 with those of d1: 140 | 141 | d0 = {0: 'zero', 1: 'one'} 142 | d1 = {0: 'zero2', 2: 'two'} 143 | assert d0.update(d1) is None 144 | assert d0 == {0: 'zero2', 1: 'one', 2: 'two'} 145 | 146 | # Create a new dict that is the union of two other dicts: 147 | 148 | d0 = {0: 'zero', 1: 'one'} 149 | d1 = {0: 'zero2', 2: 'two'} 150 | d01 = d0.copy() 151 | assert d01.update(d1) is None 152 | assert d01 == {0: 'zero2', 1: 'one', 2: 'two'} 153 | 154 | if 'Iterate / loop over dict': 155 | 156 | # Unspecified order. Python 3 has `collections.OrderedDict` (backported to 2.7). 157 | 158 | # Keys only. 159 | assert sorted([i for i in {1:-1, 2:-2}]) == [1, 2] 160 | 161 | # Keys value pairs with iteritems. 162 | assert sorted([(i,j) for i,j in {1:-1, 2:-2}.items()]) == [(1, -1), (2, -2)] 163 | 164 | if '## filter': 165 | 166 | """ 167 | Only keys in a list: 168 | http://stackoverflow.com/questions/6827834/how-to-filter-a-dict-to-contain-only-keys-in-a-given-list 169 | 170 | Arbitrary function: 171 | http://stackoverflow.com/questions/2844516/python-filter-a-dictionary 172 | 173 | Comprehensions are the only way it seems. 174 | """ 175 | -------------------------------------------------------------------------------- /distutils_cheat/README.md: -------------------------------------------------------------------------------- 1 | # distutils 2 | 3 | For each directory, do: 4 | 5 | # Fails because package not found, since the import 6 | # is on a different directory ("package"). 7 | python test.py 8 | 9 | cd package 10 | python package/setup.py install --user 11 | 12 | # Works, using the installed version. 13 | cd .. 14 | python test.py 15 | 16 | # Cleanup 17 | # http://stackoverflow.com/questions/402359/how-do-you-uninstall-a-python-package-that-was-installed-using-distutils/43650802#43650802 18 | rm -rf files.txt 19 | sudo python setup.py install --record files.txt 20 | xargs sudo rm -rf < files.txt 21 | rm -rf files.txt 22 | 23 | # Fails again. 24 | python test.py 25 | 26 | 1. [min](min/) 27 | 1. [script](script/) 28 | -------------------------------------------------------------------------------- /distutils_cheat/min/package/README.md: -------------------------------------------------------------------------------- 1 | # min 2 | 3 | Minimal sane package. 4 | -------------------------------------------------------------------------------- /distutils_cheat/min/package/python_cheat_min.py: -------------------------------------------------------------------------------- 1 | x = 1 2 | -------------------------------------------------------------------------------- /distutils_cheat/min/package/setup.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | from distutils.core import setup 3 | setup( 4 | name='python_cheat_min', 5 | py_modules=['python_cheat_min'], 6 | version='1.0', 7 | ) 8 | -------------------------------------------------------------------------------- /distutils_cheat/min/test.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | from python_cheat_min import x 3 | assert x == 1 4 | -------------------------------------------------------------------------------- /distutils_cheat/script/package/README.md: -------------------------------------------------------------------------------- 1 | # script 2 | 3 | Install a script to the path, that uses the installed library. 4 | -------------------------------------------------------------------------------- /distutils_cheat/script/package/python_cheat_min.py: -------------------------------------------------------------------------------- 1 | x = 1 2 | -------------------------------------------------------------------------------- /distutils_cheat/script/package/python_cheat_script.py: -------------------------------------------------------------------------------- 1 | x = 1 2 | -------------------------------------------------------------------------------- /distutils_cheat/script/package/python_cheat_script_script.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | from python_cheat_script import x 3 | assert x == 1 4 | -------------------------------------------------------------------------------- /distutils_cheat/script/package/setup.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | from distutils.core import setup 3 | setup( 4 | name='python_cheat_script', 5 | py_modules=['python_cheat_script'], 6 | scripts=['python_cheat_script_script.py'], 7 | version='1.0', 8 | ) 9 | -------------------------------------------------------------------------------- /distutils_cheat/script/test.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | import subprocess 3 | subprocess.call(['python_cheat_script_script.py']) 4 | -------------------------------------------------------------------------------- /doctest_cheat.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | """ 4 | Embed tests into docstrings. 5 | 6 | Serves mainly as good example for documentation. 7 | 8 | Cannot replace unittest, specially for more complex functions. 9 | 10 | The test format is exactly the same as seen in an interactive Python session. 11 | 12 | This is a docstring for the module, so tests inside it will be run. 13 | 14 | Pass: 15 | 16 | >>> print 'abc' 17 | abc 18 | 19 | Fail: 20 | 21 | >>> 1 22 | 2 23 | 24 | Define names: 25 | 26 | >>> a = 1 27 | >>> print a 28 | 1 29 | 30 | This is only works for stuff defined in current docstring: 31 | 32 | >>> mod_doc = 1 33 | 34 | Search for `mod_doc` elsewhere and see the fail. 35 | 36 | Indent: 37 | 38 | >>> if True: 39 | ... print 'a' 40 | a 41 | 42 | Multiline output: 43 | 44 | >>> for a in [1,2]: 45 | ... print a 46 | 1 47 | 2 48 | 49 | Unpredictable output: 50 | 51 | >>> f # doctest: +ELLIPSIS 52 | 53 | 54 | The comment `# doctest: +ELLIPSIS` is obligatory and is called a *directive*. 55 | 56 | Exceptions: 57 | 58 | >>> raise ZeroDivisionError 59 | Traceback (most recent call last): 60 | File "", line 1, in 61 | ZeroDivisionError 62 | 63 | Fails: 64 | 65 | >>> raise ZeroDivisionError 66 | Traceback (most recent call last): 67 | File "", line 1, in 68 | AnotherError 69 | """ 70 | 71 | def f(): 72 | """ 73 | Fail: 74 | 75 | >>> 1 76 | 2 77 | 78 | Call itself: 79 | 80 | >>> print f() 81 | 1 82 | 83 | Call other functions: 84 | 85 | >>> print f2() 86 | 2 87 | 88 | >>> mod_doc 89 | Traceback (most recent call last): 90 | File "/usr/lib/python2.7/doctest.py", line 1289, in __run 91 | compileflags, 1) in test.globs 92 | File "", line 1, in 93 | mod_doc 94 | NameError: name 'mod_doc' is not defined 95 | """ 96 | return 1 97 | 98 | """ 99 | Not a docstring becaues there is stuff before it. 100 | 101 | Not tested: 102 | 103 | >>> 1+1 104 | 4 105 | """ 106 | 107 | def f2(): 108 | return 2 109 | 110 | def func_with_very_long_name(): 111 | """ 112 | To avoid typing large names several times, you could to as follows: 113 | 114 | >>> a = func_with_very_long_name 115 | >>> a() 116 | 1 117 | >>> a() + 1 118 | 2 119 | >>> a() + 3 120 | 4 121 | """ 122 | return 1 123 | 124 | class C(): 125 | """ 126 | >>> C().f() 127 | 'C.f' 128 | """ 129 | 130 | def f(self): 131 | """ 132 | >>> C().f() 133 | 'C.f' 134 | """ 135 | return 'C.f' 136 | 137 | if __name__ == '__main__': 138 | if '##testmod': 139 | 140 | # Test current module: 141 | 142 | import doctest 143 | doctest.testmod() 144 | 145 | # Test given module: 146 | 147 | #doctest.testmod(doctest) 148 | 149 | # From the command line: 150 | 151 | #python -m doctest file.py 152 | -------------------------------------------------------------------------------- /environ.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | """ 4 | ## environ 5 | 6 | ## Environment variables 7 | """ 8 | 9 | import os 10 | 11 | # A dictionnary that contains all environment variables: 12 | 13 | print('os.environ = ' + str(os.environ)) 14 | 15 | # Get one from the dict: 16 | 17 | if 'PATH' in os.environ: 18 | print('PATH = ' + os.environ['PATH']) 19 | 20 | # Always check if it is defined before using it. 21 | 22 | # Loop over them all: 23 | 24 | #for v in os.environ: 25 | #print(v + ' = ' + os.environ[v]) 26 | 27 | if '## set values': 28 | 29 | if 'Good': 30 | 31 | os.environ['SOME_VAR'] = 'abc' 32 | assert os.environ['SOME_VAR'] == 'abc' 33 | 34 | # Subprocess will inherit this, for example those opened with `Popen`. 35 | 36 | # if 'Bad': 37 | 38 | # Does *not* work!: 39 | 40 | #os.environ = {'a':'b'} 41 | 42 | # Child process will not inherit it. 43 | -------------------------------------------------------------------------------- /exception.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | """ 4 | ## Exception 5 | """ 6 | 7 | import sys 8 | 9 | # They go up until something catches them: 10 | 11 | def e(): 12 | raise Exception 13 | 14 | def d(): 15 | e() 16 | 17 | try: 18 | d() 19 | except: 20 | pass 21 | else: 22 | raise Exception 23 | 24 | """ 25 | If nothing catches them, they explode on stdX and stop program execution! 26 | 27 | What gets printed: 28 | 29 | traceback: where the exception came from (modules, functions, lines) 30 | #this is useful for debug, so you can find where the problem comes from 31 | 32 | : 33 | raise Exception("repr") 34 | print "cant reach here" 35 | """ 36 | 37 | if '## else': 38 | 39 | # Only execute if the exception did not happen. 40 | 41 | try: 42 | raise Exception() 43 | except: 44 | pass 45 | else: 46 | assert False 47 | 48 | e = False 49 | try: 50 | pass 51 | except: 52 | assert False 53 | else: 54 | e = True 55 | assert e 56 | 57 | if '## finally': 58 | 59 | # Always executed, whether the exception happened or not. 60 | 61 | f = False 62 | try: 63 | raise Exception() 64 | except: 65 | pass 66 | else: 67 | assert False 68 | finally: 69 | f = True 70 | assert f 71 | 72 | f = False 73 | try: 74 | pass 75 | except: 76 | assert False 77 | else: 78 | pass 79 | finally: 80 | f = True 81 | assert f 82 | 83 | if '## raise': 84 | 85 | # Parenthesis or not: 86 | # http://stackoverflow.com/questions/16706956/is-there-a-difference-between-raising-an-exception-and-exception 87 | 88 | if 'What can be raised': 89 | 90 | # Only old style classes or derived classes from exception can be raised. 91 | 92 | # In particular, strings cannot be raised, or that raises a `TypeError` instead of the string. 93 | 94 | # This was made possible around Python 2.5, but removed in Python 2.6. 95 | 96 | class Old: pass 97 | try: 98 | raise Old() 99 | except Old: 100 | pass 101 | else: 102 | assert False 103 | 104 | class New(object): pass 105 | try: 106 | raise New() 107 | except TypeError: 108 | pass 109 | else: 110 | assert False 111 | 112 | class New(Exception): pass 113 | try: 114 | raise New() 115 | except New: 116 | pass 117 | else: 118 | assert False 119 | 120 | # Since `'str'` is a new style object: 121 | 122 | try: 123 | raise 'str' 124 | except TypeError: 125 | pass 126 | else: 127 | assert False 128 | 129 | # A lightweight alternative is to raise Exception with a custom message: 130 | 131 | try: 132 | raise Exception('str') 133 | except Exception: 134 | pass 135 | else: 136 | assert False 137 | 138 | if '## Custom exception': 139 | 140 | class CustomException(Exception): 141 | def __init__(self, value): 142 | self.parameter = value 143 | def __str__(self): 144 | return repr(self.parameter) 145 | try: 146 | raise CustomException('msg') 147 | except CustomException, (instance): 148 | print instance.parameter 149 | 150 | if '## except': 151 | 152 | # Except catches derived classes only: 153 | 154 | try: 155 | raise Exception() 156 | except ZeroDivisionError: 157 | print 'ZeroDivisionErrorOnly or derived classes' 158 | except Exception: 159 | print 'Exception, or its derived classes, therefore all exceptions' 160 | except: 161 | print 'same as above' 162 | 163 | if '## Pass arguments to exceptions': 164 | 165 | try: 166 | raise Exception(1, 2) 167 | # Same as above, but more verbose and implicit. NEVER user this. 168 | #raise Exception, (1, 2) 169 | except Exception, e: 170 | print 'e is an instance of Exception' 171 | print 'Exception, e = ' + str(e) 172 | print e.args[0], e.args[1] 173 | 174 | if '## reraise': 175 | 176 | # Can be used to add/modify info 177 | 178 | # It is hard to modify and reraise i python 2 179 | 180 | # It seems python 3 introduces the `raise from` statement which makes that much easier! 181 | 182 | # 183 | 184 | try: 185 | 186 | raise Exception('msg') 187 | 188 | except Exception, e: 189 | 190 | # You lose the traceback: 191 | 192 | #raise Exception("updated msg\n" + str(e)) 193 | 194 | # To keep the traceback: 195 | 196 | #import traceback 197 | #traceback.print_exc( 198 | ##file = sys.stdout #stderr is the default 199 | #) 200 | 201 | # For more info on current exception: 202 | 203 | print 'sys.exc_info() = ' 204 | print sys.exc_info() 205 | print 'sys.exc_type() = ' 206 | print sys.exc_type 207 | print 'sys.exc_value() = ' 208 | print sys.exc_value 209 | print 'sys.exc_traceback() = ' 210 | print sys.exc_value 211 | 212 | # The following forms keep the traceback: 213 | 214 | #raise e 215 | #raise 216 | 217 | if '## built-in exceptions': 218 | 219 | """ 220 | Like other built-ins, the following exceptions are always available 221 | without any imports. 222 | 223 | 224 | """ 225 | 226 | try: 227 | print 1/0 228 | except ZeroDivisionError: 229 | pass 230 | else: 231 | raise 232 | 233 | try: 234 | int('a') 235 | except ValueError: 236 | print 'not a number' 237 | 238 | try: 239 | f = open("NONEXISTENT") 240 | except IOError, (err, msg): 241 | if err == 2: 242 | print "does not exist", msg 243 | else: 244 | print "no exception" 245 | 246 | if '## KeyboardInterrupt': 247 | 248 | # Program got a SIGINT, generated when user presses control c on Linux terminals. 249 | 250 | if False: 251 | try: 252 | for i in itertools.count(): 253 | pass 254 | except KeyboardInterrupt: 255 | print "had enough of waiting" 256 | -------------------------------------------------------------------------------- /expat_cheat.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | """ 4 | Sequential XML parsing. 5 | 6 | No child/parent concept. 7 | 8 | Harder to use if you need node wise operations, 9 | but very fast and memory efficient as it does not need to read the entire file at once. 10 | 11 | Python has many other XML parsing methods: 12 | http://stackoverflow.com/questions/1912434/how-do-i-parse-xml-in-python 13 | """ 14 | 15 | import os.path 16 | import xml.parsers.expat 17 | 18 | class Parser: 19 | 20 | def __init__(self): 21 | self._output = '' 22 | self._parser = xml.parsers.expat.ParserCreate() 23 | 24 | # Set what function does what. 25 | self._parser.StartElementHandler = self.tagOpen 26 | self._parser.EndElementHandler = self.tagClose 27 | self._parser.CharacterDataHandler = self.tagData 28 | 29 | # Find attributes of matching opening tag of a closing tag. 30 | self._attr_stack = [] 31 | 32 | def feed(self, data, isfinal): 33 | """ 34 | Pass XML data string to process. 35 | 36 | Can be called multiple times with different pieces of a given XML. 37 | 38 | isfinal == True iff this is th last call. 39 | 40 | For input from file use instead: 41 | 42 | self._parser.ParseFile(open('path.xml', 'r')) 43 | """ 44 | self._parser.Parse(data, isfinal) 45 | 46 | def output(self): 47 | """ 48 | Return the processed input. 49 | """ 50 | return self._output 51 | 52 | def tagOpen(self, tag, attrs): 53 | self._output += 'open: ' + tag + ' ' + str(attrs) + '\n' 54 | self._attr_stack.append(attrs) 55 | 56 | def tagData(self, data): 57 | self._output+= 'data: ' + repr(data) + '\n' 58 | 59 | def tagClose(self, tag): 60 | self._output += 'close: ' + tag + ' ' + str(self._attr_stack[-1]) + '\n' 61 | del self._attr_stack[-1] 62 | 63 | xml_string0 = """ 64 | 65 | d 66 | d2 67 | 68 | """ 69 | xml_string1 = """ 70 | d3 71 | d4 72 | 73 | d5 74 | d6 75 | 76 | """ 77 | 78 | # Parse. 79 | p = Parser() 80 | p.feed(xml_string0, False) 81 | p.feed(xml_string1, True) 82 | print p.output() 83 | -------------------------------------------------------------------------------- /fileinput/README.md: -------------------------------------------------------------------------------- 1 | # fileinput 2 | 3 | `fileinput` implements the typical POSIX / GNU interface: 4 | 5 | - read from files with filenames in stdin[1:], one by one 6 | - if none is given, read from stdin. 7 | 8 | Run the tests: 9 | 10 | ./test_main.py 11 | 12 | Understand what `main.py` does: 13 | 14 | ./main.py a b 15 | ./main.py b a 16 | echo 'c\nc2' | ./main.py 17 | echo 'c\nc2' | ./main.py a b 18 | -------------------------------------------------------------------------------- /fileinput/a: -------------------------------------------------------------------------------- 1 | a 2 | a2 3 | -------------------------------------------------------------------------------- /fileinput/b: -------------------------------------------------------------------------------- 1 | b 2 | b2 3 | -------------------------------------------------------------------------------- /fileinput/main.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | #put input to stdout 4 | 5 | import sys 6 | import fileinput 7 | 8 | for line in fileinput.input(): 9 | sys.stdout.write(line) 10 | -------------------------------------------------------------------------------- /fileinput/test_main.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | import subprocess 4 | 5 | ##just args 6 | 7 | process = subprocess.Popen( 8 | ['python','main.py','a','b'], 9 | shell = False, 10 | stdin = subprocess.PIPE, 11 | stdout = subprocess.PIPE, 12 | stderr = subprocess.PIPE, 13 | universal_newlines = True 14 | ) 15 | stdout, stderr = process.communicate() 16 | exit_status = process.wait() 17 | assert stdout == 'a\na2\nb\nb2\n' 18 | 19 | #input order is used: 20 | 21 | process = subprocess.Popen( 22 | ['python','main.py','b','a'], 23 | shell = False, 24 | stdin = subprocess.PIPE, 25 | stdout = subprocess.PIPE, 26 | stderr = subprocess.PIPE, 27 | universal_newlines = True 28 | ) 29 | stdout, stderr = process.communicate() 30 | exit_status = process.wait() 31 | assert stdout == 'b\nb2\na\na2\n' 32 | 33 | ##just stdin 34 | 35 | process = subprocess.Popen( 36 | ['python','main.py'], 37 | shell = False, 38 | stdin = subprocess.PIPE, 39 | stdout = subprocess.PIPE, 40 | stderr = subprocess.PIPE, 41 | universal_newlines = True 42 | ) 43 | stdout, stderr = process.communicate('c\nc2\n') 44 | exit_status = process.wait() 45 | assert stdout == 'c\nc2\n' 46 | 47 | ##stdin and args 48 | 49 | #only args are used, so don't do this. 50 | 51 | process = subprocess.Popen( 52 | ['python','main.py','a','b'], 53 | shell = False, 54 | stdin = subprocess.PIPE, 55 | stdout = subprocess.PIPE, 56 | stderr = subprocess.PIPE, 57 | universal_newlines = True 58 | ) 59 | stdout, stderr = process.communicate('c\nc2\n') 60 | exit_status = process.wait() 61 | assert stdout == 'a\na2\nb\nb2\n' 62 | -------------------------------------------------------------------------------- /format_method.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | import sys 4 | 5 | """ 6 | ## format method 7 | 8 | The percent format operator becomes deprecated in Python 3.1, 9 | 10 | The `format` method is introduced and backported to Python 2, 11 | 12 | On one hand, this is saner since we now have a method instead of a magic operator `%`. 13 | 14 | On the other, C printf format strings are gone, and that is a shame. 15 | Yet another format syntax to learn. 16 | 17 | http://www.python.org/dev/peps/pep-3101/ 18 | 19 | Only operators `[]` and `.` are supported inside the formats. 20 | 21 | TODO vs `format()` built-in? 22 | http://stackoverflow.com/questions/16683518/why-does-python-have-a-format-function-as-well-as-a-format-method 23 | """ 24 | 25 | assert '{1} {0} {1} {2[0]} {a}'.format(0, 1, [0, 1], a=2 ) == '1 0 1 0 2' 26 | 27 | # Escape, literals: 28 | 29 | assert '{{}}{{a}}'.format(0) == '{}{a}' 30 | 31 | assert '{} {}'.format(0, 1) == '0 1' 32 | 33 | # Cannot use both automatic numbering and numbered references: 34 | 35 | try: 36 | '{} {0}'.format(0) 37 | except ValueError: 38 | pass 39 | else: 40 | assert False 41 | 42 | # Does not work like in Ruby where strings are magic: only the format method interprets anything. 43 | 44 | a = 2 45 | assert '{a}' != '2' 46 | 47 | if 'format_spec': 48 | 49 | # The entire format is of the form: 50 | 51 | #{[:]} 52 | 53 | # It is C printf like, but **NOT** the same! 54 | 55 | # Default for integers if not given. 56 | assert '{:d}'.format(20) == '20' 57 | assert '{:x}'.format(20) == '14' 58 | 59 | # Fill to minimum width with spaces: 60 | 61 | assert '{:2d}'.format(1) == ' 1' 62 | 63 | # With zeroes: 64 | 65 | assert '{:02d}'.format(1) == '01' 66 | 67 | # Align left: 68 | 69 | assert '{:<2d}'.format(1) == '1 ' 70 | 71 | # Decimal places: 72 | 73 | assert '{:.2f}'.format(1.0) == '1.00' 74 | assert '{0:.2f}'.format(1.0) == '1.00' 75 | assert '{x:.2f}'.format(x=1.0) == '1.00' 76 | 77 | # Format via an argument combo: 78 | 79 | assert '{0:.{1}f}'.format(1.23456, 4) == '1.2346' 80 | assert '{number:.{digits}f}'.format(number=1.23456, digits=4) == '1.2346' 81 | 82 | if '## Table printing': 83 | 84 | # There seems to be no built-in one liner. 85 | 86 | # Two rows built-in solution: 87 | 88 | print 'Label value table combo:' 89 | labels = ['label 0', 'very long label 1', 'l 2'] 90 | values = [0, 1, 2] 91 | sys.stdout.write('{:<{l}}{}\n{:<{l}}{}\n{:<{l}}{}\n'.format( 92 | *[x for t in zip(labels,values) for x in t], 93 | l=len(max(labels, key=len)) + 2 94 | )) 95 | 96 | """ 97 | Output: 98 | 99 | label 0 0 100 | very long label 1 1 101 | l 2 2 102 | 103 | Many solutions with external libraries since Python is so scientific based: 104 | - http://stackoverflow.com/questions/9535954/python-printing-lists-as-tabular-data 105 | - http://stackoverflow.com/questions/17279059/print-list-in-table-format-in-python 106 | """ 107 | -------------------------------------------------------------------------------- /format_operator.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | """ 4 | ## format operator 5 | 6 | ## % 7 | 8 | Deprecated in favor of `format` and `str.format`, so never use it in new code. 9 | 10 | Mostly like C printf. 11 | 12 | There are two forms: tuple or dict. 13 | 14 | Single value form: only works for a single input. 15 | """ 16 | 17 | assert '%d' % 1 == '1' 18 | 19 | try: 20 | assert '%d %d' % 1, 2 == '1 2' 21 | except TypeError: 22 | pass 23 | else: 24 | assert False 25 | 26 | # Tuple form: works for any number of arguments. 27 | 28 | assert '%d' % (1) == '1' 29 | assert '%d %d' % (1, 2) == '1 2' 30 | assert '%.2f' % (1.2) == '1.20' 31 | assert '%5.2f' % (1.2) == ' 1.20' 32 | assert '%s' % ('abc') == 'abc' 33 | 34 | # Map form: 35 | 36 | assert '%(v1)s %(#)03d %(v1)s %(#)03d' % {'v1':'asdf', '#':2} == 'asdf 002 asdf 002' 37 | -------------------------------------------------------------------------------- /frozenset.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | """ 4 | ## frozenset 5 | 6 | Immutable version of set. 7 | 8 | As a consequence, it is hashable. 9 | """ 10 | 11 | fs = frozenset([0, 1]) 12 | try: 13 | fs.add(2) 14 | except AttributeError: 15 | pass 16 | else: 17 | assert False 18 | 19 | assert fs == set([0, 1]) 20 | -------------------------------------------------------------------------------- /getopt_cheat.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | import getopt 4 | 5 | short = "ho:v" 6 | longs = ["help", "output="] 7 | opts, args = getopt.getopt(['-h', '-o', 'foo', '-v', 'asdf', 'qwer'], short, longs) 8 | assert(opts == [('-h', ''), ('-o', 'foo'), ('-v', '')]) 9 | assert(args == ['asdf', 'qwer']) 10 | opts, args = getopt.getopt(['--help', '--output', 'foo', 'asdf', 'qwer'], short, longs) 11 | assert(opts == [('--help', ''), ('--output', 'foo')]) 12 | assert(args == ['asdf', 'qwer']) 13 | -------------------------------------------------------------------------------- /getting-started.md: -------------------------------------------------------------------------------- 1 | # Getting started 2 | 3 | On Ubuntu: 4 | 5 | ./configure 6 | 7 | Then every time you start working on this repo: 8 | 9 | . .venv/bin/activate 10 | 11 | And when you are done: 12 | 13 | deactivate 14 | 15 | Run all tests: 16 | 17 | ./test 18 | -------------------------------------------------------------------------------- /h5py_cheat.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | ''' 4 | http://docs.h5py.org/en/stable/ 5 | ''' 6 | 7 | import sys 8 | 9 | import h5py 10 | import numpy 11 | 12 | size = 1000000000 13 | 14 | if len(sys.argv) == 1: 15 | # Create a sample file. 16 | with h5py.File('h5py_cheat.tmp.hdf5', 'w') as f: 17 | x = numpy.arange(size + 1) 18 | x[size] = size / 2 19 | f.create_dataset('x', data=x, dtype='int64') 20 | y = numpy.arange(size + 1) * 2 21 | y[size] = 3 * size / 2 22 | f.create_dataset('y', data=y, dtype='int64') 23 | z = numpy.arange(size + 1) * 4 24 | z[size] = -1 25 | f.create_dataset('z', data=z, dtype='int64') 26 | 27 | # Read the sample file and assert some values. 28 | with h5py.File('h5py_cheat.tmp.hdf5', 'r') as f: 29 | x = f['x'] 30 | assert x[0] == 0 31 | assert x[1] == 1 32 | assert x[2] == 2 33 | assert x[size - 3] == size - 3 34 | assert x[size - 2] == size - 2 35 | assert x[size - 1] == size - 1 36 | assert x[size - 0] == size / 2 37 | y = f['y'] 38 | assert y[0] == 0 39 | assert y[1] == 2 40 | assert y[2] == 4 41 | assert y[size - 3] == 2 * (size - 3) 42 | assert y[size - 2] == 2 * (size - 2) 43 | assert y[size - 1] == 2 * (size - 1) 44 | assert y[size - 0] == 3 * size / 2 45 | z = f['z'] 46 | assert z[0] == 0 47 | assert z[1] == 4 48 | assert z[2] == 8 49 | assert z[size - 3] == 4 * (size - 3) 50 | assert z[size - 2] == 4 * (size - 2) 51 | assert z[size - 1] == 4 * (size - 1) 52 | assert z[size - 0] == -1 53 | -------------------------------------------------------------------------------- /how-to-hack-python-projects.md: -------------------------------------------------------------------------------- 1 | # How to hack Python projects 2 | 3 | Next, you might want to do the following to isolate the development version of a package: 4 | 5 | - create a dir: `$DEVPATH` 6 | 7 | - add it to the `PYTHONPATH` variable. This will insert it in the `sys.path` before distro's installation paths 8 | 9 | - symlink all the packages of the project into `$DEVPATH` 10 | 11 | - to turn off your dev version of Matplotlib and fall back to the stable distro installed one, just rename `matplotlib` as `matplotlib.off` 12 | 13 | - if the project contains C/C++ extensions, you can: 14 | 15 | python setup.py build_ext --inplace 16 | 17 | The first time, and whenever you modify a C/C++ extension. 18 | 19 | This will place the compiled c/c++ outputs side by side with the python code in the repo, exactly where they need to be, without touching anything outside the repo. 20 | -------------------------------------------------------------------------------- /implementations.md: -------------------------------------------------------------------------------- 1 | # Implementations 2 | 3 | Python specifies the language and stdlib interfaces, not the implementation. 4 | 5 | The main interpreter implementations are: 6 | 7 | - [CPython](http://www.python.org/getit/source/). Reference implementation. 8 | - PyPy. Supposed to be faster than CPython. No GIL. 9 | - JPython. Compiles to Java Object Code. 10 | - IronPython. Compiles to `.NET` object code. 11 | - Cython. Translate Python as C? 12 | 13 | ## Global Interpreter Lock 14 | 15 | ## GIL 16 | 17 | 18 | 19 | 20 | 21 | ## Bytecode 22 | 23 | ### pyc 24 | 25 | TODO: CPython implementation detail? 26 | 27 | 28 | 29 | Can differ between minor versions: 30 | 31 | Only for loading modules faster, not running: 32 | 33 | ### pyd 34 | 35 | ### pyo 36 | 37 | 38 | -------------------------------------------------------------------------------- /import_cheat/README.md: -------------------------------------------------------------------------------- 1 | Minimal test of a relative import structure that works in both Python 2 and Python 3. 2 | -------------------------------------------------------------------------------- /import_cheat/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cirosantilli/python-cheat/5db8c5238bd39eeb46c963dceb9002a0be621777/import_cheat/__init__.py -------------------------------------------------------------------------------- /import_cheat/d/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cirosantilli/python-cheat/5db8c5238bd39eeb46c963dceb9002a0be621777/import_cheat/d/__init__.py -------------------------------------------------------------------------------- /import_cheat/d/notmain.py: -------------------------------------------------------------------------------- 1 | from . import notmain2 2 | 3 | d_notmain_var = 2 4 | -------------------------------------------------------------------------------- /import_cheat/d/notmain2.py: -------------------------------------------------------------------------------- 1 | d_notmain2_var = 3 2 | -------------------------------------------------------------------------------- /import_cheat/main.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | import notmain 4 | import d.notmain 5 | 6 | assert notmain.notmain_var == 1 7 | assert d.notmain.d_notmain_var == 2 8 | assert d.notmain2.d_notmain2_var == 3 9 | -------------------------------------------------------------------------------- /import_cheat/notmain.py: -------------------------------------------------------------------------------- 1 | notmain_var = 1 2 | -------------------------------------------------------------------------------- /import_cheat/test: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | set -eux 3 | find . -name '*.pyc' -delete 4 | find . -name __pycache__ -prune -exec rm -r "{}" \; 5 | python2 main.py 6 | find . -name '*.pyc' -delete 7 | find . -name __pycache__ -prune -exec rm -r "{}" \; 8 | python3 main.py 9 | -------------------------------------------------------------------------------- /interactive-friendly.md: -------------------------------------------------------------------------------- 1 | # Interactive friendly 2 | 3 | Python did not replace Bash because it is too verbose for quick and dirty CLI operations. 4 | 5 | That is the price of sanity. 6 | 7 | There are a few projects which try to make Python golf better, at the price of some extra insanity: 8 | 9 | - 10 | -------------------------------------------------------------------------------- /ipython.ipy: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ipython 2 | 3 | # Must use ipy extension, or ipython uses regular python with python file 4 | 5 | ## Review 6 | 7 | # pythonlike shell 8 | 9 | # advantages: 10 | 11 | # - all programming contructs are sane (python) 12 | # - easier to call system shell 13 | # - autocompletion 14 | # - some bash built-ins like cd 15 | # - quick documentation with ? 16 | 17 | ## Regular python 18 | 19 | # All of normal python works. 20 | 21 | a = 1 22 | print a 23 | 24 | def f(a): 25 | print a 26 | 27 | def f2(a,b): 28 | """ 29 | docstring of f2 30 | """ 31 | print a + b 32 | 33 | ## Tab completion 34 | 35 | #works even for python objects in current scope. 36 | 37 | #type f, hit tab, and see `f2`! 38 | 39 | ##bash built ins 40 | 41 | #cd works 42 | 43 | ##documentation 44 | 45 | #put docstring of f2 `less`: 46 | 47 | f2? 48 | 49 | if '##magic': 50 | 51 | #call python functions with less typing 52 | 53 | #only work at start of strings 54 | 55 | #avoid typing parenthesis and commas: 56 | 57 | /f2 1,2 58 | /f2 1 2 59 | 60 | #are the same as `f2(1,2)` 61 | 62 | #any space is converted to a comma: 63 | 64 | #/f2 1, 2 65 | 66 | #is the same as f2(1,,2) 67 | 68 | #also autoquote: 69 | 70 | ,f2 ab cd 71 | 72 | #same as `f2('ab','cd')` 73 | 74 | ,f2 12 34 75 | 76 | #same as `f2('12','34')`. They are not number anymore but strings! 77 | 78 | #autoquote as single argument: 79 | 80 | ;f a b 81 | 82 | #same as `f('a b')` 83 | 84 | #you can only have single argument functions in this mode 85 | 86 | #TODO how to get their return values? 87 | 88 | ##shell 89 | 90 | !echo a 91 | !echo a | cat 92 | 93 | !echo A > a.tmp 94 | !cat a.tmp 95 | !rm a.tmp 96 | 97 | #it really runs inside your shell: 98 | 99 | !echo * 100 | 101 | #TODO how to avoid running in a shell? (python pipes for example) 102 | 103 | ###get stdout err 104 | 105 | a = !echo abc 106 | assert a[0] == 'abc' 107 | 108 | a = !echo abc 1>&2 109 | assert a[0] == 'abc' 110 | 111 | #TODO how to separate stdout and stderr? I would love to write: 112 | 113 | #out, err = !somecommand 114 | 115 | a = !echo 'ab\ncd' 116 | assert a == ['ab','cd'] 117 | 118 | #other expressions besides equality don't work: 119 | 120 | #a = [1] + !echo ab 121 | 122 | ###pass python variable 123 | 124 | a = 'ab cd' 125 | !echo $a 126 | 127 | ###strings are python strings 128 | 129 | a = !echo 'ab\ncd' 130 | assert a == ['ab','cd'] 131 | 132 | ###exit status 133 | 134 | !false 135 | assert _exit_code == 1 136 | 137 | #but does not work when you capture stdout/stderr: 138 | 139 | !false 140 | a = !true 141 | assert _exit_code == 1 142 | 143 | #TODO how to do this? 144 | 145 | #simply does not change. 146 | 147 | ##rehashx 148 | 149 | #once used, you don't need '!' anymore 150 | 151 | #TODO it works in interactive, why not here? 152 | 153 | %rehashx 154 | 155 | #echo b 156 | 157 | ##startup files 158 | 159 | #based on profiles 160 | 161 | #to create default profile: 162 | 163 | #ipython profile create 164 | 165 | #to create a named profile: 166 | 167 | #ipython profile create $name 168 | 169 | #to locate your profiles folder (does not exist before the first profile create): 170 | 171 | #ipython locate 172 | 173 | #inside location dirs are organized as follows: 174 | 175 | #profile_/startup 176 | 177 | #anything under `startup` will be run at startup for the given profile 178 | 179 | #start ipython with an specific profile: 180 | 181 | #ipython --profile $name 182 | 183 | #if ommitted `name=default`. 184 | 185 | ## %edit 186 | 187 | # Open a given function on Vim, and run it after it is edited: 188 | 189 | #%edit myfunction 190 | 191 | # To just see the source, use: 192 | 193 | #myfunction?? 194 | -------------------------------------------------------------------------------- /issubclass.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | class Base: 4 | pass 5 | 6 | class Derived(Base): 7 | pass 8 | 9 | base = Base() 10 | derived = Derived() 11 | 12 | assert issubclass(Derived, Base) 13 | assert not issubclass(Base, Derived) 14 | 15 | # True for same object. 16 | assert issubclass(Base, Base) 17 | 18 | # Cannot use object of class. 19 | try: 20 | issubclass(derived, Base) 21 | except TypeError: 22 | pass 23 | else: 24 | assert False 25 | 26 | # Do this instead. 27 | isinstance(derived, Base) 28 | -------------------------------------------------------------------------------- /iterator_cheat.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | """ 4 | ## Iterator 5 | 6 | ## yield 7 | """ 8 | 9 | """ 10 | Iterators are more memory efficent for iterations than lists 11 | since there is no need to store the entire sequence! 12 | 13 | However, if you must calculate each new item, so more time expensive if 14 | you are going to use it more than once 15 | 16 | It is a classic space/time tradeoff. 17 | """ 18 | 19 | if '## create': 20 | 21 | # An iterator is just a function with a `yield` method: 22 | 23 | def mycount(): 24 | i = 0 25 | while True: 26 | yield i 27 | i = i + 1 28 | c = mycount() 29 | assert next(c) == 0 30 | assert next(c) == 1 31 | assert next(c) == 2 32 | 33 | # Raise exception when over: 34 | 35 | def myxrange(n): 36 | i = 0 37 | while True: 38 | yield i 39 | i = i+1 40 | if i > n: 41 | raise StopIteration 42 | x = myxrange(2) 43 | assert next(x) == 0 44 | assert next(x) == 1 45 | assert next(x) == 2 46 | try: 47 | next(x) 48 | except StopIteration: 49 | pass 50 | else: 51 | assert False 52 | 53 | if '## generator expressions': 54 | 55 | # Shorthand way to create iterators 56 | 57 | it = (i for i in xrange(10)) 58 | for i in it: 59 | print i 60 | 61 | # Parenthesis can be ommited for single argument func call: 62 | 63 | def mysum(vals): 64 | total = 0 65 | for val in vals: 66 | total += val 67 | return total 68 | 69 | assert mysum(i for i in [0, 2, 5]) == 7 70 | 71 | if '## iter': 72 | 73 | # Converts various types to iterators, 74 | # in particular generator expressions. 75 | 76 | iter('abc') 77 | iter([1, 2, 3]) 78 | 79 | if '## next': 80 | 81 | # Will not work with `xrange`! 82 | # http://late.am/post/2012/06/18/what-the-heck-is-an-xrange 83 | 84 | #next(xrange(1)) 85 | 86 | i = iter(xrange(2)) 87 | assert next(i) == 0 88 | assert i.next() == 1 89 | try: 90 | next(i) 91 | except StopIteration: 92 | pass 93 | else: 94 | assert False 95 | 96 | # Use default value if over: 97 | 98 | it = iter(xrange(1)) 99 | assert next(it) == 0 100 | assert next(it, 3) == 3 101 | assert next(it, 3) == 3 102 | 103 | # There is no has_next method. 104 | # The only way is to catch the `StopIteration` exception: 105 | # 106 | 107 | if '## iterators can\'t be rewinded': 108 | 109 | # Either store a list on memory or recalculate. 110 | 111 | # Recalculate: 112 | 113 | it = iter('asdf') 114 | for i in it: 115 | print 'first' 116 | print i 117 | it = iter('asdf') 118 | for i in it: 119 | print 'second' 120 | print i 121 | 122 | # Store on memory: 123 | 124 | it = list(iter('asdf')) 125 | for i in it: 126 | print 'first' 127 | print i 128 | for i in it: 129 | print 'second' 130 | print i 131 | 132 | if 'Built-in iterator functions': 133 | 134 | if '## enumerate': 135 | 136 | assert list(enumerate(['a', 'c', 'b']) ) == [(0, 'a'), (1, 'c'), (2, 'b'), ] 137 | 138 | if '## reduce': 139 | 140 | """ 141 | - take two leftmost, apply func 142 | - replace the two leftmost by the result 143 | - loop 144 | 145 | On the example below: 146 | 147 | - 2*3 - 1 = 5 148 | - 2*5 - 3 = 8 149 | """ 150 | 151 | assert reduce(lambda x, y: 2*x - y, [3, 1, 2]) == 8 152 | 153 | if '## itertools': 154 | 155 | import itertools 156 | 157 | """ 158 | Hardcore iterator patterns. 159 | http://docs.python.org/2/library/itertools.html#recipes 160 | 161 | Most important ones: 162 | 163 | - imap: map for iterators 164 | - izip: count to infinity 165 | - count: count to infinity 166 | """ 167 | 168 | # Cartesian product: 169 | 170 | for i, j in itertools.product(xrange(3), xrange(3)): 171 | print i, j 172 | 173 | # Join two iterators: 174 | 175 | assert [i for i in itertools.chain(xrange(2), xrange(2))] == [0, 1, 0, 1] 176 | 177 | if '## Applications': 178 | 179 | if 'Merge two lists of same length odd / even elements': 180 | 181 | # http://stackoverflow.com/questions/18041840/python-merge-two-lists-even-odd-elements 182 | 183 | # Same length: 184 | 185 | x = [0, 1] 186 | y = [2, 3] 187 | assert [ x for t in zip(x,y) for x in t ] == [0, 2, 1, 3] 188 | -------------------------------------------------------------------------------- /jupyter/.gitignore: -------------------------------------------------------------------------------- 1 | /*.html 2 | -------------------------------------------------------------------------------- /jupyter/README.md: -------------------------------------------------------------------------------- 1 | # Jupyter 2 | 3 | Usage: 4 | 5 | jupyter notebook 6 | 7 | Examples: 8 | 9 | 1. [inc](inc.ipynb) 10 | 1. [plotly](plotly.ipynb) 11 | 1. [ipywidgets_cheat](ipywidgets_cheat.ipynb) 12 | -------------------------------------------------------------------------------- /jupyter/clear_output: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | # https://stackoverflow.com/questions/28908319/how-to-clear-an-ipython-notebooks-output-in-all-cells-from-the-linux-terminal/47774393#47774393 3 | for nb in *.ipynb; do 4 | jupyter nbconvert --ClearOutputPreprocessor.enabled=True --inplace "$nb" 5 | done 6 | -------------------------------------------------------------------------------- /jupyter/get_html: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | # https://stackoverflow.com/questions/15998491/how-to-convert-ipython-notebooks-to-pdf-and-html/47773252#47773252 3 | # https://stackoverflow.com/questions/36901154/how-export-a-jupyter-notebook-to-html-from-the-command-line/47773056#47773056 4 | for nb in *.ipynb; do 5 | jupyter nbconvert --execute --to html "$nb" 6 | done 7 | -------------------------------------------------------------------------------- /jupyter/inc.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "code", 5 | "execution_count": null, 6 | "metadata": {}, 7 | "outputs": [], 8 | "source": [ 9 | "i = 0" 10 | ] 11 | }, 12 | { 13 | "cell_type": "code", 14 | "execution_count": null, 15 | "metadata": {}, 16 | "outputs": [], 17 | "source": [ 18 | "i += 1" 19 | ] 20 | }, 21 | { 22 | "cell_type": "code", 23 | "execution_count": null, 24 | "metadata": {}, 25 | "outputs": [], 26 | "source": [ 27 | "i" 28 | ] 29 | } 30 | ], 31 | "metadata": { 32 | "kernelspec": { 33 | "display_name": "Python 2", 34 | "language": "python", 35 | "name": "python2" 36 | }, 37 | "language_info": { 38 | "codemirror_mode": { 39 | "name": "ipython", 40 | "version": 2 41 | }, 42 | "file_extension": ".py", 43 | "mimetype": "text/x-python", 44 | "name": "python", 45 | "nbconvert_exporter": "python", 46 | "pygments_lexer": "ipython2", 47 | "version": "2.7.12" 48 | } 49 | }, 50 | "nbformat": 4, 51 | "nbformat_minor": 2 52 | } 53 | -------------------------------------------------------------------------------- /jupyter/inc.nbconvert.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "code", 5 | "execution_count": null, 6 | "metadata": {}, 7 | "outputs": [], 8 | "source": [ 9 | "i = 0" 10 | ] 11 | }, 12 | { 13 | "cell_type": "code", 14 | "execution_count": null, 15 | "metadata": {}, 16 | "outputs": [], 17 | "source": [ 18 | "i += 1" 19 | ] 20 | }, 21 | { 22 | "cell_type": "code", 23 | "execution_count": null, 24 | "metadata": {}, 25 | "outputs": [], 26 | "source": [ 27 | "i" 28 | ] 29 | } 30 | ], 31 | "metadata": { 32 | "kernelspec": { 33 | "display_name": "Python 2", 34 | "language": "python", 35 | "name": "python2" 36 | }, 37 | "language_info": { 38 | "codemirror_mode": { 39 | "name": "ipython", 40 | "version": 2 41 | }, 42 | "file_extension": ".py", 43 | "mimetype": "text/x-python", 44 | "name": "python", 45 | "nbconvert_exporter": "python", 46 | "pygments_lexer": "ipython2", 47 | "version": "2.7.12" 48 | } 49 | }, 50 | "nbformat": 4, 51 | "nbformat_minor": 2 52 | } 53 | -------------------------------------------------------------------------------- /jupyter/ipywidgets_cheat.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "code", 5 | "execution_count": null, 6 | "metadata": {}, 7 | "outputs": [], 8 | "source": [ 9 | "from __future__ import print_function\n", 10 | "from ipywidgets import interact, interactive, fixed, interact_manual\n", 11 | "import ipywidgets as widgets\n", 12 | "def f(x):\n", 13 | " return -x\n", 14 | "interact(f, x=10);" 15 | ] 16 | } 17 | ], 18 | "metadata": { 19 | "kernelspec": { 20 | "display_name": "Python 2", 21 | "language": "python", 22 | "name": "python2" 23 | }, 24 | "language_info": { 25 | "codemirror_mode": { 26 | "name": "ipython", 27 | "version": 2 28 | }, 29 | "file_extension": ".py", 30 | "mimetype": "text/x-python", 31 | "name": "python", 32 | "nbconvert_exporter": "python", 33 | "pygments_lexer": "ipython2", 34 | "version": "2.7.12" 35 | } 36 | }, 37 | "nbformat": 4, 38 | "nbformat_minor": 2 39 | } 40 | -------------------------------------------------------------------------------- /jupyter/plotly.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "code", 5 | "execution_count": null, 6 | "metadata": {}, 7 | "outputs": [], 8 | "source": [ 9 | "# Minimalistic example using only dicts and arrays.\n", 10 | "# TODO: is it possible to make arbitrary plots with those,\n", 11 | "# e.g. how to use bar plots like this?\n", 12 | "from plotly.offline import init_notebook_mode, iplot\n", 13 | "init_notebook_mode(connected=True)\n", 14 | "xaxis = range(5)\n", 15 | "iplot({\n", 16 | " 'data': [\n", 17 | " {\n", 18 | " 'x': xaxis, \n", 19 | " 'y': [x*x for x in xaxis],\n", 20 | " 'name': 'Positive Name',\n", 21 | " },\n", 22 | " {\n", 23 | " 'x': xaxis, \n", 24 | " 'y': [-x*x for x in xaxis],\n", 25 | " 'name': 'Negative Name',\n", 26 | " }\n", 27 | " ], \n", 28 | " 'layout': {\n", 29 | " 'title': 'Test Plot',\n", 30 | " 'xaxis': {'title': 'X Axis Title'},\n", 31 | " 'yaxis': {'title': 'Y Axis Title'},\n", 32 | " }\n", 33 | "})" 34 | ] 35 | }, 36 | { 37 | "cell_type": "code", 38 | "execution_count": null, 39 | "metadata": {}, 40 | "outputs": [], 41 | "source": [] 42 | } 43 | ], 44 | "metadata": { 45 | "kernelspec": { 46 | "display_name": "Python 2", 47 | "language": "python", 48 | "name": "python2" 49 | }, 50 | "language_info": { 51 | "codemirror_mode": { 52 | "name": "ipython", 53 | "version": 2 54 | }, 55 | "file_extension": ".py", 56 | "mimetype": "text/x-python", 57 | "name": "python", 58 | "nbconvert_exporter": "python", 59 | "pygments_lexer": "ipython2", 60 | "version": "2.7.12" 61 | } 62 | }, 63 | "nbformat": 4, 64 | "nbformat_minor": 2 65 | } 66 | -------------------------------------------------------------------------------- /keyword_only.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | ''' 4 | https://www.python.org/dev/peps/pep-3102/ 5 | ''' 6 | 7 | # Basic example. 8 | def f(a, *, b=1): 9 | return a + b 10 | 11 | # Bad, b is not named. `*` does not act as *args. 12 | try: 13 | f(1, 2) 14 | except TypeError: 15 | pass 16 | else: 17 | assert False 18 | 19 | # Good, b is named. 20 | assert f(1, b=2) == 3 21 | 22 | # Example with **kwargs as well. 23 | def g(a, *, b=1, **kwargs): 24 | return a + b + kwargs['c'] 25 | 26 | # Bad. 27 | try: 28 | g(1, 2, c=3) 29 | except TypeError: 30 | pass 31 | else: 32 | assert False 33 | 34 | # Good. 35 | assert g(1, b=2, c=3) == 6 36 | 37 | # Example with *args as well. 38 | def h(a, *args, b=1, **kwargs): 39 | return a + b + kwargs['c'] - args[0] 40 | 41 | # Impossible to set b without keyword, as that falls into *args instead. 42 | assert h(1, 2, b=3, c=4) == 6 43 | -------------------------------------------------------------------------------- /lambda.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | # Lambda is a function without name 4 | # 5 | # Lambda functions can only contain a single expression. 6 | # 7 | # This means in particular that they cannot contain assigments, 8 | # so they are very limited. 9 | 10 | f = lambda x, y: x + 2 * y + 1 11 | assert f(1, 2) == 6 12 | assert f(3, 4) == 12 13 | assert f(3, 4) == 12 14 | 15 | # Lambda that does nothing. 16 | # https://stackoverflow.com/questions/22738412/a-suitable-do-nothing-lambda-expression-in-python 17 | f = lambda *args: None 18 | f() 19 | -------------------------------------------------------------------------------- /logging_cheat.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | """ 4 | ## logging 5 | 6 | Standard way to output error messages. 7 | 8 | Advantages: 9 | 10 | - has many useful built-in error formats 11 | - has a level system 12 | - easy to change where logs go, e.g. a file. 13 | 14 | http://docs.python.org/2/howto/logging.html 15 | 16 | TODO log all at once 17 | """ 18 | 19 | import logging 20 | import sys 21 | import time 22 | 23 | if '## Default logger': 24 | 25 | logging.basicConfig( 26 | # Log to a file. Default is sys.stderr. 27 | # This can only take file path strings. 28 | # To log to stdout, use: 29 | #filename = 'example.log', 30 | # Mode defaults to `a`, which appends to old log. 31 | #filemode = 'w' 32 | 33 | # Minimum log level that will get printed. 34 | # Often taken as a CLI parameter. 35 | level = logging.DEBUG, 36 | #level = logging.INFO, 37 | #level = logging.WARNING, 38 | #level = logging.ERROR, 39 | #level = logging.CRITICAL, 40 | 41 | # Default does not contain time, so you very likely want to override this. 42 | format = ' %(levelname)s %(asctime)s %(message)s', 43 | 44 | # Format for asctime 45 | datefmt = '%m/%d/%Y %I:%M:%S %p', 46 | ) 47 | sys.stderr.write("logging:\n") 48 | logging.debug('debug') 49 | logging.info('info') 50 | logging.warning('warning') 51 | logging.error('error') 52 | logging.critical('critical') 53 | try: 54 | raise Exception 55 | except: 56 | logging.exception('inside exception. also prints exception stack') 57 | 58 | if '## Custom loggers': 59 | 60 | # Create logger 61 | logger = logging.getLogger('logger_name') 62 | logger.setLevel(logging.DEBUG) 63 | 64 | # Create console handler and set level to debug 65 | ch = logging.StreamHandler() 66 | ch.setLevel(logging.DEBUG) 67 | 68 | # Create formatter 69 | formatter = logging.Formatter(' %(asctime)s - %(name)s - %(levelname)s - %(message)s') 70 | 71 | # Add formatter to ch 72 | ch.setFormatter(formatter) 73 | 74 | # Add ch to logger 75 | logger.addHandler(ch) 76 | 77 | # Usage: 78 | sys.stderr.write("custom logger:\n") 79 | logger.debug('debug') 80 | logger.info('info') 81 | logger.warn('warn') 82 | logger.error('error') 83 | logger.critical('critical') 84 | 85 | # TODO: log all / a certain level to stdout 86 | 87 | if '## Align': 88 | 89 | """ 90 | http://stackoverflow.com/questions/7771912/how-to-right-align-level-field-in-python-logging-formatter 91 | http://stackoverflow.com/questions/20618570/python-logging-formatter-is-there-any-way-to-fix-the-width-of-a-field-and-jus 92 | 93 | For the level name, use: `%(levelname)8s` 94 | """ 95 | 96 | if '## UTC time': 97 | 98 | # http://stackoverflow.com/questions/6321160/python-logging-how-to-set-time-to-gmt 99 | 100 | logging.debug('not UTC') 101 | logging.Formatter.converter = time.gmtime 102 | logging.debug('UTC') 103 | 104 | if '## Threading': 105 | 106 | """ 107 | logging is thread safe: 108 | http://stackoverflow.com/questions/2973900/is-pythons-logging-module-thread-safe?lq=1 109 | 110 | You will likely want to log the thread name on every log write: 111 | http://stackoverflow.com/a/2357652/895245 112 | """ 113 | -------------------------------------------------------------------------------- /logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cirosantilli/python-cheat/5db8c5238bd39eeb46c963dceb9002a0be621777/logo.png -------------------------------------------------------------------------------- /math_cheat.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | """ 4 | ## math 5 | 6 | There are also some math built-in functions like abs and max. 7 | """ 8 | 9 | import math 10 | 11 | assert abs(math.sin(0) - 0.0) < 0.01 12 | assert abs(math.cos(0) - 1.0) < 0.01 13 | assert abs(math.exp(0) - 1.0) < 0.01 14 | 15 | if '## sqrt': 16 | 17 | assert abs(math.sqrt(4) - 2.0 ) < 0.01 18 | 19 | try: 20 | math.sqrt(-1) 21 | except ValueError: 22 | pass 23 | else: 24 | assert False 25 | 26 | assert abs(math.pi - 3.14) < 0.01 27 | assert abs(math.exp(0) - 1.0 ) < 0.01 28 | assert abs(math.exp(1) - 2.71) < 0.01 29 | assert math.floor( 1.5 ) == 1 30 | -------------------------------------------------------------------------------- /matplotlib.md: -------------------------------------------------------------------------------- 1 | # Matplotlib 2 | 3 | TODO install currently broken! 4 | 5 | Scientific plotting library. 6 | 7 | ## Install 8 | 9 | Although it is available in PyPi, there are tons of dependencies which pip may not install, and it even fails silently! 10 | 11 | Therefore **don't** use the pip install: but use the distro's package manager. On Ubuntu: 12 | 13 | sudo aptitude install python-matplotlib 14 | 15 | ## Developing 16 | 17 | Clone besides of being able to hack Matplotlib, you also get of tons of example files with this! 18 | 19 | If you are on Ubuntu get the built dependencies: 20 | 21 | sudo aptitude build-dep python-matplotlib 22 | 23 | Then build C extensions and install with: 24 | 25 | sudo python setup.py install 26 | 27 | ### Test hacks 28 | 29 | You cannot put the Python files in your python path simply without installing, because the compiled dependencies won't go to the correct place without an install (crashes on `_path` not found). 30 | 31 | So, after you made changes do again: 32 | 33 | sudo python setup.py install 34 | 35 | After you build the files C files, which is what takes the longest, you don't have to build them again, so after you hack just: 36 | 37 | The problem with this is that you cannot keep the distro default installed also. 38 | 39 | TODO how not to install after every change. 40 | 41 | ## Architecture 42 | 43 | ### State machine 44 | 45 | Not object based, but state machine based. 46 | 47 | This means that you often have a current something, and you modify the current something. 48 | 49 | This methods like `gca()` which get you the current something. 50 | 51 | Rationale: easier to type on interactive sessions 52 | 53 | ### Objects 54 | 55 | - figure: everything 56 | - axes: each subplot, including several axis 57 | - axis (!= axes): the line with the ticks and numbers 58 | 59 | ## show 60 | 61 | Plot to screen: 62 | 63 | plt.plot([0,1]) 64 | plt.show() 65 | 66 | On window close, clears plot, so if you have to replot if you want to reuse the old plot: 67 | 68 | plt.plot([1,0]) 69 | plt.show() 70 | 71 | ## savefig 72 | 73 | Plot to file 74 | 75 | Recommended formats are: 76 | 77 | - SGV: vector. Very precise, but needs to be transformed into bits before being put in a PDF. 78 | - PNG: lossless compression. Simpler to put in PDF because it represents bits directly. 79 | 80 | examples: 81 | 82 | plt.plot([0,1]) 83 | plt.savefig( 'svg.png', format='png', bbox_inches='tight' ) 84 | plt.savefig( 'png.png', format='png', bbox_inches='tight' ) 85 | 86 | ## format options 87 | 88 | Many format options can be given on either: 89 | 90 | - in a single format string at once 91 | - in separate `kwargs` 92 | 93 | use only separate `kwargs` in non-interactive programs since this is more manageable 94 | 95 | ### string 96 | 97 | plt.plot([0,1], 'r--') 98 | plt.show() 99 | 100 | ### kwargs 101 | 102 | plt.plot([0,1,2,3], [0,1,4,9], color='r', linestyle='--' ) 103 | save_svg_clear('r--kwargs') 104 | 105 | ## pylab 106 | 107 | Part of matplotlib: 108 | -------------------------------------------------------------------------------- /multifile/README.md: -------------------------------------------------------------------------------- 1 | # Multi-file operations 2 | 3 | 1. `main.py` 4 | 1. `a.py` 5 | 6 | Illustrates concepts which can only be demonstrated on multi python file projects, such as: 7 | 8 | - imports 9 | - modules 10 | - `execfile` 11 | 12 | All the tests are run by running `main.py`. 13 | 14 | You must execute `main.py` from current dir because some of the examples depend on `os.getcwd`. 15 | -------------------------------------------------------------------------------- /multifile/a: -------------------------------------------------------------------------------- 1 | a = 'a' 2 | -------------------------------------------------------------------------------- /multifile/a.py: -------------------------------------------------------------------------------- 1 | a = 'a.a' 2 | 3 | def f(): 4 | return 'a.f()' 5 | 6 | def g(): 7 | return 'a.g()' 8 | 9 | class C: 10 | def m(self): 11 | return 'a.C.m()' 12 | 13 | #imports on child and stuff defined in the import are not passed to parent 14 | 15 | import imported_from_a 16 | assert imported_from_a.n == 1 17 | 18 | ##__name__ 19 | 20 | #it is visible to the imported file 21 | 22 | #assuming this was imported from .main: 23 | 24 | #assert __name__ == 'a' 25 | 26 | #assuming this was imported as 27 | 28 | #b = imp.load_source('c','a.py') 29 | 30 | #from .main: 31 | 32 | #assert __name__ == 'c' 33 | 34 | #imports from the importing file are not put into this namespace 35 | 36 | try: 37 | imported_from_main.f() 38 | except NameError: 39 | pass 40 | else: 41 | assert False 42 | 43 | # This does not work: 44 | 45 | def __call__(): 46 | return "a.__call__()" 47 | 48 | import sys 49 | syspath = sys.path 50 | import contains_list 51 | print 'contains_list.l = ' + str(contains_list.l) 52 | assert contains_list.l == [1] 53 | -------------------------------------------------------------------------------- /multifile/aln.py: -------------------------------------------------------------------------------- 1 | a -------------------------------------------------------------------------------- /multifile/contains_list.py: -------------------------------------------------------------------------------- 1 | l = [1] 2 | -------------------------------------------------------------------------------- /multifile/d/__init__.py: -------------------------------------------------------------------------------- 1 | #BAD: has the same name as a module! 2 | 3 | #a = 'd.a' 4 | 5 | def f(): 6 | return "d.f()" 7 | -------------------------------------------------------------------------------- /multifile/d/a.py: -------------------------------------------------------------------------------- 1 | a = "d.a" 2 | -------------------------------------------------------------------------------- /multifile/d/a2.py: -------------------------------------------------------------------------------- 1 | def f(): 2 | return "d.a2.f()" 3 | 4 | #imports are relative to current dir: 5 | 6 | import d2 7 | 8 | assert d2.f() == "d.d2.f()" 9 | 10 | #using from . only imports relative to current dir, does not look into python path: 11 | 12 | from . import os 13 | 14 | assert os.f() == "d.os.f()" 15 | 16 | #only works because we are a submodule! 17 | -------------------------------------------------------------------------------- /multifile/d/aln.py: -------------------------------------------------------------------------------- 1 | ../a -------------------------------------------------------------------------------- /multifile/d/d2/__init__.py: -------------------------------------------------------------------------------- 1 | def f(): 2 | return "d.d2.f()" 3 | -------------------------------------------------------------------------------- /multifile/d/d2/a3.py: -------------------------------------------------------------------------------- 1 | def f(): 2 | return "d.d2.a3.f()" 3 | -------------------------------------------------------------------------------- /multifile/d/d2/d3/__init__.py: -------------------------------------------------------------------------------- 1 | def f(): 2 | return "d.d2.d3.f()" 3 | -------------------------------------------------------------------------------- /multifile/d/d2/d3/a4.py: -------------------------------------------------------------------------------- 1 | def f(): 2 | return "d.d2.d3.a4.f()" 3 | -------------------------------------------------------------------------------- /multifile/d/os.py: -------------------------------------------------------------------------------- 1 | def f(): 2 | return "d.os.f()" 3 | -------------------------------------------------------------------------------- /multifile/dict_cheat.py: -------------------------------------------------------------------------------- 1 | """doc""" 2 | a = 1 3 | def f(): 4 | b = 2 5 | class C: 6 | c = 3 7 | -------------------------------------------------------------------------------- /multifile/execed.py: -------------------------------------------------------------------------------- 1 | defined_in_execed = 1 2 | -------------------------------------------------------------------------------- /multifile/imported_from_a.py: -------------------------------------------------------------------------------- 1 | n = 1 2 | -------------------------------------------------------------------------------- /multifile/imported_from_main.py: -------------------------------------------------------------------------------- 1 | def f(): 2 | return "imported_from_main.f()" 3 | -------------------------------------------------------------------------------- /multifile/raise_exception.py: -------------------------------------------------------------------------------- 1 | raise Exception 2 | -------------------------------------------------------------------------------- /net.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | 4 | """ 5 | Operations that involve networking. 6 | 7 | Running this may take some time or fail. 8 | """ 9 | 10 | import urllib2 11 | 12 | if "##POST request": 13 | 14 | ''' 15 | ##urlopen 16 | 17 | Does the actual request. 18 | 19 | Raises urllib2.URLError on error. 20 | 21 | It timeout not given a global default is used. 22 | 23 | Retruns bytestring, not unicode. 24 | 25 | Encoding can sometimes be inferred from Content-Type HTTP header: 26 | 27 | Content-Type: text/html; charset=ISO-8859-1 28 | 29 | Returns a file like object with some extra methods. 30 | 31 | info() returns an object with methods shown in: 32 | ''' 33 | 34 | print "GitHub Markdown:" 35 | url = 'https://api.github.com/markdown' 36 | data = '{"text":"**Hello World 你好**", "mode":"gfm", "context":"github/gollum"}' 37 | req = urllib2.Request(url, data) 38 | # Custom request headers; 39 | #request = urllib2.Request("http://www.google.com", headers={"Accept" : "text/html"}) 40 | try: 41 | response = urllib2.urlopen(req, timeout=10) 42 | except urllib2.URLError, e: 43 | print e 44 | sys.exit(1) 45 | response_body = response.read() 46 | assert type(response_body) == str 47 | print 'response body = ' + response_body 48 | print 'response status = {}'.format(response.getcode()) 49 | info = response.info() 50 | # Header string list 51 | print 'response info = ' + repr(info.headers) 52 | # Header key val dict 53 | print 'response info = ' + repr(info.items()) 54 | 55 | ##retry 56 | 57 | # Exponential backoff retry: http://www.saltycrane.com/blog/2009/11/trying-out-retry-decorator-python/ 58 | -------------------------------------------------------------------------------- /networkx_cheat.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | """ 4 | Graph library. 5 | 6 | Previously LANL. 7 | 8 | Homepage: 9 | 10 | Source: 11 | 12 | Official tutorial: 13 | 14 | Install: 15 | 16 | sudo pip install networkx 17 | """ 18 | 19 | import networkx as nx 20 | 21 | if '##dijkstra': 22 | 23 | edge_weights = [ 24 | (0, 2, 1), (1, 1, 2), (1, 3, 1), (1, 4, 2), (2, 1, 7), 25 | (2, 3, 3), (3, 4, 1), (4, 0, 1), (4, 1, 1) 26 | ] 27 | G = nx.DiGraph() 28 | G.add_edges_from([(x, y, {'weight':z}) for x,y,z in edge_weights]) 29 | assert nx.dijkstra_path(G, 0, 4) == [0, 2, 3, 4] 30 | -------------------------------------------------------------------------------- /nltk_cheat.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | """ 4 | Natural language processing toolkit. 5 | 6 | Homepage: http://www.nltk.org/ 7 | 8 | Source: https://github.com/nltk/nltk 9 | 10 | Install: 11 | 12 | sudo pip install nltk 13 | 14 | To use ceratin functions, you must data files. 15 | 16 | All data files can be downloaded with: 17 | 18 | python -m nltk.downloader all 19 | 20 | but that takes up 1.8Gb. 21 | 22 | Download interactively with a GUI application: 23 | 24 | python -c 'import nltk; nltk.download()' 25 | """ 26 | 27 | import nltk 28 | 29 | sentence = """At eight o'clock on Thursday morning 30 | Arthur didn't feel very good.""" 31 | 32 | print "Input:" 33 | print sentence 34 | print 35 | 36 | print "#word_tokenize" 37 | tokens = nltk.word_tokenize(sentence) 38 | print str(tokens) 39 | print 40 | 41 | tagged = nltk.pos_tag(tokens) 42 | print "#pos_tag" 43 | print tagged 44 | print 45 | 46 | print "#entities" 47 | entities = nltk.chunk.ne_chunk(tagged) 48 | print entities 49 | print 50 | 51 | from nltk.corpus import treebank 52 | t = treebank.parsed_sents('wsj_0001.mrg')[0] 53 | t.draw() 54 | print 55 | -------------------------------------------------------------------------------- /number.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | """ 4 | ## int 5 | 6 | ## long 7 | 8 | ## float 9 | 10 | Implement the Number "interface": http://docs.python.org/2/library/numbers.html 11 | """ 12 | 13 | import numbers 14 | 15 | assert isinstance(0, numbers.Integral) 16 | assert isinstance(0, numbers.Rational) 17 | assert isinstance(0, numbers.Real) 18 | assert isinstance(0, numbers.Complex) 19 | assert not isinstance(1j, numbers.Real) 20 | 21 | # int, float and long are classes. 22 | # It is just that `1` and `1.1` are nice looking literals. 23 | 24 | assert (1).__add__(1) == 2 25 | assert 1L.__add__(1L) == 2L 26 | assert 1.1.__add__(1.1) == 2.2 27 | 28 | # It is not possible to omit parenthesis because the lexer would treate 29 | # the `1.` as a float causing an ambiguity. 30 | 31 | #a = 1.__add__(1) # SyntaxError 32 | 33 | # A less readable alternative is to use a space: 34 | 35 | assert 1 .__add__(1) == 2 36 | 37 | # As any built-in class, they have global constructor functions: 38 | 39 | assert 1 == int(1) 40 | assert 1 == long(1L) 41 | assert 1.1 == float(1.1) 42 | 43 | # The constructors also support construction from any numeric type 44 | # or strings: 45 | 46 | assert 1 == int(1.5) 47 | assert 1.1 == float('1.1') 48 | 49 | # Each of them has a class with the same name: 50 | 51 | class myint(int): 52 | pass 53 | 54 | assert myint(1) + myint(2) == myint(3) 55 | 56 | if '# float': 57 | 58 | # Unlike int, has a maximum range, machine defined I suppose. 59 | # In orther words, no implicit arbitrary precision convertion. 60 | 61 | # How to get the max: 62 | # http://stackoverflow.com/questions/3477283/what-is-the-maximum-float-in-python 63 | 64 | # If you write a constant that is larger than that, it becomes infinity. 65 | #assert 9e99999999999999999999999999999999999999999 == float('inf') 66 | 67 | # Arbitrary precision feature request: 68 | # http://stackoverflow.com/questions/11522933/python-floating-point-arbitrary-precision-available 69 | 70 | pass 71 | 72 | if 'inf': 73 | 74 | # Watch out for the max float, which then EQUALS infinity. 75 | assert(1e10 < float('inf')) 76 | 77 | assert(float('-inf') < -1e10) 78 | 79 | assert(float('inf') == float('inf')) 80 | assert(float('-inf') == float('-inf')) 81 | 82 | # int always works, even though float has limited size. 83 | # http://stackoverflow.com/questions/24587994/infinite-integer-in-python 84 | 85 | assert(999999999999999999999999999999999999999999999 < float('inf')) 86 | 87 | if 'nan': 88 | 89 | # float('inf')) * 0 90 | 91 | pass 92 | 93 | if '## imaginary ## complex': 94 | 95 | """ 96 | Imaginary numbers have built-in literals of the form `Nj`. 97 | """ 98 | 99 | assert 1j * 1j == -1 100 | 101 | assert 1 + 2j == complex(1, 2) 102 | 103 | j = 2 104 | assert 1j * 1j == -1 105 | assert j * j == 4 106 | 107 | assert 1j * 1j == -1 108 | assert (1 + 2j).real == 1 109 | assert (1 + 2j).imag == 2 110 | assert 1j.conjugate() == -1j 111 | -------------------------------------------------------------------------------- /numpy_cheat.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | import StringIO 4 | 5 | import numpy as np 6 | 7 | def norm2(a): 8 | """ 9 | Mean squared norm. 10 | """ 11 | return np.linalg.norm(a) / a.size 12 | 13 | def dist2(a, a2): 14 | return norm2(a - a2) 15 | 16 | def array_equal(a, a2, err=10e-6, dist=dist2): 17 | """ 18 | True iff two np.arrays are equal within a given `err` precision for given `dist` distance. 19 | """ 20 | return dist(a, a2) < err 21 | 22 | if '## ndarray': 23 | 24 | if '## slicing': 25 | 26 | x = np.array([ 27 | [0, 1, 2], 28 | [3, 4, 5], 29 | [6, 7, 8], 30 | ]) 31 | 32 | assert np.array_equal( 33 | x[:, 0], 34 | [0, 3, 6] 35 | ) 36 | 37 | assert np.array_equal( 38 | x[0, :], 39 | [0, 1, 2] 40 | ) 41 | 42 | assert np.array_equal( 43 | x[0:3:2, 0:3:2], 44 | [ 45 | [0, 2], 46 | [6, 8], 47 | ] 48 | ) 49 | 50 | # Pairwise list! 51 | assert np.array_equal( 52 | x[[0, 1], [1, 2]], 53 | [1, 5] 54 | ) 55 | 56 | # Submtraix. 57 | assert np.array_equal( 58 | x[[[0], [1]], [1, 2]], 59 | [ 60 | [1, 2], 61 | [4, 5], 62 | ] 63 | ) 64 | 65 | # Transposed. 66 | assert np.array_equal( 67 | x[[0, 1], [[1], [2]]], 68 | [ 69 | [1, 4], 70 | [2, 5], 71 | ] 72 | ) 73 | 74 | if '## Split by value of column': 75 | 76 | """ 77 | http://stackoverflow.com/questions/21757680/python-separate-matrix-by-column-values 78 | """ 79 | 80 | a = np.array([ 81 | [0, 1, 1], 82 | [1, 1, -1], 83 | [0, 2, 2], 84 | [1, 2, -2], 85 | [0, 3, 3], 86 | [1, 3, -3], 87 | ]) 88 | aa = np.array([ 89 | [ 90 | [0, 1, 1], 91 | [0, 2, 2], 92 | [0, 3, 3], 93 | ], 94 | [ 95 | [1, 1, -1], 96 | [1, 2, -2], 97 | [1, 3, -3], 98 | ], 99 | ]) 100 | 101 | if '## Known keys': 102 | 103 | assert np.array_equal( 104 | a[a[:, 0] == 0, :], 105 | np.array([ 106 | [0, 1, 1], 107 | [0, 2, 2], 108 | [0, 3, 3], 109 | ]) 110 | ) 111 | assert np.array_equal( 112 | a[a[:, 0] == 1, :], 113 | np.array([ 114 | [1, 1, -1], 115 | [1, 2, -2], 116 | [1, 3, -3], 117 | ]) 118 | ) 119 | 120 | if '## Unknown values': 121 | 122 | keys = list(set(a[:, 0])) 123 | for key in keys: 124 | assert np.array_equal( 125 | a[a[:, 0] == key, :], 126 | aa[key], 127 | ) 128 | 129 | if '## sum': 130 | 131 | # Over all elements. 132 | assert array_equal( 133 | np.sum([ 134 | [0, 1], 135 | [2, 3] 136 | ]), 137 | 6 138 | ) 139 | 140 | # Some dimensions only. 141 | assert array_equal( 142 | np.sum([[0, 1], [2, 3]], axis = 0), 143 | [2, 4] 144 | ) 145 | assert array_equal( 146 | np.sum([[0, 1], [2, 3]], axis = 1), 147 | [1, 5] 148 | ) 149 | 150 | if '## Structured array ## dtype': 151 | 152 | """ 153 | Using dtype changes the form of the array. 154 | It becomes a list of tuples. 155 | Insane. 156 | 157 | Types specifiers at: http://docs.scipy.org/doc/numpy/reference/arrays.dtypes.html 158 | """ 159 | 160 | x = np.array([ 161 | (0, 1), 162 | (2, 3), 163 | ], 164 | dtype=[ 165 | ('a', 'i4'), 166 | ('b', 'f4') 167 | ] 168 | ) 169 | assert type(x) == np.ndarray 170 | assert type(x[0]) == np.void 171 | assert type(x[0][0]) == np.int32 172 | assert type(x[0][1]) == np.float32 173 | assert type(x[1][0]) == np.int32 174 | assert type(x[1][1]) == np.float32 175 | assert np.array_equal(x['a'], [0, 2]) 176 | assert np.array_equal(x['b'], [1.0, 3.0]) 177 | assert x[0]['a'] == 0 178 | 179 | # Does not work with arrays here. Insane. 180 | # x = np.array([ 181 | # [0, 1], 182 | # [2, 3], 183 | # ], 184 | # dtype=[('a','i4'),('b','f4')] 185 | # ) 186 | 187 | # Cannot use two indexes. 188 | try: 189 | assert x[0, 0] == 1 190 | except IndexError: 191 | pass 192 | else: 193 | assert False 194 | 195 | # print type(a[0]) 196 | # assert a[0] == (1, 2.0, 'ab') 197 | 198 | if '## file io': 199 | 200 | # TODO: examples 201 | 202 | """ 203 | a = np.zeros((2, 3)) 204 | 205 | # Space separated. 206 | np.savetxt("a.tmp", a) 207 | 208 | np.savetxt("b.tmp", delimiter = ", ") 209 | 210 | # single width format 211 | np.savetxt("c.tmp", delimiter = 3) 212 | 213 | # multi width format 214 | np.savetxt("d.tmp", delimiter = (4, 3, 2)) 215 | 216 | # strip trailing/starting whitespace 217 | np.savetxt("e.tmp", autostrip = True) 218 | 219 | # stop reading line when # is found 220 | np.savetxt("f.tmp", comments = '# ') 221 | 222 | # skip first line, and last two lines 223 | np.savetxt("g.tmp", skip_header = 1, skip_footer = 2) 224 | 225 | # only use first and last columns 226 | np.savetxt("h.tmp", usecols = (0, -1)) 227 | 228 | # same, give names 229 | np.savetxt("b.tmp", names = "a, b, c", usecols = ("a", "c")) 230 | 231 | b = genfromtxt("a.tmp") 232 | 233 | b = loadtxt("a.tmp") 234 | """ 235 | 236 | if 'loadtxt': 237 | 238 | assert np.array_equal( 239 | np.loadtxt(StringIO.StringIO("0 1\n2 3\n")), 240 | [ 241 | [0.0, 1.0], 242 | [2.0, 3.0], 243 | ] 244 | ) 245 | 246 | # Dtype works like for the array constructor. 247 | x = np.loadtxt( 248 | StringIO.StringIO("0 1\n2 3\n"), 249 | dtype=[('a', 'i4'), ('b', 'f4')] 250 | ) 251 | assert type(x) == np.ndarray 252 | assert type(x[0]) == np.void 253 | assert type(x[0][0]) == np.int32 254 | assert type(x[0][1]) == np.float32 255 | assert type(x[1][0]) == np.int32 256 | assert type(x[1][1]) == np.float32 257 | 258 | 259 | # usecols 260 | 261 | assert array_equal( 262 | np.loadtxt( 263 | StringIO.StringIO("0 1\n2 3\n"), 264 | usecols=(1,) 265 | ), 266 | [ 267 | [1.0, 3.0], 268 | ] 269 | ) 270 | 271 | # It is slow for large files: 272 | # http://stackoverflow.com/questions/18259393/numpy-loading-csv-too-slow-compared-to-matlab 273 | -------------------------------------------------------------------------------- /operators.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | """ 4 | In python everything is an object. 5 | 6 | There is operator overload: every operator has a correponding method 7 | 8 | In Python, methods that can become operators are prefixed and suffixed by `__`. 9 | 10 | For example: 11 | 12 | - `==` and `__eq__()` 13 | - `+` and `__add__()` 14 | - `**` and `__pow__()` 15 | - `//` and `__TODO__()` 16 | 17 | Built-in classes like `int` simply implement those methods. 18 | """ 19 | 20 | assert 0 == 0 21 | 22 | assert 2 * 3 == 6 23 | 24 | # C like division arithmetic: 25 | 26 | assert 1 / 2 == 0 27 | assert 1 / 2.0 == 0.5 28 | assert 1 / float(2) == 0.5 29 | 30 | # Floor division: 31 | 32 | assert 9.0 // 2.0 == 4 33 | 34 | # pow: 35 | 36 | assert 2 ** 3 37 | 38 | if '## boolean operator': 39 | 40 | assert not True == False 41 | assert True and False == False 42 | assert True or False == True 43 | 44 | if '## chained comparison': 45 | 46 | # Insane sugar: 47 | # http://stackoverflow.com/questions/24436150/how-does-interval-comparison-work 48 | 49 | assert 1 < 2 < 3 < 4 < 5 50 | -------------------------------------------------------------------------------- /optparse_cheat.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | import optparse 4 | 5 | # action append 6 | parser = optparse.OptionParser() 7 | parser.add_option("-a", action='append') 8 | options, args = parser.parse_args() 9 | assert(options == {'a': None}) 10 | options, args = parser.parse_args(['-a', 'b']) 11 | assert(options == {'a': ['b']}) 12 | -------------------------------------------------------------------------------- /os_cheat.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | """ 4 | ## os 5 | 6 | Wrappers for os specific stuff. 7 | 8 | Lots of important file and directory operations. 9 | """ 10 | 11 | import tempfile 12 | import os 13 | import shutil 14 | 15 | if '## sep': 16 | 17 | # Path separator ('/' linux/mac '\' on windows): 18 | 19 | print('os.sep = ' + os.sep.encode('string-escape')) 20 | 21 | if '## linesep': 22 | 23 | # System newline separator ('\n' Linux, '\r' Mac, '\n\r' Windows): 24 | 25 | print('os.linesep = ' + os.linesep.encode('string-escape')) 26 | 27 | if '## listdir ## ls': 28 | 29 | # **Always** use Unicode input since the output gets the same encoding as this input 30 | # and filenames may contain non ASCII chars! 31 | 32 | print('os.listdir(u".") = ' + str(os.listdir(u'/'))) 33 | 34 | if '## unlink ## rm': 35 | 36 | path = "open.tmp" 37 | f = open(path, "w") 38 | assert os.path.isfile(path) 39 | os.unlink(path) 40 | assert not os.path.exists(path) 41 | 42 | if '## touch': pass 43 | 44 | # http://stackoverflow.com/questions/12654772/create-empty-file-using-python 45 | # open('/path/to/file', 'a').close() 46 | 47 | if '## mkdir ## rmdir': 48 | 49 | # Only works if directory is empty. 50 | # For recursive directory removal, see `shutil.rmtree`. 51 | 52 | path = 'dir.tmp' 53 | os.mkdir(path) 54 | assert os.path.isdir(path) 55 | os.rmdir(path) 56 | assert not os.path.exists(path) 57 | 58 | if '## makedirs': 59 | 60 | path0 = 'tmp0' 61 | path1 = 'tmp1' 62 | path2 = 'tmp2' 63 | path = os.path.join(path0, path1, path2) 64 | 65 | os.makedirs(path) 66 | assert os.path.isdir(path) 67 | os.removedirs(path) 68 | 69 | if '## getcwd #pwd #chdir #cd': 70 | 71 | # Get current working dir (each process has a cwd) 72 | 73 | print('os.getcwd() = ' + os.getcwd()) 74 | 75 | if '## symlink': 76 | 77 | """ 78 | os.symlink(name, origin) 79 | Where name is the place the symlinke will be created at, 80 | and origin what it points to. 81 | """ 82 | 83 | if '## listdir ## ls': 84 | 85 | # List basenames in a directory, excluding `.` and `..`. 86 | 87 | d = tempfile.mkdtemp() 88 | open(os.path.join(d, 'a'), 'a').close() 89 | open(os.path.join(d, 'b'), 'a').close() 90 | print(os.listdir(d)) 91 | assert sorted(os.listdir(d)) == ['a', 'b'] 92 | shutil.rmtree(d) 93 | 94 | if '## walk ## find': 95 | 96 | """ 97 | Walk all subdirectories recursively. 98 | 99 | Out of the box options: 100 | 101 | - up down or down up 102 | - onerror callback function 103 | - followlinks or not 104 | 105 | For input like: 106 | 107 | for root, dirs, files in os.walk(u"tests"): 108 | print(root) 109 | print(dirs) 110 | print(files) 111 | print() 112 | 113 | The output is of the form: 114 | 115 | directory path 116 | [basename of directories inside it] 117 | [basename of files inside it] 118 | 119 | It loops over all directories. 120 | 121 | **Be paranoid and always use unicode `u"."` in Python 2.7**, since the output has the same encoding as that input, 122 | and paths are primary examples of things that may contain unicode characters. 123 | """ 124 | 125 | # Get relative paths to all non-directory files: 126 | 127 | for root, dirs, files in os.walk(u'.'): 128 | for basename in files: 129 | path = os.path.join(root, basename) 130 | #print(path) 131 | 132 | # Get relative paths to all directories: 133 | 134 | for root, dirs, files in os.walk(u'.'): 135 | for basename in dirs: 136 | path = os.path.join(root, basename) 137 | #print(path) 138 | 139 | # Does not include current directory dot `.` nor upper directory two dots `..`. 140 | 141 | # Get relative paths to all files and directories: 142 | 143 | for root, dirs, files in os.walk(u'.'): 144 | for basename in dirs + files: 145 | path = os.path.join(root, basename) 146 | #print(path) 147 | 148 | # To do all of Bash `find` filtering, jus use regular ifs. Sanity! 149 | 150 | for root, dirs, files in os.walk(u'.'): 151 | for basename in dirs + files: 152 | path = os.path.join(root, basename) 153 | if os.path.splitext(path)[1] == '.pdf': 154 | #print(path) 155 | pass 156 | 157 | # The order and choice of directories which will be descended into is determined by `dirs`. 158 | 159 | # If you modify if in-place, you can alter the descent order! Typical applications include: 160 | 161 | # - `sort` to fix descent order 162 | 163 | # Only sorts each level and the descent order: 164 | 165 | # - files come after directories 166 | # - shallow come before deep 167 | 168 | for root, dirs, files in os.walk(u'.'): 169 | dirs.sort() 170 | files.sort() 171 | for basename in dirs + files: 172 | path = os.path.join(root, basename) 173 | #print(path) 174 | 175 | # For a full sort, the only way is to put all paths in a list and sort the list. 176 | 177 | # That is less efficient because 2n log 2n > 2(n log n and rarely necessary. 178 | 179 | # - `remove` to prune any directories with a given basename: 180 | 181 | for root, dirs, files in os.walk(u'.'): 182 | try: 183 | dirs.remove(u'prune_me') 184 | except ValueError: 185 | pass 186 | for basename in dirs + files: 187 | path = os.path.join(root, basename) 188 | #print(path) 189 | 190 | if '## devnul.': 191 | 192 | print('os.devnull = ' + os.devnull) 193 | 194 | if '## system': 195 | 196 | # https://docs.python.org/2/library/os.html#os.system 197 | 198 | # Run command from default shell. 199 | 200 | # Return the exit status. 201 | 202 | # See subprocess for a better option. 203 | 204 | pass 205 | 206 | if '## glob': 207 | 208 | """ 209 | Searches directories using POSIX glob patterns. 210 | 211 | Applications: 212 | 213 | - list files at a given level: os.glob('*/*/*') 214 | """ 215 | -------------------------------------------------------------------------------- /pandas_cheat.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | import pandas as pd 4 | 5 | s = pd.Series([1, 2, 4]) 6 | s.iloc[-1] 7 | # TODO compare. 8 | s.rolling(2, min_periods=1).mean() == [1, 1.5, 3.5] 9 | # s.rolling(2, min_periods=1).mean()[-1] 10 | -------------------------------------------------------------------------------- /path_cheat.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | """ 4 | ## path 5 | 6 | os.path vs os: 7 | http://stackoverflow.com/questions/2724348/should-i-use-import-os-path-or-import-os 8 | """ 9 | 10 | import os.path 11 | import tempfile 12 | 13 | if '## join': 14 | 15 | assert os.path.join('a', 'b', 'c') == 'a{s}b{s}c'.format(s=os.sep) 16 | os.path.join('a//', '/b') 17 | 18 | if '## split ## splitext': 19 | 20 | path = os.path.join('a', 'b', 'c.e') 21 | root, basename = os.path.split(path) 22 | basename_noext, ext = os.path.splitext(basename) 23 | assert root == os.path.join('a', 'b') 24 | assert basename_noext == 'c' 25 | assert ext == '.e' 26 | 27 | if '## exists': 28 | 29 | # Returns False for broken symlinks. 30 | # lexists returns True in that case. 31 | 32 | temp = tempfile.NamedTemporaryFile() 33 | assert os.path.exists(temp.name) 34 | temp.close() 35 | assert not os.path.exists(temp.name) 36 | 37 | temp = tempfile.mkdtemp() 38 | assert os.path.exists(temp) 39 | os.rmdir(temp) 40 | 41 | if '## isfile': 42 | 43 | # Exists and is file, not directory. 44 | 45 | temp = tempfile.NamedTemporaryFile() 46 | assert os.path.isfile(temp.name) 47 | temp.close() 48 | assert not os.path.isfile(temp.name) 49 | 50 | temp = tempfile.mkdtemp() 51 | assert not os.path.isfile(temp) 52 | os.rmdir(temp) 53 | 54 | if '## isdir': 55 | 56 | # Exists and is directory. 57 | 58 | temp = tempfile.NamedTemporaryFile() 59 | assert not os.path.isdir(temp.name) 60 | temp.close() 61 | 62 | temp = tempfile.mkdtemp() 63 | assert os.path.isdir(temp) 64 | os.rmdir(temp) 65 | assert not os.path.isdir(temp) 66 | 67 | if '## islink': 68 | 69 | # Detect if given path is a symbolic link. 70 | 71 | # TODO example. 72 | 73 | os.path.islink('/a') 74 | 75 | if '## abspath': 76 | 77 | # Absolute path: 78 | 79 | print('os.path.abspath(u\'.\') = ' + os.path.abspath(u'.')) 80 | 81 | if '## relpath': 82 | 83 | # Absolute path resolving links recursively: 84 | 85 | os.path.relpath(u'/a') 86 | 87 | if '## commonprefix': 88 | 89 | assert os.path.commonprefix([ 90 | '{s}a{s}b{s}c{s}d'.format(s=os.sep), 91 | '{s}a{s}b{s}e{s}d'.format(s=os.sep) 92 | ]) == '{s}a{s}b{s}'.format(s=os.sep) 93 | 94 | def isparent(path1, path2): 95 | return os.path.commonprefix([path1, path2]) == path1 96 | 97 | def ischild(path1, path2): 98 | return os.path.commonprefix([path1, path2]) == path2 99 | -------------------------------------------------------------------------------- /pexpect/python_test.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | ''' 3 | Test with the Python REPL itself. 4 | ''' 5 | import sys 6 | import pexpect 7 | prompt = '>>> ' 8 | child = pexpect.spawn('python3', encoding='utf-8') 9 | child.setecho(False) 10 | child.expect(prompt) 11 | child.sendline('1 + 1') 12 | child.expect(prompt) 13 | assert child.before.rstrip() == '2' 14 | child.sendline('2 + 2') 15 | child.expect(prompt) 16 | assert child.before.rstrip() == '4' 17 | child.sendcontrol('d') 18 | child.close() 19 | -------------------------------------------------------------------------------- /pickle_cheat.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | import pickle 3 | 4 | if 'slots': 5 | 6 | if 'Default getstate and setstate with slots': 7 | 8 | # Use -1 pickling version. 9 | # http://stackoverflow.com/questions/2204155/why-am-i-getting-an-error-about-my-class-defining-slots-when-trying-to-pickl/2204702#2204702 10 | 11 | class C(object): 12 | __slots__ = 'a' 13 | def __init__(self, a): 14 | self.a = a 15 | s = pickle.dumps(C(1), -1) 16 | assert pickle.loads(s).a == 1 17 | 18 | # Expects a tuple of (__dict__, dict with __slots__ as keys). 19 | # https://www.python.org/dev/peps/pep-0307/ 20 | 21 | class C(object): 22 | __slots__ = 'i', 'j' 23 | def __init__(self, i): 24 | self.i = i 25 | self.j = -i 26 | def __getstate__(self): 27 | return (None, {'i': self.i}) 28 | assert pickle.loads(pickle.dumps(C(1), -1)).i == 1 29 | try: 30 | assert pickle.loads(pickle.dumps(C(1), -1)).j == -1 31 | except AttributeError: 32 | pass 33 | else: 34 | raise 35 | 36 | class C(object): 37 | __slots__ = 'i' 38 | def __init__(self, i): 39 | self.i = i 40 | def __setstate__(self, t): 41 | d = t[1] 42 | self.i = d['i'] 43 | assert pickle.loads(pickle.dumps(C(1), -1)).i == 1 44 | 45 | # Or fully explicit dict. 46 | 47 | class C(object): 48 | __slots__ = ('i',) 49 | def __init__(self, i): 50 | self.i = i 51 | def __getstate__(self): 52 | return { k:getattr(self, k) for k in self.__class__.__slots__ } 53 | def __setstate__(self, d): 54 | for k in d: 55 | setattr(self, k, d[k]) 56 | assert pickle.loads(pickle.dumps(C(1), -1)).i == 1 57 | 58 | # All but one. 59 | # http://stackoverflow.com/questions/6635331/pickle-all-attributes-except-one/41896767#41896767 60 | 61 | class C(object): 62 | _pickle_slots = ['i'] 63 | __slots__ = _pickle_slots + ['j'] 64 | def __init__(self, i, j): 65 | self.i = i 66 | self.j = j 67 | def __getstate__(self): 68 | return (None, {k:getattr(self, k) for k in C._pickle_slots}) 69 | o = pickle.loads(pickle.dumps(C(1, 2), -1)) 70 | assert o.i == 1 71 | try: 72 | o.j 73 | except: 74 | pass 75 | else: 76 | raise 77 | 78 | if 'instancemethod error': 79 | 80 | # http://stackoverflow.com/questions/27318290/why-can-i-pass-an-instance-method-to-multiprocessing-process-but-not-a-multipro 81 | 82 | # Basic example 83 | 84 | class A(object): 85 | def z(self): 86 | return 1 87 | try: 88 | pickle.dumps(A.z, -1) 89 | except pickle.PicklingError: 90 | pass 91 | else: 92 | raise 93 | 94 | # Less obvious via inner member: 95 | 96 | class A(object): 97 | def __init__(self): 98 | self.f = self.f 99 | def f(): 100 | return 1 101 | try: 102 | pickle.dumps(A(), -1) 103 | except pickle.PicklingError: 104 | pass 105 | else: 106 | raise 107 | 108 | # Fine with regular functions: 109 | 110 | def f(): 111 | return 1 112 | class A(object): 113 | def __init__(self): 114 | self.f = f 115 | s = pickle.dumps(A(), -1) 116 | pickle.loads(s).f() == 1 117 | 118 | if '# getstate # setstate': 119 | 120 | if 'Minimal example': 121 | 122 | """ 123 | - __getstate__ spits a dict 124 | - __setstate__ reads the dict and uses it to setup an object 125 | """ 126 | 127 | class C(object): 128 | 129 | def __init__(self, i): 130 | self.i = i 131 | 132 | def f(self): 133 | return self.i + 1 134 | 135 | def __getstate__(self): 136 | return {'a': self.i} 137 | 138 | def __setstate__(self, d): 139 | self.i = d['a'] 140 | 141 | assert pickle.loads(pickle.dumps(C(1), -1)).i == 1 142 | 143 | # You don't need to pickle methods. 144 | assert pickle.loads(pickle.dumps(C(1), -1)).f() == 2 145 | 146 | if 'Example that shows call order': 147 | 148 | x = 0 149 | 150 | class C(object): 151 | 152 | def __init__(self, i): 153 | self.i = i 154 | 155 | def __getstate__(self): 156 | global x 157 | x = 1 158 | self.i *= 2 159 | return self.__dict__ 160 | 161 | def __setstate__(self, d): 162 | global x 163 | x = 2 164 | self.__dict__ = d 165 | self.i *= 3 166 | 167 | c = C(1) 168 | assert c.i == 1 169 | assert x == 0 170 | 171 | s = pickle.dumps(C(1)) 172 | # __getstate__ was called. 173 | assert x == 1 174 | # But it is not called on the original object, which was not changed. 175 | assert c.i == 1 176 | 177 | c2 = pickle.loads(s) 178 | # __setstate__ was called. 179 | assert x == 2 180 | assert c.i == 1 181 | assert c2.i == 6 182 | 183 | if '# inheritance': 184 | 185 | # Works by default without custom methods. 186 | 187 | class C(object): 188 | def __init__(self, i): 189 | self.i = i 190 | class D(C): 191 | def __init__(self, i, j): 192 | super(self.__class__, self).__init__(i) 193 | self.j = j 194 | assert pickle.loads(pickle.dumps(C(1), -1)).i == 1 195 | assert pickle.loads(pickle.dumps(D(1, 2), -1)).i == 1 196 | assert pickle.loads(pickle.dumps(D(1, 2), -1)).j == 2 197 | -------------------------------------------------------------------------------- /pip.md: -------------------------------------------------------------------------------- 1 | # Pip 2 | 3 | Python CLI package manager. 4 | 5 | Analogous to Ruby `gem`. 6 | 7 | Not part of the stdlib. 8 | 9 | Manages package dependencies. 10 | 11 | `pip` looks by default for packages under PyPi (aka the cheeseshop) located at: 12 | 13 | It is also possible to add custom servers, and even to install from source control protocols such as Git directly. 14 | 15 | Install `pip`: 16 | 17 | wget -O- https://bootstrap.pypa.io/get-pip.py | sudo python 18 | 19 | Upgrade pip version: 20 | 21 | pip install -U pip 22 | 23 | Search for a package: 24 | 25 | pip search $pkg 26 | 27 | Install package: 28 | 29 | sudo pip install $pkg 30 | 31 | List installed packages with versions to stdout: 32 | 33 | pip freeze 34 | 35 | Install packages listed on a pip file: 36 | 37 | pip install -r requirements.txt 38 | 39 | Good simple way to give a requirement list for projects intended only for developers who will clone, 40 | not end users who will do `pip install`. 41 | 42 | Install from git repo: 43 | 44 | sudo pip install git+git@github.com/cirosantilli/python.git@master 45 | 46 | `.pip` files is just a newline separated list of filenames. 47 | It is exactly the same generated by `pip freeze`. 48 | 49 | Show all files of installed package: 50 | 51 | pip show -f $pkg 52 | 53 | Uninstall package: 54 | 55 | sudo pip uninstall $pkg 56 | -------------------------------------------------------------------------------- /pros-and-cons.md: -------------------------------------------------------------------------------- 1 | # Pros and cons 2 | 3 | ## Pros 4 | 5 | Python is part of the [LSB](http://refspecs.linux-foundation.org/LSB_4.1.0/LSB-Languages/LSB-Languages/python.html), so any Linux distribution must have it. Perl is too, but Java and Ruby are not. 6 | 7 | Python is great for small / medium projects: 8 | 9 | - built-in lists and dictionary literals `[]` `{}`. Really helpful to type less for shorter scripts. 10 | 11 | - dynamic typing: 12 | 13 | a = 1 14 | a = "abc" 15 | 16 | Good when writing smaller scripts because it means much less typing. 17 | 18 | - domains it dominates for scripting: 19 | 20 | - scientific: 21 | - binary executable analysis automation for hackers: http://www.amazon.com/dp/1593271921/ , https://github.com/aquynh/capstone , IDA Pro https://www.hex-rays.com/products/ida/support/idapython_docs/ 22 | 23 | ## Cons 24 | 25 | - dynamic typing: 26 | 27 | a = 1 28 | a = "abc" 29 | 30 | What this means is that tons of projects will not document what types of objects functions need to get and large projects become a mess. 31 | 32 | - putting self in every class method: `__init__(self)` 33 | 34 | - global functions that should be methods functions: `len([1,2])` instead of `[1.2].len()` 35 | 36 | - there are some key tools missing from the stdlib and without one very dominant implementation: 37 | 38 | - package management 39 | - auto documentation tools (e.g. Sphinx) 40 | - Rake equivalent 41 | 42 | -------------------------------------------------------------------------------- /py_from_c/Makefile: -------------------------------------------------------------------------------- 1 | .POSIX: 2 | 3 | CC = gcc 4 | CXX = g++ 5 | CFLGS = -std=c99 6 | CCFLGS = -ggdb3 -O0 -pedantic-errors -Wall -Wextra 7 | CXXFLGS = -std=c++11 8 | IN_EXT = .c 9 | IN_CXX_EXT = .cpp 10 | OUT_EXT = .out 11 | 12 | OUTS = $(addsuffix $(OUT_EXT), $(basename $(wildcard *$(IN_EXT))) $(basename $(wildcard *$(IN_CXX_EXT)))) 13 | 14 | .PHONY: all clean test 15 | 16 | all: $(OUTS) 17 | 18 | %$(OUT_EXT): %$(IN_EXT) 19 | $(CC) $(CFLGS) $(CCFLGS) $$(pkg-config --cflags python3) -o '$@' '$<' $$(pkg-config --libs python3) 20 | 21 | %$(OUT_EXT): %$(IN_CXX_EXT) 22 | $(CXX) $(CXXFLGS) $(CCFLGS) $$(pkg-config --cflags python3) -o '$@' '$<' $$(pkg-config --libs python3) 23 | 24 | clean: 25 | rm -rf *'$(OUT_EXT)' __pycache__ *.pyc 26 | 27 | test: all 28 | @\ 29 | for t in *"$(OUT_EXT)"; do\ 30 | if ! ./"$$t"; then\ 31 | echo "ASSERT FAILED: $$t";\ 32 | exit 1;\ 33 | fi;\ 34 | done;\ 35 | -------------------------------------------------------------------------------- /py_from_c/README.md: -------------------------------------------------------------------------------- 1 | # Python from C 2 | 3 | How to call Python from c. 4 | 5 | This is called embedding Python. 6 | 7 | It basically means calling the Python interpreter from C, and passing values between the two. 8 | 9 | Examples adapted from: 10 | -------------------------------------------------------------------------------- /py_from_c/eval.c: -------------------------------------------------------------------------------- 1 | /* Adapted from: https://docs.python.org/3.7/extending/embedding.html#very-high-level-embedding 2 | * 3 | * Simply `eval` a Python string in C, don't communicate any values between the two. Not very exciting. 4 | */ 5 | 6 | #define PY_SSIZE_T_CLEAN 7 | #include 8 | 9 | int main(int argc, char *argv[]) { 10 | (void)argc; 11 | wchar_t *program = Py_DecodeLocale(argv[0], NULL); 12 | if (program == NULL) { 13 | fprintf(stderr, "Fatal error: cannot decode argv[0]\n"); 14 | exit(1); 15 | } 16 | Py_SetProgramName(program); 17 | Py_Initialize(); 18 | PyRun_SimpleString(argv[1]); 19 | if (Py_FinalizeEx() < 0) { 20 | exit(120); 21 | } 22 | PyMem_RawFree(program); 23 | return 0; 24 | } 25 | -------------------------------------------------------------------------------- /py_from_c/pure.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | # This is provided by the C file. 4 | # But since we are embedding Python, we don't even need to create a separate 5 | # .so file: it is provided directly through the Python invocation! 6 | 7 | import my_native_module 8 | 9 | def test_native_method(a, b): 10 | return my_native_module.my_native_method(a, b) 11 | 12 | def test_native_class(): 13 | # Positional arguments. 14 | my_native_object = my_native_module.MyNativeClass('ab', 'cd', 13) 15 | assert my_native_object.name() == 'ab cd' 16 | 17 | # Named arguments. 18 | my_native_object = my_native_module.MyNativeClass(first='ef', last='gh', number=13) 19 | assert my_native_object.name() == 'ef gh' 20 | 21 | # Default values and set property. 22 | my_native_object = my_native_module.MyNativeClass() 23 | my_native_object.first = 'ih' 24 | assert my_native_object.name() == 'ih ' 25 | 26 | # TODO see TODO in pure.c. 27 | #my_derived_native_object = my_native_module.MyDerivedNativeClass('ab', 'cd', 13, 'ef', 'gh', 21) 28 | #print(my_derived_native_object.name2()) 29 | return 13 30 | -------------------------------------------------------------------------------- /py_from_c/test: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | set -eu 3 | [ "$(./eval.out 'print(2 ** 3)')" = 8 ] 4 | [ "$(PYTHONPATH="${PYTHONPATH:-}:." ./pure.out pure test_native_method 2 3)" = 6 ] 5 | [ "$(PYTHONPATH="${PYTHONPATH:-}:." ./pure.out pure test_native_class)" = 13 ] 6 | [ "$(PYTHONPATH="${PYTHONPATH:-}:." ./pure_cpp.out pure test_native_method 2 3)" = 6 ] 7 | [ "$(PYTHONPATH="${PYTHONPATH:-}:." ./pure_cpp.out pure test_native_class)" = 13 ] 8 | -------------------------------------------------------------------------------- /pysocks_cheat/tor.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | """ 4 | http://stackoverflow.com/questions/711351/using-urllib-with-tor 5 | http://stackoverflow.com/a/34493721/895245 6 | 7 | Before running, make sure that Tor is running on port 9050. Ubuntu 15.10: 8 | 9 | sudo apt-get install tor 10 | 11 | Multiple connections at the same time: http://stackoverflow.com/a/8100870/895245 12 | """ 13 | 14 | import socket 15 | import socks 16 | import urllib2 17 | 18 | ipcheck_url = 'http://checkip.amazonaws.com/' 19 | 20 | # Actual IP. 21 | print(urllib2.urlopen(ipcheck_url).read()) 22 | 23 | # Tor IP. 24 | socks.setdefaultproxy(socks.PROXY_TYPE_SOCKS5, '127.0.0.1', 9050) 25 | socket.socket = socks.socksocket 26 | print(urllib2.urlopen(ipcheck_url).read()) 27 | print(urllib2.urlopen(ipcheck_url).read()) 28 | 29 | # Another Tor IP. 30 | #socks.setdefaultproxy(socks.PROXY_TYPE_SOCKS5, '127.0.0.1', 9052) 31 | #print(urllib2.urlopen(ipcheck_url).read()) 32 | -------------------------------------------------------------------------------- /python-utility.md: -------------------------------------------------------------------------------- 1 | # python utility 2 | 3 | - `-O`: optimize. 4 | 5 | - `assert` is removed from `.pyc` 6 | 7 | - `__debug__ == False` 8 | 9 | You can write stuff like 10 | 11 | if __debug__: print "debug" 12 | 13 | and it will only show show is `-O` is off. 14 | -------------------------------------------------------------------------------- /python3/README.md: -------------------------------------------------------------------------------- 1 | # Python 3 2 | 3 | 1. [main](main.py) 4 | 1. [pip](pip.md) 5 | 1. Standard library 6 | 1. [enum](enum_cheat.py) 7 | -------------------------------------------------------------------------------- /python3/enum_cheat.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | from enum import Enum 4 | 5 | # http://stackoverflow.com/questions/36932/how-can-i-represent-an-enum-in-python 6 | 7 | Animal = Enum('Animal', 'ant bee cat') 8 | assert Animal.ant == Animal.ant 9 | assert Animal.ant != Animal.bee 10 | 11 | # The main advantage of the enum class, 12 | # is that enums are diferent from any other value. 13 | assert Animal.ant != 1 14 | -------------------------------------------------------------------------------- /python3/pip.md: -------------------------------------------------------------------------------- 1 | # pip 2 | 3 | On Ubuntu, `pip` can be used with python 3 as: 4 | 5 | sudo apt-get install python3-pip 6 | pip3 install ... 7 | -------------------------------------------------------------------------------- /random_cheat.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | """ 4 | ## random 5 | """ 6 | 7 | import random 8 | 9 | if '## uniform': 10 | 11 | # Real on interval: 12 | 13 | n = 1000 14 | su = 0 15 | l = 0 16 | r = 1 17 | for i in xrange(n): 18 | rand = random.uniform(l,r) 19 | #print(rand) 20 | assert rand >= l and rand <= r 21 | su += random.uniform(0,1) 22 | 23 | # Check average: 24 | 25 | assert su/float((r - l)) - n < 1 26 | 27 | if '## randint': 28 | 29 | # Uniform int on interval inclusive. 30 | 31 | n = random.randint(0, 3) 32 | assert n >= 0 33 | assert n <= 3 34 | 35 | if '## choice': 36 | 37 | # Take one element at random from an iterable. 38 | 39 | assert random.choice([0, 1]) in [0, 1] 40 | 41 | if '## sample': 42 | 43 | # Takes n *different* elements at random from iterable. Returns an iterable. 44 | 45 | vals = {1:0, 2:0, 3:0} 46 | n = 2 47 | for i in random.sample(vals.keys(), 2): 48 | assert i in vals.keys() 49 | vals[i] += 1 50 | 51 | for i in vals.keys(): 52 | assert vals[i] == 0 or vals[i] == 1 53 | 54 | assert sum(vals[k] for k in vals.keys()) == n 55 | -------------------------------------------------------------------------------- /re_cheat.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | ''' 4 | https://docs.python.org/3/library/re.html 5 | ''' 6 | 7 | import re 8 | 9 | if '## Syntax': 10 | 11 | if '## Lookahead': 12 | 13 | # Don't eat front part or regex 14 | 15 | p = re.compile(r'a.') 16 | assert p.sub('0', 'abaac') == '00c' 17 | 18 | p = re.compile(r'a(?=.)') 19 | assert p.sub('0', 'abaac') == '0b00c' 20 | 21 | if '## re module': 22 | 23 | if '## compile': 24 | 25 | """ 26 | Return a RegexObject object. 27 | 28 | Caches the regex parsing to make it faster. 29 | 30 | Always use this unless you will long match once. 31 | 32 | Contains basically the same methods as the `re` module. 33 | """ 34 | 35 | p = re.compile(r'a.c') 36 | assert p.match('abc') 37 | 38 | if '## flags': 39 | 40 | assert re.match('a', 'A', re.IGNORECASE) 41 | 42 | # Need flags= for re.sub, or set the count= 43 | # https://stackoverflow.com/questions/42581/python-re-sub-with-a-flag-does-not-replace-all-occurrences/42597#42597 44 | assert re.sub('^a', '0', 'ab\nab\n', flags=re.MULTILINE) == '0b\n0b\n' 45 | 46 | if '## sub': 47 | 48 | # Replace what was matched. 49 | 50 | p = re.compile('(a.|b.)') 51 | 52 | # By string: 53 | 54 | assert p.sub('0', 'a_b_abc') == '000c' 55 | 56 | # By callable: 57 | 58 | assert p.sub(lambda m: m.group(1)[1:], 'a_b-abc') == '_-bc' 59 | 60 | # Count: 61 | 62 | assert p.sub('0', 'a_b_abc', count=1) == '0b_abc' 63 | 64 | if '## subn': 65 | 66 | # Same as sub, but also returns number of subs made: 67 | 68 | assert p.subn('0', 'a_b_abc') == ('000c', 3) 69 | 70 | if '## match': 71 | 72 | re.match(r'a.c', 'abc') 73 | 74 | assert re.match(r'a.c', 'abc') 75 | 76 | # Must match from beginning of string! 77 | # Consider re.search instead. 78 | # http://stackoverflow.com/questions/28840903/python-regex-match-middle-of-string 79 | 80 | assert re.match(r'a.c', '0abc') is None 81 | 82 | # Does not however have to match until the end: 83 | 84 | assert re.match(r'a.c', 'abc0') 85 | 86 | if '## search': 87 | 88 | """ 89 | Like match, but also matches in the middle. 90 | """ 91 | 92 | assert re.search(r'a.c', '0abc') 93 | # Works. 94 | 95 | assert re.search(r'a.c', 'abcaBc') 96 | # . == b, stops at first match. to find all matches, use finditer 97 | 98 | # Line start and end are still honoured. 99 | assert not re.search(r'^a', 'ba') 100 | 101 | # search and group 102 | assert re.search(r'a(.)c(.)e', 'Xa0c1eYa2c3eZ').group(1) == ('0') 103 | assert re.search(r'a(.)c(.)e', 'Xa0c1eYa2c3eZ').group(2) == ('1') 104 | assert re.search(r'a(.)c(.)e', 'Xa0c1eYa2c3eZ').group(1, 2) == ('0', '1') 105 | 106 | if '## finditer': 107 | 108 | # A list of all non-overlapping match objects. 109 | 110 | matches = list(re.finditer(r'a.c', 'abcaBc')) 111 | 112 | if '## split': 113 | 114 | assert re.split(r'[ab]+', '0abba1aaaaa2') == ['0', '1', '2'] 115 | 116 | # https://stackoverflow.com/questions/2136556/in-python-how-do-i-split-a-string-and-keep-the-separators 117 | assert re.split('(0|1)', 'a0bc1d0ef') == ['a', '0', 'bc', '1', 'd', '0', 'ef'] 118 | 119 | # https://stackoverflow.com/questions/24443995/list-comprehension-joining-every-two-elements-together-in-a-list 120 | def split_and_keep(reg, string): 121 | reg = '(' + reg + ')' 122 | lst = re.split(reg, string) 123 | if len(lst) % 2 == 1: 124 | lst.append('') 125 | for x, y in zip(lst[0::2], lst[1::2]): 126 | yield x + y 127 | assert list(split_and_keep('0|1', 'a0bc1d0ef')) == ['a0', 'bc1', 'd0', 'ef'] 128 | 129 | """ 130 | ## Match object 131 | 132 | ## MatchObject 133 | 134 | https://docs.python.org/2/library/re.html#re.MatchObject 135 | 136 | Impossible to access this class: http://stackoverflow.com/questions/4835352/how-to-subclass-the-matchobject-in-python ... 137 | 138 | Important methods: TODO examples 139 | 140 | group() Return the string matched by the RE 141 | start() Return the starting position of the match 142 | end() Return the ending position of the match 143 | span() Return a tuple containing the (start, end) positions of the match 144 | """ 145 | 146 | """ 147 | ## RegexObject 148 | 149 | Returned by compile. 150 | 151 | https://docs.python.org/2/library/re.html#re.RegexObject 152 | """ 153 | -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | Babel==2.3.4 2 | Jinja2==2.8 3 | MarkupSafe==0.23 4 | PySocks==1.5.7 5 | Pygments==2.1.3 6 | Sphinx==1.4.6 7 | Unidecode==0.4.19 8 | alabaster==0.7.9 9 | backports.shutil-get-terminal-size==1.0.0 10 | chardet==2.3.0 11 | cycler==0.10.0 12 | decorator==4.0.10 13 | docutils==0.12 14 | h5py==2.9.0 15 | imagesize==0.7.1 16 | ipython-genutils==0.1.0 17 | ipython==5.1.0 18 | jupyter==1.0.0 19 | matplotlib==3.2.2 20 | mpmath==0.19 21 | networkx==1.11 22 | nltk==3.2.1 23 | numpy==1.11.1 24 | numpydoc==0.6.0 25 | pandas==0.21.0 26 | pathlib2==2.1.0 27 | pexpect==4.2.1 28 | pickleshare==0.7.4 29 | prompt-toolkit==1.0.7 30 | ptyprocess==0.5.1 31 | pyparsing==2.1.8 32 | python-dateutil==2.5.3 33 | pytz==2016.6.1 34 | simplegeneric==0.8.1 35 | six==1.10.0 36 | snowballstemmer==1.2.1 37 | srtmerge==1.0 38 | sympy==1.0 39 | termcolor==1.1.0 40 | traitlets==4.2.2 41 | virtualenv==15.0.3 42 | wcwidth==0.1.7 43 | yolk==0.4.3 44 | -------------------------------------------------------------------------------- /set.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | """ 4 | ## set 5 | 6 | Unordered mutable set of unique elements. 7 | 8 | Quick reference: 9 | 10 | len(s) cardinality of set s 11 | x in s test x for membership in s 12 | x not in s test x for non-membership in s 13 | s.issubset(t) s <= t test whether every element in s is in t 14 | s.issuperset(t) s >= t test whether every element in t is in s 15 | s.union(t) s | t new set with elements from both s and t 16 | s.intersection(t) s & t new set with elements common to s and t 17 | s.difference(t) s - t new set with elements in s but not in t 18 | s.symmetric_difference(t) s ^ t new set with elements in either s or t but not both 19 | s.copy() new set with a shallow copy of s 20 | s.update(t) s |= t return set s with elements added from t 21 | s.intersection_update(t) s &= t return set s keeping only elements also found in t 22 | s.difference_update(t) s -= t return set s after removing elements found in t 23 | s.symmetric_difference_update(t) s ^= t return set s with elements from s or t but not both 24 | s.add(x) add element x to set s 25 | s.remove(x) remove x from set s; raises KeyError if not present 26 | s.discard(x) removes x from set s if present 27 | s.pop() remove and return an arbitrary element from s; raises KeyError if empty 28 | s.clear() remove all elements from set s 29 | """ 30 | 31 | # Literals: 32 | 33 | assert {0, 1} == set([0, 1]) 34 | 35 | # Empty set literal: nope, syntax conflict with dict: 36 | # http://stackoverflow.com/questions/6130374/empty-set-literal-in-python 37 | 38 | assert {} == dict() 39 | assert set() == set([]) 40 | 41 | # List *without* order of unique elements: 42 | 43 | assert {2, 1} == {1, 2} 44 | 45 | # Iteration order undefined. 46 | 47 | # Factory built-in method: takes any iteratorable. 48 | 49 | assert set([1, 2]) == set((1, 2)) 50 | 51 | # Add new element: 52 | 53 | s = {1, 2} 54 | assert s.add(3) is None 55 | assert s == {1, 2, 3} 56 | 57 | # If already present, do nothing: 58 | 59 | assert s.add(2) is None 60 | assert s == {1, 2, 3} 61 | 62 | # Remove an element: 63 | 64 | s = {1, 2} 65 | assert s.remove(2) is None 66 | assert s == {1} 67 | 68 | # If not present, raises `KeyError`: 69 | 70 | try: 71 | s.remove(2) 72 | except KeyError: 73 | pass 74 | else: 75 | assert False 76 | 77 | # Elements must implement `__hash__`. This *excludes* any mutable built-in type. 78 | 79 | s = set() 80 | try: 81 | s.add([1]) 82 | except TypeError: 83 | pass 84 | else: 85 | assert False 86 | 87 | # Union of multiple sets 88 | 89 | sets = [{0,1}, {2,3}, {4,5}] 90 | assert set.union(*sets) == set(range(6)) 91 | 92 | # Add multiple elements to a set at once: 93 | 94 | s = set() 95 | s.update([1, 2, 3]) 96 | assert s == set([1, 2, 3]) 97 | 98 | # Remove multiple elements to a set at once: 99 | 100 | s = set([1, 2, 3]) 101 | s.difference_update([1, 2]) 102 | assert s == set([3]) 103 | -------------------------------------------------------------------------------- /simplehttpserver_cheat.md: -------------------------------------------------------------------------------- 1 | # SimpleHTTPServer 2 | 3 | Start server on current directory: 4 | 5 | python -m SimpleHTTPServer 8080 6 | 7 | Python 3: 8 | 9 | python3 -m http.server 8080 10 | 11 | Faster / more robust alternatives: 12 | -------------------------------------------------------------------------------- /slots.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | if 'Single string': 4 | 5 | # Works with a single string, until you start doing serialization loops. 6 | # So never do it, always use tuples of strings. 7 | 8 | class C(object): 9 | # Bad. 10 | # __slots__ = "ab" 11 | # Good. 12 | __slots__ = ("ab",) 13 | def __init__(self): 14 | self.ab = 1 15 | def __getstate__(self): 16 | return (None, {k:getattr(self, k) for k in C.__slots__}) 17 | assert C().ab == 1 18 | import pickle 19 | assert pickle.loads(pickle.dumps(C(), -1)).ab == 1 20 | -------------------------------------------------------------------------------- /smtplib_cheat.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | """ 4 | Before running, setup credentials (of a throw-away test email) with: 5 | 6 | cp smtplib_cheat_local.py.sample smtplib_cheat_local.py 7 | 8 | - http://stackoverflow.com/questions/6270782/sending-email-with-python 9 | - http://stackoverflow.com/questions/10147455/trying-to-send-email-gmail-as-mail-provider-using-python 10 | """ 11 | 12 | import email.mime.text 13 | import smtplib 14 | import smtplib_cheat_local 15 | 16 | def send_email(server_url, user, password, recipient, subject, body): 17 | to = recipient if type(recipient) is list else [recipient] 18 | tos = ', '.join(to) 19 | server = smtplib.SMTP(server_url, 587) 20 | server.set_debuglevel(1) 21 | server.ehlo() 22 | server.starttls() 23 | server.login(user, password) 24 | 25 | #message = 'From: %s\nTo: %s\nSubject: %s\n\n%s' % (user, tos, subject, body) 26 | 27 | msg = email.mime.text.MIMEText(body) 28 | msg['Subject'] = subject 29 | msg['From'] = user 30 | msg['To'] = tos 31 | message = msg.as_string() 32 | 33 | server.sendmail(user, to, message) 34 | server.quit() 35 | 36 | send_email( 37 | smtplib_cheat_local.server, 38 | smtplib_cheat_local.user, 39 | smtplib_cheat_local.password, 40 | smtplib_cheat_local.recipient, 41 | 'subject0', 42 | 'body0') 43 | -------------------------------------------------------------------------------- /smtplib_cheat_local.py.sample: -------------------------------------------------------------------------------- 1 | server = 'smtp.gmx.com' 2 | # - gmail: for username@gmail.com use 'username' 3 | # - gmx: for username@gmx.com use 'username@gmx.com' itself. 4 | # Must use domain likely because they offer multiple domains. 5 | user = 'bugOsvazLy@gmx.com' 6 | password = 'mTDCjqgRxq' 7 | recipient = 'ciro.santilli@gmail.com' 8 | -------------------------------------------------------------------------------- /sphinx/Makefile: -------------------------------------------------------------------------------- 1 | .PHONY: all 2 | 3 | all: 4 | make -C doc html 5 | xdg-open doc/_build/html/index.html 6 | -------------------------------------------------------------------------------- /sphinx/README.md: -------------------------------------------------------------------------------- 1 | # Sphinx 2 | 3 | HTML/PDF documentation from rst markup. 4 | 5 | May use docstrings with a default extension. 6 | 7 | It is used on the python official documentation 8 | 9 | The automatic doc finding / generation is not yet very good IMHO, but the rest works well. 10 | 11 | ## Directory structure structure 12 | 13 | This simulates a real project, with documentation in `doc/`, and `mod` and `mod2` are modules. 14 | 15 | ### Build 16 | 17 | cd doc 18 | make html 19 | 20 | I added a make `firefox` rule to the `Makefile` to make it easier to test: 21 | 22 | make firefox 23 | 24 | And also automated `sphinx-autodoc` generation on my `Makefile`. 25 | 26 | ## Extensions 27 | 28 | ### Autodoc 29 | 30 | Generate doc from docstrings 31 | 32 | Enable `autodoc`. Add: 33 | 34 | 'sphinx.ext.autodoc', 35 | 36 | To `extensions` and the module to path: 37 | 38 | import os.path 39 | 40 | sys.path.append( os.path.join( os.path.dirname( os.getcwd() ) ) ) 41 | 42 | in `conf.py`. 43 | 44 | From now on, you can the following directive once for each module in path you want to auto-generate documentation do: 45 | 46 | .. automodule:: mod.a 47 | :members: 48 | :undoc-members: 49 | :show-inheritance: 50 | 51 | Autodoc does **not** however recursively search for all modules in path, but you can use the default tool `sphinx-apidoc` to do this for you: 52 | 53 | sphinx-apidoc -o py-source-root doc-root 54 | 55 | where: 56 | 57 | - `doc-root` is the same dir that contains `index.rst` and `conf.py` 58 | - `py-source-root` is the same dir that contains all the python files that you want to document. 59 | 60 | This generates the two files in your documentation root: 61 | 62 | - `modules.rst` 63 | - `mod.rst` 64 | 65 | and finally all you have to do to use them is include them in you `index.rst`. 66 | 67 | You could either do: 68 | 69 | .. include:: modules.rst 70 | 71 | or add mod it to the `toctree`: 72 | 73 | .. toctree: 74 | 75 | (files) 76 | mod 77 | 78 | which searches for a file mod.(rst|txt) in current dir and adds its doctree here. 79 | 80 | #### First time 81 | 82 | You can all of this automatically the first time by using the `-F` option: 83 | 84 | sphinx-apidoc -F -o py-source-root doc-root 85 | 86 | Which also generates the templates that were generated with `sphinx-quickstart`, but adapted for `apidoc`. 87 | 88 | Note however that in current version if you add a file to your module, it is not automatically added on the default make, and you have to run `sphinx-apidoc` manually. 89 | 90 | ### Math 91 | 92 | there are two default methods: MathJax or PNG. 93 | 94 | #### PNG 95 | 96 | I prefer PNG because it loads instantaneously. 97 | 98 | For PNG math, you need to have the `dvipng` program installed and in your path. 99 | 100 | This program converts DVI to PNG *surprise!* 101 | 102 | On Ubuntu 12.04: 103 | 104 | sudo aptitude install dvipng 105 | 106 | ### doctest 107 | 108 | Check all `>>>` unit test snippets. 109 | 110 | Enable extension: 111 | 112 | 'sphinx.ext.doctest', 113 | 114 | Build for it: 115 | 116 | sphinxbuild -b doctest 117 | -------------------------------------------------------------------------------- /sphinx/doc/Makefile: -------------------------------------------------------------------------------- 1 | # Makefile for Sphinx documentation 2 | # 3 | 4 | # You can set these variables from the command line. 5 | SPHINXOPTS := 6 | SPHINXBUILD := sphinx-build 7 | PAPER := 8 | BUILDDIR := _build 9 | PY_SOURCE_ROOTS := ../mod/ ../mod2/ #directory that contains all the python source you want to document 10 | 11 | # Internal variables. 12 | PAPEROPT_a4 = -D latex_paper_size=a4 13 | PAPEROPT_letter = -D latex_paper_size=letter 14 | ALLSPHINXOPTS = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) . 15 | # the i18n builder cannot share the environment and doctrees with the others 16 | I18NSPHINXOPTS = $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) . 17 | 18 | .PHONY: help clean html dirhtml singlehtml pickle json htmlhelp qthelp devhelp epub latex latexpdf text man changes linkcheck doctest gettext sphinx-apidoc 19 | 20 | help: 21 | @echo "Please use \`make ' where is one of" 22 | @echo " html to make standalone HTML files" 23 | @echo " dirhtml to make HTML files named index.html in directories" 24 | @echo " singlehtml to make a single large HTML file" 25 | @echo " pickle to make pickle files" 26 | @echo " json to make JSON files" 27 | @echo " htmlhelp to make HTML files and a HTML help project" 28 | @echo " qthelp to make HTML files and a qthelp project" 29 | @echo " devhelp to make HTML files and a Devhelp project" 30 | @echo " epub to make an epub" 31 | @echo " firefox make html and open index with firefox" 32 | @echo " latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter" 33 | @echo " latexpdf to make LaTeX files and run them through pdflatex" 34 | @echo " text to make text files" 35 | @echo " man to make manual pages" 36 | @echo " texinfo to make Texinfo files" 37 | @echo " info to make Texinfo files and run them through makeinfo" 38 | @echo " gettext to make PO message catalogs" 39 | @echo " changes to make an overview of all changed/added/deprecated items" 40 | @echo " linkcheck to check all external links for integrity" 41 | @echo " doctest to run all doctests embedded in the documentation (if enabled)" 42 | 43 | clean: 44 | -rm -rf $(BUILDDIR)/* 45 | 46 | html: sphinx-apidoc 47 | $(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html 48 | @echo 49 | @echo "Build finished. The HTML pages are in $(BUILDDIR)/html." 50 | 51 | firefox: html 52 | firefox $(BUILDDIR)/html/index.html 53 | 54 | dirhtml: sphinx-apidoc 55 | $(SPHINXBUILD) -b dirhtml $(ALLSPHINXOPTS) $(BUILDDIR)/dirhtml 56 | @echo 57 | @echo "Build finished. The HTML pages are in $(BUILDDIR)/dirhtml." 58 | 59 | singlehtml: sphinx-apidoc 60 | $(SPHINXBUILD) -b singlehtml $(ALLSPHINXOPTS) $(BUILDDIR)/singlehtml 61 | @echo 62 | @echo "Build finished. The HTML page is in $(BUILDDIR)/singlehtml." 63 | 64 | pickle: sphinx-apidoc 65 | $(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) $(BUILDDIR)/pickle 66 | @echo 67 | @echo "Build finished; now you can process the pickle files." 68 | 69 | json: sphinx-apidoc 70 | $(SPHINXBUILD) -b json $(ALLSPHINXOPTS) $(BUILDDIR)/json 71 | @echo 72 | @echo "Build finished; now you can process the JSON files." 73 | 74 | htmlhelp: sphinx-apidoc 75 | $(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) $(BUILDDIR)/htmlhelp 76 | @echo 77 | @echo "Build finished; now you can run HTML Help Workshop with the" \ 78 | ".hhp project file in $(BUILDDIR)/htmlhelp." 79 | 80 | qthelp: sphinx-apidoc 81 | $(SPHINXBUILD) -b qthelp $(ALLSPHINXOPTS) $(BUILDDIR)/qthelp 82 | @echo 83 | @echo "Build finished; now you can run "qcollectiongenerator" with the" \ 84 | ".qhcp project file in $(BUILDDIR)/qthelp, like this:" 85 | @echo "# qcollectiongenerator $(BUILDDIR)/qthelp/projectname.qhcp" 86 | @echo "To view the help file:" 87 | @echo "# assistant -collectionFile $(BUILDDIR)/qthelp/projectname.qhc" 88 | 89 | devhelp: sphinx-apidoc 90 | $(SPHINXBUILD) -b devhelp $(ALLSPHINXOPTS) $(BUILDDIR)/devhelp 91 | @echo 92 | @echo "Build finished." 93 | @echo "To view the help file:" 94 | @echo "# mkdir -p $$HOME/.local/share/devhelp/projectname" 95 | @echo "# ln -s $(BUILDDIR)/devhelp $$HOME/.local/share/devhelp/projectname" 96 | @echo "# devhelp" 97 | 98 | epub: sphinx-apidoc 99 | $(SPHINXBUILD) -b epub $(ALLSPHINXOPTS) $(BUILDDIR)/epub 100 | @echo 101 | @echo "Build finished. The epub file is in $(BUILDDIR)/epub." 102 | 103 | latex: sphinx-apidoc 104 | $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex 105 | @echo 106 | @echo "Build finished; the LaTeX files are in $(BUILDDIR)/latex." 107 | @echo "Run \`make' in that directory to run these through (pdf)latex" \ 108 | "(use \`make latexpdf' here to do that automatically)." 109 | 110 | latexpdf: sphinx-apidoc 111 | $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex 112 | @echo "Running LaTeX files through pdflatex..." 113 | $(MAKE) -C $(BUILDDIR)/latex all-pdf 114 | @echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex." 115 | 116 | text: sphinx-apidoc 117 | $(SPHINXBUILD) -b text $(ALLSPHINXOPTS) $(BUILDDIR)/text 118 | @echo 119 | @echo "Build finished. The text files are in $(BUILDDIR)/text." 120 | 121 | man: sphinx-apidoc 122 | $(SPHINXBUILD) -b man $(ALLSPHINXOPTS) $(BUILDDIR)/man 123 | @echo 124 | @echo "Build finished. The manual pages are in $(BUILDDIR)/man." 125 | 126 | texinfo: sphinx-apidoc 127 | $(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo 128 | @echo 129 | @echo "Build finished. The Texinfo files are in $(BUILDDIR)/texinfo." 130 | @echo "Run \`make' in that directory to run these through makeinfo" \ 131 | "(use \`make info' here to do that automatically)." 132 | 133 | info: sphinx-apidoc 134 | $(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo 135 | @echo "Running Texinfo files through makeinfo..." 136 | make -C $(BUILDDIR)/texinfo info 137 | @echo "makeinfo finished; the Info files are in $(BUILDDIR)/texinfo." 138 | 139 | gettext: sphinx-apidoc 140 | $(SPHINXBUILD) -b gettext $(I18NSPHINXOPTS) $(BUILDDIR)/locale 141 | @echo 142 | @echo "Build finished. The message catalogs are in $(BUILDDIR)/locale." 143 | 144 | changes: sphinx-apidoc 145 | $(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) $(BUILDDIR)/changes 146 | @echo 147 | @echo "The overview file is in $(BUILDDIR)/changes." 148 | 149 | linkcheck: sphinx-apidoc 150 | $(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) $(BUILDDIR)/linkcheck 151 | @echo 152 | @echo "Link check complete; look for any errors in the above output " \ 153 | "or in $(BUILDDIR)/linkcheck/output.txt." 154 | 155 | doctest: sphinx-apidoc 156 | $(SPHINXBUILD) -b doctest $(ALLSPHINXOPTS) $(BUILDDIR)/doctest 157 | @echo "Testing of doctests in the sources finished, look at the " \ 158 | "results in $(BUILDDIR)/doctest/output.txt." 159 | 160 | sphinx-apidoc: sphinx-apidoc 161 | for PY_SOURCE_ROOT in $(PY_SOURCE_ROOTS); do \ 162 | sphinx-apidoc -f -o . $$PY_SOURCE_ROOT; \ 163 | done 164 | -------------------------------------------------------------------------------- /sphinx/doc/index.rst: -------------------------------------------------------------------------------- 1 | .. mod documentation master file, created by 2 | sphinx-quickstart on Thu Apr 4 15:55:28 2013. 3 | You can adapt this file completely to your liking, but it should at least 4 | contain the root `toctree` directive. 5 | 6 | Welcome to mod's documentation! 7 | =============================== 8 | 9 | toctree: 10 | 11 | .. toctree:: 12 | :maxdepth: 4 13 | 14 | mod 15 | mod2 16 | toctree_include 17 | 18 | adding a name to the list, will search for `name.rst` and add its `toctree` here. 19 | 20 | Indices and tables 21 | ================== 22 | 23 | * :ref:`genindex` 24 | * :ref:`modindex` 25 | * :ref:`search` 26 | 27 | -------------------------------------------------------------------------------- /sphinx/doc/mod.rst: -------------------------------------------------------------------------------- 1 | mod package 2 | =========== 3 | 4 | Submodules 5 | ---------- 6 | 7 | mod.a module 8 | ------------ 9 | 10 | .. automodule:: mod.a 11 | :members: 12 | :undoc-members: 13 | :show-inheritance: 14 | 15 | mod.b module 16 | ------------ 17 | 18 | .. automodule:: mod.b 19 | :members: 20 | :undoc-members: 21 | :show-inheritance: 22 | 23 | mod.main module 24 | --------------- 25 | 26 | .. automodule:: mod.main 27 | :members: 28 | :undoc-members: 29 | :show-inheritance: 30 | 31 | 32 | Module contents 33 | --------------- 34 | 35 | .. automodule:: mod 36 | :members: 37 | :undoc-members: 38 | :show-inheritance: 39 | -------------------------------------------------------------------------------- /sphinx/doc/mod2.rst: -------------------------------------------------------------------------------- 1 | mod2 package 2 | ============ 3 | 4 | Module contents 5 | --------------- 6 | 7 | .. automodule:: mod2 8 | :members: 9 | :undoc-members: 10 | :show-inheritance: 11 | -------------------------------------------------------------------------------- /sphinx/doc/modules.rst: -------------------------------------------------------------------------------- 1 | mod2 2 | ==== 3 | 4 | .. toctree:: 5 | :maxdepth: 4 6 | 7 | mod2 8 | -------------------------------------------------------------------------------- /sphinx/doc/toctree_include.rst: -------------------------------------------------------------------------------- 1 | title of toctree_include 2 | ======================== 3 | 4 | content of title 5 | 6 | subtitle of toctree_include 7 | --------------------------- 8 | 9 | content of subtitle 10 | -------------------------------------------------------------------------------- /sphinx/mod/__init__.py: -------------------------------------------------------------------------------- 1 | """ 2 | mod docstring 3 | """ 4 | 5 | """ 6 | mod.f() docstring 7 | """ 8 | def f(): 9 | pass 10 | -------------------------------------------------------------------------------- /sphinx/mod/a.py: -------------------------------------------------------------------------------- 1 | """ 2 | a docstring 3 | """ 4 | 5 | """ 6 | a.f() docstring 7 | """ 8 | def f(): 9 | pass 10 | -------------------------------------------------------------------------------- /sphinx/mod/b.py: -------------------------------------------------------------------------------- 1 | """ 2 | a docstring 3 | """ 4 | 5 | """ 6 | a.f() docstring 7 | """ 8 | def f(): 9 | pass 10 | -------------------------------------------------------------------------------- /sphinx/mod/main.py: -------------------------------------------------------------------------------- 1 | #: globvar doc 2 | globalvar = 1 3 | 4 | def f(arg1, arg2, arg3, state=None): 5 | r"""Short summary. 6 | 7 | Longer explanation. 8 | 9 | LaTeX math: :math:`a^2 + \alpha`. 10 | 11 | Function link: :func:`f2` 12 | 13 | Class link: :class:`C` 14 | 15 | Relative module function link: :func:`.a.f` 16 | 17 | Cannot have headers here. 18 | 19 | Othernormal `reST `_ 20 | 21 | - l1 22 | - l2 23 | 24 | :param arg1: the first value 25 | :type arg1: int 26 | 27 | :param arg2: the first value 28 | :type arg2: int 29 | 30 | :param arg3: the first value 31 | :type arg3: int 32 | 33 | :param class_with_dot: another class with dot 34 | :type arg4: :class:`.C` 35 | 36 | :param class_without_dot: another class without dot 37 | :type class_without_dot: :class:`C` 38 | 39 | :param multi_type: multiple types! 40 | :type multi_type: :class:`.C` or :class:`.D` 41 | 42 | :param class_and_union: class and Union type hinting together 43 | :type class_and_union: Union[:class:`C`, :class:`.D`] 44 | 45 | :param type_hint: type_hint 46 | :type type_hint: List[C] 47 | 48 | http://stackoverflow.com/questions/21799554/how-do-i-automatically-link-to-a-parameter-type-in-rest-docstrings-in-sphinx 49 | :param :class:`.C` inline_link: inline link 50 | 51 | :returns: 0 52 | :rtype: int 53 | 54 | :raises: AttributeError, KeyError 55 | 56 | :example: 57 | 58 | .. doctest:: 59 | 60 | >>> 1+1 61 | 2 62 | >>> 1+1 63 | 1 64 | 65 | .. note:: can be useful to emphasize 66 | important feature 67 | .. seealso:: :class:`MainClass2` 68 | .. warning:: arg2 must be non-zero. 69 | 70 | """ 71 | return 0 72 | 73 | def f2(): 74 | pass 75 | 76 | class C(): 77 | """ 78 | :ivar i: instance variable 79 | :vartype i: int 80 | 81 | :var v: TODO variable? TODO shows the same as the others in 1.2.2. 82 | :vartype v: int 83 | 84 | :cvar c: class variable. TODO shows the same as the others in 1.2.2. 85 | :vartype c: int 86 | """ 87 | 88 | def g(self): 89 | """ 90 | Method link: :func:`g2` 91 | """ 92 | pass 93 | 94 | def g2(self): 95 | """ 96 | """ 97 | pass 98 | 99 | def __init__( self ): 100 | self.i = 0 101 | 102 | class D(): 103 | pass 104 | -------------------------------------------------------------------------------- /sphinx/mod2/__init__.py: -------------------------------------------------------------------------------- 1 | """ 2 | mod2 docstring 3 | """ 4 | -------------------------------------------------------------------------------- /style-guides.md: -------------------------------------------------------------------------------- 1 | # Style guides 2 | 3 | - [PEP 8](https://www.python.org/dev/peps/pep-0008) for most of the language, and [PEP 257](https://www.python.org/dev/peps/pep-0257) for docstrings. 4 | 5 | Official recommendations. 6 | 7 | - [Google Python Style Guide](https://google.github.io/styleguide/pyguide.html) 8 | 9 | Since Google is a heavy Python user, this one should be very good. 10 | 11 | ## Lint tools 12 | 13 | - [Pylint](https://bitbucket.org/logilab/pylint). 14 | 15 | Likely the most popular one. 16 | 17 | Source: 18 | -------------------------------------------------------------------------------- /subprocess_cheat/check_output.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | ''' 3 | Reads stdout from program. 4 | ''' 5 | import subprocess 6 | assert subprocess.check_output(['./stdout_stderr.py']) == b'stdout\n' 7 | try: 8 | subprocess.check_output(['./false.py']) 9 | except subprocess.CalledProcessError: 10 | pass 11 | else: 12 | assert False 13 | -------------------------------------------------------------------------------- /subprocess_cheat/count.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | ''' 3 | Count to stdout at 10Hz: 4 | ./count.py [n=2 [dt=1]] 5 | Write the latest number to the count.tmp file. 6 | ''' 7 | import sys 8 | import time 9 | if len(sys.argv) > 1: 10 | n = int(sys.argv[1]) 11 | else: 12 | n = 2 13 | if len(sys.argv) > 2: 14 | dt = float(sys.argv[2]) 15 | else: 16 | dt = 1 17 | for i in range(n): 18 | print(i) 19 | sys.stdout.flush() 20 | with open('count.tmp', 'w') as f: 21 | f.write(str(i)) 22 | time.sleep(dt) 23 | -------------------------------------------------------------------------------- /subprocess_cheat/false.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | import sys 3 | sys.exit(1) 4 | -------------------------------------------------------------------------------- /subprocess_cheat/popen_background.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | ''' 3 | proc.stdout.read() blocks: 4 | https://stackoverflow.com/questions/1196074/how-to-start-a-background-process-in-python/53751896#53751896 5 | ''' 6 | import subprocess 7 | import os 8 | path = 'count.tmp' 9 | if os.path.exists(path): 10 | os.unlink(path) 11 | with subprocess.Popen( 12 | ['./count.py', '2', '0.1'], 13 | # This makes the read wait. 14 | stdout=subprocess.PIPE, 15 | ) as proc: 16 | stdout = proc.stdout.read() 17 | if os.path.exists(path): 18 | with open(path, 'r') as f: 19 | s = f.read() 20 | # Counted until the end. 21 | assert s == '1' 22 | -------------------------------------------------------------------------------- /subprocess_cheat/stdout_stderr.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | import sys 3 | sys.stdout.buffer.write(b'stdout\n') 4 | sys.stderr.buffer.write(b'stderr\n') 5 | -------------------------------------------------------------------------------- /subprocess_cheat/stdout_stderr_test.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | ''' 3 | Get stdout and sterr from process separately. 4 | ''' 5 | import subprocess 6 | process = subprocess.Popen( 7 | ['./stdout_stderr.py'], 8 | stdout = subprocess.PIPE, 9 | stderr = subprocess.PIPE, 10 | ) 11 | exit_status = process.wait() 12 | assert exit_status == 0 13 | stdout, stderr = process.communicate() 14 | assert stdout == b'stdout\n' 15 | assert stderr == b'stderr\n' 16 | -------------------------------------------------------------------------------- /subprocess_cheat/test: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | set -eu 3 | ./check_output.py 4 | ./stdout_stderr_test.py 5 | ./popen_background.py 6 | -------------------------------------------------------------------------------- /sympy_cheat.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | """ 4 | Good tutorial on docs: 5 | 6 | http://docs.sympy.org/0.7.2/tutorial.html 7 | 8 | Does precisely: 9 | 10 | - fractions 11 | 12 | - + * ** 13 | 14 | - simplification 15 | 16 | - substitution: x**2, x = y+1 17 | 18 | - derivatives of known functions 19 | 20 | 1/(x^2+1) = 1/y + 1/z 21 | 22 | Attempts with heuristics: 23 | 24 | - integrals 25 | 26 | - exact solution of differential equations! 27 | """ 28 | 29 | from sympy import Symbol, cos 30 | x = Symbol("x") 31 | (1/cos(x)).series(x, 0, 10) 32 | -------------------------------------------------------------------------------- /sys_cheat.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | import sys 4 | 5 | if '## command line arguments ## argv': 6 | 7 | print 'sys.argv[0] = ' + repr(sys.argv[0]) 8 | print 'sys.argv[1:] = ' + repr(sys.argv[1:]) 9 | 10 | if '## version_info': 11 | 12 | import sys 13 | print 'sys.version_info = ' + str(sys.version_info) 14 | print 'sys.version_info.major = ' + str(sys.version_info.major) 15 | 16 | # Check for Python 2.x code. 17 | if sys.version_info.major == 2: 18 | pass 19 | 20 | if '## exit': 21 | 22 | # Raises an exception instead of realy exiting... 23 | # http://stackoverflow.com/questions/10166686/how-do-i-exit-program-in-try-except 24 | 25 | try: 26 | sys.exit(1) 27 | except SystemExit, e: 28 | pass 29 | else: 30 | assert False 31 | 32 | # If no call is made to sys.exit, exit code is 0. 33 | 34 | #sys.exit() 35 | #sys.exit(0) 36 | #sys.exit(1) 37 | -------------------------------------------------------------------------------- /tempfile_cheat.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | """ 4 | ## tempfile 5 | 6 | Create temporary files and directories. 7 | 8 | 1: 126 | nthreads = int(sys.argv[1]) 127 | if nthreads == 0: 128 | nthreads = None 129 | else: 130 | nthreads = None 131 | if argv_len > 2: 132 | min_ = int(sys.argv[2]) 133 | else: 134 | min_ = 1 135 | if argv_len > 3: 136 | max_ = int(sys.argv[3]) 137 | else: 138 | max_ = 100 139 | if argv_len > 4: 140 | c = sys.argv[4][0] 141 | else: 142 | c = '0' 143 | if c == '1': 144 | handle_output = handle_output_print_no_exit 145 | elif c == '2': 146 | handle_output = handle_output_queue 147 | elif c == '3': 148 | handle_output = handle_output_raise 149 | else: 150 | handle_output = handle_output_print 151 | 152 | # Action. 153 | error = run_in_parallel( 154 | my_func, 155 | get_work(min_, max_), 156 | handle_output, 157 | nthreads 158 | ) 159 | if error is not None: 160 | print('error: {!r}'.format(error)) 161 | if handle_output == handle_output_queue: 162 | while not out_queue.empty(): 163 | print(out_queue.get()) 164 | -------------------------------------------------------------------------------- /time_cheat.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | """ 4 | ## time 5 | """ 6 | 7 | import time 8 | 9 | if '## time()': 10 | 11 | # Get number of seconds since 1970: 12 | 13 | # Returns a float, thus potentially allowing greater precision, 14 | # but that depends on system support. 15 | 16 | # UTC: http://stackoverflow.com/questions/13890935/does-pythons-time-time-return-the-local-or-utc-timestamp 17 | 18 | print('time.time() = ' + str(time.time())) 19 | 20 | if '## clock': 21 | 22 | # Quoting the man: "This is the function to use for benchmarking Python or timing algorithms." 23 | 24 | start_time = time.clock() 25 | "-".join(str(n) for n in range(10000)) 26 | elapsed_time = time.clock() - start_time 27 | print('clock elapsed = {0:.6f}s'.format(elapsed_time)) 28 | 29 | # Not accurate for wall time. Does not measure time of external programs. 30 | 31 | if '## timeit': 32 | 33 | # Benchmark code snippets from strings. Relies internally on either time or clock. 34 | 35 | import timeit 36 | print('timeit time of all iterations= {0}s'.format( 37 | timeit.timeit('"-".join(str(n) for n in range(100))', number=10000))) 38 | 39 | # From the command line: 40 | 41 | #python -m timeit '"-".join(str(n) for n in range(100))' 42 | 43 | if '## sleep': 44 | 45 | """Sleep for the given number of seconds""" 46 | 47 | #time.sleep(3) 48 | -------------------------------------------------------------------------------- /tk/README.md: -------------------------------------------------------------------------------- 1 | # Tk 2 | 3 | GUI toolkit. 4 | 5 | The interface is Part of the stdlib, however Tk is not. Ubuntu 12.04 interpreted this as Tk is optional, and it not installed by default. So you should not rely on it being there everywhere... 6 | 7 | Tk seems less advanced than GTK/QT, but could be fine for one page GUIs. 8 | 9 | The IDLE editor is written on it, and is part of the stdlib too. 10 | -------------------------------------------------------------------------------- /tk/hello_world.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | import Tkinter 4 | 5 | app = Tkinter.Tk() 6 | Tkinter.Button(app, text="quit", command=app.quit).pack() 7 | app.mainloop() 8 | -------------------------------------------------------------------------------- /tk/main.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | import Tkinter 4 | 5 | def ok_func(): 6 | print 'entry = ' + entry.get() 7 | print 'entry_variable = ' + entry_variable_var.get() 8 | print 'checkbutton = ' + str(checkbutton_var.get()) 9 | 10 | app = Tkinter.Tk() 11 | 12 | #if "##frame": 13 | 14 | #if "##grid": 15 | 16 | if "##entry": 17 | 18 | # Value can bre retreived both via variables and via `get()` directly. 19 | 20 | grid = Tkinter.Frame(app) 21 | row = 0 22 | 23 | Tkinter.Label(grid, text="entry").grid(row=row, column=0, sticky='W') 24 | entry = Tkinter.Entry(grid) 25 | entry.grid(row=row, column=1) 26 | row += 1 27 | 28 | entry_variable_var = Tkinter.StringVar() 29 | Tkinter.Label(grid, text="entry_variable").grid(row=row, column=0, sticky='W') 30 | entry_variable = Tkinter.Entry(grid, textvariable=entry_variable_var) 31 | entry_variable.grid(row=row, column=1) 32 | row += 1 33 | 34 | if "##checkbutton": 35 | 36 | # It does not seem possible to get the value wihtout an extra var: 37 | # 38 | 39 | Tkinter.Label(grid, text="checkbutton").grid(row=row, column=0, sticky='W') 40 | checkbutton_var = Tkinter.IntVar() 41 | checkbutton = Tkinter.Checkbutton( 42 | grid, 43 | text = "", 44 | variable = checkbutton_var, 45 | onvalue = 1 46 | ) 47 | checkbutton.grid(row=row, column=1, sticky='W') 48 | row += 1 49 | 50 | #if "##open file" 51 | 52 | #import tkFileDialog 53 | #from tkinter.filedialog import askopenfilename 54 | #filename = askopenfilename() 55 | 56 | ##pass argument to callback: 57 | 58 | #lambda: action(someNumber) 59 | 60 | grid.pack() 61 | Tkinter.Button(app, text="ok", command=ok_func).pack() 62 | Tkinter.Button(app, text="quit", command=app.quit).pack() 63 | app.mainloop() 64 | -------------------------------------------------------------------------------- /trac.md: -------------------------------------------------------------------------------- 1 | # Trac 2 | 3 | Top Python written bug tracker. 4 | 5 | Not written in Django unfortunately. 6 | 7 | Dependency: 8 | 9 | sudo aptitude install -y python-mysqldb 10 | 11 | Install: 12 | 13 | sudo pip install trac 14 | 15 | ## Prerequisites 16 | 17 | Learn how to use <#apache> if you ever want to do serious deployment. 18 | 19 | ## Create project 20 | 21 | create db to use: 22 | 23 | mysql -u root -p -e 'create database trac_test character set utf8' 24 | 25 | **MUST BE UTF8!!!** 26 | 27 | make a directory and install there: 28 | d="test" 29 | mkdir "$d" 30 | trac-admin "$d" initenv 31 | 32 | enter: 33 | 34 | test 35 | mysql://user:pass@host:3306/dbname 36 | ^^^^ 37 | default mysql port 38 | 39 | ##test server 40 | 41 | tracd --port 8000 /path/to/project 42 | firefox localhost:8000 43 | 44 | ##apache deployment 45 | 46 | For real deployment, can be much faster. 47 | 48 | ###access rights 49 | 50 | the server process must have ownership of the project dir 51 | 52 | by default, the owner of the dir is the owner who run ``trac-admin`` 53 | 54 | however, usually apache runs as a different user. 55 | 56 | to find out the user: 57 | 58 | cat ps -Af | grep apache 59 | 60 | to find out his group: 61 | 62 | groups $username 63 | 64 | finally, change ownership: 65 | 66 | chown -R $username.$groupname "$d" 67 | 68 | on Ubuntu at the time of writing the default was: 69 | 70 | username=www-data 71 | groupname=www-data 72 | 73 | ###Authentication 74 | 75 | Trac uses <#http authentication> and cookies. 76 | 77 | you have to set http authentication to the (virtual) location ``/trac/projectname/login``. 78 | 79 | when an user hits this URL authenticated, Trac sends session cookies back to him. 80 | 81 | to create an admin user, choose the `htpasswd` user you want to promote to admin, 82 | and do: 83 | 84 | trac-admin "$project_dir" permission add "$admin_username" TRAC_ADMIN 85 | 86 | where ``"$admin_username"`` is exactly one of the `htpasswd` users. 87 | 88 | ###fastgci 89 | 90 | Install fastgci. 91 | 92 | FastCgiConfig -initial-env TRAC_ENV_PARENT_DIR=/usr/share/trac/projects/ 93 | 94 | `TRAC_ENV_PARENT_DIR` is the parent of all Trac projects. 95 | 96 | ###automated 97 | 98 | this section automates full project creation and setup 99 | 100 | it uses: 101 | - multiple projects on a dir 102 | - http basic authentication with cookies 103 | - shared authentication for all projects 104 | 105 | add to apache config: 106 | 107 | inputs: 108 | 109 | root="/usr/share/trac/" 110 | projects_dir="$root/projects" 111 | server_user=www-data 112 | server_group=www-data 113 | deploy_dir=/tmp/trac_deploy/ 114 | db_user=trac 115 | db_pass=asdf 116 | db_host=localhost 117 | project_name=test3 118 | project_dir="$projects_dir/$project_name" 119 | db=trac_$project_name 120 | passwd_file="$root/passwd" 121 | admin_username="admin" 122 | 123 | first time: 124 | 125 | sudo mkdir -p "$projects_dir" "$deploy_dir" 126 | sudo chown $u.$g "$project_dir" "$deploy_dir" 127 | mysql -u root -p -e "CREATE USER $db_user@$db_host IDENTIFIED BY $db_pass;" 128 | htpasswd -c "$passwd_file" "$admin_username" 129 | 130 | new project: 131 | 132 | mysql -u root -p -e "create database $db character set utf8; grant all on $db.* to $db_user@localhost;" 133 | sudo -u $u mkdir -p "$project_dir" 134 | echo -e "$project_name\nmysql://$db_user:$db_pass@localhost:3306/$db" | sudo -u $u trac-admin "$project_dir" initenv 135 | trac-admin "$project_dir" permission add "$admin_username" TRAC_ADMIN 136 | 137 | first time after first new project: 138 | 139 | sudo -u $u trac-admin "$r" deploy "$d" 140 | sudo mv "$deploy_dir"/* "$root" 141 | sudo rmdir "$deploy_dir" 142 | -------------------------------------------------------------------------------- /tuple.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | """ 4 | ## tuple 5 | 6 | # Immutable list of elements of any type 7 | """ 8 | 9 | # Special constructor notation: 10 | 11 | t = (1, 2, 3) 12 | t = 1, 2, 3 13 | 14 | # For a single element, a trailing comma is needed 15 | # to differentiate from numeric expressions: 16 | 17 | assert (1) == 1 18 | assert type((1,)) == tuple 19 | 20 | # Also works without parenthesis on some cases: 21 | 22 | a = 1, 23 | 24 | # Global factory method from list: 25 | 26 | assert tuple([1, 2, 3]) == (1, 2, 3) 27 | 28 | # Doest not exist: 29 | 30 | #t = tuple(1, 2, 3) 31 | 32 | t2 = (4, 5, 6) 33 | t3 = (4, 5, 1) 34 | tb = (False, False, True) 35 | tm = (1, 1.1, True, 'asdf') 36 | 37 | # Index access: 38 | 39 | t = (1, 2, 3) 40 | assert t[0] == 1 41 | assert t[1] == 2 42 | assert t[2] == 3 43 | 44 | # Unpack: 45 | 46 | a, b, c = (1, 2, 3) 47 | assert a == 1 48 | assert b == 2 49 | assert c == 3 50 | 51 | if 'tuples are immutable': 52 | 53 | t = (0) 54 | try: 55 | t[0] = 'a' 56 | except TypeError: 57 | pass 58 | else: 59 | assert False 60 | 61 | # Concatenate: 62 | 63 | assert (0, 1) + (2, 3) == (0, 1, 2, 3) 64 | 65 | t = (0, 1) 66 | assert t * 2 == (0, 1, 0, 1) 67 | assert 2 * t == (0, 1, 0, 1) 68 | 69 | # Compare: does alphabetical like compare from left to right. 70 | 71 | assert (0, 1) == (0, 1) 72 | assert (0, 1) < (1, 2) 73 | assert (0, 10) < (1, 1) 74 | # TODO why: 75 | #assert (0, 1) > (1) 76 | 77 | # The list global functions also work on tuples: 78 | 79 | assert len((0,1)) == 2 80 | assert max((0,1)) == 1 81 | assert min((0,1)) == 0 82 | assert any((True, False)) == True 83 | assert all((True, False)) == False 84 | -------------------------------------------------------------------------------- /unittest_cheat.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | #http://docs.python.org/2/library/unittest.html 4 | #http://www.diveintopython.net/unit_testing/index.html 5 | 6 | import sys 7 | import unittest 8 | 9 | class SomeInput: 10 | pass 11 | 12 | class SomeOutput: 13 | 14 | def __init__(self,i,j): 15 | self.i = i 16 | self.j = j 17 | 18 | def __eq__(self, other): 19 | """ 20 | all attributes of objects are equal 21 | """ 22 | if type(other) is type(self): 23 | return self.__dict__ == other.__dict__ 24 | return False 25 | 26 | class SomeTest(unittest.TestCase): 27 | 28 | @classmethod 29 | def setUpClass(self): 30 | """ 31 | called once before all test methods 32 | """ 33 | print 'test.setUpClass' 34 | 35 | @classmethod 36 | def tearDownClass(self): 37 | """ 38 | called once before all test methods 39 | """ 40 | print 'test.tearDownClass' 41 | 42 | def setUp(self): 43 | """ 44 | called before each test method 45 | """ 46 | print 'test.setUp' 47 | 48 | def tearDown(self): 49 | """ 50 | called after each test method 51 | """ 52 | print 'test.tearDown' 53 | 54 | ##tests have 3 possible outcomes 55 | 56 | #- OK: The test passes. 57 | 58 | #- FAIL: The test does not pass, and raises an AssertionError exception. 59 | 60 | # This is raised by unit test `assert*` methods as well as the built in `assert`. 61 | 62 | #- ERROR: The test raises an exception other than AssertionError. 63 | 64 | def test_pass(self): 65 | """ 66 | this test passes 67 | """ 68 | self.assertEqual( 1, 1 ) 69 | 70 | def test_fail(self): 71 | """ 72 | basic 73 | """ 74 | self.assertEqual( 1, 2 ) 75 | 76 | #stops after first fail because fails raise exceptions: 77 | assert(False) 78 | 79 | def test_fail2(self): 80 | """ 81 | any assertion error gives a fail 82 | """ 83 | raise AssertionError 84 | 85 | def test_error(self): 86 | """ 87 | this is an error, not a fail! 88 | """ 89 | raise ZeroDivisionError 90 | 91 | def test_fail_message(self): 92 | """ 93 | fail message can be explicitly set: 94 | """ 95 | self.assertEqual( 1, 2, 'message' ) 96 | 97 | ##assertEqual 98 | 99 | #with assertTrue() you could make all the others. 100 | 101 | #so why use `assertEqual`? 102 | 103 | #one reason: in case of fail `assertEqual(v,v2)`, 104 | #it automatically prints a nice message `v + ' != ' v2` for you 105 | 106 | #furthermore, assert equal recognizes the types of inputs 107 | #and automatically uses one of the nice formattings if available: 108 | 109 | #- assertItemsEqual(a, b) sorted(a) == sorted(b) and works with unhashable objs 2.7 110 | #- assertMultiLineEqual(a, b) strings 2.7 111 | #- assertSequenceEqual(a, b) sequences 2.7 112 | #- assertListEqual(a, b) lists 2.7 113 | #- assertTupleEqual(a, b) tuples 2.7 114 | #- assertSetEqual(a, b) sets or frozensets 2.7 115 | 116 | def test_assertEqual_int(self): 117 | """ 118 | """ 119 | self.assertEqual(1,2) 120 | 121 | def test_assertEqual_dict(self): 122 | """ 123 | notice the nice formatting that only shows differences! 124 | """ 125 | self.assertEqual({1:1,2:2},{1:2,3:3}) 126 | 127 | 128 | def test_objects(self): 129 | """ 130 | there is no assertEqual for objects. 131 | 132 | there are two alternatives to get the nice formatting 133 | 134 | IMHO, the best way to get this for formatting is: 135 | 136 | 1) if the objects are equal iff __dict__ are equal, 137 | use assertEqual + explicit __dict__ so you get the nice dict formatting. 138 | 139 | 2) if the equality is more complex, implement, it 140 | """ 141 | self.assertEqual( SomeOutput(1,1).__dict__, SomeOutput(1,2).__dict__ ) 142 | 143 | def test_because_starts_with_test(self): 144 | self.assertEqual(1,1) 145 | self.assertEqual(1,2,'test.another') 146 | 147 | def not_a_test_because_does_not_start_with_test(self): 148 | print 'test.not_a_test_because_starts_with_test' 149 | self.assertEqual(1,1) 150 | self.assertEqual(1,2,'test.another') 151 | 152 | class SomeTest2(unittest.TestCase): 153 | 154 | @classmethod 155 | def setUpClass(self): 156 | print 'test2.setUpClass' 157 | 158 | @classmethod 159 | def tearDownClass(self): 160 | print 'test2.tearDownClass' 161 | 162 | def setUp(self): 163 | print 'test2.setUp' 164 | 165 | def tearDown(self): 166 | print 'test2.tearDown' 167 | 168 | def tearDown(self): 169 | print 'test2.tearDown' 170 | 171 | def test(self): 172 | print 'test2.test' 173 | self.assertEqual(1,1) 174 | self.assertEqual(1,2,'message') 175 | 176 | if __name__ == '__main__': 177 | 178 | ##run tests from a single class 179 | 180 | suite = unittest.TestLoader().loadTestsFromTestCase(SomeTest) 181 | unittest.TextTestRunner().run(suite) 182 | 183 | ##main 184 | 185 | #finds every class derived from `unittest.TestCase` 186 | #in cur module and calls their `runTest()` methods 187 | 188 | ##runTest 189 | 190 | #the default is to: 191 | 192 | #- call setUpClass 193 | 194 | #- search for every method in the class that 195 | #starts with the string `test` then call in order the class': 196 | 197 | #- setUp 198 | #- test* 199 | #- tearDown 200 | 201 | #- call tearDownClass 202 | 203 | #in this order. 204 | 205 | #you could override this method, but the default is pretty good 206 | #and standard already 207 | 208 | ###exit 209 | 210 | #if True (default), exits program immediately. 211 | #exit status = 0 if all pass, 1 otherwise. 212 | 213 | #else continue 214 | 215 | unittest.main( exit = False ) 216 | 217 | unittest.main() 218 | assert False 219 | -------------------------------------------------------------------------------- /urllib2_cheat/README.md: -------------------------------------------------------------------------------- 1 | # urllib2 2 | 3 | Update to `urllib`. 4 | 5 | Renamed back to `urllib` in Python 3. 6 | 7 | Likely `urllib2` is the better choice in Python 2. 8 | 9 | 1. [POST](post.py) 10 | 1. [HTTP proxy](http_proxy.py) 11 | -------------------------------------------------------------------------------- /urllib2_cheat/http_proxy.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | """ 4 | http://stackoverflow.com/questions/1450132/proxy-with-urllib2 5 | """ 6 | 7 | import urllib2 8 | 9 | urllib2.install_opener(urllib2.build_opener(urllib2.ProxyHandler({'http': '127.0.0.1:9050'}))) 10 | print(urllib2.urlopen(urllib2.Request('http://checkip.amazonaws.com/')).read()) 11 | -------------------------------------------------------------------------------- /urllib2_cheat/post.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | 4 | """ 5 | ## POST 6 | """ 7 | 8 | import urllib2 9 | 10 | ''' 11 | ## urlopen 12 | 13 | Does the actual request. 14 | 15 | Raises urllib2.URLError on error. 16 | 17 | It timeout not given a global default is used. 18 | 19 | Retruns bytestring, not unicode. 20 | 21 | Encoding can sometimes be inferred from Content-Type HTTP header: 22 | 23 | Content-Type: text/html; charset=ISO-8859-1 24 | 25 | Returns a file like object with some extra methods. 26 | 27 | info() returns an object with methods shown in: 28 | ''' 29 | 30 | req = urllib2.Request( 31 | 'https://api.github.com/markdown', 32 | '{"text":"**Hello World 你好**", "mode":"gfm", "context":"github/gollum"}') 33 | # Custom request headers; 34 | #request = urllib2.Request("http://www.google.com", headers={"Accept" : "text/html"}) 35 | try: 36 | response = urllib2.urlopen(req, timeout=10) 37 | except urllib2.URLError, e: 38 | print e 39 | sys.exit(1) 40 | response_body = response.read() 41 | assert type(response_body) == str 42 | print('response body = ' + response_body) 43 | print('response status = {}'.format(response.getcode())) 44 | info = response.info() 45 | # Header string list 46 | print('response info = ' + repr(info.headers)) 47 | # Header key val dict 48 | print('response info = ' + repr(info.items())) 49 | 50 | ##retry 51 | 52 | # Exponential backoff retry: http://www.saltycrane.com/blog/2009/11/trying-out-retry-decorator-python/ 53 | -------------------------------------------------------------------------------- /virtualenv/.gitignore: -------------------------------------------------------------------------------- 1 | /venv* 2 | -------------------------------------------------------------------------------- /virtualenv/Makefile: -------------------------------------------------------------------------------- 1 | all: 2 | virtualenv -p python2.7 --distribute venv2.7 3 | virtualenv -p python3.3 --distribute venv3.3 4 | . venv2.7/bin/activate && pip install termcolor==1.0.0 && python main.py 5 | . venv3.3/bin/activate && pip install termcolor==1.1.0 && python main.py 6 | 7 | clean: 8 | rm -rf venv* 9 | -------------------------------------------------------------------------------- /virtualenv/README.md: -------------------------------------------------------------------------------- 1 | # Virtualenv 2 | 3 | Allows you to run programs in a controlled Python environment: 4 | 5 | - python interpreter version 6 | - version of each installed python module 7 | 8 | It is therefore a virtualization method for Python aspects of the program, and helps ensure that every developer of a project runs the same environment. 9 | 10 | `pip` is unlike most other more modern languages which have two separate utilities: 11 | 12 | - an interpreter virtualizer (RVM, NVM) 13 | - a package manager capable of doing local packages (Bundler, NPM) 14 | 15 | virtualenv does not seem to install Python: it only uses what you specify: which should be a `pythonX.Y` executable in your path. 16 | 17 | Install virtualenv with pip: 18 | 19 | sudo pip install --upgrade virtualenv 20 | 21 | The typical usage for virtualenv is to create a new one inside the project you are working on: 22 | 23 | cd python-project 24 | 25 | Create a new environment that will use the `python2.7` interpreter: 26 | 27 | virtualenv -p python2.7 --distribute venv2.7 28 | 29 | `--distribute` is recommended as this flags tells Virtualenv to use `distribute` instead of `setuptools` which is better as of 2013. 30 | 31 | If `-p` is not given, the version used to run `virtualenv` is used instead. 32 | 33 | Create a new environment that will use the `python3.3` interpreter: 34 | 35 | virtualenv -p python3.3 --distribute venv3.3 36 | 37 | To activate the 2.7 environment we must source: 38 | 39 | . venv3.5/bin/activate 40 | 41 | This has the following effects: 42 | 43 | - `pip` now refers to a local `pip` of the environment under `venv2.7`, as can be seen by: 44 | 45 | readlink -f "$(which pip)" 46 | 47 | `pip install` only installs packages locally to this environment. 48 | 49 | - `python` now refers to TODO what? The symlink chain ends in a python under `venv2.7`. Where did that interpreter come from? 50 | 51 | - `PS1` was changed, so that every shell lines starts with: 52 | 53 | (venv2.7)~/path/to/myproject 54 | user@host 55 | 56 | Note how this is not like `git`: if we change directory we are still in the virtual environment, because we actually sourced something into our current shell. 57 | 58 | When you want to exit do: 59 | 60 | deactivate 61 | 62 | This has been defined by the activate source command and undoes it. But don't do that yet. 63 | 64 | Check out that our Python version really is the one we wanted: 65 | 66 | python --version 67 | 68 | Check out all the distribute installed programs: 69 | 70 | pip freeze 71 | 72 | There should be very few in the list, much less than all of those we have previously installed. This means that we have a very clean environment for our new project to run on! Amongst the few present, `distribute` should be there since we will be using it to install the other dependencies. 73 | 74 | Install a `termcolor` version `1.0.0` on it: 75 | 76 | pip install termcolor==1.0.0 77 | 78 | Open up `venv2.7` and find the `termcolor` installed in there. 79 | It is all local on our super clean environment. 80 | 81 | Check our python version and `termcolor` version by running a script: 82 | 83 | python main.py 84 | 85 | Now lets switch to the other env, but this time we install `termcolor` 1.1.0: 86 | 87 | . venv3.3/bin/activate 88 | pip install termcolor==1.1.0 89 | 90 | And just like magic, if we run the same `python main.py` we see that the python version and `termcolor` versions both changed! How cool is that?! 91 | 92 | Do open up `venv3.3` just to see that everything is in there once again: python interpreter and installed packages. 93 | 94 | Once you've have enough fun, just do: 95 | 96 | deactivate 97 | 98 | And we are back to the normal world. 99 | 100 | ## git and virtualenv 101 | 102 | You should gitignore the local environment: 103 | 104 | Use `pip freeze` to get the packages I need into a `requirements.txt` and track that instead. 105 | 106 | TODO: how to automatically specify which Python version is to be used? Like `.rvm` file for Ruby? 107 | 108 | ## Bibliography 109 | 110 | - 111 | - 112 | -------------------------------------------------------------------------------- /virtualenv/main.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | import os 4 | import pkg_resources 5 | import sys 6 | 7 | sys.stdout.write(('python version = %d.%d ' + os.linesep) % 8 | (sys.version_info.major, sys.version_info.minor)) 9 | sys.stdout.write('termcolor version = ' 10 | + str(pkg_resources.get_distribution('termcolor').version) + os.linesep) 11 | -------------------------------------------------------------------------------- /waf/.gitignore: -------------------------------------------------------------------------------- 1 | build 2 | -------------------------------------------------------------------------------- /waf/README.md: -------------------------------------------------------------------------------- 1 | # Waf 2 | 3 | Like Make, but sane and flexible because is plain Python. 4 | 5 | Does not seem to be available on PyPi: 6 | 7 | Install: 8 | 9 | SOMEWHERE_IN_BIN_PATH="" 10 | 11 | cd $SOMEWHERE_IN_BIN_PATH 12 | wget http://waf.googlecode.com/files/waf-1.7.3 13 | mv waf-1.7.3 waf 14 | python waf --version 15 | chmod +x waf 16 | -------------------------------------------------------------------------------- /waf/d/wscript: -------------------------------------------------------------------------------- 1 | #! /usr/bin/env python 2 | 3 | def subwaf(ctx): 4 | print('d/subwaf') 5 | -------------------------------------------------------------------------------- /waf/test.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | #test several calls to waf 4 | 5 | waf a 6 | waf a b 7 | waf ctx 8 | waf subwaf 9 | -------------------------------------------------------------------------------- /waf/wscript: -------------------------------------------------------------------------------- 1 | #! /usr/bin/env python 2 | # encoding: utf-8 3 | 4 | top = '.' 5 | out = 'build' 6 | 7 | def a(ctx): 8 | print('a') 9 | 10 | def b(ctx): 11 | print('b') 12 | 13 | def ctx(ctx): 14 | """ 15 | properties of ctx 16 | """ 17 | print('ctx') 18 | print( 'ctx.path.abspath() ==' + ctx.path.abspath() ) 19 | print( 'id(ctx) == %d' % id(ctx) ) 20 | 21 | def subwaf(ctx): 22 | """ 23 | call another wscript 24 | 25 | by default searchs for target named `subwaf` 26 | """ 27 | print('subwaf') 28 | ctx.recurse('d') 29 | 30 | def options(ctx): 31 | ctx.add_option( 32 | '--aa', 33 | action='store', 34 | default=False, 35 | help='help' 36 | ) 37 | 38 | def configure(ctx): 39 | print('configure') 40 | ctx.env.AA = ctx.options.aa 41 | #check if program exists: 42 | #- if not say it 43 | #- if yes, assign it to a variable containing its path 44 | ctx.find_program('touch', var='TOUCH') 45 | #ctx.find_program('idontexist', var='IDONTEXIST') 46 | 47 | def build(bld): 48 | print('build') 49 | print(ctx.env.TOUCH) 50 | print(ctx.env.FOO) 51 | bld(rule='${TOUCH} ${TGT}', target='foo.txt') 52 | -------------------------------------------------------------------------------- /wsgi.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | """ 4 | WSGI is a Python standrad interface for server communication. 5 | 6 | It is much like CGI, but Python specific. 7 | 8 | The stdlib funishes a WSGI reference implementation. 9 | 10 | There are however other important implementations: 11 | 12 | - Apache mod_wsgi 13 | - gunicorn 14 | 15 | The advantage of WSGI is that a single python web script can be run on several 16 | different implementations with same results. 17 | """ 18 | 19 | def application(environ, start_response): 20 | """ 21 | This function is the central piece that implements WSGI. 22 | 23 | Inputs: 24 | 25 | - `environ` string to string dict. 26 | 27 | Contains key information about the query that allows our server to generate the correct response. 28 | 29 | For example: 30 | 31 | REQUEST_METHOD: GET 32 | PATH_INFO: /a/b 33 | QUERY_STRING: c=d 34 | RAW_URI: /a/b?c=d 35 | 36 | This may or may not contain `os.environ`. 37 | 38 | - `start_response`: TODO function of string and list of string pairs 39 | 40 | Return value 41 | 42 | - response_body string. 43 | 44 | The function name is optional for the wsgiref server, 45 | but is very coventional may be obligatory for apache's mod_wsgi, 46 | so always use it. 47 | """ 48 | env = [ 49 | '%s: %s' % (key, value) 50 | for key, value in sorted(environ.items()) 51 | ] 52 | response_body = 'WSGI Test\n\n' 53 | response_body += '\n'.join(env) 54 | status = '200 OK' 55 | response_headers = [ 56 | ('Content-Type', 'text/plain'), 57 | ('Content-Length', str(len(response_body))) 58 | ] 59 | start_response(status, response_headers) 60 | return [response_body] 61 | 62 | if __name__ == '__main__': 63 | 64 | ##wsgiref 65 | 66 | # Set server params: 67 | 68 | from wsgiref.simple_server import make_server 69 | 70 | httpd = make_server( 71 | 'localhost', # hostname 72 | 8051, # port 73 | application # the function with the given WSGI specifications 74 | ) 75 | 76 | # Handle single request and quit: 77 | 78 | #`httpd.handle_request()` 79 | 80 | # Handle requests forever: 81 | 82 | httpd.serve_forever() 83 | 84 | ##apache mod_wsgi 85 | 86 | # First install and load mod_wsgi: 87 | 88 | #``` {.bash} 89 | #sudo aptitude install -y libapache2-mod-wsgi 90 | #``` 91 | 92 | # Exceptions are now logged to the server log file. 93 | 94 | # Put this in your `apache.conf`: 95 | 96 | #WSGIScriptAlias /the/url /var/www/path/to/wsgi.py 97 | 98 | # Works just like a `ScriptAlias` 99 | 100 | # Append dir to the *end* of the python search path: 101 | 102 | #WSGIPythonPath /path/to/dir1:/path/to/dir2 103 | 104 | ##gunicorn 105 | 106 | #DO: 107 | 108 | #gunicorn main:application 109 | --------------------------------------------------------------------------------