You are on page 1of 21

Contents I Decided not to be Lazy

Denoted as subject 6.00SC, this MIT course introduces basic programming concepts ˆ Moving onto actual lectures
and makes use of Python programming language for explanations. Available online,
including video lectures. I decided not to be lazy and do away with the old bullet-list format for making notes
This note file contains course notes. as I work. (I also want to stop duplicating data, by using interesting titles for the notes,
instead of just dates.) This format has been very useful to me the last few days, but
not due to this very encumbering format, but because doing any writing during work
NEXT Python Learning Notes helps me think, and see progress even in things that take a lot of time to develop. One
of those is obviously learning programming. One of the biggest problems with learning
ˆ State ”DONE” from ”NEXT” [2018-03-13 Tue 21:00] programming for me, is the ability to keep track how much road I already covered – not
to mention how much of it is in front of me, which is infinitelly harder.
ˆ State ”DONE” from ”NEXT” [2018-03-01 Thu 22:49]
Installing Python2.6 in a Docker
ˆ State ”DONE” from ”NEXT” [2018-02-28 Wed 22:51]
Some of the lectures require Python in version 2.6, which is not available in Ubuntu 16.04.
ˆ State ”DONE” from ”NEXT” [2018-02-26 Mon 23:02] That’s why decided to install it in containment using Docker. Steps for installing Docker
on Ubuntu 16.04, according to always useful DigitalOcean:
ˆ State ”DONE” from ”NEXT” [2018-02-24 Sat 22:43]
https://www.digitalocean.com/community/tutorials/how-to-install-and-use-docker-on-ubun
ˆ State ”DONE” from ”NEXT” [2018-02-23 Fri 23:48] sudo add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu $(l
sudo apt-get update
ˆ State ”DONE” from ”NEXT” [2018-02-22 Thu 22:26] apt-cache policy docker-ce # make sure official docker repo is used
# instead of some Ubuntu-maintained repos
ˆ State ”DONE” from ”NEXT” [2018-02-21 Wed 22:14] sudo systemctl status docker # verify
sudo usermod -aG docker ${USER} # run docker as regular user
ˆ State ”DONE” from ”TODO” [2018-02-19 Mon 21:58] su - ${USER} # apply settings

But that is not enough for me, since I want to run a graphical program inside Docker.
2018-02-19 Monday
For this I need this script:
ˆ starting this course since I need to refresh my programming skills and get into a
habit of programming daily SOCK=/tmp/.X11-unix
XAUTH=/tmp/.docker.xauth-2
ˆ compiling resources xauth nlist $DISPLAY | sed -e ’s/^..../ffff/’ | xauth -f $XAUTH nmerge -
chmod 777 $XAUTH
ˆ reading and understanding syllabus docker run -ti -e DISPLAY=$DISPLAY -v $XSOCK:$XSOCK -v $XAUTH:$XAUTH -e XAUTHORITY=$XA

ˆ really feels like a python course primarily Finally, my image doesn’t have python2.6 or IDLE preinstalled on it, so I need a
script that would install them for me and execute IDLE:
2018-02-21 Wednesday
#!/bin/bash
ˆ looking for a python book to buy SOCK=/tmp/.X11-unix
XAUTH=/tmp/.docker.xauth-2
ˆ took me 50min to find and buy books xauth nlist $DISPLAY | sed -e ’s/^..../ffff/’ | xauth -f $XAUTH nmerge -
chmod 777 $XAUTH
ˆ just learned that there is a precourse, yay! ID=$(docker run -ti -e DISPLAY=$DISPLAY -v $XSOCK:$XSOCK -v $XAUTH:$XAUTH -e XAUTHORIT
# docker exec -it ${ID} apt-get install -y idle-python2.6
ˆ created a schedule for the precourse docker exec -it ${ID} idle-python2.6

1 2
Pre-course: Exercises for week 2 and starting week 3 Textbooks
Textbook: Introduction to Computation and Programming Using Python
About this course With Application to Understanding Data ATTACH
ˆ Undergraduate course designed for independent study. Programming: An Introduction to Computer Science ATTACH
ˆ A complete set of Lecture Videos by Prof. Guttag. Learn Python the Hard Way ATTACH

ˆ Resources for each lecture video, such as Handouts, Slides, and Code Files. https://learnpythonthehardway.org/book/

ˆ Recitation Videos by course TA’s to review content and problem solving techniques. A Byte of Python ATTACH
ˆ Homework problems with sample student solutions. http://www.ibiblio.org/swaroopch/byteofpython/read/

ˆ Further Study collections of links to supplemental online content. Dive Into Python
ˆ Self-Assessment tools, including lecture questions with answers and unit quizzes http://www.diveintopython.net/
with solutions, to assess your subject mastery.
Code Like a Pythonista: Idiomatic Python
What you will be learning http://python.net/~goodger/projects/pycon/2007/idiomatic/handout.html

ˆ Goals:
Python Programming Wikibook ATTACH
– Help students writing small programs https://en.wikibooks.org/wiki/Python_Programming
– Map scientific problems into computational networks
– Providing competence and confidence in computational problem solving How to Think Like a Computer Scientist, Learning with Python ATTACH
– Provide easy entry for new students of computer science Think python: Part of A Gentle Introduction to Python (precourse) readings.

ˆ Topics or Objectives:
References (2.5.4, course version)
– Learning Python – language for expressing computations Python Style Guide
– Learning about the process of writing and debugging
http://www.python.org/dev/peps/pep-0008/
– Learning about the process of moving from a problem statement to solution
– Learning basic algorithms Python Documentation
https://docs.python.org/3/
Course Home Page
Python Tutorial
ˆ Landing page at MITOpenCourseWare
https://docs.python.org/3/tutorial/index.html
ˆ Video lectures
Python Reserved Words
ˆ Landing page at MITx
https://docs.python.org/3/reference/lexical_analysis.html#identifiers

Resources Python 2.5.4 Reserved Words


From course references. https://docs.python.org/2.5/ref/keywords.html

3 4
Python 2.5.4 Reference Card Syllabus ATTACH
https://michaelgoerz.net/refcards/#python25

Python Cheat Sheet Grade is a weighted average of the following:

http://www.addedbytes.com/cheat-sheets/python-cheat-sheet/

Python IDLE

https://docs.python.org/3.3/library/idle.html
Finger exercises (during video lectures) 10%
Further Readings Problem Sets 40%
Quiz 25%
1. Floating Point Arithmetic Final Exam 25%

2. Strings

3. Tuples

4. Lists

5. Dictionaries
ˆ ¿= 90%: A
6. Recursion

7. Probability

8. Normal distribution
ˆ ¿= 75%: B
9. Confidence interval

10. Simulation Methods (Monte Carlo method, Random Walks, Matplotlib/pylab ref-
erence)

11. Breadth-first and Depth-first Searches


ˆ ¿= 65%: C (required to pass)
12. Scoping: 6.01SC course notes (start at section 3.2.2, page 42), and a blog post:
Notes on Python variable scope

Blogs
Invent With Python

https://inventwithpython.com
See also its entry in computing.org Exams take place online and are timed (8 hours), and there are no re-takes.

5 6
Lecture 1: Introduction to Python could cause difficulties in this course.
Knowledge ˆ course home at MITOpenCourseWare
Machines ˆ There is only one textbook associated with the course: How to Think Like a Com-
Languages puter Scientist, Learning with Python

Types ˆ Also useful are Python Tutorial and Python IDLE

Variables ˆ Comprehensive and fast-paced (3 weeks) introduction to Python

Operators and Branching ˆ There are no videos, and lectures are in the form of text

Lecture 2: Core Elements of Programs ˆ grading:

Bindings – plus (every problem attempted with effort, commented and tested code),
Strings – check (very little effort on at least one problem),
– minus (no effort on at least half of the problems),
Input/Output
– earn pluses on at least half of the assignments to pass.
IDEs
ˆ Lectures: 4 sessions / week for 3 weeks, 1 hour / session
Control Flow
ˆ Labs: 3 sessions / week for 3 weeks, 2 hours / session
Iteration
Guess and Check
TODO A Gentle Introduction to python
Lecture 3: Simple Programs
DONE 1 Introduction (Homework 1 out)
Approximate Solutions
ˆ State ”DONE” from ”TODO” [2018-02-26 Mon 22:39]
Bisection Search
Textook: Think python: chapters 1 and 2, section 4.12 Notes: Introduction
Floats and Fractals
Newton-Raphson DONE Exercises exercise

Lecture 4: Functions ˆ State ”DONE” from [2018-02-26 Mon 22:39]

Decomposition and Abstraction ˆ DONE Exercise 1.0 - Installing Python


Functions and Scope – State ”DONE” from ”NEXT” [2018-02-26 Mon 21:54]
Keyword Arguments Actually not that easy in my case. See Installing Python2.6 in a Docker.
Specifications ˆ DONE Exercise 1.1 - Hello, world!
Iteration vs Recursion – State ”DONE” from ”NEXT” [2018-02-26 Mon 21:57]
Inductive Reasoning
# crecca
Towers of Hanoi # hello_world.py
Fibonacci # 2018-02-26 Mon

Recursion on non-numerics
Files # prints "Hello, world!" to the screen
print "Hello, world!"
Lecture 5: Tuples and Lists
7 8
Tuples
Lists
ˆ DONE Exercise 1.2 - Printing x = (3*5)/(2+3)
print x
– State ”DONE” from ”NEXT” [2018-02-26 Mon 22:03]
y = ((7+9)**0.5)*2
# Name: crecca print y
# Section: birds
# Date: 2018-02-26 Mon z = (4-7)**3
# hw1.py print z

##### Template for Homework 1, exercises 1.2-1.5 ###### j = (-19+100)**(1/4.0)


print j
print "********** Exercise 1.2 **********"
k = 6 - 4*(6/4)
# Do your work for Exercise 1.2 here print k

print " | | " print "********* Part III *************"


print "--------"
print " | | " p = 4 * (5 + 3)
print "--------" q = (4 * 5) + 3
print " | | "
print p
print q
ˆ DONE Exercise 1.3 - Variables

– State ”DONE” from ”NEXT” [2018-02-26 Mon 22:06] ˆ DONE Exercise 1.5 - User Input

print "********** Exercise 1.3 **********" – State ”DONE” from ”NEXT” [2018-02-26 Mon 22:19]

# Do your work for Excercise 1.3 here. Hint - how many different print "********** Exercise 1.5 **********"
# variables will you need?
name = raw_input(’Enter your first name: ’)
vertical = " | | " last_name = raw_input(’Enter your last name: ’)
horizontal = "--------" print "Enter your date of birth:"
month = raw_input(’Month? ’)
print vertical day = raw_input(’Day? ’)
print horizontal year = raw_input(’Year? ’)
print vertical print name, last_name, "was born on", month, day+’,’, year+’.’
print horizontal
print vertical ˆ DONE Exercise 1.9 - Variable Names

– State ”DONE” from ”NEXT” [2018-02-26 Mon 22:30]


ˆ DONE Exercise 1.4 - Operators/Order of Operation
1. and - illegal, reserved keyword
– State ”DONE” from ”NEXT” [2018-02-26 Mon 22:14] 2. and - legal
3. var - legal
print "********** Exercise 1.4 **********"
print "********* Part II *************" 4. var1 - legal
5. 1var - illegal, variable name cannot start with a digit

9 10
6. my-name - illegal, hypen (-) is not a legal character inside a variable name – State ”DONE” from ”NEXT” [2018-02-28 Wed 20:28]
7. your name - legal Truth table for all possible choices for player 1 and 2, and the outcome of the game:
8. COLOR - legal
Player 1 Player 2 Result
ˆ DONE Exercise 1.10 - Types Rock Rock Tie
Rock Scissors Player 1
– State ”DONE” from ”NEXT” [2018-02-26 Mon 22:33] Rock Paper Player 2
Scissors Rock Player 2
1. a = False - bool
Scissors Scissors Tie
2. b = 3.7 - float Scissors Paper Player 1
3. c = ’Alex’ - str Paper Rock Player 1
Paper Scissors Player 2
4. d = 7 - int
Paper Paper Tie
5. e = ’True’ - str
6. f = 17 - int # Name: crecca
# Section: birds
7. g = ’17’ - str
# Date: 2018-02-28 Wed
8. h = True - bool # rps.py
9. i = ’3.14159’ - str #
# rock-paper-scissors game for 2 players: top play, write rock, scissors, or pape
ˆ DONE Exercise 1.11 - Natural Language Processing
player1 = raw_input("Player 1? ")
– State ”DONE” from ”NEXT” [2018-02-26 Mon 22:38] player2 = raw_input("Player 2? ")
Preprositional phrase attachment ftw!
if player1 == player2: # if both inputs are the same then we have a tie
print "Tie."
DONE 2 Conditionals, Loops elif player1 == "rock" and player2 == "paper" or\
ˆ State ”DONE” from ”TODO” [2018-03-01 Thu 22:49]
player1 == "paper" and player2 == "scissors" or\
player1 == "scissors" and player2 == "rock": # all cases when player 2 wins
Think python: Sections 4.1, 4.2, 4.4-4.7, and 6.1-6.2 print "Player 2 wins."

elif player1 == "rock" and player2 == "scissors" or\


DONE Exercises
player1 == "paper" and player2 == "rock" or\
ˆ State ”DONE” from ”TODO” [2018-03-01 Thu 22:49] player1 == "scissors" and player2 == "paper": # all cases when player 1 wins
print "Player 1 wins."
ˆ DONE Exercise 1.6 - New Operators else: # all valid cases were covered
print "This is not a valid object selection"
– State ”DONE” from ”NEXT” [2018-02-28 Wed 19:09]
ˆ DONE Exercise 1.8 - For & While Loops
a = 6
b = 10 – State ”DONE” from ”NEXT” [2018-02-28 Wed 21:12]
False == (a == b)
# Name: crecca
a = True # Section: birds
b = (5 < 7) # Date: 2018-02-28 Wed
a == b # loops.py

ˆ DONE Exercise 1.7 - Rock, Paper, Scissors ### part 1

11 12
### print out decimal equivalents of 1/2, 1/3, 1/4,...,1/10 – State ”DONE” from ”NEXT” [2018-02-28 Wed 21:50]
print "\npart1 ================\n"
# Name: crecca
for i in range(2,11):
# Section: birds
print 1.0/i
# Date: 2018-02-28 Wed
# zellers.py
### part 2
#
### countdown
# Calculate day of the week on which you were born using Zeller’s algorithm
print "\npart2 ================\n"
name = raw_input(’Enter your first name: ’)
n = input("Countdown from? ")
last_name = raw_input(’Enter your last name: ’)
print "Enter your date of birth:"
# if n is negative, we want to "count-up", that is subtract -1
month = input(’Month? ’)
if n < 0:
day = input(’Day? ’)
mod = -1
year = input(’Year? ’)
else: # if n is positive, we ant to "count-down", that is subtract 1
mod = 1
# January and February are counted as months 11 and 12 of the previous year
zeller_month = ((9 + month) % 12) + 1
# subtract until we reach zero
while (n != 0):
if month <= 2:
print n,
zeller_year = year - 1
n -= mod
else:
zeller_year = year
### part 3
### exponentials
# zeller century is 19 if year is 1989
print "\npart3 ================\n"
zeller_century = zeller_year / 100
# zeller year is 89 if year is 1989
base = input("base of exponentation? ")
zeller_year %= 100
exp = input("exponent of exponentation? ")
print name, last_name, "was born on", month, str(day)+’,’, str(year)+’.’
# result by default is 1, because if loop doesn’t start, it means exponent is 0
print "zeller month:", zeller_month
print "zeller year:", zeller_year
if type(exp) != int:
print "zeller century:", zeller_century
print "We can do exponentation with loops only if exponent is an integer"
else:
# Zeller’s algorithm
result = 1 # if exp == 0, the result will be 1
w = (13*zeller_month - 1) /5
if exp > 0: # exponent is positive
x = zeller_year / 4
start = 0
y = zeller_century / 4
end = exp
z = w + x + y + day + zeller_year - 2*zeller_century
else: # exponent is negative
base = 1.0/base # n to negative power is the same as 1/n to absolute value of that power
# 0 -> Sunday, 1 -> Monday, 2 -> Tuesday, 6 -> Saturday
start = exp # we want to start counting from exp to zero, so we need to "reverse" the range
day_of_the_week = z % 7
end = 0
for i in range(start,end):
if day_of_the_week == 0:
result *= base # multiply base by itself as many times as exponent says
dotw_name = "Sunday"
print result
elif day_of_the_week == 1:
dotw_name = "Monday"
ˆ DONE Exercise OPT.1 - Zeller’s Algorithm elif day_of_the_week == 2:

13 14
dotw_name = "Tuesday" # print result
elif day_of_the_week == 3: print "The encoded phrase is:", encoded_phrase
dotw_name = "Wednesday"
elif day_of_the_week == 4: For a very interesting Python solution to Ceasar cipher, see this blog post on
dotw_name = "Thursday" koderdojo.com.
elif day_of_the_week == 5:
dotw_name = "Friday" ˆ DONE Exercise 1.12 - Boolean operators
else: – State ”DONE” from ”NEXT” [2018-02-28 Wed 19:13]
dotw_name = "Saturday"
1. False
print "You were born on", dotw_name
2. True
3. True
ˆ DONE Exercise OPT.2 - Secret Messages
4. True
– State ”DONE” from ”NEXT” [2018-03-01 Thu 22:49]
ˆ DONE Exercise 1.13 - Conditionals

# Name: crecca – State ”DONE” from ”NEXT” [2018-02-28 Wed 19:27]


# Section: birds
# Date: 2018-02-28 Wed 1. “No way”
# caesar.py 2. “No thanks, I can find something better.”
# 3. “I’ll take it!”
# Encode a message using Caesar cipher
4. “So long, suckers! I’ll take it!”
phrase = raw_input(’Enter sentence to encrypt: ’) 5. “No thanks, I can find something better.”
shift = input(’Enter shift value: ’)
# Name: crecca
# in ASCII standard all letter codes are numerically adjacent and are sorted alphabetically # Section: birds
# capital letter ’A’ has value (65) # Date: 2018-02-28 Web
# lowercase letter ’a’ has value (97) # salary.py
all_letters = 26 # in English alphabet #
# Making decision of whether to take a job based on salary and place of employmen
def func(param);
pay = 40000 # preferrably in range: 40,000 -- 100,000+, in ra
encoded_phrase = ’’ location = "Massachusetts" # alternatively: California, Space

# iterate over each letter in phrase if location == "U.S.S. Enterprise":


for i in phrase: print "So long, suckers! I’ll take it!"
ascii_code = ord(i) elif location == "Massachusetts":
if ord(’A’) <= ascii_code <= ord(’z’): # a letter if pay < 100000:
if ascii_code <= ord(’Z’): # capital letter print "No way"
else:
correction = ord(’A’) # correction to make to ASCII code obtain position of the letter in alphabet
else: # lowercase letter print "I’ll take it!"
correction = ord(’a’) elif location == "California" and pay > 40000:
ascii_code -= correction # position of the letter in alphabet print "I’ll take it!"
ascii_code = (ascii_code + shift) % 26 # cyclic shift elif pay > 60000:
ascii_code += correction print "I’ll take it!"
encoded_phrase += chr(ascii_code) # string together encoded letters else:
print "No thanks, I can find something better."

15 16
ˆ DONE Exercise 1.14 - Understanding Loops iteration n i
1 10 10
– State ”DONE” from ”NEXT” [2018-02-28 Wed 19:35] 2 10 5
3 10 6
4 10 3
1. prints numbers, each on its own line: 10, 9, 8, 7, 6, 5, 4. 5 10 4
2. prints number, each on its own line: 0, 1, 2, 3, 4. 6 10 2
7 10 1
3. prints number, each on its own line: 10, 9, 8, 7. 8 10 2
9 10 1
4. prints lines “Letter # 0 is S”, “Letter # 1 is n”, “Letter # 2 is o”, “Letter #
10 10 2
3 is w”, “Letter # 3 is !”.
11 10 1
12 10 2
ˆ DONE Exercice 1.15 - Buggy loop (aka Find the Bug!) ... .. ..
454 10 1
– State ”DONE” from ”NEXT” [2018-02-28 Wed 19:49] 455 10 2
... .. ..
Buggy code:
NEXT 3 Defining Functions (Homework 1 due, H2 out)ATTACH
n = 10 Think python: Chapter 3, appendix A, sections 6.5-6.9
i = 10 Sections 2.1, 2.2, and 2.3 (up to the heading ”Lists”) from the 6.01 course notes
beginning.
while i > 0: See notes: Functions
print i
if i % 2 == 0:
i = i/2 TODO 4 Strings, lists, list comprehensions
else:
Think python: Chapters 7 and 8
i = i+1
Chapter 2 from ”Lists” on, from the 6.01 course notes
More on list comprehensions is available here and on Wikipedia.
I think that the author just wanted to divide a number by half if it’s even, until
it is reduced to just number 2. If i is odd, either initially or anytime during the TODO (Optional) Recursion (H2 due, Project 1 out)
operation of the loop, it is turned into the next even number, which is i+1. n is
simply useless here and can be omitted. The loop is non-terminating because the TODO 5 Tuples, dictionaries, common Python mistakes (P1 due,
conditional should be i > 1, because 2 is the smallest positive and even integer,
and 2 divided by 2 is 1, which is the case ending the loop.
H3 out)
Think python: Chapters 9 and 10

i = 10
TODO 6 Classes
while i > 1:
Think python: Chapters 12-14 (read chapter 14 well; get through at least section 14.6)
print i
if i % 2 == 0: This tutorial on classes may also be helpful.
i = i/2
else: TODO 7 More about classes (H3 due, H4 out)
i = i+1
Think python: Finish chapters 12-14; read chapter 16

17 18
TODO 8 Inheritance (P2 out) A program is a sequence of instructions that specifies how to perform a computation.
The details of what constitutes computation look different in different languages. It
Wikipedia: Conway’s Game of Life (Project 2)
always comes down to mathematical operations on bits, but programming languages use
clever techniques to disguise those operations as something more useful, like ”show this
TODO 9 Review (P2 and H4 due, P3 out) line of text” or ”play this sound”. We can distinguish few basic instructions that exist
in every language:
Think python: For the final week, make sure you know and understand chapters 12-14
and 16.
1. Input: Get input from the keyboard, a file, or some other device
Chapters 11, 15, 18, 19, and 20 are very interesting, but not covered in this course;
take 6.01, 6.042, and 6.006 to learn more about programming and data structures. 2. Output: Display data on the screen or send data to a file or other device

TODO 10 More review 3. Math: Perform basic mathemacial operations like addition and multiplication

TODO 11 Questions and applications (P3 due) 4. Conditional execution: Check for certain conditions and execute approriate part
of the program
Exercises exercise 5. Repetition: perform some action repeatedly, usually with some variation

Introduction Programs are built out of these five basic blocks, which is possible thanks to the
process of breaking large, complex task into smaller and smaller subtasks.
Book: Think python: chapters 1 and 2, section 4.12 Course: A Gentle Introduction to Now, the term instruction is a little bit ambiguous. It comes from the machine
Python –¿ 1 Introduction (Homework 1 out) instruction term, or instruction set, which is a set of machine instructions a given
Computer scientists use formal languages like mathematicians, design things by as- computer architecture can use, and a machine instruction is a small operation to be
sembling systems and evaluating alternative solutions like engineers, and observe, hy- exucted by a processor, for example copy information from one place of memory to
pothesize, and test their predictions like scientists. another, instruction to execute some other instruction, etc. In high-level languages the
The single most important skill for a computer scientist is problem solving, which concept got somewhat dilluted, and is now more abstract. Now instructions are higher-
is practiced while learning to program. level operations, like “show this message on the screen” or “assign this value to this
Python is a high-level language, like C, C++, Java or Perl. Programs written in variable”. Those instructions translate to often thousands of machine instructions.
high-level languages need to be processed before they run. This extra processing takes Errors in programs are called bugs (for whimsical reasons), and the process of tracking
some time, and might add to software stack complexity, but in turn writing programs them down is called debugging. There are three kinds of errors: syntax errors, runtime
is faster and easier, and are more likely to be correct. They can be portable, meaning errors, and semantic errors.
that programs written in them can run on variety of types of machines, no matter the
underlying hardware. For these reasons only very few specialized programs are still
1. Syntax errors: Python can execute a program only if its syntactically correct.
written using low-level languages.
Syntax refers to the structure of a program and the rules about that structure.
Two kinds of programs turn high-level languages into low-level languages (a necessary
process before they can be run): interpreters and compilers. Interpreter processes the 2. Runtime errors/exceptions: error does not appear until you run the program.
program a little at a time and executes processed parts immediately. Compiler translates Rare in the simple programs.
the program completely, and execution is possible after it finishes its job.
Python is said to be an interpreted language, because Python programs are exe- 3. Semantic errors: program executes successfuly, but does not do the right thing.
cuted by the interpreter.
There are two ways to use interpreter: command-line mode and script mode. Semantics is the meaning of the program or its results.
In the first mode, you type commands in a given language syntax, and the results are Formal languages are languages designed for specific applications. Programming
presented immediately (the interpreter interprets the command and gives back its result languages are formal languages that express computations. Formal languages tend to
if it has one). When you write a program into a file you can use interpreter to execute have strict syntax rules. Those come in two flavors:
the contents of the file, which is the script mode.
Python files by convention end with .py extension. To execute the program simply 1. Rules about tokens: basic elements of the language, such as words, numbers, and
run python latoya.py. To use command-line mode, execute python, and a prompt chemical elements
(>>>) will appear waiting for input. Alernatively you can use some IDE (Integrated
Development Environment), for example IDLE. 2. Rules about structure: the way that tokens are arranged.

19 20
For example, sentence thidf is andsw. This ntence has good struue, but wrong tokens. print message # --> What’s up, Doc?
And strucutre this not sentence bad. (The three English sentences before have in turn: print n # --> 17
bad tokens and bad structure, bad tokens, and the last: bad structure.) When you read print pi # --> 3.14159
a sentence you have to figure out what the structure of the sentence is. This process is
called parsing. For example when hearing sentence “The other shoe fell,” you identify Variables also have types.
“the other shoe” as the subject, and “fell” as the predicate.
So, formal languages have tokens, structure, syntax, and semantics. type(message) # --> <type ’str’>
It takes much effort to read programs. Structure is important, so it makes little type(n) # --> <type ’int’>
sense to read them top-to-bottom like prose. Instead parse the program in your head, type(pi) # --> <type ’float’>
identifying the tokens and interpreting the structure. Details matter.
We’ll now move on to writing our first program. Hello World program in Python is Variable names are usually chosen to be meaningful - describe what they represent.
as simple as it gets. Variable names can have any length, and contain letters, numbers and an underscore ( ),
as long as they don’t start with a number. Convention is to use lowercase letters, but
print "Hello, World!" you can use uppercase, just remember that case matters: Bruce and bruce are different
variables. There is also another rule: variable name cannot be one of the reserved Python
A print statement is an instruction that causes the Python interpreter to display a keywords. Keywords define the language’s rules and structure, and they cannot be used
value on the screen - in this case a text saying Hello, World!. as variable names. Python has 29 keywords.
Value is one of the fundamental things that a program manipulates. This can be a
number, a letter, or a string of letters. The different kinds of values are types. Types and def exec if not return
are useful to determine how a given value might be used in an expression (we’ll get to assert del finally import or try
them later). You can find out what type a value is by writing type(’value’). break elif for in pass while
class else from is print yield
print 4 # --> 4
continue except global lambda raise
type(’hello’) # --> <type ’str’>
type(17) # --> <type ’int’>
So far we’ve learned about the print statement and assignment statement. But what
are statements? In Python a statement is an instruction that the Python interpreter
A text ’hello’ has a type str, which is a short for string. It is so-called because it
can execute. It represents a command or action. After a statement is executed on the
contains letters that are “strung” together. Strings are identified as such by interpreter
command line, you see its result printed on the screen, if there is one. The result of a
thanks to quotation marks that enclose them. The value 17 is type int, which is a
print statement is a value. Assignments don’t produce results.
short for integer. Integer is a type that generally speaking encompasses whole numbers.
A script usually contains more than one statement, and so the results appear one at
Numbers with decimal point are a type called float, because they are represented in
a time as the statements execute.
memory in a floating-point format.
Programming languages can manipulate variables, that is names that refer to a value. An expression is a combination of values, variables, and operators. (In reality, there
You create variables using the assignment statement. are more elements that can be a part of an expression, but these are the most used ones.)
If you type an expression on the command line, the interpreter evaluates it and displays
message = "What’s up, Doc?" the result. Thus, an expression must represent a single result value.
n = 17
pi = 3.14159 1 + 1 # --> 2
17 # --> 17
This example creates three new variables and gives them values. First variable is called pi # --> 3.14159
message and has value of string "What’s up, Doc?", the second assigns the integer 17
to the name n, and in similar fashion variable pi gets value 3.14159. Not every expression contains all of these elemenets. A value all by itself is considered
A common way to represent variables on paper is to write the name with an arrow an expression, and so is a variable, as you can see above. (An operator by itself does not;
pointing to the variable’s value. Writing down such diagrams is a common programming we’ll get to them soon.) However, evaluating an expression is not quite the same thing
technique which can help developing and debugging programs. This particular diagram as printing a value.
is called state diagram, because it shows what state each of the variables are in. This
kind of information is often useful to know. message = ’Hello, World!’
Now we can combine the print statement with variables to “print” to the screen message # --> ’Hello, World!’
current values of the variables. print message # --> Hello, World!

21 22
When displaying a value of an expression, Python uses the same format you would use The analogy to mathemathical operation is somewhat strong, as for example 2*’Fun’
to enter it. In case of strings it includes the quotation marks. But with print statement, is the same as ’Fun’+’Fun’, but on the other hand order of operands matters for strings,
contents of the string are displayed sans the quotes. and string operations don’t have distributive property.
Another difference is that expression evaluation does not display a result when used
in a script (although it is a legal statement, i.e. it is syntactically correct). In only does fun = ’fun’
so on the command line as a matter of convenience. fruit + fun # --> BananaFun
Operators are special symbols that represent computations like addition and multi- fun + fruit # --> FunBanana
plication. The values the operator uses for its computation are called operands. Rules 2*(fun + fruit) # --> FunBananaFunBanana
for how the computation is carried out, what kind of operands an operator operates on, 2*fun+2*fruit # --> FunFunBananaBanana
how many of them is needed or can be used, and what is the proper syntax to use the
operator, ultimately depends on the operator itself, however most of the basic operands So far we got to know some of the most important elements of a program - variables,
follow the same, similar, or well-known rules. expressions, and statements. We did so in isolation. But turns out, we can combine
them. This is one of the most powerful features of programming languages: their ability
20+32 # addition to take small building blocks and compose them.
hour-1 # subtraction Composition is the ability to combine simple expressions and statements into com-
hour*60+minute # multiplication and addition, standard rules of precedence applypund statements and expressions in order to represent complex computations concisely.
minute/60 # division For example, we can use the print statement and combine it with an expression to
5**2 # exponentation return the result of that expression. Command line inteface of the interpreter actually
(5+9)*(15-7) # multiplication of parenthesized expressions does that for us, but it is how it’s done under the hood, and that is how you can display
results in a script file.
When a variable name appears in the place of an operand, it is replaced with its value
before the operation is performed. print 17 + 3 # --> 20
Addition, subtraction, multiplication, exponentiation, rules of precendence, and paren-
You can also put arbitrary expressions on the right-hand side of an assignment state-
theses (not an operator, but one of those “additional” elements of an expression) behave
ment.
as you would expect, but you might be surprised by the divsion.
percentage = (minute * 100) / 60
minute = 59
minute/60 # --> 0 Be wary, however, since there are some limits on where you can use certain expressions.
For example, the left-hand side of an assignment statement has to be a variable name,
59 divided by 60 should be 0.98333, not 0. The reason for this discrepancy is that not an expression. So minute+1 = hour is illegal.
Python is performing integer division here. When both operands are integer the result Last but not least, another element of a program are comments. They help in
also must be an integer, and by conention, integer division always rounds down. A reading and understanding what the program does. Comments are little (or not so little)
possible solution is to calculate a percentage. notes you leave behind for future reference.
minute*100/60 # --> 98 # compute the percentage of the hour that has elapsed
percentage = (minute * 100) / 60 # caution: integer division
With the most recent Python (3.5), division operator performs “true” division, and
the result can be a floating-point number. In both versions of Python you can use // In later section we’re going to need programs that accept keyboard input from the
(double slash) operator to perform integer division. user. This feature is very useful when writing programs as script files: user then has no
PEMDAS acronym is useful For remembering mathematical precedence rules which access to interactive command-line. The fundamental way to get keyboard input is to use
apply to Python as well. raw input function (I know, we didn’t learn about functions yet, but we will soon). This
In general you cannot perform mathematical operations on strings, however there is a function after execution causes the program to stop exeucting, and waits for input from
+ operator for string which performs concatenation (joining the two operands by linking the user. Once the user types in its input and presses enter, program is resumed. The
them end-to-end). There is also * operator which performs repetetition. input can be stored in a variable when we combine raw input with assignment statement.

fruit = ’banana’ input = raw_input ()


bakedGood = ’ nut bread’ # <-- What are you waiting for?
print fruit + bakedGood # --> banana nut bread print input # --> What are you waiting for?
print ’Fun’*3 # FunFunFun input = raw_input (’What is your name? ’) # this causes the string

23 24
# "What is your name?" to be 5 == 5 # --> True
# displayed as the prompt 5 == 6 # --> False
# for the input
# --> What is your name? <-- Arthur, King of the Britons! == operator is one of the comparison operators. Below is the whole list.
print input # --> Arthur, King of the Britons! x != y # x is not equal to y
This is useful for strings, but what if we want to get a number from the user? We can x > y # x is greater than y
use input function for that. x < y # x is less than y
x >= y # x is greater than or equal to y
prompt = "What...is the airspeed velocity of an unladen swallow?\n" x <= y # x is less than or equal to y
# "\n" represents a newline, so the user input to appear below the prompt x == y # x is equal to y
speed = input(prompt)
# --> What...is the airspeed velocity of an unladen swallow? There is no such thing as => or =<, and remember that a single equal sign (=) is an
# <-- 90 assignment operator, and == is a comparison operator.
print speed # --> 90 There are three logical operators: and, or, and not. The semantics are similar to
semantic of those words in English. For example n%2 == 0 or n%3 == 0 is true if either
However when you provide a string instead, Python will complain about syntax error n is divisible by 2 or 3.
(because it expects a number, not a string). Strictly speaking operands of logical operators should be boolean expressions, but
Python is not very strict. Any nonzero number is interpreted as True.
speed = input(prompt)
# --> What...is the airspeed velocity of an unladen swallow? x = 5
# <-- What do you mean, an African or a European swallow? x and 1 # --> 1
# --> SyntaxError: invalid syntax y = 0
See rawinputexample.py for more examples. This script introduces one new concept we’ve y and 1 # --> 0
not seen yet: “gluing” together values in a print statement, by providing several values In general this is not kosher. Better explicitly compare a value to zero if you need it.
separated by commas to it. Note that it is different from concatenating strings using + Almost always in useful programs we make use of conditional statements, which
operator, in that it does not require providing separating spaces by hand: it does this check conditions and change the behavior of the program accordingly. Simplest form is
automatically for us. the if statement.
The example script also uses an int function, which in this example converts a
floating-point result of an expression age - (0.15*age) into an integer. if x > 0:
print "x is positive"

Conditionals and Loops The boolean expression after the if statement is called the condition. If it evaluates
to true, then the indented statemenet gets executed, and otherwise nothing happens.
Think python: Sections 4.1, 4.2-4.7, and 6.1-6.2 Course: A Gentle Introduction to Python Like other compound statements, if statement is made up of a header and a
–¿ 2 Conditionals, Loops block of statements:
Modulus operator works on integers (and integer expressions) and yields the remain-
HEADER:
der when the first operand is divided by the second. The modulus operator is a percent
FIRST STATEMENT
sign (%). The syntax is the same as for other mathematical operators:
LAST STATEMENT
quotient = 7 / 3
The header begins on a new line and ends with a colon (:). The statements are
print quotient # --> 2
indented, and are called a block. The first unindented statement marks the end of the
remainder = 7 % 3
block. A statement block inside a compound statement is called the statement body.
print remainder # --> 1
It has to have at least one statement. Sometimes it would be useful to have empty
Modulus operator is surprisingly useful. You can check if one number is divisible by statement body, but in such situations you have to use the pass statement, which does
another, or extract the right-most digit or digits from a number (for example x % 100 nothing.
will yield the last two digits). A second form of the if statement is alternative execution, in which there are two
Boolean expression is either true or false. An example boolean expression uses the ways that the program can go: either conditional statement is true, in which case the
operator ==, which compares two values and produces a boolean value: either True, if first statement block is executed, or it is false, in which case the second statement block
both operands are equal, or False if they are not. is executed.

25 26
if x%2 == 0: You can trace the logic of those two conditionals and see that their outcome is the
print x, "is even" same, since the first print is executed only if we make past the two conditionals, so they
else: both need to evaluate to True. In fact, these kind of operations are so common, that
print x, "is odd" Python provides an alternative syntax that is similar to mathematical notation a < b <
c.
If the remainder when x is divided by 2 is 0, then we know that x is even, and
the program displays a message to that effect. If the condition is false, the second set of if 0 < x < 10:
statements is executed. Exactly one of the alternatives will be executed. The alternatives print "x is a positive single digit."
are called branches, because they are branches in the flow of execution.
Sometimes you want more than two possibilities, in which case you can use chained Here is an example of how you can use more complex logic in your conditions.
conditional.
if not (10 == 4) and 9 > 5:
if x < y: print "Yay, basic math competency achieved!"
print x, "is less than", y else:
elif x > y: print ":("
print x, "is greater than", y
else: And now for something completely different. At this point it is useful to look at the
print x, "and", y, "are equal" case multiple assignment more closely. You know already that it is possible to make
more than one assignment to the same variable. A new assignment simply makes an
existing variable refer to a new value (and stop referring the old one).
elif is an abbrevation of “else if.” There is no limit of how many branches you can
create, but the last branch must be an else statement. Each condition is checked in
bruce = 5
order. If the first is false, the next is checked, and so on. If one of them is true, the
print bruce,
corresponding branch executes, and the statement ends. Only the first true condition
bruce = 7
triggers execution of its branch.
print bruce # --> 5 7
Finally, conditionals can also be nested.
Here we used a trick to make both print statements to use the same line, by appending
if x == y: a comma to the first print statement, which suppressed the newline after the output.
print x, "and", y, "are equal" With multiple assignment it is especially important to distinguish assignment from
else: equality, which are not the same things. A statement a = b does not mean that a is equal
if x < y: to b. First difference: equality is commutative and assignment is not. Second difference:
print x, "is less than", y equality is always true.
else:
print x, "is greater than", y a = 5
b = a # a and b are now equal
The outer conditional contains two branches. The first branch is a simple output a = 3 # a and b are no longer equal, since b is still 5
instruction, but the second branch contains another conditional, which has two branches
of its own. Those could have conditional statements as well. It is good idea to avoid Although multiple assignment is often helpful, you should use it with caution. If
nested conditionals if you can, since they can be hard to read. variable’s value changes often, it can make reading the code difficult.
Logical operators are useful tools in simplifying nested conditionals. There is one more thing. We didn’t talk about loops! Loops are there to automate
repetitive tasks. They repeat identical or similar tasks. Such repetition is also called
# instead of iteration. Python provides several language features to make iteration easy, and one of
if 0 < x: the main ones is the while statement.
if x < 10:
print "x is a positive single digit." n = 10
while n > 0:
# we can write print n
if 0 < x and x < 10: n = n-1
print "x is a positive single digit." print "Blastoff!"

27 28
Above code is a countdown program, which displays digits starting from 10 and ending betty = type("32")
with 1, and then displays “Blastoff!” The flow of execution of the while statement: print betty
# --> <type ’str’>
1. Evaluate the condition, yielding 0 or 1.
As another example, the id function takes a value or a variable and returns an integer
2. If the condition is false (0), exit the while statement and continue execution at the
that acts as a unique identifier for the value.
next statement.

3. If condition is true (1), execute each of the statements in the body and then go id(3)
back to step 1. # --> 134882108
betty = 3
The body consists of all of the statements below the header with the same indentation. id(betty)
This type of flow is called loop because the third step of the flow loops back around # --> 134882108
to the top. Notice a certain characteristic of the while loop: if the condition is false the
first time through the loop, the statements inside the loop are never executed. Every value has an id, which is an unique number related to where it is stored in the
Of course, the body of the loop should change the value of one or more variables memory of the computer. The id of a variable is id of the value which it stores.
so that eventually the condition becomes false. Otherwise the loop will repeat forever, We’ve already learned about the int function, which does type conversion: it takes
which is called an infinite loop. any type of value, and tries to converts it into integer, if it is possible, or complains
In case of countdown, we can proove that the loop terminates, because we know that otherwise.
the value of n is finite, and we can see that the value of n gets smaller and smaller, in
steps by 1, so eventually we have to get to 0. But it is not always so easy to tell. int("32")
Consider the following. # --> 32
int("Hello")
n = 3 # can be any value...
# --> ValueError: invalid literal for int(): Hello
while n != 1:
print n,
If you give int a float, it will return an integer by truncating the floating part. float
if n%2 == 0: # n is even
function converts types to float, and str – to strings.
n = n/2
else: # n is odd It may seem odd that Python distinguishes 1 (integer) from 1.0 (float), but this is
n = n*3+1 because they are represented differently inside the memory.
This type conversion allows as to force floating point division of two integer types.
Since n sometimes increase and sometimes descreases, there is no obvious proof that
n will ever reach 1, which is required to terminate the loop. For some particular values minute = 59
of n we can prove termination (for example, if the starting value is a power of two, then float(minute) / 60
it will always decrease through the loop). Can we prove that this program terminates for
all positive values of n? So far, no one has been able to prove it or disprove it! But we can also use type coercion, that is make use of the automatic type conversion
which happens here when any of the operands are floating point.

Functions minute = 59
minute / 60.0
Think python: Chapter 3, sections 6.5-6.9 Course: A Gentle Introduction to Python –¿
3 Defining Functions
We have already seen several function calls: int(age - (0.15*age)), input(prompt), Python functions can be composed the same way as expressions and other statements.
raw input (’What is your name? ’), type(pi), type(message) and others. For example, you can use any expression as an argument to a function.
In a function call type("32"), the function name is type, and the result of this
function is the type of a value or a variable. In general, the value or variable is called the x = math.cos(angle + math.pl/2)
argument of the function, and the result is called return value. The argument must
be enclosed in parentheses. It is common to say that function ”takes” an argument and You can also take the result of one function and pass it as an argument to another.
”returns” a result. Instead of printing the resulted value we could store it in a variable
using assignment statement. x = math.exp(math.log(10.0))

29 30
So far we’ve worked with functions that come with Python, but we can also add our Function calls are like a detour in the flow of execution. Instead of going to the
own functions. Creating new functions to solve problems is one of the most useful things next statement, the flow jumps to the first line of the called function, executes all the
about a general-purpose programming language. statements there, and then comes back to pick up where it left off. When there is a
In programming, a function is a named sequence of statements that performs a function call as part of function’s definition (three new lines()), when executing such
desired operation. This operation is specified in a function definition. So far functions call, Python needs to remember to pick up where it left off in the function that called it.
have been defined for us, and their definitions are hidden from our view (however we can When reading code, follow the flow of execution.
always find them by looking into Python libraries source code). This is good, since we Some functions take an argument, and some take more than one. For example, pow
can use the functions without worrying about the details of their definitions. The syntax takes two arguments, the base and the exponent. Inside the function, the values that are
for a function definition makes use of a def keyword, and is a compound statement. passed get assigned to variables called parameters.

def NAME( LIST OF PARAMETERS ): def print_twice(bruce):


STATEMENTS print bruce, bruce

As with variables, you can use any name for NAME, except for reserved keywords. The This function takes a single argument, and assigns it to a parameter named bruce.
list of parameters specifies what information, if any, you have to provide in order to use The value of the parameter (whatever it is) gets printed twice, and on its own line. This
the new function. A function can be defined without parameters. works for any type that can be printed.

def new_line(): print_twice(’Spam’)


print Spam Spam

The purpose of the above function is to print a new line. The empty parentheses Same rules of composition that apply to built-in functions also apply to user-defined
indicate that it has no parameters. The syntax for calling the new function is the same functions, so we can use any kind of expression as an argument for print twice(). As
as the syntax for built-in functions. usual, the expression is evaluated before the function is run, so print twice(’Spam’*4)
first evaluates ’Spam’*4 to ’SpamSpamSpamSpam’, and then prints it twice. We can also
print "First Line." use a variable as an argument.
new_line()
michael = ’Eric, the half a bee.’
print "Second Line."
print_twice(michael)
The output is: # --> Eric, the half a bee. Eric, the half a bee.

First line. Note that the name of the variable we pass as an argument has nothing to do with
the name of the parameter (bruce). The value of variable michael is passed to variable
Second line. bruce, which is a parameter of the function print twice. We call this argument pass-
ing. (The exact details of how this realized under-the-hood might be different, however.)
If we wanted to have even more space between the line we could call new line() When you create a local variable inside a function, it only exists inside the function,
three times, or define a new function, three new lines(), which would contain three and you cannot use it outside.
calls to new line() as its definition. The main takeway from this simple exercise is that
def cat_twice(part1, part2):
you can call the same procedure repeatedly, and that you can have a function that calls
cat = part1 + part2
another function. But there are also other advantages. Creating a new function gives an
print_twice(cat)
opportunity to give a name to a group of statements. This way you can hide complex
computation behind a simple word or a phrase. Functions can also make your program This function takes two arguments, concatenates them, and then prints the result
smaller, thanks to code ”reuse”. For example, you could call three new lines() three twice. When cat twice terminates, the variable cat is destroyed. If we try to print it,
times as a function nine new lines()! we get an error.
To know if a function is defined before its first use, you must first know about flow of
execution. Execution always begins at the first statement of the program. Statements chant1 = "Pie Jesu domine, "
are then executed in order from top to bottom, one at a time. Function definitions do chant2 = "Dona eis requiem."
not alter the flow of execution of the program, and statements inside the function are cat_twice(chant1, chant2)
not executed until that function is called. (You can define a function inside a function
definition, which is rarely needed. In such cases, the inner definition is not executed until print cat
the function is called.) # --> NameError: cat

31 32
Parameters are also local: you can’t use part1 and part2 outside of cat twice. 2. dividing a long program into functions allows you to separate parts of the program,
After learning a state diagram, it’s time to learn a stack diagram. Like them, they debug them in isolation, and then compose them into a whole,
show the value of each variable, but they also show the function to which each variable
belongs. Each function is represented by a frame. A frame is a box with the name of a 3. functions facilitate both recursion and iteration,
function beside it and the parmeters and variables of the function inside it. 4. well-designed function can often be used and reused in different programs
A stack diagram for the previous example looks like this:
chant1 –¿ ”Pie Jesu domine,” chant2 –¿ ”Dona eis requiem.” As an example of useful encapsulation, consider the last block of code from the Con-
part1 –¿ ”Pie Jesu domine,” part2 –¿ ”Dona eis requiem.” cat –¿ ”Pie Jesu domine, ditionals and Loops section from before:
Dona eis requiem.”
bruce –¿ ”Pie Jesu domine, Dona eis requiem.” n = 3 # can be any value...
The order of the stack shows the flow of execution. print twice was called by while n != 1:
cat twice, and cat twice was called by main , which is a special name for the topmost print n,
function. When you create a variable outside of any function, it belongs to main . if n%2 == 0: # n is even
Notice that each parameter refers to the same value as its corresponding argument. n = n/2
So, part1 has the same value as chant1, part2 has the same value as chant2, and bruce else: # n is odd
has the same value as cat. If an error occurs during a function call, Python prints the n = n*3+1
name of the function, and the name of the function that called it, and the name of the
function that called that, all the way back to main . For example if we try to access # wrapped in a function:
cat from within print twice we get a NameError:
def print_parity(x):
def print_twice(bruce): while x != 1:
cat = bruce print n,
print bruce, bruce if x%2 == 0: # n is even
x = x/2
cat_twice(chant1, chant2) else: # n is odd
# --> x = x*3+1
# Traceback (most recent call last):
# File "/usr/bin/test.py", line 10, in <module> Generalization means taking something specific, such as printing the multiples of
# cat_twice(chant1, chant2) 2, and making it more general, such as printing the multiples of any integer.
# File "/usr/bin/test.py", line 6, in cat_twice
# print_twice(cat) i = 1
# File "/usr/bin/test.py", line 2, in print_twice while i <= 6:
# print cat, cat print 2*i, ’ ’,
# NameError: global name ’cat’ is not defined i = i + 1
print
This list of functions is called a traceback. Note the similarity with the stack dia-
gram. # generalize printing of multiples of 2, with a function printing multiples of n (any
So far we silently ignored the fact, that some built-in functions return results, while def print_multiples(n):
we only wrote functions that do not. But lets consider those two types of functions first: i = 1
what are the consequences of such behavior? I.e. what happens if you call a function while i <= 6:
and you don’t do anything with the result? And what happens if you a function without print n*i, ’\t’,
a result as part of an expression, such as newline() + 7? Good way for resolving such i = i + 1
burning issues is to test them with the interpreter. print
Functions are so useful because they allow for code encapsulation, which is the
process of wrapping a piece of code in a function, which is essentially giving a name to a To encapsulate we had to add the first line, which declares the name of the function
sequence of statements, allowing to take advantage of ”all the things functions are good and the parameter list. to generalize, we had to replace the value 2 with the parameter
for”. And functions are good for a number of things: n.
Now we can write a program that prints a multiplication table. And we can encap-
1. makes your program easier to read and debug, sulate further. . .

33 34
i = 1 i = 1
while i <= 6: while i <= high:
print_multiples(i) print n*i, ’\t’,
i = i + 1 i = i + 1
print
def print_mult_table():
i = 1 def print_mult_table(high):
while i <= 6: i = 1
print_multiples(i) while i <= high:
i = i + 1 print_multiples(i, high)
i = i + 1
The process demonstrated above is a common development plan. We develop code
by writing lines of code outside any function, or typing them in to the interpreter. When When you generalize a function appropriately, you often end up with a program with
we get the code working, we extract it and wrap it up in a function. This process is useful capabilities you didn’t plan or specifically tried to implement. For example notice that
if you don’t know how to divide the program into functions before you start writing it. the resulting multiplication table ”doubles” each multiplication result, since ab = ba.
This approach lets you deesign as you go along. You could save ink by printing an appropriate half of the table, and this can be done
One more thing. The i variable in the code above is used twice, with two different by simple modification of the function headercall: print multiplies(i,i) instead of
meanings. It has one meaning for print mult table, and another for print multiples. print multiples(i, high).
This is possible thanks to local variables. Remember, variables created inside a function As you start writing bigger programs, you might want to keep function definitions in
definition are local; you can’t access a local variable from outside its ”home” function. a separate file. Such files are called modules. After you save a file you can then import
That means you are free to have multiple variables with the same name as long as they it with the import statement. For example we could save the functions print multiples
are not in the same function. You can use a stack diagram to trace how it works exactly. and print mult table in file multtable.py, and then in another program, or on Python
i –¿ 1 i –¿ 2 i –¿ 3 shell, we could do import multtable to make those functions available for us to use.
i –¿ 1 i –¿ 2 n –¿ 3 We have not yet written a function which would return a result, but we already know
The value of i inside prtint mult table() goes from 1 to 6: at this point in the how such functions are used. To define a function with a return value, we need to use a
loop it is 3, and next time throug the while loop it will be 4. Each time through the return statement.
loop it calls print multiples(n) with the current value of i as argument n. Inside
def f(x):
print multiples(n) the value of i goes from 1 to 6, so during the first loop it is 1.
return x + 1
It is perfectly legal and very common to use variables with same names in different
functions. Variables named i and j are frequently used as loop variables. If you avoid
f(2)
using variable names just because you used them somewhere else, you might make your
# --> 3
code harder too read.
To present one more example of generalization, we can rewrite print mult table()
4 + f(2)
function to print a multiplication table of any size, not just six-by-six. We can do this
# --> 7
by including a parameter for specifying the table size.

def print_mult_table(high): f(f(f(4)))


i = 1 # --> 7
while i <= high: The above function takes one numeric argument, and returns that number plus one.
print_multiples(i) An example use of such a function is in an expression (here adding the returned value of
i = i + 1 the function to the number 4), and as an argument to another function (here “feeding”
the function to itself, incrementing the number 4 three times to obtain final result 7). We
As you can see, this was a matter of replacing the 6 in while loop with the parameter
can also evaluate this and other functions by itself, without specifying the parameters.
high. Notice that we also needed to change the first line of the function definition
Then Python interpreter will tell us that it is a function.
to include the new parameter. This time the function will iterate as many times as
it is specified by the function argument. We can go further and similarly modify the f
print multiples() function. # --> <function f at 0x82570>

def print_multiples(n, high): Lets try those examples with a function which doesn’t use the return statement.

35 36
# this is a perfectly valid function without a return statement
def g(x): # but...
x + 1
print(f1(3))
# however it won’t do anything useful, as the value x + 1 is discarded # --> 4
# after the function does its job # --> None
print(f2(3))
# thus, after evaluating it, nothing happens # --> 4
g(4)
Here we can see that the function f1 does return a value, but it is not 4 - it’s None.
# what if we use it in expression? However the number 4 is printed on the screen, because that is what the print x + 1
g(g(4)) does inside the function definition. Using print with f2 will only print the value that is
# --> Traceback (most recent call last): returned by the function. In first case the print is caused by function evaluation, while in
# --> File "<stdin>", line 1, in ? the second function returns 4, and that value is printed by the Python shell. The most
# --> File "<stdin>", line 2, in g obvious difference is using the function in the expression. The value that is printed by
# --> TypeError: unsupported operand type(s) for +: ’NoneType’ and ’int’ function f1 does not end up being part of the expression which makes the call to f1.

The expression produces an error and displays a traceback of its function calls. First f1(3) + 1
was the inner g(4) evaluated, which returned. . . nothing. Or more precisely, a special # --> 4
value called None, which has a special type NoneType. This value is special, and is used # --> Traceback (most recent call last):
for exactly this occasion: this is a ”default” value that is returned by all functions without # --> File "<stdin>", line 1, in ?
the return statement. This is the passed to the outer call to g, and the value None is # --> TypeError: unsupported operand type(s) for +: ’NoneType’ and ’int’
passed as the function’s x parameter. This type cannot be used with the + operator, and f2(3) + 1
the Python interpreter complains. # --> 5
These runtime errors are typical for weakly typed languages like Python. Weakly
typed means that coherence between types of variables and their actual values is not
checked by a type checker during the compilation, and so errors resulting from assign- Debugging
ments of incorrect types to variables are only caught when program runs. This has the
benefit of having much more terse programs: in strongly typed languages you have Think python: appendix A Course: A Gentle Introduction to Python –¿ 3 Defining
to make variable declarations for each variable, which specify the intention of using Functions
a particular value type. This makes it easier to catch errors, but also is less flexible. We briefly mentioned what types of errors Python can produce, namely syntax, run-
For example in Python, you can easily create an array (we will talk about them later) time, and semantic errors. Lets describe them more precisely:
with values of different types, while in Java, a strongly typed language, it is much more
1. Syntax errors are produced by Python when it is translating the source code into
convoluted. In Python you can also assign values of different types to the same variable
byte code. They usually indicate that there is something wrong with the syntax
at different points in the program.
of the program, like missing colon at the end of a def statement (an error simply
Lets also make sure we understand the difference between the print and return
described as ”invalid syntax”.
statement. After all, they can be both used to produce seemingly the same effect.
2. Runtime errors happen if something goes wrong while the program is running.
def f1(x):
Most runtime error messages include information about where the error occured
print x + 1
and what functions were executing. For example, an infinite recursion causes a
runtime error of ”maximum recursion depth exeeded.”
def f2(x):
return x + 1 3. Semantic errors are problem with a program that doesn’t do the right thing, but
has no runtime or syntax errors. For example, an expression may not be evaluated
f1(3) in the order you expect, yielding an unexpected result.
# --> 4
The first step of debugging is figuring out which kind of error you’re dealing with.
f2(3) Syntax errors are usually easy to fix, once you know what they are. Unfortunately,
# --> 4 because of their very nature, the error messages are often not helpful: either invalid

37 38
syntax of invalid token. Luckily, it usually is specified where the error occured (some- while x > 0 and y < 0:
times the actual error is to be found just before that location). If you’re building the # do something to x
program incrementally, it will be easier to find syntax error – it will be somewhere in the # do something to y
code you’ve recently written. Here is some bullet-list for dealing with syntax errors:
1. Make sure you are not using a Python keyword for a variable name print "x: ", x
print "y: ", y
2. Check that you have a colon at the end of the header of every compound statement print "condition: ", (x > 0 and y < 0)
3. Check that indentation is consistent. Use either spaces or tabs. Each level should
be nested the same amount. If you’re unsure about the flow of execution, add print "entering function
<foo>" at the beginning of every function, to trace each function as it is invoked.
4. Make sure that strings have matching quotes.
3. Exception during program execution – error message includes the name of the
5. Terminate multiline strings properly (unterminated string may cause invalid token exception, the location of the error, and a traceback, which also identifies line
error at the end of your program, or it may treat the following part as a string until numbers of each called function. Start debugging from the point where the error
it comes to the next string, in which case it might not produce an error message). occured. These are the most common runtime errors:
6. An unclosed bracket makes Python continue with the next line as part of the current (a) NameError: you’re trying to use a variable that doesn’t exist in the current
statement. Generally, an error occurs almost immediately in the next line. environment (i.e. it is not local to the current function).
7. Check for = instead of == inside a conditional (b) TypeError: you’re trying to use a value improperly (indexing a string, list,
or tuple with something other than integer, etc.), there is a mismatch between
8. If program still can’t run, make sure that you and the compile are looking at the
the items in a format string and the items passed for conversion (also if the
same code. Check your environment to make sure the program you’re editing is the
number of items does not match), or you’re passing the wrong number of
same you’re trying to run. If you’re not sure, try putting an obvious and deliberate
arguments to a function or method (for methods, check if the first parameter
syntax error at the begginbeginning of the program. Now run the program, and if
is self, and make sure that you’re invoking the method on an object with the
the compiler doesn’t find the new error, then there is something wrong. One thing
right type, and providing the other arguments correctly).
you can do in such situations is to start agaain with a new program like ”Hello,
World!”, and make sure you can get a known program to run. Then gradually add (c) KeyError: trying to access an element of a dictionary using a key value that
the pieces of the new program to the working one. the dictionary does not contain.
Once your program is syntactically correct Python can start running it. But there (d) AttributeError: trying to access an attribute or method that does not exist.
can be runtime errors. (e) IndexError: index you’re using is greater than a given list, string, or a tuple
1. Program does nothing, while it should do something – make sure that the pro- length, minus one. Immediately before the site of the error, add a print
gram actually invokes something to start execution (i.e. it doesn’t consist only of statement to display the value of the index and the length of the array. Is the
functions and classes definitions). array the right size? Is the index the right value?

2. Program ”hangs” – program is caught in an infinite loop or an infinite recursion. 4. After a while – too many print statements used for debugging! In such cases,
If there is a particular suspect loop, surround it with print statements, saying simplify the output or simplify the program. Remove or comment out print state-
something like ”entering the loop” and ”leaving the loop”. ments that aren’t helping, or combine them, or format the output so it is easier to
Infinite recursion will usually cause ”Maximum recursion depth exceeded” error, understand. Scale down the problem that the program tries to solve (for example
but not always. In case of such error, make sure that there is a base case. In if you’re sorting an array – sort a small array). Clean up the program. Remove
other words, there should be condition that causes the recursive function to finish dead code and reorganize the program to make it as easy to read as possible. For
without making a recursive invocation. I there is no base case, you need to rethink example, if error is in a deeply nested part, reorganize the program so that it has
the algoirthm and identify a base case. If there is a base case, program might not be simpler structure. If you suspect a large function, split it into smaller functions.
able to reach it. Add a print statement at the beginning of the function that prints Often the process of finding the minimal test case leads you to the bug.
the parameters. When you run, you can see the parameters not moving toward the Semantic errors are the hardest to debug, because neither compiler, nor the runtime
base case, and you might get some ideas about why not. system can provide information about what is wrong. Only you know what the program
If you have an infinite loop, you can use print at the end of suspect loop to see is supposed to do, and that it isn’t doing it.
values of the variables in the condition and the value of the condition. The last run First off, you need a hypothesis about what the program is actually doing, and why.
through the loop should yield False as the condition value. You might wish to slow down the program to human speed, so you can see what it is

39 40
actually doing, and with some debuggers you can. But often the cost of setting up the Toys to Break
debugger,inserting and removing breakpoints, and ”walking” the program to where the
bug occurs is higher and unnecessary compared to few well-placed print statements. Python toys are mini-programs trying to solve real-world problems.

1. Program doesn’t work – ask yourself: what is not happening that should happen?
Find the code fragment responsible for this task and look what it is actually doing; TODO Command Line Specification Parser
is something happening that shouldn’t? Find the code that does that and see if it Take a line like this: show xdsl counters (near-end|far-end) (channel|line) (current|previou
is executing when it shouldn’t; is a section of code producing an effect that is not (example taken from Listing transmission errors on the command line).
what you expected? Make sure you understand that code, read the documentations And construct every possible combination for that line, i.e. the output should be:
for functions it invokes, and try them out by writing simple test cases and checking
the results. 1. show xdsl counters near-end channel current-1day
In order to program, you need to have a mental model of how programs work. 2. show xdsl counters near-end channel current-interval
Often when the program doesn’t do what you expect it is because the problem is
in your mental model. Break the program into smaller functions and methods, and 3. show xdsl counters near-end channel previous-1day
test assumptions you have about each part. Once you find the discrepancy between
your model and reality, you can solve the problem. 4. and so on

Build and test components as you go. Then when there is a problem, there is only
a small amount of new code that is not proven to be correct. DONE Convert CSV file into other format
2. Big hairy expression doesn’t do what I expect – break it down to a series of assign- See Importing Assets.
ments to temporary variables. A common mistake is assuming order of operations
incorrectly. Reimplementation of snmpwalk
3. Function or method doesn’t return expected value – in such cases you might not Seee snmpwalk till the end.
get a chance to print the return value before returning. Use something like this:
DSLAM Tester by pożar
#instead of
return self.hands[i].remove_matches() See tester by pożar. This program is written by my co-worker, Pożar.

# you could write


count = self.hands[i].remove_matches()
return count

4. I can’t for the life of me – it happens. Stretch your legs a bit and come back later.
5. No, really, I’m stuck – bring another pair of eyes in. Before you do that, make sure
that:
(a) You exhausted all the techniques described here
(b) Your program is as simple as possible, and you work on the smallest input
that causes the error
(c) You have print statements in appropriate places
(d) If there is an error message, make sure you know it
(e) What was the last thing you did before the error occured? Or the last lines of
code you wrote? What is the new test case that fails?
(f) What have you tried so far, and what have you learned?
Once you find the bug, think about what you could have done to find it faster. The
goal is to learn how to make the program work.

41 42

You might also like