Think Python 2e by Allen Downey š
Intro
This a review of Think Python 2e by Allen Downey.
This book is divided into 21 chapters and is about 257 pages long
1  Way of the program š„

most important skill for computer scientist is problem solving

a program is a sequence of instructions that specifies how to perform a computation

formal languages are designed by people for specific applications

evidence that shows people respond to computers as if they are people (the media equation, Reeves & Nass 1996)
2  variables, expressions and statements ā½
 a variable is a name that refers to a value
 an assignment creates new variables and gives them values e.g.
x = 2
 an expression is a combination of values, variables and operators e.g.
x + y
 a statement is a unit of code that the python interpreter can execute e.g.
print('hello world')
3  functions ā”ļø
 the expression in parentheses is called the argument of the function
 a module is a file that contains a collection of related functions
 a function definition specifies the name of a new function and the sequence of statements that execute when the function is called
 to ensure that a function is defined before its first use, you have to know the order statements run in which is called the flow of execution
 a parameter is what is defined in the function, and the argument is what is passed into the function.
 to keep track of which variables can be used, we can draw stack diagrams
 each function is represented by a frame
 if an error occurs, a list of functions is printed which is called a traceback
 fruitful šĀ functionsĀ return something; void šĀ functions donāt
4  interface design

turtle š¢Ā module

wrapping a piece of code in a function is called encapsulation š

a docstring šĀ is a string at the beginning of a function that explains the interface like:
def x: """this function does something"""
5  conditionals and recursion š
 floor division operator
//
divides two numbers and rounds down to an integer; an alternative is the modulus operator%
which divides two numbers and returns the remainder  3 logical operators:
and
,or
, andnot
 the bottom of a recursive function stack is called the base case as there are no more frames to call
6  fruitful functions š
 code thatās never reached is called dead code šµ
 to deal with increasingly complex programs, you can try incremental development. This is when you add and test a small amount of code each time.
 Scaffolding š§Ā is when you have code that is helpful for building the program, but not part of the final product
 Following the flow of execution is one way to read a program; the other way is to do the āleap of faithā, which is when you assume the function works correctly.
7  iteration š
 reassignment is when you make an existing variable refer to a new value; equality is a symmetric relationship, and assignment is not
>>> x = 5
>>> x
5
>>> x = 7
>>> x
7
 algorithm is a mechanical process for solving a category of problems
 exercise 7.3  ramanujanās infinite series
import math
def estimate_pi():
sum = 0
epsilon = math.pow(10, 15)
k = 0
i = 1 # initialize i, the value doesn't matter
while i > epsilon:
i = math.factorial(4 * k) * (1103 + 26390 * k) \
/ (math.pow(math.factorial(k), 4) * math.pow(396, 4 * k))
sum += i
k += 1
inverse = 2 * math.sqrt(2) * sum / 9801
return 1 / inverse
print (estimate_pi())
print (math.pi)
print (estimate_pi()  math.pi)
8  strings š§µ
 a string is a sequence of characters
 traversal is when you visit and perform computation on each character
 segment of a string is called a slice
 Python šĀ strings are immutable
 a method call is called an invocation
9  word play
 if you see that
uses_all
was an instance of a previously solved problem, you are practicing a program development plan called reduction to a previously solved problem.
10  lists
 list is a sequence of values; you can have nested lists
 lists are mutable
 you can traverse a list with a
for
loop
def add_all(t):
total = 0
for x in t:
total += x
return total
 ^ as the loop runs,
total
accumulates the sum of elements. a variable used like this is sometimes called an accumulator
>>> t = [1, 2, 3]
>>> sum(t)
6
 ^ an operation like above combines a sequence of elements into a single value and is sometimes called
reduce
 an operation like
capitalize_all
is sometimes called a map as it āmapsā a function onto each element in a list  you can use
pop
,del
, orremove
to delete elements from a list  the association of a variable within an object is called a reference
 an object with >1 reference has more than one name, and we can say that the object is aliased
11  dictionaries š
 a dictionary is like a list but more general. A dictionary represents a mapping from keys to values.
 hashtable explanation on page 251
 given a dictionary d and a key k, we can find a corresponding value v = d[k]; this operation is called a lookup
raise
statement causes an exception singleton is a list that contains a single element
 dictionary is implemented using a hashtable which means keys must be hashable (e.g. lists cannot be keys); keys must be immutable to maintain idempotent lookups
 recursive fibonacci algorithm has a call graph that shows repeated computed values
 a previously computed value thatās stored for later use is called a memo
# memoized version of fibonacci
known = {0:0, 1:1}
def fibonacci(n):
if n in known:
return known[n]
res = fibonacci(n1) + fibonacci(n2)
known[n] = res
return res
 variables in
__main__
are sometimes called global as they can be accessed from any function  Itās common to use global variables as flags
12  tuples šØāšØāš§āš§
 a tuple is a sequence of values; tuples are immutable
>>> t = 'a', 'b', 'c'
>>> t
('a', 'b', 'c')
 to create a tuple with a single element, you have to include a final comma
>>> u = 'a',
>>> u
('a',)
 tuple assignment  no need for third variable when swapping the values of two variables
>>> a, b = b, a
divmod
takes two arguments and returns a tuple of two values: the quotient and remainder
>>> t = divmod(7, 3)
>>> t
(2, 1)
 a parameter name that begins with
*
gathers arguments into a tuple
def printall(*args):
print(args)
 the complement of gather is scatter (use
*
operator)
>>> t = (7,3)
>>> divmod(*t) # scatter the tuple
zip
function takes two or more sequences and returns a list of tuples where each tuple contains 1 element from each sequence dictionaries šĀ have a method called
items
that returns a sequence of tuples, where each tuple is a k:v pair  compound data structures are useful but prone to āshape errorsā
13  DS selection
 prefixes  strings, list of strings, tuple of strings
 suffixes  list / histogram (dictionary)
 mapping from prefix to suffix  dictionary
14  files š
 persistence is when some data is kept in permanent storage
os
module has functions for working with files and directories e.g.os.cwd
gets the name of the current directory sometimes errors happens when reading/writing files; handling an exception with a
try
statement is called catching an exception  a database is a file thatās organized for storing data; python has a module called dbm
pickle
module can translate any type of object into a string suitable for storage in a database
15  classes and objects
 OOP uses programmerdefined types to organize both code and data
 a programmerdefined type is also called a class
 a state diagram that shows an object and its attributes is called an object diagram
 an object thatās an attribute of another object is embedded
 shallow copy copies the object and any references it contains, but not embedded objects
16  classes and functions
 prototype and patch is a type of development plan that deals with complex problems by starting with a simple prototype and increasingly deals with complications
 pure functions donāt have side effects
 functions that modifies objects it gets as parameters can be called modifiers
 the author recommends you resort to writing pure functions whenever possible, and use modifiers only if thereās a compelling advantage. this approach is called the functional programming style
 an alternative style to prototype and patch is designed development, where highlevel insight into the problem can make programming easier
 invariants are conditions that should always be true
17  classes and methods
 a method is a function thatās associated with a particular class.
 there are 2 syntactic differences: 1) theyāre defined inside a class definition in order to make the r/s b/w the class and method explicit
 the syntax for invoking a method is different
 positional argument is an argument that doesnāt have a default value
sketch(parrot, cage, dead=True)
 ^
parrot
andcage
are positional,dead
is a keyword argument __init__
is a special method thatās invoked when an object is instantiated__str__
is a special method thatās supposed to return a string representation of an object 17.7 Changing the behavior of an operator so that it works with programmerdefined types is called operator overloading
 17.8 A typebased dispatch dispatches a computation to different methods based on the type of arguments
 17.9 Functions that work with several types are called polymorphic. Polymorphism šĀ can facilitate code reuse.
 17.11 a design principle that helps make software more maintainable is to keep the interface separate from implementation
18  inheritance
 inheritance is the ability to define a new class thatās a modified version of an existing class
 a veneer is a thin method that uses another method without doing much work
 when a new class inherits from an existing one, the existing one is called the parent and the new class is called the child
 pros of inheritance include code reuse; cons of inheritance are that it sometimes makes programs difficult to read
 when objects in one class contain references to objects in another class; this relationship is called HASA
 when one class might inherit from another; this relationship is called ISA
 these relationships can be shown in a class diagram
 data encapsulation (aka data hiding) is the mechanism where implementation details of a class are hidden from a user
19  the goodies
 conditional expressions
y = math.log(x) if x > 0 else float('nan')
 list comprehensions
# without LC
def capitalize_all(t):
res = []
for s in t:
res.append(s.capitalize())
return res
# with LC
def capitalize_all(t):
return [s.capitalize() for s in t]
 generator expressions are similar to LCs but with parentheses instead of []
>>> g = (x**2 for x in range(5))
 knows how to iterate through a sequence of values but waits to be asked to do so
any
 takes a sequence of Booleans and returns True if any value is True
>>> any([False, False, True])
True
all
 returns True if every element of a sequence is True a set behaves like a collection of dictionary keys with no values
def has_duplicates(t):
return len(set(t)) < len(t)
 a
Counter
is a natural way to represent a multiset (mathematical idea)
from collections import Counter
def is_anagram(w1, w2):
return Counter(w1) == Counter(w2)
defaultdict
is like a dictionary but if youāre trying to access a key that doesnāt exist, it will create one on the fly a function used to create objects is sometimes called a factory
20  debugging
 infinite recursion can cause a āMaximum recursion depth exceededā error
 if youāre stuck on a bug, maybe go for a walk
21  algorithm analysis
 analysis of algorithms is a branch of CS that studies the performance of algorithms, especially their runtime and space requirements
 relative performance might depend on details of the dataset; one way to avoid this is to analyze the worstcase scenario.
 the leading term is the term with the highest exponent
 in general we expect an algorithm with a smaller leading term to be a better algorithm for large problems, but for small problems, there may be a crossover point
 an order of growth is a set of functions whose growth behavior is considered equivalent.
 Some examples include O(1) constant, O(log n) (logarithmic for any base), O(n) linear, O(n log n) linearithmic, O(n^2) quadratic, O(n^3) cubic, O(c^n) exponential (for any c)
 in python šĀ , most arithmetic operations are constant time. Indexing operations are also constant time.
 a for loop that traverses a sequence/dictionary is usually linear
 Python dictionaries are implemented using hashtables
Conclusion
Overall I liked this book and recommend it to anyone who is interested in the Python programming language. It is written in an easy to read style, and the examples are quite manageable.