├── ts.txt ├── README.rst ├── testmarkov.py ├── markov.py └── repl-output.txt /ts.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mattharrison/pycon-adv-markov-2017/master/ts.txt -------------------------------------------------------------------------------- /README.rst: -------------------------------------------------------------------------------- 1 | =========================================== 2 | Hands-on Intermediate Python 3.6 Bootcamp 3 | =========================================== 4 | 5 | This repository contains the final output from the 2017 PyCon 6 | tutorial `Intermediate Python Bootcamp 7 | `_. 8 | 9 | 10 | Resources 11 | ----------- 12 | 13 | * https://github.com/mattharrison/Tiny-Python-3.6-Notebook 14 | * http://setosa.io/blog/2014/07/26/markov-chains/ 15 | * http://www.gutenberg.org/ebooks/74 16 | 17 | 18 | -------------------------------------------------------------------------------- /testmarkov.py: -------------------------------------------------------------------------------- 1 | from collections import Counter 2 | import unittest 3 | 4 | import markov as mar 5 | 6 | class TestMarkov(unittest.TestCase): 7 | def test_char_iter(self): 8 | lines = ['abc', 'def'] 9 | c = mar.CharIter(lines) 10 | res = list(c) 11 | self.assertEqual(res, ['a', 'b', 'c', 'd', 'e', 'f']) 12 | 13 | def test_char_gen(self): 14 | lines = ['abc', 'def'] 15 | c = mar.char_gen(lines) 16 | res = list(c) 17 | self.assertEqual(res, ['a', 'b', 'c', 'd', 'e', 'f']) 18 | 19 | def test_word_gen(self): 20 | lines = ['hello world', 'bye matt'] 21 | w = mar.word_gen(lines) 22 | res = list(w) 23 | self.assertEqual(res, ['hello', 'world', 'bye', 'matt']) 24 | 25 | def test_window(self): 26 | lines = ['hello world', 'bye matt'] 27 | w = mar.word_gen(lines) 28 | win = mar.window_gen(w, 2) 29 | res = list(win) 30 | self.assertEqual(res, 31 | [['hello', 'world'], ['world', 'bye'], ['bye', 'matt']] 32 | ) 33 | 34 | def test_cmarkov(self): 35 | lines = ['abc', 'def'] 36 | m = mar.CharMarkov(lines, 3) 37 | self.assertEqual(m.tables, [{'a': Counter({'b': 1}), 'b': Counter({'c': 1}), 'c': Counter({'d': 1})}, {'ab': Counter({'c': 1}), 'bc': Counter({'d': 1}), 'cd': Counter({'e': 1})}, {'abc': Counter({'d': 1}), 'bcd': Counter({'e': 1}), 'cde': Counter({'f': 1})}]) 38 | 39 | 40 | def test_get_table(self): 41 | lines = ['abc', 'def'] 42 | t = mar.get_table(mar.char_gen(lines)) 43 | self.assertEqual(t, {'a': {'b': 1}, 'b': {'c': 1}, 'c': {'d': 1}, 'd': {'e': 1}, 'e': {'f': 1}}) 44 | 45 | 46 | if __name__ == '__main__': 47 | unittest.main() 48 | -------------------------------------------------------------------------------- /markov.py: -------------------------------------------------------------------------------- 1 | """ 2 | This is a docstring. Here is an example 3 | of running a Markov prediction: 4 | 5 | >>> m = Markov('ab') 6 | >>> m.predict('a') 7 | 'b' 8 | 9 | >>> m.predict('c') 10 | Traceback (most recent call last): 11 | ... 12 | KeyError 13 | 14 | >>> get_table('ab') 15 | {'a': {'b': 1}} 16 | 17 | >>> random.seed(42) 18 | >>> m = Markov('Find a city, find yourself a city to live in', 4) 19 | >>> test_predict(m, 20, 'F', 4) 20 | 'Find a city, find a c' 21 | 22 | >>> with open('ts.txt', encoding='windows_1252') as fin: 23 | ... data = fin.read() 24 | >>> m2 = Markov(data, 4) 25 | >>> test_predict(m2, 100, 'T', 4) 26 | """ 27 | 28 | import argparse 29 | from collections import Counter 30 | import functools 31 | import random 32 | import sys 33 | import time 34 | 35 | class CharIter: 36 | def __init__(self, lines): 37 | self.data = iter(lines) 38 | self.line = None 39 | self.pos = 0 40 | 41 | def __iter__(self): 42 | return self 43 | 44 | def __next__(self): 45 | while 1: 46 | if self.line is None: 47 | self.line = next(self.data) 48 | try: 49 | char = self.line[self.pos] 50 | except IndexError: 51 | self.line = next(self.data) 52 | self.pos = 0 53 | else: 54 | self.pos += 1 55 | return char 56 | 57 | def noisy(f): 58 | @functools.wraps(f) 59 | def inner(*args, **kwargs): 60 | # before 61 | print("Before") 62 | res = f(*args, **kwargs) 63 | # after 64 | print("After") 65 | return res 66 | return inner 67 | 68 | def timer(f): 69 | @functools.wraps(f) 70 | def inner(*args, **kwargs): 71 | # before 72 | start = time.time() 73 | res = f(*args, **kwargs) 74 | # after 75 | print("Took {} seconds".format( 76 | time.time()-start)) 77 | return res 78 | return inner 79 | 80 | def cheat(f): 81 | @functools.wraps(f) 82 | def inner(*args, **kwargs): 83 | return 42 84 | return inner 85 | 86 | 87 | @timer 88 | def sleep(x): 89 | time.sleep(x) 90 | 91 | @noisy 92 | def adder(x, y): 93 | return x + y 94 | 95 | #adder = noisy(adder) 96 | 97 | def char_gen(lines): 98 | """ This is a generator """ 99 | for line in lines: 100 | for c in line: 101 | yield c 102 | 103 | def word_gen(lines): 104 | for line in lines: 105 | for word in line.split(): 106 | yield word 107 | 108 | def window_gen(data, size): 109 | win = [] 110 | for thing in data: 111 | win.append(thing) 112 | if len(win) == size: 113 | yield win 114 | win = win[1:] 115 | 116 | 117 | def blastoff(): 118 | print("Hi") 119 | yield 1 120 | print("after 1") 121 | yield 2 122 | print("Goodbye") 123 | 124 | 125 | def just_name(klass): 126 | def name(self): 127 | return '{}'.format( 128 | self.__class__.__name__) 129 | klass.__str__ = name 130 | return klass 131 | 132 | @just_name 133 | class Markov: 134 | def __init__(self, data, size=1): 135 | self.tables = [] 136 | for i in range(size): 137 | self.tables.append(get_table(data, i+1)) 138 | #self.table = get_table(data) 139 | 140 | def predict(self, data_in): 141 | table = self.tables[len(data_in) - 1] 142 | options = table.get(data_in, {}) 143 | if not options: 144 | raise KeyError() 145 | possible = '' 146 | for result, count in options.items(): 147 | possible += result*count 148 | result = random.choice(possible) 149 | return result 150 | 151 | 152 | class WordMarkov(Markov): 153 | def __init__(self, lines, size=1): 154 | data = word_gen(lines) 155 | self.tables = get_tables(data, size) 156 | 157 | 158 | class CharMarkov(Markov): 159 | def __init__(self, lines, size=1): 160 | data = char_gen(lines) 161 | self.tables = get_tables(data, size) 162 | 163 | 164 | def get_tables(data, size=1, join_char=''): 165 | tables = [] 166 | for tokens in window_gen(data, size+1): 167 | for i in range(size): 168 | try: 169 | table = tables[i] 170 | except IndexError: 171 | tables.append({}) 172 | table = tables[i] 173 | key = join_char.join(tokens[:i+1]) 174 | try: 175 | result = tokens[i+1] 176 | except IndexError: 177 | continue 178 | counts = table.setdefault(key, Counter()) 179 | counts[result] += 1 180 | return tables 181 | 182 | 183 | 184 | def get_table(data, size=1, join_char=''): 185 | results = {} 186 | for tokens in window_gen(data, size+1): 187 | item = join_char.join(tokens[:size]) 188 | try: # if i == len(line): # Look before you leap 189 | output = tokens[size] 190 | except IndexError: 191 | # easier to ask for forgiveness than permission 192 | break 193 | inner_dict = results.get(item, {}) 194 | inner_dict.setdefault(output, 0) 195 | inner_dict[output] += 1 196 | results[item] = inner_dict 197 | return results 198 | 199 | def test_predict(m, num_chars, start, size=1): 200 | res = [start] 201 | for i in range(num_chars): 202 | let = m.predict(start) 203 | res.append(let) 204 | start = ''.join(res)[-size:] 205 | return ''.join(res) 206 | 207 | def repl(m, size=1): 208 | """ 209 | This starts a repl, provide a Markov and 210 | optional size 211 | """ 212 | while 1: 213 | txt = input(">") 214 | try: 215 | res = m.predict(txt[-size:]) 216 | except KeyError: 217 | print("Try again...") 218 | print(res) 219 | 220 | def main(args): 221 | p = argparse.ArgumentParser() 222 | p.add_argument('-f', '--file', help='Input file') 223 | p.add_argument('--encoding', help='File encoding default(utf8)', 224 | default='utf8') 225 | p.add_argument('-s', '--size', help='Size of input default(1)', 226 | default=1, type=int) 227 | p.add_argument('-t', '--test', help='run tests', action='store_true') 228 | 229 | opts = p.parse_args(args) 230 | if opts.file: 231 | with open(opts.file, encoding=opts.encoding) as fin: 232 | data = fin.read() 233 | m = Markov(data, opts.size) 234 | repl(m) 235 | if opts.test: 236 | import doctest 237 | doctest.testmod() 238 | 239 | 240 | if __name__ == '__main__': 241 | print("EXECUTED") 242 | #import doctest 243 | #doctest.testmod() 244 | main(sys.argv[1:]) 245 | else: 246 | print("IMPORTED") 247 | 248 | 249 | -------------------------------------------------------------------------------- /repl-output.txt: -------------------------------------------------------------------------------- 1 | Python 3.6.0 (default, Dec 24 2016, 08:01:42) 2 | [GCC 4.2.1 Compatible Apple LLVM 8.0.0 (clang-800.0.42.1)] on darwin 3 | Type "copyright", "credits" or "license()" for more information. 4 | >>> WARNING: The version of Tcl/Tk (8.5.9) in use may be unstable. 5 | Visit http://www.python.org/download/mac/tcltk/ for current information. 6 | 7 | >>> 2 + 2 8 | 4 9 | >>> 10 | RESTART: /Users/matt/Dropbox/work/training/metasnake/pycon-2017/adv-markov/markov.py 11 | EXECUTED 12 | >>> m = Markov('Find a city, find yourself a city to live in') 13 | >>> dir() 14 | ['Markov', '__annotations__', '__builtins__', '__doc__', '__file__', '__loader__', '__name__', '__package__', '__spec__', 'argparse', 'get_table', 'm', 'main', 'random', 'repl', 'sys', 'test_predict'] 15 | >>> m.predict('i') 16 | 't' 17 | >>> m.predict('t') 18 | 'o' 19 | >>> m.predict('o') 20 | 'u' 21 | >>> m.predict('u') 22 | 'r' 23 | >>> test_predict(m, 100) 24 | Traceback (most recent call last): 25 | File "", line 1, in 26 | test_predict(m, 100) 27 | TypeError: test_predict() missing 1 required positional argument: 'start' 28 | >>> test_predict(m, 100, 'F') 29 | 'Fitourse civelf livelitourse lity, ty a fityourself find cind ind cind ityo lind a live lf ind cind f' 30 | >>> m2 = Markov('Find a city, find yourself a city to live in', 4) 31 | >>> test_predict(m2, 100, 'F', 4) 32 | Traceback (most recent call last): 33 | File "", line 1, in 34 | test_predict(m2, 100, 'F', 4) 35 | File "/Users/matt/Dropbox/work/training/metasnake/pycon-2017/adv-markov/markov.py", line 74, in test_predict 36 | let = m.predict(start) 37 | File "/Users/matt/Dropbox/work/training/metasnake/pycon-2017/adv-markov/markov.py", line 46, in predict 38 | raise KeyError() 39 | KeyError 40 | >>> test_predict(m2, 100, 'i', 4) 41 | Traceback (most recent call last): 42 | File "", line 1, in 43 | test_predict(m2, 100, 'i', 4) 44 | File "/Users/matt/Dropbox/work/training/metasnake/pycon-2017/adv-markov/markov.py", line 74, in test_predict 45 | let = m.predict(start) 46 | File "/Users/matt/Dropbox/work/training/metasnake/pycon-2017/adv-markov/markov.py", line 46, in predict 47 | raise KeyError() 48 | KeyError 49 | >>> m2.tables 50 | [{'F': {'i': 1}, 'i': {'n': 3, 't': 2, 'v': 1}, 'n': {'d': 2}, 'd': {' ': 2}, ' ': {'a': 2, 'c': 2, 'f': 1, 'y': 1, 't': 1, 'l': 1, 'i': 1}, 'a': {' ': 2}, 'c': {'i': 2}, 't': {'y': 2, 'o': 1}, 'y': {',': 1, 'o': 1, ' ': 1}, ',': {' ': 1}, 'f': {'i': 1, ' ': 1}, 'o': {'u': 1, ' ': 1}, 'u': {'r': 1}, 'r': {'s': 1}, 's': {'e': 1}, 'e': {'l': 1, ' ': 1}, 'l': {'f': 1, 'i': 1}, 'v': {'e': 1}}, {'Fi': {'n': 1}, 'F': {'n': 1}, 'in': {'d': 2}, 'i': {'e': 1}, 'nd': {' ': 2}, 'n': {' ': 2}, 'd ': {'a': 1, 'y': 1}, 'd': {'a': 1, 'y': 1}, ' a': {' ': 2}, ' ': {'n': 1}, 'a ': {'c': 2}, 'a': {'c': 2}, ' c': {'i': 2}, 'ci': {'t': 2}, 'c': {'t': 2}, 'it': {'y': 2}, 'ty': {',': 1, ' ': 1}, 't': {' ': 1}, 'y,': {' ': 1}, 'y': {'t': 1}, ', ': {'f': 1}, ',': {'f': 1}, ' f': {'i': 1}, 'fi': {'n': 1}, 'f': {'a': 1}, ' y': {'o': 1}, 'yo': {'u': 1}, 'ou': {'r': 1}, 'o': {'l': 1}, 'ur': {'s': 1}, 'u': {'s': 1}, 'rs': {'e': 1}, 'r': {'e': 1}, 'se': {'l': 1}, 's': {'l': 1}, 'el': {'f': 1}, 'e': {'i': 1}, 'lf': {' ': 1}, 'l': {'v': 1}, 'f ': {'a': 1}, 'y ': {'t': 1}, ' t': {'o': 1}, 'to': {' ': 1}, 'o ': {'l': 1}, ' l': {'i': 1}, 'li': {'v': 1}, 'iv': {'e': 1}, 've': {' ': 1}, 'v': {' ': 1}, 'e ': {'i': 1}, ' i': {'n': 1}}, {'Fin': {'d': 1}, 'F': {'d': 1}, 'ind': {' ': 2}, 'i': {' ': 1}, 'nd ': {'a': 1, 'y': 1}, 'n': {'a': 1, 'y': 1}, 'd a': {' ': 1}, 'd': {'o': 1}, ' a ': {'c': 2}, ' ': {'v': 1}, 'a c': {'i': 2}, 'a': {'i': 2}, ' ci': {'t': 2}, 'cit': {'y': 2}, 'c': {'y': 2}, 'ity': {',': 1, ' ': 1}, 'ty,': {' ': 1}, 't': {'l': 1}, 'y, ': {'f': 1}, 'y': {'o': 1}, ', f': {'i': 1}, ',': {'i': 1}, ' fi': {'n': 1}, 'fin': {'d': 1}, 'f': {' ': 1}, 'd y': {'o': 1}, ' yo': {'u': 1}, 'you': {'r': 1}, 'our': {'s': 1}, 'o': {'i': 1}, 'urs': {'e': 1}, 'u': {'e': 1}, 'rse': {'l': 1}, 'r': {'l': 1}, 'sel': {'f': 1}, 's': {'f': 1}, 'elf': {' ': 1}, 'e': {'n': 1}, 'lf ': {'a': 1}, 'l': {'e': 1}, 'f a': {' ': 1}, 'ty ': {'t': 1}, 'y t': {'o': 1}, ' to': {' ': 1}, 'to ': {'l': 1}, 'o l': {'i': 1}, ' li': {'v': 1}, 'liv': {'e': 1}, 'ive': {' ': 1}, 've ': {'i': 1}, 'v': {'i': 1}, 'e i': {'n': 1}}, {'Find': {' ': 1}, 'F': {' ': 1}, 'ind ': {'a': 1, 'y': 1}, 'i': {'i': 1}, 'nd a': {' ': 1}, 'n': {'o': 1}, 'd a ': {'c': 1}, 'd': {'u': 1}, ' a c': {'i': 2}, ' ': {'e': 1}, 'a ci': {'t': 2}, 'a': {'t': 2}, ' cit': {'y': 2}, 'city': {',': 1, ' ': 1}, 'c': {',': 1, ' ': 1}, 'ity,': {' ': 1}, 'ty, ': {'f': 1}, 't': {'i': 1}, 'y, f': {'i': 1}, 'y': {' ': 1}, ', fi': {'n': 1}, ',': {'n': 1}, ' fin': {'d': 1}, 'find': {' ': 1}, 'f': {'c': 1}, 'nd y': {'o': 1}, 'd yo': {'u': 1}, ' you': {'r': 1}, 'your': {'s': 1}, 'ours': {'e': 1}, 'o': {'v': 1}, 'urse': {'l': 1}, 'u': {'l': 1}, 'rsel': {'f': 1}, 'r': {'f': 1}, 'self': {' ': 1}, 's': {' ': 1}, 'elf ': {'a': 1}, 'e': {'a': 1}, 'lf a': {' ': 1}, 'l': {' ': 1}, 'f a ': {'c': 1}, 'ity ': {'t': 1}, 'ty t': {'o': 1}, 'y to': {' ': 1}, ' to ': {'l': 1}, 'to l': {'i': 1}, 'o li': {'v': 1}, ' liv': {'e': 1}, 'live': {' ': 1}, 'ive ': {'i': 1}, 've i': {'n': 1}, 'v': {'n': 1}}] 51 | >>> test_predict(m2, 100, 'i') 52 | 'ind ind ind a tourse f a lf find ito f civelind cind cind f find ind ind a cito lfind cind ivelfind c' 53 | >>> test_predict(m2, 100, 'i', 2) 54 | 'ity, find a city to live ind a city to live ind yourself a city to live ind yourself a city, find you' 55 | >>> test_predict(m2, 100, 'i', 3) 56 | Traceback (most recent call last): 57 | File "", line 1, in 58 | test_predict(m2, 100, 'i', 3) 59 | File "/Users/matt/Dropbox/work/training/metasnake/pycon-2017/adv-markov/markov.py", line 74, in test_predict 60 | let = m.predict(start) 61 | File "/Users/matt/Dropbox/work/training/metasnake/pycon-2017/adv-markov/markov.py", line 46, in predict 62 | raise KeyError() 63 | KeyError 64 | >>> test_predict(m2, 100, 'i', 2) 65 | 'ity to live ind a city to live ind a city, find a city to live ind yourself a city, find a city to li' 66 | >>> repl(m2, 4) 67 | >i 68 | t 69 | >it 70 | y 71 | >ity 72 | , 73 | > 74 | Traceback (most recent call last): 75 | File "", line 1, in 76 | repl(m2, 4) 77 | File "/Users/matt/Dropbox/work/training/metasnake/pycon-2017/adv-markov/markov.py", line 85, in repl 78 | txt = input(">") 79 | KeyboardInterrupt 80 | >>> 'a' * 5 81 | 'aaaaa' 82 | >>> data = [1, 2, 3] 83 | >>> for thing in data: 84 | print(thing) 85 | 86 | 87 | 1 88 | 2 89 | 3 90 | >>> it = iter(data) 91 | >>> it 92 | 93 | >>> next(it) 94 | 1 95 | >>> next(it) 96 | 2 97 | >>> next(it) 98 | 3 99 | >>> next(it) 100 | Traceback (most recent call last): 101 | File "", line 1, in 102 | next(it) 103 | StopIteration 104 | >>> data 105 | [1, 2, 3] 106 | >>> type(data) 107 | 108 | >>> dir(data) 109 | ['__add__', '__class__', '__contains__', '__delattr__', '__delitem__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__getitem__', '__gt__', '__hash__', '__iadd__', '__imul__', '__init__', '__init_subclass__', '__iter__', '__le__', '__len__', '__lt__', '__mul__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__reversed__', '__rmul__', '__setattr__', '__setitem__', '__sizeof__', '__str__', '__subclasshook__', 'append', 'clear', 'copy', 'count', 'extend', 'index', 'insert', 'pop', 'remove', 'reverse', 'sort'] 110 | >>> it = data.__iter__() 111 | >>> it 112 | 113 | >>> dir(it) 114 | ['__class__', '__delattr__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__iter__', '__le__', '__length_hint__', '__lt__', '__ne__', '__new__', '__next__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__setstate__', '__sizeof__', '__str__', '__subclasshook__'] 115 | >>> it.__next__() # next(it) 116 | 1 117 | >>> it.__next__() # next(it) 118 | 2 119 | >>> it.__next__() # next(it) 120 | 3 121 | >>> it.__next__() # next(it) 122 | Traceback (most recent call last): 123 | File "", line 1, in 124 | it.__next__() # next(it) 125 | StopIteration 126 | >>> iter 127 | 128 | >>> data[2] 129 | 3 130 | >>> data 131 | [1, 2, 3] 132 | >>> data[3] 133 | Traceback (most recent call last): 134 | File "", line 1, in 135 | data[3] 136 | IndexError: list index out of range 137 | >>> 138 | RESTART: /Users/matt/Dropbox/work/training/metasnake/pycon-2017/adv-markov/markov.py 139 | EXECUTED 140 | >>> dir() 141 | ['CharIter', 'Markov', '__annotations__', '__builtins__', '__doc__', '__file__', '__loader__', '__name__', '__package__', '__spec__', 'argparse', 'get_table', 'main', 'random', 'repl', 'sys', 'test_predict'] 142 | >>> c = CharIter(['hello', 'world']) 143 | >>> for letter in CharIter: 144 | print(letter) 145 | 146 | 147 | Traceback (most recent call last): 148 | File "", line 1, in 149 | for letter in CharIter: 150 | TypeError: 'type' object is not iterable 151 | >>> for letter in c: 152 | print(letter) 153 | 154 | 155 | h 156 | e 157 | l 158 | l 159 | o 160 | w 161 | o 162 | r 163 | l 164 | d 165 | >>> 166 | RESTART: /Users/matt/Dropbox/work/training/metasnake/pycon-2017/adv-markov/testmarkov.py 167 | E 168 | ====================================================================== 169 | ERROR: test_char_iter (__main__.TestMarkov) 170 | ---------------------------------------------------------------------- 171 | Traceback (most recent call last): 172 | File "/Users/matt/Dropbox/work/training/metasnake/pycon-2017/adv-markov/testmarkov.py", line 6, in test_char_iter 173 | c = CharIter(lines) 174 | NameError: name 'CharIter' is not defined 175 | 176 | ---------------------------------------------------------------------- 177 | Ran 1 test in 0.018s 178 | 179 | FAILED (errors=1) 180 | >>> 181 | RESTART: /Users/matt/Dropbox/work/training/metasnake/pycon-2017/adv-markov/testmarkov.py 182 | IMPORTED 183 | 184 | Warning (from warnings module): 185 | File "/Users/matt/Dropbox/work/training/metasnake/pycon-2017/adv-markov/testmarkov.py", line 10 186 | self.assertEquals(res, ['a','b']) 187 | DeprecationWarning: Please use assertEqual instead. 188 | F 189 | ====================================================================== 190 | FAIL: test_char_iter (__main__.TestMarkov) 191 | ---------------------------------------------------------------------- 192 | Traceback (most recent call last): 193 | File "/Users/matt/Dropbox/work/training/metasnake/pycon-2017/adv-markov/testmarkov.py", line 10, in test_char_iter 194 | self.assertEquals(res, ['a','b']) 195 | AssertionError: Lists differ: ['a', 'b', 'c', 'd', 'e', 'f'] != ['a', 'b'] 196 | 197 | First list contains 4 additional elements. 198 | First extra element 2: 199 | 'c' 200 | 201 | - ['a', 'b', 'c', 'd', 'e', 'f'] 202 | + ['a', 'b'] 203 | 204 | ---------------------------------------------------------------------- 205 | Ran 1 test in 0.043s 206 | 207 | FAILED (failures=1) 208 | >>> 209 | RESTART: /Users/matt/Dropbox/work/training/metasnake/pycon-2017/adv-markov/testmarkov.py 210 | IMPORTED 211 | . 212 | ---------------------------------------------------------------------- 213 | Ran 1 test in 0.005s 214 | 215 | OK 216 | >>> 217 | RESTART: /Users/matt/Dropbox/work/training/metasnake/pycon-2017/adv-markov/testmarkov.py 218 | IMPORTED 219 | . 220 | ---------------------------------------------------------------------- 221 | Ran 1 test in 0.014s 222 | 223 | OK 224 | >>> data = ['abc', 'def'] 225 | >>> chars = [] 226 | >>> for line in data: 227 | for c in line: 228 | chars.append(c) 229 | 230 | 231 | >>> chars 232 | ['a', 'b', 'c', 'd', 'e', 'f'] 233 | >>> 234 | RESTART: /Users/matt/Dropbox/work/training/metasnake/pycon-2017/adv-markov/markov.py 235 | EXECUTED 236 | >>> b = blastoff() 237 | >>> type(b) 238 | 239 | >>> b 240 | 241 | >>> dir(b) 242 | ['__class__', '__del__', '__delattr__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__iter__', '__le__', '__lt__', '__name__', '__ne__', '__new__', '__next__', '__qualname__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', 'close', 'gi_code', 'gi_frame', 'gi_running', 'gi_yieldfrom', 'send', 'throw'] 243 | >>> bit = iter(b) 244 | >>> bit 245 | 246 | >>> res = next(b) 247 | Hi 248 | >>> res 249 | 1 250 | >>> res = next(b) 251 | after 1 252 | >>> res 253 | 2 254 | >>> res = next(b) 255 | Goodbye 256 | Traceback (most recent call last): 257 | File "", line 1, in 258 | res = next(b) 259 | StopIteration 260 | >>> for thing in blastoff(): 261 | print(thing) 262 | 263 | 264 | Hi 265 | 1 266 | after 1 267 | 2 268 | Goodbye 269 | >>> 270 | RESTART: /Users/matt/Dropbox/work/training/metasnake/pycon-2017/adv-markov/markov.py 271 | EXECUTED 272 | >>> lines = ['hello', 'world'] 273 | >>> c_gen = char_iter(lines) 274 | >>> for c in c_gen: 275 | print(c) 276 | 277 | 278 | h 279 | e 280 | l 281 | l 282 | o 283 | w 284 | o 285 | r 286 | l 287 | d 288 | >>> for c in c_gen: 289 | print(c) 290 | 291 | 292 | >>> for c in c_gen: 293 | print(c) 294 | 295 | 296 | >>> bool([]) 297 | False 298 | >>> data 299 | Traceback (most recent call last): 300 | File "", line 1, in 301 | data 302 | NameError: name 'data' is not defined 303 | >>> lines 304 | ['hello', 'world'] 305 | >>> bool(lines) 306 | True 307 | >>> bool(c_gen) 308 | True 309 | >>> c_gen = char_iter(lines) 310 | >>> animals = ['dog', 'cat', 'bird'] 311 | >>> animals[1:2] 312 | ['cat'] 313 | >>> animals[1:3] 314 | ['cat', 'bird'] 315 | >>> c_gen[1:3] 316 | Traceback (most recent call last): 317 | File "", line 1, in 318 | c_gen[1:3] 319 | TypeError: 'generator' object is not subscriptable 320 | >>> 321 | RESTART: /Users/matt/Dropbox/work/training/metasnake/pycon-2017/adv-markov/testmarkov.py 322 | IMPORTED 323 | E. 324 | ====================================================================== 325 | ERROR: test_char_gen (__main__.TestMarkov) 326 | ---------------------------------------------------------------------- 327 | Traceback (most recent call last): 328 | File "/Users/matt/Dropbox/work/training/metasnake/pycon-2017/adv-markov/testmarkov.py", line 14, in test_char_gen 329 | c = mar.char_gen(lines) 330 | AttributeError: module 'markov' has no attribute 'char_gen' 331 | 332 | ---------------------------------------------------------------------- 333 | Ran 2 tests in 0.027s 334 | 335 | FAILED (errors=1) 336 | >>> 337 | RESTART: /Users/matt/Dropbox/work/training/metasnake/pycon-2017/adv-markov/testmarkov.py 338 | IMPORTED 339 | .. 340 | ---------------------------------------------------------------------- 341 | Ran 2 tests in 0.027s 342 | 343 | OK 344 | >>> import unittest 345 | >>> dir(unittest) 346 | ['BaseTestSuite', 'FunctionTestCase', 'SkipTest', 'TestCase', 'TestLoader', 'TestProgram', 'TestResult', 'TestSuite', 'TextTestResult', 'TextTestRunner', '_TextTestResult', '__all__', '__builtins__', '__cached__', '__doc__', '__file__', '__loader__', '__name__', '__package__', '__path__', '__spec__', '__unittest', 'case', 'defaultTestLoader', 'expectedFailure', 'findTestCases', 'getTestCaseNames', 'installHandler', 'load_tests', 'loader', 'main', 'makeSuite', 'registerResult', 'removeHandler', 'removeResult', 'result', 'runner', 'signals', 'skip', 'skipIf', 'skipUnless', 'suite', 'util'] 347 | >>> 348 | >>> 349 | >>> line = 'hello world' 350 | >>> dir(line) 351 | ['__add__', '__class__', '__contains__', '__delattr__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__getitem__', '__getnewargs__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__iter__', '__le__', '__len__', '__lt__', '__mod__', '__mul__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__rmod__', '__rmul__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', 'capitalize', 'casefold', 'center', 'count', 'encode', 'endswith', 'expandtabs', 'find', 'format', 'format_map', 'index', 'isalnum', 'isalpha', 'isdecimal', 'isdigit', 'isidentifier', 'islower', 'isnumeric', 'isprintable', 'isspace', 'istitle', 'isupper', 'join', 'ljust', 'lower', 'lstrip', 'maketrans', 'partition', 'replace', 'rfind', 'rindex', 'rjust', 'rpartition', 'rsplit', 'rstrip', 'split', 'splitlines', 'startswith', 'strip', 'swapcase', 'title', 'translate', 'upper', 'zfill'] 352 | >>> line.split() 353 | ['hello', 'world'] 354 | >>> line 355 | 'hello world' 356 | >>> 357 | RESTART: /Users/matt/Dropbox/work/training/metasnake/pycon-2017/adv-markov/testmarkov.py 358 | IMPORTED 359 | ..F 360 | ====================================================================== 361 | FAIL: test_word_gen (__main__.TestMarkov) 362 | ---------------------------------------------------------------------- 363 | Traceback (most recent call last): 364 | File "/Users/matt/Dropbox/work/training/metasnake/pycon-2017/adv-markov/testmarkov.py", line 22, in test_word_gen 365 | self.assertEqual(res, []) 366 | AssertionError: Lists differ: ['hello', 'world', 'bye', 'matt'] != [] 367 | 368 | First list contains 4 additional elements. 369 | First extra element 0: 370 | 'hello' 371 | 372 | - ['hello', 'world', 'bye', 'matt'] 373 | + [] 374 | 375 | ---------------------------------------------------------------------- 376 | Ran 3 tests in 0.046s 377 | 378 | FAILED (failures=1) 379 | >>> 380 | RESTART: /Users/matt/Dropbox/work/training/metasnake/pycon-2017/adv-markov/testmarkov.py 381 | IMPORTED 382 | ... 383 | ---------------------------------------------------------------------- 384 | Ran 3 tests in 0.047s 385 | 386 | OK 387 | >>> 388 | RESTART: /Users/matt/Dropbox/work/training/metasnake/pycon-2017/adv-markov/testmarkov.py 389 | IMPORTED 390 | ..E. 391 | ====================================================================== 392 | ERROR: test_window (__main__.TestMarkov) 393 | ---------------------------------------------------------------------- 394 | Traceback (most recent call last): 395 | File "/Users/matt/Dropbox/work/training/metasnake/pycon-2017/adv-markov/testmarkov.py", line 27, in test_window 396 | win = mar.window_gen(w) 397 | AttributeError: module 'markov' has no attribute 'window_gen' 398 | 399 | ---------------------------------------------------------------------- 400 | Ran 4 tests in 0.064s 401 | 402 | FAILED (errors=1) 403 | >>> 404 | RESTART: /Users/matt/Dropbox/work/training/metasnake/pycon-2017/adv-markov/testmarkov.py 405 | IMPORTED 406 | ..E. 407 | ====================================================================== 408 | ERROR: test_window (__main__.TestMarkov) 409 | ---------------------------------------------------------------------- 410 | Traceback (most recent call last): 411 | File "/Users/matt/Dropbox/work/training/metasnake/pycon-2017/adv-markov/testmarkov.py", line 27, in test_window 412 | win = mar.window_gen(w) 413 | TypeError: window_gen() missing 1 required positional argument: 'size' 414 | 415 | ---------------------------------------------------------------------- 416 | Ran 4 tests in 0.060s 417 | 418 | FAILED (errors=1) 419 | >>> 420 | RESTART: /Users/matt/Dropbox/work/training/metasnake/pycon-2017/adv-markov/testmarkov.py 421 | IMPORTED 422 | ..F. 423 | ====================================================================== 424 | FAIL: test_window (__main__.TestMarkov) 425 | ---------------------------------------------------------------------- 426 | Traceback (most recent call last): 427 | File "/Users/matt/Dropbox/work/training/metasnake/pycon-2017/adv-markov/testmarkov.py", line 29, in test_window 428 | self.assertEqual(res, ['hello', 'world', 'bye', 'matt']) 429 | AssertionError: Lists differ: [['hello', 'world'], ['world', 'bye'], ['bye', 'matt']] != ['hello', 'world', 'bye', 'matt'] 430 | 431 | First differing element 0: 432 | ['hello', 'world'] 433 | 'hello' 434 | 435 | Second list contains 1 additional elements. 436 | First extra element 3: 437 | 'matt' 438 | 439 | - [['hello', 'world'], ['world', 'bye'], ['bye', 'matt']] 440 | ? - ----------- --------- - 441 | 442 | + ['hello', 'world', 'bye', 'matt'] 443 | 444 | ---------------------------------------------------------------------- 445 | Ran 4 tests in 0.064s 446 | 447 | FAILED (failures=1) 448 | >>> 449 | RESTART: /Users/matt/Dropbox/work/training/metasnake/pycon-2017/adv-markov/testmarkov.py 450 | IMPORTED 451 | .... 452 | ---------------------------------------------------------------------- 453 | Ran 4 tests in 0.064s 454 | 455 | OK 456 | >>> ['a', 'b'] 457 | ['a', 'b'] 458 | >>> ['a', 'b'][:1] 459 | ['a'] 460 | >>> 461 | RESTART: /Users/matt/Dropbox/work/training/metasnake/pycon-2017/adv-markov/testmarkov.py 462 | IMPORTED 463 | ..E.. 464 | ====================================================================== 465 | ERROR: test_get_table (__main__.TestMarkov) 466 | ---------------------------------------------------------------------- 467 | Traceback (most recent call last): 468 | File "/Users/matt/Dropbox/work/training/metasnake/pycon-2017/adv-markov/testmarkov.py", line 34, in test_get_table 469 | t = mar.get_table(mar.char_gen(lines)) 470 | File "/Users/matt/Dropbox/work/training/metasnake/pycon-2017/adv-markov/markov.py", line 113, in get_table 471 | inner_dict[ouput] += 1 472 | NameError: name 'ouput' is not defined 473 | 474 | ---------------------------------------------------------------------- 475 | Ran 5 tests in 0.080s 476 | 477 | FAILED (errors=1) 478 | >>> 479 | RESTART: /Users/matt/Dropbox/work/training/metasnake/pycon-2017/adv-markov/testmarkov.py 480 | IMPORTED 481 | ..F.. 482 | ====================================================================== 483 | FAIL: test_get_table (__main__.TestMarkov) 484 | ---------------------------------------------------------------------- 485 | Traceback (most recent call last): 486 | File "/Users/matt/Dropbox/work/training/metasnake/pycon-2017/adv-markov/testmarkov.py", line 35, in test_get_table 487 | self.assertEqual(t, {}) 488 | AssertionError: {'a': {'b': 1}, 'b': {'c': 1}, 'c': {'d': 1}, 'd': {'e': 1}, 'e': {'f': 1}} != {} 489 | - {'a': {'b': 1}, 'b': {'c': 1}, 'c': {'d': 1}, 'd': {'e': 1}, 'e': {'f': 1}} 490 | + {} 491 | 492 | ---------------------------------------------------------------------- 493 | Ran 5 tests in 0.079s 494 | 495 | FAILED (failures=1) 496 | >>> 497 | RESTART: /Users/matt/Dropbox/work/training/metasnake/pycon-2017/adv-markov/testmarkov.py 498 | IMPORTED 499 | ..... 500 | ---------------------------------------------------------------------- 501 | Ran 5 tests in 0.081s 502 | 503 | OK 504 | >>> 2 + 3 505 | 5 506 | >>> type(2) 507 | 508 | >>> id(2) 509 | 4396743184 510 | >>> 2.__add__(3) 511 | SyntaxError: invalid syntax 512 | >>> (2) 513 | 2 514 | >>> (2).__add__ 515 | 516 | >>> (2).__add__(3) 517 | 5 518 | >>> 519 | RESTART: /Users/matt/Dropbox/work/training/metasnake/pycon-2017/adv-markov/markov.py 520 | 521 | >>> 522 | EXECUTED 523 | >>> 524 | RESTART: /Users/matt/Dropbox/work/training/metasnake/pycon-2017/adv-markov/markov.py 525 | EXECUTED 526 | >>> 527 | RESTART: /Users/matt/Dropbox/work/training/metasnake/pycon-2017/adv-markov/testmarkov.py 528 | IMPORTED 529 | ..... 530 | ---------------------------------------------------------------------- 531 | Ran 5 tests in 0.081s 532 | 533 | OK 534 | >>> 535 | RESTART: /Users/matt/Dropbox/work/training/metasnake/pycon-2017/adv-markov/testmarkov.py 536 | IMPORTED 537 | ..E... 538 | ====================================================================== 539 | ERROR: test_cmarkov (__main__.TestMarkov) 540 | ---------------------------------------------------------------------- 541 | Traceback (most recent call last): 542 | File "/Users/matt/Dropbox/work/training/metasnake/pycon-2017/adv-markov/testmarkov.py", line 34, in test_cmarkov 543 | m = mar.CharMarkov(lines, 3) 544 | AttributeError: module 'markov' has no attribute 'CharMarkov' 545 | 546 | ---------------------------------------------------------------------- 547 | Ran 6 tests in 0.098s 548 | 549 | FAILED (errors=1) 550 | >>> 551 | RESTART: /Users/matt/Dropbox/work/training/metasnake/pycon-2017/adv-markov/testmarkov.py 552 | IMPORTED 553 | ..F... 554 | ====================================================================== 555 | FAIL: test_cmarkov (__main__.TestMarkov) 556 | ---------------------------------------------------------------------- 557 | Traceback (most recent call last): 558 | File "/Users/matt/Dropbox/work/training/metasnake/pycon-2017/adv-markov/testmarkov.py", line 35, in test_cmarkov 559 | self.assertEqual(m.tables, []) 560 | AssertionError: Lists differ: [{'a': {'b': 1}, 'b': {'c': 1}, 'c': {'d':[38 chars], {}] != [] 561 | 562 | First list contains 3 additional elements. 563 | First extra element 0: 564 | {'a': {'b': 1}, 'b': {'c': 1}, 'c': {'d': 1}, 'd': {'e': 1}, 'e': {'f': 1}} 565 | 566 | + [] 567 | - [{'a': {'b': 1}, 'b': {'c': 1}, 'c': {'d': 1}, 'd': {'e': 1}, 'e': {'f': 1}}, 568 | - {}, 569 | - {}] 570 | 571 | ---------------------------------------------------------------------- 572 | Ran 6 tests in 0.095s 573 | 574 | FAILED (failures=1) 575 | >>> 576 | RESTART: /Users/matt/Dropbox/work/training/metasnake/pycon-2017/adv-markov/testmarkov.py 577 | IMPORTED 578 | ..TABLE [{'a': {'b': 1}, 'b': {'c': 1}, 'c': {'d': 1}, 'd': {'e': 1}, 'e': {'f': 1}}, {}, {}] 579 | F... 580 | ====================================================================== 581 | FAIL: test_cmarkov (__main__.TestMarkov) 582 | ---------------------------------------------------------------------- 583 | Traceback (most recent call last): 584 | File "/Users/matt/Dropbox/work/training/metasnake/pycon-2017/adv-markov/testmarkov.py", line 37, in test_cmarkov 585 | self.assertEqual(m.tables, []) 586 | AssertionError: Lists differ: [{'a': {'b': 1}, 'b': {'c': 1}, 'c': {'d':[38 chars], {}] != [] 587 | 588 | First list contains 3 additional elements. 589 | First extra element 0: 590 | {'a': {'b': 1}, 'b': {'c': 1}, 'c': {'d': 1}, 'd': {'e': 1}, 'e': {'f': 1}} 591 | 592 | + [] 593 | - [{'a': {'b': 1}, 'b': {'c': 1}, 'c': {'d': 1}, 'd': {'e': 1}, 'e': {'f': 1}}, 594 | - {}, 595 | - {}] 596 | 597 | ---------------------------------------------------------------------- 598 | Ran 6 tests in 0.198s 599 | 600 | FAILED (failures=1) 601 | >>> 602 | RESTART: /Users/matt/Dropbox/work/training/metasnake/pycon-2017/adv-markov/markov.py 603 | EXECUTED 604 | >>> 605 | RESTART: /Users/matt/Dropbox/work/training/metasnake/pycon-2017/adv-markov/testmarkov.py 606 | IMPORTED 607 | ..TABLE [{'a': {'b': 1}, 'b': {'c': 1}, 'c': {'d': 1}, 'd': {'e': 1}, 'e': {'f': 1}}, {}, {}] 608 | F... 609 | ====================================================================== 610 | FAIL: test_cmarkov (__main__.TestMarkov) 611 | ---------------------------------------------------------------------- 612 | Traceback (most recent call last): 613 | File "/Users/matt/Dropbox/work/training/metasnake/pycon-2017/adv-markov/testmarkov.py", line 37, in test_cmarkov 614 | self.assertEqual(m.tables, []) 615 | AssertionError: Lists differ: [{'a': {'b': 1}, 'b': {'c': 1}, 'c': {'d':[38 chars], {}] != [] 616 | 617 | First list contains 3 additional elements. 618 | First extra element 0: 619 | {'a': {'b': 1}, 'b': {'c': 1}, 'c': {'d': 1}, 'd': {'e': 1}, 'e': {'f': 1}} 620 | 621 | + [] 622 | - [{'a': {'b': 1}, 'b': {'c': 1}, 'c': {'d': 1}, 'd': {'e': 1}, 'e': {'f': 1}}, 623 | - {}, 624 | - {}] 625 | 626 | ---------------------------------------------------------------------- 627 | Ran 6 tests in 0.193s 628 | 629 | FAILED (failures=1) 630 | >>> 631 | RESTART: /Users/matt/Dropbox/work/training/metasnake/pycon-2017/adv-markov/testmarkov.py 632 | IMPORTED 633 | ..E... 634 | ====================================================================== 635 | ERROR: test_cmarkov (__main__.TestMarkov) 636 | ---------------------------------------------------------------------- 637 | Traceback (most recent call last): 638 | File "/Users/matt/Dropbox/work/training/metasnake/pycon-2017/adv-markov/testmarkov.py", line 35, in test_cmarkov 639 | m = mar.CharMarkov(lines, 3) 640 | File "/Users/matt/Dropbox/work/training/metasnake/pycon-2017/adv-markov/markov.py", line 103, in __init__ 641 | self.tables = get_tables(data, size) 642 | NameError: name 'data' is not defined 643 | 644 | ---------------------------------------------------------------------- 645 | Ran 6 tests in 0.096s 646 | 647 | FAILED (errors=1) 648 | >>> 649 | RESTART: /Users/matt/Dropbox/work/training/metasnake/pycon-2017/adv-markov/markov.py 650 | EXECUTED 651 | >>> 652 | RESTART: /Users/matt/Dropbox/work/training/metasnake/pycon-2017/adv-markov/testmarkov.py 653 | IMPORTED 654 | ..TABLE [] 655 | .... 656 | ---------------------------------------------------------------------- 657 | Ran 6 tests in 0.179s 658 | 659 | OK 660 | >>> 661 | RESTART: /Users/matt/Dropbox/work/training/metasnake/pycon-2017/adv-markov/testmarkov.py 662 | IMPORTED 663 | ..TABLE [{'a': Counter({'b': 1}), 'b': Counter({'c': 1}), 'c': Counter({'d': 1})}, {'ab': Counter({'c': 1}), 'bc': Counter({'d': 1}), 'cd': Counter({'e': 1})}, {'abc': Counter({'d': 1}), 'bcd': Counter({'e': 1}), 'cde': Counter({'f': 1})}] 664 | F... 665 | ====================================================================== 666 | FAIL: test_cmarkov (__main__.TestMarkov) 667 | ---------------------------------------------------------------------- 668 | Traceback (most recent call last): 669 | File "/Users/matt/Dropbox/work/training/metasnake/pycon-2017/adv-markov/testmarkov.py", line 37, in test_cmarkov 670 | self.assertEqual(m.tables, []) 671 | AssertionError: Lists differ: [{'a': Counter({'b': 1}), 'b': Counter({'c[184 chars]1})}] != [] 672 | 673 | First list contains 3 additional elements. 674 | First extra element 0: 675 | {'a': Counter({'b': 1}), 'b': Counter({'c': 1}), 'c': Counter({'d': 1})} 676 | 677 | + [] 678 | - [{'a': Counter({'b': 1}), 'b': Counter({'c': 1}), 'c': Counter({'d': 1})}, 679 | - {'ab': Counter({'c': 1}), 'bc': Counter({'d': 1}), 'cd': Counter({'e': 1})}, 680 | - {'abc': Counter({'d': 1}), 'bcd': Counter({'e': 1}), 'cde': Counter({'f': 1})}] 681 | 682 | ---------------------------------------------------------------------- 683 | Ran 6 tests in 0.196s 684 | 685 | FAILED (failures=1) 686 | >>> 687 | RESTART: /Users/matt/Dropbox/work/training/metasnake/pycon-2017/adv-markov/testmarkov.py 688 | IMPORTED 689 | ..TABLE [{'a': Counter({'b': 1}), 'b': Counter({'c': 1}), 'c': Counter({'d': 1})}, {'ab': Counter({'c': 1}), 'bc': Counter({'d': 1}), 'cd': Counter({'e': 1})}, {'abc': Counter({'d': 1}), 'bcd': Counter({'e': 1}), 'cde': Counter({'f': 1})}] 690 | .... 691 | ---------------------------------------------------------------------- 692 | Ran 6 tests in 0.200s 693 | 694 | OK 695 | >>> def adder(x, y): 696 | """returns x + y""" 697 | return x + y 698 | 699 | >>> adder 700 | 701 | >>> dir(adder) 702 | ['__annotations__', '__call__', '__class__', '__closure__', '__code__', '__defaults__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__get__', '__getattribute__', '__globals__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__kwdefaults__', '__le__', '__lt__', '__module__', '__name__', '__ne__', '__new__', '__qualname__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__'] 703 | >>> adder.__doc__ 704 | 'returns x + y' 705 | >>> adder.__name__ 706 | 'adder' 707 | >>> adder.__call__(2, 4) 708 | 6 709 | >>> args = (2, 3) 710 | >>> kwargs = {'x':4, 'y':7} 711 | >>> adder(2, 4) 712 | 6 713 | >>> adder(*args) 714 | 5 715 | >>> adder(args[0], args[1]) 716 | 5 717 | >>> adder(**kwargs) 718 | 11 719 | >>> adder(x=kwargs['x'], y=kwargs['y']) 720 | 11 721 | >>> def foo(*args, **kwargs): 722 | print(args, kwargs) 723 | 724 | 725 | >>> m = dict(zip('mt', [3, 4])) 726 | >>> m 727 | {'m': 3, 't': 4} 728 | >>> adder(**m) 729 | Traceback (most recent call last): 730 | File "", line 1, in 731 | adder(**m) 732 | TypeError: adder() got an unexpected keyword argument 'm' 733 | >>> foo() 734 | () {} 735 | >>> foo(2, 3) 736 | (2, 3) {} 737 | >>> foo(2, 3, matt='cool') 738 | (2, 3) {'matt': 'cool'} 739 | >>> 740 | >>> def add10(x): 741 | return x + 10 742 | 743 | >>> add10(5) 744 | 15 745 | >>> def addtxt(x): 746 | return x + '.txt' 747 | 748 | >>> addtxt('report') 749 | 'report.txt' 750 | >>> def create_adder(val): 751 | def add(x): 752 | return x + val 753 | return add 754 | 755 | >>> a10 = create_adder(10) 756 | >>> a10 757 | .add at 0x1125a5a60> 758 | >>> a10(7) 759 | 17 760 | >>> atxt = create_adder(.txt) 761 | SyntaxError: invalid syntax 762 | >>> atxt = create_adder('.txt') 763 | >>> atxt('report') 764 | 'report.txt' 765 | >>> def iden(func): 766 | return func 767 | 768 | >>> adder 769 | 770 | >>> adder2 = iden(adder) 771 | >>> adder2 772 | 773 | >>> help(adder2) 774 | Help on function adder in module __main__: 775 | 776 | adder(x, y) 777 | returns x + y 778 | 779 | >>> adder2(4, 5) 780 | 9 781 | >>> def iden2(f): 782 | def inner(*args, **kwargs): 783 | res = f(*args, **kwargs) 784 | return res 785 | return inner 786 | 787 | >>> adder3 = iden2(adder) 788 | >>> adder3 789 | .inner at 0x1125a5c80> 790 | >>> adder3(3, 4) 791 | 7 792 | >>> def iden3(f): 793 | def inner(*args, **kwargs): 794 | # before 795 | print("Before") 796 | res = f(*args, **kwargs) 797 | # after 798 | print("After") 799 | return res 800 | return inner 801 | 802 | >>> adder4 = iden3(adder) 803 | >>> adder(10, 12) 804 | 22 805 | >>> adder4(10, 12) 806 | Before 807 | After 808 | 22 809 | >>> def iden3(f): 810 | @functools.wraps(f) 811 | def inner(*args, **kwargs): 812 | # before 813 | print("Before") 814 | res = f(*args, **kwargs) 815 | # after 816 | print("After") 817 | return res 818 | return inner 819 | 820 | >>> import functools 821 | >>> 822 | >>> @iden3 823 | def sub(x, y): 824 | return x - y 825 | 826 | >>> sub(5, 4) 827 | Before 828 | After 829 | 1 830 | >>> 831 | RESTART: /Users/matt/Dropbox/work/training/metasnake/pycon-2017/adv-markov/markov.py 832 | Traceback (most recent call last): 833 | File "/Users/matt/Dropbox/work/training/metasnake/pycon-2017/adv-markov/markov.py", line 79, in 834 | @timer 835 | File "/Users/matt/Dropbox/work/training/metasnake/pycon-2017/adv-markov/markov.py", line 68, in timer 836 | @functools.wraps(f) 837 | NameError: name 'functools' is not defined 838 | >>> 839 | RESTART: /Users/matt/Dropbox/work/training/metasnake/pycon-2017/adv-markov/markov.py 840 | EXECUTED 841 | >>> dir() 842 | ['CharIter', 'CharMarkov', 'Counter', 'Markov', 'WordMarkov', '__annotations__', '__builtins__', '__doc__', '__file__', '__loader__', '__name__', '__package__', '__spec__', 'adder', 'argparse', 'blastoff', 'char_gen', 'functools', 'get_table', 'get_tables', 'main', 'noisy', 'random', 'repl', 'sleep', 'sys', 'test_predict', 'time', 'timer', 'window_gen', 'word_gen'] 843 | >>> sleep(5) 844 | Took 5.0049889087677 seconds 845 | >>> 846 | RESTART: /Users/matt/Dropbox/work/training/metasnake/pycon-2017/adv-markov/markov.py 847 | EXECUTED 848 | >>> 849 | RESTART: /Users/matt/Dropbox/work/training/metasnake/pycon-2017/adv-markov/markov.py 850 | EXECUTED 851 | ********************************************************************** 852 | File "/Users/matt/Dropbox/work/training/metasnake/pycon-2017/adv-markov/markov.py", line 6, in __main__ 853 | Failed example: 854 | m.predict('a') 855 | Expected: 856 | 'b' 857 | Got: 858 | 42 859 | ********************************************************************** 860 | File "/Users/matt/Dropbox/work/training/metasnake/pycon-2017/adv-markov/markov.py", line 9, in __main__ 861 | Failed example: 862 | m.predict('c') 863 | Expected: 864 | Traceback (most recent call last): 865 | ... 866 | KeyError 867 | Got: 868 | 42 869 | ********************************************************************** 870 | File "/Users/matt/Dropbox/work/training/metasnake/pycon-2017/adv-markov/markov.py", line 19, in __main__ 871 | Failed example: 872 | test_predict(m, 20, 'F', 4) 873 | Exception raised: 874 | Traceback (most recent call last): 875 | File "/usr/local/Cellar/python3/3.6.0/Frameworks/Python.framework/Versions/3.6/lib/python3.6/doctest.py", line 1330, in __run 876 | compileflags, 1), test.globs) 877 | File "", line 1, in 878 | test_predict(m, 20, 'F', 4) 879 | File "/Users/matt/Dropbox/work/training/metasnake/pycon-2017/adv-markov/markov.py", line 197, in test_predict 880 | start = ''.join(res)[-size:] 881 | TypeError: sequence item 1: expected str instance, int found 882 | ********************************************************************** 883 | File "/Users/matt/Dropbox/work/training/metasnake/pycon-2017/adv-markov/markov.py", line 25, in __main__ 884 | Failed example: 885 | test_predict(m2, 100, 'T', 4) 886 | Exception raised: 887 | Traceback (most recent call last): 888 | File "/usr/local/Cellar/python3/3.6.0/Frameworks/Python.framework/Versions/3.6/lib/python3.6/doctest.py", line 1330, in __run 889 | compileflags, 1), test.globs) 890 | File "", line 1, in 891 | test_predict(m2, 100, 'T', 4) 892 | File "/Users/matt/Dropbox/work/training/metasnake/pycon-2017/adv-markov/markov.py", line 197, in test_predict 893 | start = ''.join(res)[-size:] 894 | TypeError: sequence item 1: expected str instance, int found 895 | ********************************************************************** 896 | 1 items had failures: 897 | 4 of 10 in __main__ 898 | ***Test Failed*** 4 failures. 899 | >>> Markov 900 | 901 | >>> print(Markov) 902 | 903 | >>> 904 | RESTART: /Users/matt/Dropbox/work/training/metasnake/pycon-2017/adv-markov/markov.py 905 | EXECUTED 906 | >>> print(Markov) 907 | 908 | >>> Markov 909 | 910 | >>> Markov.__str__ 911 | .name at 0x10b031840> 912 | >>> Markov.__str__() 913 | Traceback (most recent call last): 914 | File "", line 1, in 915 | Markov.__str__() 916 | TypeError: name() missing 1 required positional argument: 'self' 917 | >>> Markov.__str__ 918 | .name at 0x10b031840> 919 | >>> m = Markov(['abc']) 920 | >>> m 921 | <__main__.Markov object at 0x10aff02e8> 922 | >>> print(m) 923 | Markov 924 | >>> lines = ['hello world', 'bye matt'] 925 | >>> chars = [] 926 | >>> for line in lines: 927 | for c in line: 928 | chars.append(c) 929 | 930 | 931 | >>> chars 932 | ['h', 'e', 'l', 'l', 'o', ' ', 'w', 'o', 'r', 'l', 'd', 'b', 'y', 'e', ' ', 'm', 'a', 't', 't'] 933 | >>> chars = [c for line in lines for c in line] 934 | >>> chars 935 | ['h', 'e', 'l', 'l', 'o', ' ', 'w', 'o', 'r', 'l', 'd', 'b', 'y', 'e', ' ', 'm', 'a', 't', 't'] 936 | >>> lines = ['Hello world', 'Chapter 1', 'It was a'] 937 | >>> new_lines = [] 938 | >>> for line in lines: 939 | if not line.startswith('Chapter'): 940 | new_lines.append(line) 941 | 942 | 943 | >>> new_lines 944 | ['Hello world', 'It was a'] 945 | >>> new_lines = [line for line in lines if not line.startswith('Chapter')] 946 | >>> new_lines 947 | ['Hello world', 'It was a'] 948 | >>> for line in lines: 949 | if not line.startswith('Chapter'): 950 | new_lines.append(line) 951 | 952 | 953 | >>> new_lines = [] 954 | >>> for line in lines: 955 | if not line.startswith('Chapter'): 956 | new_lines.append(line.upper()) 957 | 958 | 959 | >>> new_lines 960 | ['HELLO WORLD', 'IT WAS A'] 961 | >>> map(lambda x: x.upper(), lines) 962 | 963 | >>> lines(map(lambda x: x.upper(), lines)) 964 | Traceback (most recent call last): 965 | File "", line 1, in 966 | lines(map(lambda x: x.upper(), lines)) 967 | TypeError: 'list' object is not callable 968 | >>> list(map(lambda x: x.upper(), lines)) 969 | ['HELLO WORLD', 'CHAPTER 1', 'IT WAS A'] 970 | >>> new_lines = [line.upper() for line in lines if not line.startswith('Chapter')] 971 | >>> 972 | >>> new_lines 973 | ['HELLO WORLD', 'IT WAS A'] 974 | >>> new_lines = (line.upper() for line in lines if not line.startswith('Chapter')) 975 | >>> new_lines 976 | at 0x10b044a40> 977 | >>> it = iter(new_lines) 978 | >>> next(it) 979 | 'HELLO WORLD' 980 | >>> next(it) 981 | 'IT WAS A' 982 | >>> next(it) 983 | Traceback (most recent call last): 984 | File "", line 1, in 985 | next(it) 986 | StopIteration 987 | >>> new_lines = (line.upper() for line in lines if not line.startswith('Chapter')) 988 | >>> dir(new_lines) 989 | ['__class__', '__del__', '__delattr__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__iter__', '__le__', '__lt__', '__name__', '__ne__', '__new__', '__next__', '__qualname__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', 'close', 'gi_code', 'gi_frame', 'gi_running', 'gi_yieldfrom', 'send', 'throw'] 990 | >>> new_lines 991 | at 0x10b044af0> 992 | >>> iter(new_lines) 993 | at 0x10b044af0> 994 | >>> next(new_lines) 995 | 'HELLO WORLD' 996 | >>> with open('ts.txt') as fin: 997 | line1 = next(fin) 998 | line2= next(fin) 999 | 1000 | 1001 | Traceback (most recent call last): 1002 | File "", line 2, in 1003 | line1 = next(fin) 1004 | File "/usr/local/Cellar/python3/3.6.0/Frameworks/Python.framework/Versions/3.6/lib/python3.6/codecs.py", line 321, in decode 1005 | (result, consumed) = self._buffer_decode(data, self.errors, final) 1006 | UnicodeDecodeError: 'utf-8' codec can't decode byte 0x93 in position 1142: invalid start byte 1007 | >>> with open('ts.txt', encoding='windows_1252') as fin: 1008 | line1 = next(fin) 1009 | line2= next(fin) 1010 | 1011 | 1012 | >>> line1 1013 | '\n' 1014 | >>> line2 1015 | 'The Project Gutenberg EBook of The Adventures of Tom Sawyer, Complete by\n' 1016 | >>> fin 1017 | <_io.TextIOWrapper name='ts.txt' mode='r' encoding='windows_1252'> 1018 | >>> line3 = next(fin) 1019 | Traceback (most recent call last): 1020 | File "", line 1, in 1021 | line3 = next(fin) 1022 | ValueError: I/O operation on closed file. 1023 | >>> fin 1024 | <_io.TextIOWrapper name='ts.txt' mode='r' encoding='windows_1252'> 1025 | >>> id(fin) 1026 | 4479338464 1027 | >>> dir(fin) 1028 | ['_CHUNK_SIZE', '__class__', '__del__', '__delattr__', '__dict__', '__dir__', '__doc__', '__enter__', '__eq__', '__exit__', '__format__', '__ge__', '__getattribute__', '__getstate__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__iter__', '__le__', '__lt__', '__ne__', '__new__', '__next__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '_checkClosed', '_checkReadable', '_checkSeekable', '_checkWritable', '_finalizing', 'buffer', 'close', 'closed', 'detach', 'encoding', 'errors', 'fileno', 'flush', 'isatty', 'line_buffering', 'mode', 'name', 'newlines', 'read', 'readable', 'readline', 'readlines', 'seek', 'seekable', 'tell', 'truncate', 'writable', 'write', 'writelines'] 1029 | >>> import time 1030 | >>> class stopwatch: 1031 | def __enter__(self): 1032 | self.start = time.time() 1033 | def __exit__(self, *args): 1034 | print('Took {} seconds'.format(time.time() - self.start)) 1035 | 1036 | 1037 | >>> with stopwatch(): 1038 | pass 1039 | 1040 | Took 4.0531158447265625e-06 seconds 1041 | >>> with stopwatch(): 1042 | time.sleep(5) 1043 | 1044 | 1045 | Took 5.001406908035278 seconds 1046 | >>> import contextlib 1047 | >>> @contextlib.contextmanager 1048 | def timer(): 1049 | start = time.time() 1050 | try: 1051 | yield 1052 | finally: 1053 | print("TOOK {} Seconds".format(time.time() - start)) 1054 | 1055 | 1056 | >>> time 1057 | 1058 | >>> timer 1059 | 1060 | >>> with timer(): 1061 | time.sleep(5) 1062 | 1063 | 1064 | TOOK 5.000734090805054 Seconds 1065 | 1066 | 1067 | 1068 | 1069 | >>> 1070 | --------------------------------------------------------------------------------