Flatten a dictionary -------------------- ```python In [1]: k = {'name': 'Og Maciel', 'age': 40, 'mansions': '', 'kids': 3} In [2]: ' '.join("--{!s}={!r}".format(key,val) for (key,val) in k.iteritems()) "--age=40 --kids=3 --name='Og Maciel' --mansions=''" ``` Run Unittest TestCase from IPython ---------------------------------- ```python In [1]: import sys In [2]: import unittest In [3]: class MyTest(unittest.TestCase): ....: ....: def test_fail(self): ....: self.assertEquals(1, 2) ....: def test_pass(self): ....: self.assertEquals(1, 1) ....: In [4]: suite = unittest.TestLoader().loadTestsFromTestCase(MyTest) In [5]: unittest.TextTestRunner(verbosity=1,stream=sys.stderr).run(suite) F. ====================================================================== FAIL: test_fail (__main__.MyTest) ---------------------------------------------------------------------- Traceback (most recent call last): File "", line 4, in test_fail self.assertEquals(1, 2) AssertionError: 1 != 2 ---------------------------------------------------------------------- Ran 2 tests in 0.000s FAILED (failures=1) Out[5]: In [6]: unittest.TextTestRunner(verbosity=1).run(suite) F. ====================================================================== FAIL: test_fail (__main__.MyTest) ---------------------------------------------------------------------- Traceback (most recent call last): File "", line 4, in test_fail self.assertEquals(1, 2) AssertionError: 1 != 2 ---------------------------------------------------------------------- Ran 2 tests in 0.000s FAILED (failures=1) Out[6]: In [7]: suite = unittest.TestSuite() In [8]: suite.addTest(MyTest('test_fail')) In [9]: unittest.TextTestRunner(verbosity=2).run(suite) test_foo (__main__.MyTest) ... FAIL ====================================================================== FAIL: test_foo (__main__.MyTest) ---------------------------------------------------------------------- Traceback (most recent call last): File "", line 4, in test_foo self.assertEquals(1, 2) AssertionError: 1 != 2 ---------------------------------------------------------------------- Ran 1 test in 0.000s FAILED (failures=1) Out[9]: In [10]: suite = unittest.TestSuite() In [11]: suite.addTest(MyTest('test_pass')) In [12]: unittest.TextTestRunner(verbosity=2).run(suite) test_pass (__main__.MyTest) ... ok ---------------------------------------------------------------------- Ran 1 test in 0.000s OK Out[12]: ``` Playing with Mock ----------------- ```python In [1]: import mock In [2]: class Car(object): ...: def shift_down(self): ...: print "Down" ...: def shift_up(self): ...: print "Up" ...: In [3]: with mock.patch('__main__.Car') as mocked_car: ....: my_car = mocked_car() ....: my_car.shift_up() ....: my_car.shift_down() ....: my_car.foo() ....: print my_car.method_calls ....: [call.shift_up(), call.shift_down(), call.foo()] In [4]: def beep(): ...: return "Beep!" ...: In [5]: with mock.patch.object(Car, 'shift_down') as mocked_shift_down: ....: mocked_shift_down.return_value = beep() ....: my_car = Car() ....: my_car.shift_up() ....: print my_car.shift_down() ....: Up Beep! ``` Using Unittest SubTests ----------------------- ```python >>> import unittest >>> class MyTest(unittest.TestCase): ... def test_is_greater_than(self): ... values = {4, 5, 6} ... for value in values: ... with self.subTest(value): ... self.assertGreater(value, 1) ... >>> suite = unittest.TestLoader().loadTestsFromTestCase(MyTest) >>> unittest.TextTestRunner(verbosity=1).run(suite) . ---------------------------------------------------------------------- Ran 1 test in 0.000s OK ``` MetaClass for Data Driven testing --------------------------------- An example of using a python MetaClass for Data Driven testing. ```python import unittest from ddt import data from ddt import ddt class MetaTest(type): """ Metaclass to tweak test classes dynamically """ def __new__(cls, name, bases, dic): """Add test methods to new classes""" _klass = super(MetaTest, cls).__new__(cls, name, bases, dic) setattr(_klass, "test_greater_than_zero", cls.test_greater_than_zero) return _klass @staticmethod @data(1, 2, 3, 4) def test_greater_than_zero(cls, value): """Simple test""" cls.assertTrue(value > 0) class Base(unittest.TestCase): """Base class for all tests""" @classmethod def setUpClass(cls): """Adds a baz attribute to test classes""" cls.baz = "Bazinga" @ddt class TestMetaClass(Base): """A simple test class""" __metaclass__ = MetaTest def test_baz_exists(self): """Checks that baz is not None""" self.assertTrue(self.baz) ``` This will give you: ```bash $ nosetests test_metaclass.py test_baz_exists (tests.cli.test_foo.TestMetaClass) ... ok test_greater_than_zero_1 (tests.cli.test_foo.TestMetaClass) ... ok test_greater_than_zero_2 (tests.cli.test_foo.TestMetaClass) ... ok test_greater_than_zero_3 (tests.cli.test_foo.TestMetaClass) ... ok test_greater_than_zero_4 (tests.cli.test_foo.TestMetaClass) ... ok Ran 5 tests in 0.001s OK ``` PhantomJS --------- Using PhantomJS for quick UI testing using Selenium's WebDriver. ```python In [1]: from selenium import webdriver In [2]: service_args = ['--ignore-ssl-errors=true'] In [3]: driver = webdriver.PhantomJS(service_args=service_args) In [4]: driver.get("https://aaa.bbb.ccc") In [5]: driver.title Out[5]: u'Login' ``` Import On Demand ---------------- ```python def render(engine_id, template, **kwargs): engines = { "jinja2": "jinja2", "mako": "make.template", } try: module = engines[engine_id] engine = __import__( module, globals(), locals(), ['Template'], -1) except (KeyError, ImportError) as err: print "Template engine not found!" return '' return engine.Template(template).render(**kwargs) print render("jinja2", "Hi {{f}}", f="John") print render("mako", "Hi ${f} ${l}", f="John", l="Doe") ``` See if a module exists without actually importing it ---------------------------------------------------- ```python from importlib.util import find_spec if find_spec('modname'): print('yep') ``` Get Logging for Python console ------------------------------ ```python import logging logging.getLogger().setLevel(logging.DEBUG) ``` Python Decorators ----------------- Without arguments ================= Usage equivalent to `f = decorator_name(f)` ```python import functools def decorator_name(f): @functools.wraps(f) def wrapped(*args, **kwargs): # do work before original function result = f(*args, **kwargs) # do work after original function # modify result if necessary return result return wrapped ``` With arguments ============== Usage equivalent to `f = decorator_name(args)(f)` ```python import functools def decorator_name(args): def decorator(f): @functools.wraps(f) def wrapped(*args, **kwargs): # do work before original function result = f(*args, **kwargs) # do work after original function # modify result if necessary return result return wrapped return decorator ``` Wraps ===== ```python from functools import wraps def logged(func): @wraps(func) def with_logging(*args, **kwargs): print func.__name__ + " was called" return func(*args, **kwargs) return with_logging @logged def f(x): """does some math""" return x + x * x print f.__name__ # prints 'f' print f.__doc__ # prints 'does some math' ``` Tokenizer --------- * File: `tokenize-example-1.py` ```python import tokenize file = open("tokenize-example-1.py") def handle_token(type, token, (srow, scol), (erow, ecol), line): print "%d,%d-%d,%d:\t%s\t%s" % \ (srow, scol, erow, ecol, tokenize.tok_name[type], repr(token)) tokenize.tokenize( file.readline, handle_token ) ``` Outputs: ```shell 1,0-1,6: NAME 'import' 1,7-1,15: NAME 'tokenize' 1,15-1,16: NEWLINE '\012' 2,0-2,1: NL '\012' 3,0-3,4: NAME 'file' 3,5-3,6: OP '=' 3,7-3,11: NAME 'open' 3,11-3,12: OP '(' 3,12-3,35: STRING '"tokenize-example-1.py"' 3,35-3,36: OP ')' 3,36-3,37: NEWLINE '\012' ... ``` * The `tokenize` function takes two callable objects; the first argument is called repeatedly to fetch new code lines, and the second argument is called for each token. * The generator produces 5-tuples with these members: * the token type; * the token string; * a 2-tuple (srow, scol) of ints specifying the row and column where the token begins in the source; * a 2-tuple (erow, ecol) of ints specifying the row and column where the token ends in the source; * and the line on which the token was found. The line passed (the last tuple item) is the logical line; continuation lines are included. Switch Statement ---------------- ```python def dispatch_dic(operator, x, y): return { 'add': lambda: x + y, 'sub': lambda: x - y, 'mul': lambda: x * y, 'div': lambda: x / y, }.get(operator, lambda: None)() ```