Think Python

  1. Chapter 1: The First Program
  2. Chapter 2: Variables, expressions and statements
  3. Chapter 3: Functions
  4. Chapter 4: Conditionals and recursion
  5. Chapter 5: Fruitful functions
  6. Chapter 6: Iteration
  7. Chapter 7: Strings
  8. Chapter 8: Lists
  9. Chapter 9: Dictionaries
  10. Chapter 10: Tuples

Chapter 1: The First Program

Python interpreter

  • Type python in the command line to start interpreter
1
2
3
4
Python 3.4.0 (default, Jun 19 2015, 14:20:21)
[GCC 4.8.2] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>>
  • The first three lines contain information about the interpreter and the operating system it’s
    running on, so it might be different for you. But you should check that the version number,
    which is 3.4.0 in this example, begins with 3, which indicates that you are running Python 3. If it begins with 2, you are running (you guessed it) Python 2.
    The last line is a prompt that indicates that the interpreter is ready for you to enter pre. If
    you type a line of pre and hit Enter, the interpreter displays the result:
1
2
>>> 1 + 1
2

Basic Arthmetic

1
2
3
4
5
6
>>> 40 + 2
42
>>> 43 - 1
42
>>> 6 * 7
42
  • The operator / performs division:
1
2
>>> 84 / 2
42.0
  • You might wonder why the result is 42.0 instead of 42. I’ll explain in the next section. Finally, the operator ** performs exponentiation; that is, it raises a number to a power:
1
2
>>> 6**2 + 6
42
  • In some other languages, ^ is used for exponentiation, but in Python it is a bitwise operator called XOR. If you are not familiar with bitwise operators, the result will surprise you:
1
2
>>> 6 ^ 2
4

Values and Types

  • If you are not sure what type a value has, the interpreter can tell you:
1
2
3
4
5
6
>>> type(2)
< class 'int'>
>>> type(42.0)
< class 'float'>
>>> type('Hello, World!')
< class 'str'>

Chapter 2: Variables, Expressions and Statements

Statement

  • An assignment statement creates a new variable and gives it a value:
1
2
3
>>> message = 'And now for something completely different'
>>> n = 17
>>> pi = 3.1415926535897932

Expressions

  • An expression is a combination of values, variables, and operators. A value all by itself is considered an expression, and so is a variable, so the following are all legal expressions:
1
2
3
4
5
6
>>> 42
42
>>> n
17
>>> n + 25
42
  • When you type an expression at the prompt, the interpreter evaluates it, which means that it finds the value of the expression. In this example, n has the value 17 and n + 25 has the value 42. A statement is a unit of pre that has an effect, like creating a variable or displaying a value.

Order of operations

  • Parentheses have the highest precedence and can be used to force an expression to evaluate in the order you want. Since expressions in parentheses are evaluated first, 2 * (3-1) is 4, and (1+1)**(5-2) is 8. You can also use parentheses to make an expression easier to read, as in (minute * 100) / 60, even if it doesn’t change the result.

  • Exponentiation has the next highest precedence, so 1 + 2**3 is 9, not 27, and 2 * 3**2 is 18, not 36.

  • Multiplication and Division have higher precedence than Addition and Subtraction. So 2*3-1 is 5, not 4, and 6+4/2 is 8, not 5.

  • Operators with the same precedence are evaluated from left to right (except exponentiation). So in the expression degrees / 2 * pi, the division happens first and the result is multiplied by pi. To divide by 2π, you can use parentheses or write degrees / 2 / pi.

Comments

  • comments, and they start with the # symbol. “”“fdsfsdfsd”"" for multiple lines of comments

Chapter 3: Functions

  • In the context of programming, a function is a named sequence of statements that performs a computation. When you define a function, you specify the name and the sequence of statements. Later, you can “call” the function by name.

  • It is common to say that a function “takes” an argument and “returns” a result. The result is also called the return value.

  • Python has a math module that provides most of the familiar mathematical functions. A module is a file that contains a collection of related functions. Before we can use the functions in a module, we have to import it with an import statement:

1
>>>> import math

Adding new functions

  • So far, we have only been using the functions that come with Python, but it is also possible to add new functions. A function definition specifies the name of a new function and the sequence of statements that run when the function is called.
1
2
3
def print_lyrics():
print("I'm a lumberjack, and I'm okay.")
print("I sleep all night and I work all day.")
  • The first line of the function definition is called the header; the rest is called the body. The header has to end with a colon and the body has to be indented. By convention, indentation is always four spaces. The body can contain any number of statements.

  • A function can be inside another function

Parameters and arguments

  • Some of the functions we have seen require arguments. For example, when you call math.sin you pass a number as an argument. Some functions take more than one argument: math.pow takes two, the base and the exponent

  • When you create a variable inside a function, it is local, which means that it only exists inside the function

Encapsulation

  • Wrapping a piece of pre up in a function is called encapsulation. One of the benefits of encapsulation is that it attaches a name to the pre, which serves as a kind of documentation. Another advantage is that if you re-use the pre, it is more concise to call a function twice than to copy and paste the body!

Chapter 4: Conditionals and recursion

Floor divisions and modulus

  • The floor division operator, //, divides two numbers and rounds down to an integer
  • e the modulus operator, %, which divides two numbers and returns the remainder

Boolean expressions

  • A boolean expression is an expression that is either true or false. The following examples use the operator ==, which compares two operands and produces True if they are equal and False otherwise:
1
2
3
4
>>> 5 == 5
True
>>> 5 == 6
False

Logical operators

  • AND
  • OR
  • NOT

Conditional execution

1
2
3
4
if x % 2 == 0:
print('x is even')
else:
print('x is odd')

Chained conditions

1
2
3
4
5
6
if x < y:
print('x is less than y')
elif x > y:
print('x is greater than y')
else:
print('x and y are equal')

Recursion

  • It is legal for one function to call another; it is also legal for a function to call itself.
1
2
3
4
5
6
def countdown(n):
if n <= 0:
print('Blastoff!')
else:
print(n)
countdown(n-1)

Keyboard input

  • Python provides a built-in function called input that stops the program and waits for the user to type something. When the user presses Return or Enter, the program resumes and input returns what the user typed as a string
1
2
3
4
>>> text = input()
What are you waiting for?
>>> text
'What are you waiting for?'

Chapter 5: Fruitful functions

  • Functions that return a value
1
2
3
4
5
def absolute_value(x):
if x < 0:
return -x
else:
return x

Incremental development

  • Start with a working program and make small incremental changes. At any point, if there is an error, you should have a good idea where it is.

Chapter 6: Iteration

  • The ability to run a block of statements repeatedly

The while statement

1
2
3
4
5
def countdown(n):
while n > 0:
print(n)
n = n - 1
print('Blastoff!')
  1. Determine whether the condition is true or false.
  2. If false, exit the while statement and continue execution at the next statement.
  3. If the condition is true, run the body and then go back to step 1.

Break

  • Sometimes you don’t know it’s time to end a loop until you get half way through the body. In that case you can use the break statement to jump out of the loop
1
2
3
4
5
6
while True:
line = input('> ')
if line == 'done':
break
print(line)
print('Done!')

Chapter 7: Strings

  • Strings are not like integers, floats, and booleans. A string is a sequence of characters, which means it is an ordered collection of other values. In this chapter you’ll see how to access the characters that make up a string, and you’ll learn about some of the methods strings provide
1
2
3
4
5
6
>>> fruit = 'banana'
>>> letter = fruit[1]
>>> letter
'a'
>>> len(fruit)
6

Traversal with a for loop

  • A lot of computations involve processing a string one character at a time. Often they start at the beginning, select each character in turn, do something to it, and continue until the end. This pattern of processing is called a traversal. One way to write a traversal is with a while loop:
1
2
3
4
5
index = 0
while index < len(fruit):
letter = fruit[index]
print(letter)
index = index + 1
  • another way to traverse is to use a for loop
1
2
for letter in fruit:
print(letter)

Strings slices

  • A segment of a string is called a slice. Selecting a slice is similar to selecting a character:
1
2
3
4
5
>>> s = 'Monty Python'
>>> s[0:5]
'Monty'
>>> s[6:12]
'Python'
  • The operator [n:m] returns the part of the string from the “n-eth” character to the “m-eth” character, including the first but excluding the last

  • If you omit the first index (before the colon), the slice starts at the beginning of the string. If you omit the second index, the slice goes to the end of the string:

1
2
3
4
5
6
7
8
>>> fruit = 'banana'
>>> fruit[:3]
'ban'
>>> fruit[3:]
'ana'
>>> fruit = 'banana'
>>> fruit[3:3]
''

Strings are immutable

1
2
3
>>> greeting = 'Hello, world!'
>>> greeting[0] = 'J'
TypeError: 'str' object does not support item assignment

The in operator

  • The word in is a boolean operator that takes two strings and returns True if the first appears as a substring in the second:
1
2
3
4
>>> 'a' in 'banana'
True
>>> 'seed' in 'banana'
False

String comparison

  • Upper case letters come before lower case letters, we can use > or < or == to compare strings

Chapter 8: Lists

List is a sequence

  • Like a string, a list is a sequence of values. In a string, the values are characters; in a list, they can be any type. The values in a list are called elements or sometimes items.

  • There are several ways to create a new list; the simplest is to enclose the elements in square brackets ([ and ]):

  • The elements of a list don’t have to be the same type.

1
2
3
4
5
>>> cheeses = ['Cheddar', 'Edam', 'Gouda']
>>> numbers = [42, 123]
>>> empty = []
>>> print(cheeses, numbers, empty)
['Cheddar', 'Edam', 'Gouda'] [42, 123] []

Lists are mutable

1
2
3
4
>>> numbers = [42, 123]
>>> numbers[1] = 5
>>> numbers
[42, 5]

Traversing a list

1
2
for i in range(len(numbers)):
numbers[i] = numbers[i] * 2

List operations

1
2
3
4
5
6
7
8
9
>>> a = [1, 2, 3]
>>> b = [4, 5, 6]
>>> c = a + b
>>> c
[1, 2, 3, 4, 5, 6]
>>> [0] * 4
[0, 0, 0, 0]
>>> [1, 2, 3] * 3
[1, 2, 3, 1, 2, 3, 1, 2, 3]

List slices

1
2
3
4
5
6
7
>>> t = ['a', 'b', 'c', 'd', 'e', 'f']
>>> t[1:3]
['b', 'c']
>>> t[:4]
['a', 'b', 'c', 'd']
>>> t[3:]
['d', 'e', 'f']

List methods

  • append adds a new element to the end of a list:
  • extend takes a list as an argument and appends all of the elements:
  • sort arranges the elements of the list from low to high:
1
2
3
4
5
6
7
8
9
10
11
12
13
>>> t = ['a', 'b', 'c']
>>> t.append('d')
>>> t
['a', 'b', 'c', 'd']
>>> t1 = ['a', 'b', 'c']
>>> t2 = ['d', 'e']
>>> t1.extend(t2)
>>> t1
['a', 'b', 'c', 'd', 'e']
>>> t = ['d', 'c', 'e', 'b', 'a']
>>> t.sort()
>>> t
['a', 'b', 'c', 'd', 'e']

Deleting elements

  • If you know the index of the element you want, you can use pop:
  • pop modifies the list and returns the element that was removed. If you don’t provide an index, it deletes and returns the last element.
1
2
3
4
5
6
>>> t = ['a', 'b', 'c']
>>> x = t.pop(1)
>>> t
['a', 'c']
>>> x
'b'
  • If you don’t need the removed value, you can use the del operator:
1
2
3
4
>>> t = ['a', 'b', 'c']
>>> del t[1]
>>> t
['a', 'c']
  • If you know the element you want to remove (but not the index), you can use remove:
1
2
3
4
>>> t = ['a', 'b', 'c']
>>> t.remove('b')
>>> t
['a', 'c']

Objects and values

  • In one case, a and b refer to two different objects that have the same value. In the second case, they refer to the same object.
1
2
3
4
5
6
7
8
9
10
>>> a = "word1"
>>> b = "word1"
>>> a is b
True
>>> a = [1,2,3]
>>> b = [1,2,3]
>>> a is b
False
>>> a == b
True

Aliasing

  • If a refers to an object and you assign b = a, then both variables refer to the same object, even for a list
  • Its also called shallow copy
1
2
3
4
>>> a = [1, 2, 3]
>>> b = a
>>> b is a
True
  • For objects that may take lots of memory space, the program will prefer to only make a reference to its original object when you create another variable to points to it.

List arguments

  • When you pass a list to a function, the function gets a reference to the list. If the function modifies the list, the caller sees the change.
1
2
3
4
5
6
7
def delete_head(t):
del t[0]

>>> letters = ['a', 'b', 'c']
>>> delete_head(letters)
>>> letters
['b', 'c']

Chapter 9: Dictionaries

  • A dictionary contains a collection of indices, which are called keys, and a collection of values. Each key is associated with a single value. The association of a key and a value is called a key-value pair or sometimes an item

  • The function dict creates a new dictionary with no items. Because dict is the name of a built-in function, you should avoid using it as a variable name

1
2
3
4
5
6
>>> eng2sp = dict()
>>> eng2sp
{}
>>> eng2sp['one'] = 'uno' # add an item with key = 'one' and value = 'uno'
>>> eng2sp
{'one': 'uno'}
  • The order of the key-value pairs might not be the same. If you type the same example on your computer, you might get a different result. In general, the order of items in a dictionary is unpredictable. This is because when we insert items into the dictionary, it randomly put items into buckets, so it could be different everytime. (Hash)

  • check whether a dictionary contains some key

1
2
3
4
>>> 'one' in eng2sp
True
>>> 'uno' in eng2sp
False
  • check whether a dictionary contains some value
1
2
3
>>> vals = eng2sp.values()
>>> 'uno' in vals
True
  • Python dictionaries use a data structure called a hashtable that has a remarkable property: the in operator takes about the same amount of time no matter how many items are in the dictionary. Instant lookup time!

Dictionary as a collection of counters

  • Suppose you are given a string and you want to count how many times each letter appears. There are several ways you could do it
  1. You could create 26 variables, one for each letter of the alphabet. Then you could traverse the string and, for each character, increment the corresponding counter, probably using a chained conditional.
  2. You could create a list with 26 elements. Then you could convert each character to a number (using the built-in function ord), use the number as an index into the list, and increment the appropriate counter.
  3. You could create a dictionary with characters as keys and counters as the corresponding values. The first time you see a character, you would add an item to the dictionary. After that you would increment the value of an existing item.
  • An implementation is a way of performing a computation; some implementations are better than others. For example, an advantage of the dictionary implementation is that we don’t have to know ahead of time which letters appear in the string and we only have to make room for the letters that do appear.
1
2
3
4
5
6
7
8
def histogram(s):
d = dict()
for c in s:
if c not in d:
d[c] = 1
else:
d[c] += 1
return d

Looping and dictionaries

1
2
3
def print_hist(h):
for c in h:
print(c, h[c])
  • Given a dictionary d and a key k, it is easy to find the corresponding value v = d[k]. This operation is called a lookup. But what if you have v and you want to find k? You have two problems: first, there might be more than one key that maps to the value v. Depending on the application, you might be able to pick one, or you might have to make a list that contains all of them. Second, there is no simple syntax to do a reverse lookup; you have to search
1
2
3
4
5
def reverse_lookup(d, v):
for k in d:
if d[k] == v:
return k
raise LookupError()

Chapter 10: Tuples

Tuples are immutable

  • A tuple is a sequence of values. The values can be any type, and they are indexed by integers, so in that respect tuples are a lot like lists. The important difference is that tuples are immutable.
1
2
3
>>> t = tuple()
>>> t
()
  • Most list operators also work on tuples. The bracket operator indexes an element:
1
2
3
4
5
6
7
>>> t = ('a', 'b', 'c', 'd', 'e')
>>> t[0]
'a'
>>> t[1:3]
('b', 'c')
>>> t[0] = 'A'
TypeError: object doesn't support item assignment

Tuples and return values

  • Strictly speaking, a function can only return one value, but if the value is a tuple, the effect is the same as returning multiple values. For example, if you want to divide two integers and compute the quotient and remainder, it is inefficient to compute x//y and then x%y. It is better to compute them both at the same time
  • The built-in function divmod takes two arguments and returns a tuple of two values, the quotient and remainder. You can store the result as a tuple:
1
2
3
>>> t = divmod(7, 3)
>>> t
(2, 1)