A Python Crash Course for the Statically Typed Programmer November 15, 2013

def factorial(n):
if n <= 1:
return 1
else:
return n * factorial(n - 1)
# or
def factorial(n):
res = 1
while n:
res *= n
n -= 1
return res


>>> def foo(this, that):
... return (this + that) * 2
...
>>> foo(3, 5)
16
>>> foo("hello", "world")
'helloworldhelloworld'
>>> 5+3
8
>>> 27**63
149939874158678820041423971072487610193361136600
3344657118522818557991334322919287339806483L
>>> 5+3j
(5+3j)
>>> 1/(5+3j)
(0.14705882352941177-0.08823529411764706j)
>>> [1,2,3]
[1, 2, 3]
>>> [1,2,3] + [4,5,6]
[1, 2, 3, 4, 5, 6]
>>> (1,2,3)
(1, 2, 3)
>>> d={"a":4, 7:()}
>>> d["a"]
4
>>> d[7]
()
>>> True, False, None
(True, False, None)
>>> set([2,6,2,7,2,8,6])
set([8, 2, 6, 7])
>>> "hello" + "world"
'helloworld'
>>> a="this is a single line string"
>>> a[5]
'i'
>>> a[5:12]
'is a si'
>>> a.upper()
'THIS IS A SINGLE LINE STRING'
>>> a.count("i")
5
>>> a.replace("i", "j")
'thjs js a sjngle ljne strjng'
>>> a.startswith("thi")
True
>>> "single" in a
True
>>> "multiple" in a
False
>>> a.split()
['this', 'is', 'a', 'single', 'line', 'string']
>>> a.split("i")
['th', 's ', 's a s', 'ngle l', 'ne str', 'ng']
>>> "hello".encode("hex")
'68656c6c6f'
>>> "hello".encode("utf16")
'\xff\xfeh\x00e\x00l\x00l\x00o\x00'
>>> "hello".encode("zlib")
'x\x9c\xcbH\xcd\xc9\xc9\x07\x00\x06,\x02\x15'
>>> "My name is %s. You %s, prepare to %s" % ("Inigo Montoya",
... "killed my father", "die")
'My name is Inigo Montoya. You killed my father, prepare to die'
>>>
>>> "My name is %03d" % (7,)
'My name is 007'
>>> ":".join(["AA", "BB", "CC"])
'AA:BB:CC'
>>> b="""this is
... a multi
... line string"""
>>> b
'this is\na multi\nline string'
>>> b.splitlines()
['this is', 'a multi', 'line string']
>>> help
Type help() for interactive help, or help(object) for help about object.
>>> dir()
['__builtins__', '__doc__', '__name__', '__package__']
>>> help(dir)
dir([object]) -> list of strings
If called without an argument, return the names in the current scope.
Else, return an alphabetized list of names comprising (some of) the attributes
>>> dir("hello")
['__add__', '__class__', '__contains__', '__delattr__', '__doc__', '__eq__', '__for
_mod__', '__mul__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__',
nter', 'count', 'decode', 'encode', 'endswith', 'expandtabs', 'find', 'format', 'in
index', 'rjust', 'rpartition', 'rsplit', 'rstrip', 'split', 'splitlines', 'startswi']
>>> type(5)
<type 'int'>
>>> type("hello")
<type 'str'>
>>> int
<type 'int'>
>>> str
<type 'str'>
>>> list
<type 'list'>
>>> int(5.1)
5
>>> int("5")
5
>>> str(5)
'5'
>>> list("hello")
['h', 'e', 'l', 'l', 'o']
>>> 5 + "6"
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: unsupported operand type(s) for +: 'int' and 'str'
>>> 5 + int("6")
11
>>> str(5) + "6"
'56'
>>> repr(5)
'5'
>>> repr("hello")
"'hello'"
>>> print "Hello %s" % ("foo\n\tbar",)
Hello foo
bar
>>> print "Hello %r" % ("foo\n\tbar",)
Hello 'foo\n\tbar'
>>> range(10)
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> range(10,20)
[10, 11, 12, 13, 14, 15, 16, 17, 18, 19]
>>> range(10,20,2)
[10, 12, 14, 16, 18]
>>> range(20,10,-2)
[20, 18, 16, 14, 12]
>>> len([2,5,2,6,2,6])
6
>>> len("hello")
5
>>> a=[2,5,2,6,2,6]
>>> max(a)
6
>>> min(a)
2
>>> b=["what", "is", "this", "thing"]
>>> max(b)
'what'
>>> max(b, key = len)
'thing'
>>> a=range(10,20)
>>> a[0]
10
>>> a[-1]
19
>>> a[3:7]
[13, 14, 15, 16]
>>> a[7:]
[17, 18, 19]
>>> a[-3:]
[17, 18, 19]
>>> a[:-3]
[10, 11, 12, 13, 14, 15, 16]
>>> lambda x: x * 2
<function <lambda> at 0x0297EEB0>
>>> f = lambda x: x * 2
>>> f(6)
12
>>> map(f, range(10))
[0, 2, 4, 6, 8, 10, 12, 14, 16, 18]
>>> filter(lambda x: x % 2 == 0, range(10))
[0, 2, 4, 6, 8]
>>> f = open("/etc/profile")
>>> f.read(100)
'# /etc/profile: system-wide .profile file for the Bourne shell (sh(1))\n# and Bourne compatible shell'
>>> f.readline()
's (bash(1), ksh(1), ash(1), ...).\n'
>>> f.readline()
'\n'
>>> f.readline()
'if [ "$PS1" ]; then\n'
>>> list(f)[:4]
[' if [ "$BASH" ] && [ "$BASH" != "/bin/sh" ]; then\n',
' # The file bash.bashrc already sets the default PS1.\n',
" # PS1='\\h:\\w\\$ '\n",
' if [ -f /etc/bash.bashrc ]; then\n']
>>> f.close()
>>> with open("/etc/profile") as f:
... f.read(100)
...
'# /etc/profile: system-wide .profile file for the Bourne shell (sh(1))\n# and Bourne compatible shell'
>>> [x for x in range(10)]
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> [x * 2 for x in range(10)]
[0, 2, 4, 6, 8, 10, 12, 14, 16, 18]
>>> [x for x in range(10) if x % 2 == 0]
[0, 2, 4, 6, 8]
>>> [x * 2 for x in range(10) if x % 2 == 0]
[0, 4, 8, 12, 16]
>>> [i * j for i in range(1,5) for j in range(1,5)]
[1, 2, 3, 4, 2, 4, 6, 8, 3, 6, 9, 12, 4, 8, 12, 16]
>>> [[i * j for i in range(1,5)] for j in range(1,5)]
[[1, 2, 3, 4], [2, 4, 6, 8], [3, 6, 9, 12], [4, 8, 12, 16]]
>>> [" ".join(["%3d" % (i * j,) for i in range(1,5)])
... for j in range(1,5)]
[' 1 2 3 4', ' 2 4 6 8', ' 3 6 9 12',
' 4 8 12 16']
>>> print "\n".join([" ".join(["%3d" % (i * j,) for i in range(1,11)])
... for j in range(1,11)])
1 2 3 4 5 6 7 8 9 10
2 4 6 8 10 12 14 16 18 20
3 6 9 12 15 18 21 24 27 30
4 8 12 16 20 24 28 32 36 40
5 10 15 20 25 30 35 40 45 50
6 12 18 24 30 36 42 48 54 60
7 14 21 28 35 42 49 56 63 70
8 16 24 32 40 48 56 64 72 80
9 18 27 36 45 54 63 72 81 90
10 20 30 40 50 60 70 80 90 100
>>> def myfunc():
... yield 1
... yield 2
... yield 3
...
>>> g=myfunc()
>>> g
<generator object myfunc at 0x02A3A8F0>
>>> g.next()
1
>>> g.next()
2
>>> g.next()
3
>>> g.next()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
StopIteration
>>> def fib():
... a = b = 1
... while True:
... yield a
... a, b = b, a + b
...
>>> g = fib()
>>> g.next(), g.next(), g.next(), g.next(), g.next(), g.next(), g.next()
(1, 1, 2, 3, 5, 8, 13)
>>> import itertools
>>> list(itertools.islice(fib(),10))
[1, 1, 2, 3, 5, 8, 13, 21, 34, 55]
>>>
>>> list(itertools.takewhile(lambda x: x < 50, fib))
[1, 1, 2, 3, 5, 8, 13, 21, 34]
>>>
>>> list(itertools.combinations([1,2,3,4],2))
[(1, 2), (1, 3), (1, 4), (2, 3), (2, 4), (3, 4)]
>>>
>>> list(itertools.permutations([1,2,3]))
[(1, 2, 3), (1, 3, 2), (2, 1, 3), (2, 3, 1), (3, 1, 2), (3, 2, 1)]
>>> (x for x in range(10))
<generator object <genexpr> at 0x02A37F30>
>>> (x * 2 for x in range(10))
<generator object <genexpr> at 0x02A34670>
>>> (x * 2 for x in range(10) if x % 2 == 0)
<generator object <genexpr> at 0x02A37918>
>>> list(x * 2 for x in range(10) if x % 2 == 0)
[0, 4, 8, 12, 16]
>>> sum(range(1000000000))
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
MemoryError
>>> sum(xrange(1000000000))
499999999500000000L
>>> class Animal(object):
... def __init__(self, name):
... self.name = name
... def drink(self):
... print "*Gulp gulp gulp*"
...
>>> class Dog(Animal):
... def drink(self):
... Animal.drink(self) # or super(Dog, self).drink()
... print "*Tongue drips*"
... def bark(self):
... print "Woof woof woof"
...
>>> rex = Dog("Rex t3h Dawg")
>>> rex.drink()
*Gulp gulp gulp*
*Tongue drips*
>>> rex.bark()
Woof woof woof
>>> rex.__dict__
{'name' : 'Rex t3h Dawg'}
>>> rex.tail = "recursion"
>>> rex.__dict__
{'name' : 'Rex t3h Dawg', 'tail' : 'recursion'}
>>> Animal.__dict__.keys()
['__module__', 'drink', '__dict__', '__init__', '__weakref__', '__doc__']
>>>
>>> def sleep(self):
... print "Zzzzzz"
...
>>> Animal.sleep = sleep # monkey-patching
>>> rex.sleep()
Zzzzzz
>>> (5).__add__(6)
11
>>> Animal.__base__
<type 'object'>
>>> Dog.__base__
<class '__main__.Animal'>
>>> Dog.__mro__
(<class '__main__.Dog'>, <class '__main__.Animal'>, <type 'object'>)
>>> type(Dog)
<type 'type'>
>>> type
<type 'type'>
>>> type.__base__
<type 'object'>
>>> type(type)
<type 'type'>
>>> type(object)
<type 'type'>
>>> globals()
{'__builtins__': <module '__builtin__' (built-in)>}
>>> def f(a, b):
... print locals()
... c = a+b
... print locals()
...
>>> globals()
{'__builtins__': <module '__builtin__' (built-in)>, 'f': <function f at 0x028CEEB0>}
>>>
>>> f(6,7)
{'a': 6, 'b': 7}
{'a': 6, 'c': 13, 'b': 7}

>>> import this
The Zen of Python, by Tim Peters
Beautiful is better than ugly.
Explicit is better than implicit.
Simple is better than complex.
Complex is better than complicated.
Flat is better than nested.
Sparse is better than dense.
Readability counts.
Special cases aren't special enough to break the rules.
Although practicality beats purity.
Errors should never pass silently.
Unless explicitly silenced.
In the face of ambiguity, refuse the temptation to guess.
There should be one-- and preferably only one --obvious way to do it.
Although that way may not be obvious at first unless you're Dutch.
Now is better than never.
Although never is often better than *right* now.
If the implementation is hard to explain, it's a bad idea.
If the implementation is easy to explain, it may be a good idea.
