An object is some value + its operations bundled together - we will see below
In [1]:
(-1 + 0) * 3 ** (3 - 1) / (1 + 2)
Out[1]:
Warning: by default division is integer division in Python 2!
In [2]:
1 / 2
Out[2]:
In [3]:
# an integer is an object, operators are accessible via "magic methods" - magic because of their name and the translation
1 - 2
print 'sub', (1).__sub__(2)
3 / 2
print 'div', (3).__div__(2)
print 'truediv', (3).__truediv__(2) # true division is in the __future__
# from __future__ import division
In [4]:
1.2
Out[4]:
In [5]:
2 / 3.
Out[5]:
Warning: they are inexact representations of the number:
In [6]:
0.1
Out[6]:
In [7]:
0.1 * 8
Out[7]:
In [8]:
0.1 + 0.1 + 0.1 + 0.1 + 0.1 + 0.1 + 0.1 + 0.1
Out[8]:
In [9]:
# float -> integet
int(1.9)
Out[9]:
In [10]:
import math
int(math.ceil(1.5))
Out[10]:
In [11]:
math.asin(0.5) * 6
Out[11]:
In [12]:
# integer -> float
float(1)
Out[12]:
In [13]:
(1, 2)
Out[13]:
In [14]:
# corner case awkwardness, tuple with only one item: mandatory comma inside paren
(1,)
Out[14]:
In [15]:
# arbitrary nesting:
((2, (3, 4, 5)), 2)
Out[15]:
In [16]:
len((1, 2, 3))
Out[16]:
In [17]:
len(((2, (3, 4, 5)), 2))
Out[17]:
In [18]:
(1, 2, 3) + (5, 6)
Out[18]:
In [19]:
# multiplication = self concatenation
(1, 2) * 3
Out[19]:
In [20]:
(1, 2, 3)[1]
Out[20]:
In [21]:
(1, 2, 3)[1:2]
Out[21]:
In [22]:
(1, 2, 3)[1:]
Out[22]:
In [23]:
(1, 2, 3)[:2]
Out[23]:
In [24]:
(1, 2, 3)[:]
Out[24]:
In [25]:
tuple(x * 2 for x in (1, 2, 3, 9) if x > 2)
Out[25]:
In [26]:
sum(1 for x in (1, 2, 3, 5, 2, 11, 4, 1, -1) if x < 3)
Out[26]:
In [27]:
# concatenation
u'string1' + u'string2'
Out[27]:
In [28]:
# Indexing - extracting single "character"
u'string'[1]
Out[28]:
In [29]:
# extracting substring (slicing)
u'string'[1:3]
Out[29]:
In [30]:
# more slicing
u'string'[1:]
Out[30]:
In [31]:
# even more slicing
u'string'[:3]
Out[31]:
In [32]:
# check for substring
(u'str' in u'string', u'sing' in u'string')
Out[32]:
In [33]:
# converting a string to a tuple of its characters
tuple(u'string')
Out[33]:
In [34]:
# converting something to a string
str(3)
Out[34]:
In [35]:
str(str)
Out[35]:
In [36]:
str(u'tuple')
Out[36]:
In [37]:
str(max)
Out[37]:
In [38]:
# another, subtly different way to get at the string representation of something that sometimes works, when str does not:
repr(max)
Out[38]:
In [39]:
# embed values into strings
u'The {} opened {} {}'.format(u'drunkard', 2, u'bottles')
Out[39]:
Python 2: there are two string types,
from __future__ import unicode_literals
changes the default meaning of strings to be unicode instead of byte string
In [40]:
'árvíztűrő tükörfúrógép'
Out[40]:
In [41]:
len('árvíztűrő tükörfúrógép')
Out[41]:
In [42]:
print 'árvíztűrő tükörfúrógép'
In [43]:
u'árvíztűrő tükörfúrógép'
Out[43]:
In [44]:
len(u'árvíztűrő tükörfúrógép')
Out[44]:
In [45]:
print u'árvíztűrő tükörfúrógép'
In [47]:
str(u'árvíztűrő tükörfúrógép')
In [48]:
'\xc3\xa1rv\xc3\xadzt\xc5\xb1r\xc5\x91 t\xc3\xbck\xc3\xb6rf\xc3\xbar\xc3\xb3g\xc3\xa9p'.decode('utf-8')
Out[48]:
In [49]:
u'árvíztűrő tükörfúrógép'.encode('utf-8')
Out[49]:
In [50]:
u'''
multiline
strings
'''
Out[50]:
In [51]:
u"in double-quote"
Out[51]:
In [52]:
u"""
multiline
strings in double-quote
"""
Out[52]:
In [53]:
print u"""
multiline
strings in double-quote
"""
In [54]:
a_name = u'árvíztűrő tükörfúrógép'
In [55]:
print a_name
In [56]:
len(a_name)
Out[56]:
In [57]:
print a_name + u' ' + a_name
In [58]:
print a_name[2:5]
built in functions/functions in standard library - see https://docs.python.org/2/library/functions.html
In [59]:
def fact(n):
''' n! '''
return n * fact(n - 1) if n > 1 else 1
assert fact(3) == 6
assert fact(4) == 24
In [60]:
def sin0(x):
''' sin calculated by Taylor series for sin around 0 '''
return x - (1./fact(3))*x**3 + (1./fact(5))*x**5 - (1./fact(7))*x**7 # + (1./fact(9))*x**9
assert sin0(0) == 0
# check at angle 30 - should be very close to 0.5
error = abs(sin0(3.14159265358 / 6) - 0.5)
assert error < 1e-8, 'error is {} - greater than expected!'.format(error)
In [61]:
import math
def sindiff(a):
return math.sin(a) - sin0(a)
print sindiff(0.1)
print sindiff(math.pi / 5)
print sindiff(math.pi / 4)
print sindiff(math.pi / 3)
print sindiff(math.pi / 2)
print sindiff(-math.pi)
print sindiff(2 * math.pi)
print sindiff(3 * math.pi)
Binomials
In [62]:
def nk(n, k):
''' select k from n values '''
return fact(n) / (fact(k) * fact(n - k))
In [63]:
# Pascal's triangle - n-th row = nk for all k
def pascal(n):
return add_tuples(shift_left(pascal(n - 1)), shift_right(pascal(n - 1))) if n > 0 else (1,)
def shift_left(t):
return t + (0,)
def shift_right(t):
return (0,) + t
def add_tuples(t1, t2):
return (t1[0] + t2[0],) + add_tuples(t1[1:], t2[1:]) if t1 else ()
pascal(12)
Out[63]:
In [64]:
nk(12, 3)
Out[64]:
In [65]:
# problem: it slows down radically as n goes up - time complexity
pascal(20)
Out[65]:
In [66]:
# fix: calculate the previous value only once
def fast_pascal(n):
if n > 0:
prev = fast_pascal(n - 1)
return add_tuples(shift_left(prev), shift_right(prev))
else:
return (1,)
fast_pascal(30)
Out[66]:
replace operation + for composing new row with another function
In [67]:
def op_pascal(op, n):
if n > 0:
prev = op_pascal(op, n - 1)
return compose_tuples(op, shift_left(prev), shift_right(prev))
else:
return (1,)
def compose_tuples(op, t1, t2):
return (op(t1[0], t2[0]),) + compose_tuples(op, t1[1:], t2[1:]) if t1 else ()
# ops to try:
def addp(a, b):
return a + b + 1
def minp(a, b):
return min(a, b) + 1
def minpx2(a, b):
return (min(a, b) + 1) * 2
op_pascal(minpx2, 8)
Out[67]:
In [68]:
import operator
def fact2(n):
return reduce(operator.mul, range(1, n + 1))
assert fact2(5) == fact(5)
print fact2(5), fact2(6), operator.mul
In [69]:
class Auto(object):
def __init__(self, brand, type, color):
self.brand = brand
self.type = type
self.color = color
def repaint(self, color):
return Auto(self.brand, self.type, color)
def __repr__(self):
return u'{0.__class__.__name__}({0.brand}, {0.type}, {0.color})'.format(self)
# Auto is a ~function that returns Auto objects
In [70]:
yellow_suzuki = Auto('Suzuki', 'Ignis', 'yellow')
print yellow_suzuki
print yellow_suzuki.color
In [73]:
red_suzuki = yellow_suzuki.repaint('red')
red_suzuki
Out[73]:
= I am a micromanaging boss, I tell you what to do, and how
lists - like tuples, but changeable
In [74]:
l = [1, 2, (u'tuple-string',)]
l
Out[74]:
In [75]:
l[2] = u'I do not like tuples of length 1 syntax'
l
Out[75]:
In [76]:
del l[1:]
l
Out[76]:
In [77]:
l.append(u'new item')
l
Out[77]:
In [78]:
data = (1, 2)
data
Out[78]:
In [79]:
old_data = data
data = data + (3, 4)
print old_data
print data
In [80]:
i = 5
l = []
while i < 10:
l.append(i)
i = i + 1
print l
In [81]:
l = []
for i in range(5, 10):
l.append(i * 3 + 1)
print l
why? distributing responsibility
In [82]:
# this is list comprehension as above!
g = (x*2 for x in (1, 2, 3, 9) if x > 2)
g
Out[82]:
In [83]:
tuple(g)
Out[83]:
In [84]:
tuple(g)
Out[84]:
In [85]:
g = (x*2 for x in (1, 2, 3, 9) if x > 2)
g
Out[85]:
In [86]:
next(g)
Out[86]:
In [87]:
next(g)
Out[87]:
In [89]:
next(g)
In [90]:
g = (x*2 for x in (1, 2, 3, 9) if x > 2)
for x in g:
print x
In [91]:
def gen2x(nums):
for x in nums:
if x > 2:
yield x * 2
gen2x((1, 2, 4, 0, 1, 12, 1))
Out[91]:
In [92]:
tuple(gen2x((1, 2, 4, 0, 1, 12, 1)))
Out[92]: