Week 3

Revision from last week: Write a program that will reverse a given string

Key things we'll cover:

  • Conditionals
  • Comparison Operators
  • Boolean Values
  • Libraries/Modules

Programming Flow

  • In programming, flow refers to the order in which programming statements are executed.
  • In Python, a program starts running at the first non-indented program statement that is not a function definition.
  • Program flow then proceeds sequentially, waiting for one statement to finish before starting another.
  • We have learned one way to make program flow not sequential -- using loops to give us repetitions

Conditional Statements

  • Conditional statements produce a branch in the programming flow.
  • They are also sometimes called decision, or selection structures
  • They allow us to selectively execute certain programming statements, depending on the result of a condition

Syntax

if *condition*:
    body: do if condition evaluates to True

(draw and explain flowchart)

In [1]:
my_speed = int(raw_input("How fast are you driving? "))
if my_speed > 65:
    print "That's too fast!"
How fast are you driving? 85
That's too fast!


  • A condition is an expression that gives a value of True or False.
  • (An expression is something that generates a value. For example, 3+5 is an expression that generates an int. A variable by itself is also an expression -- it generates a value that's equal to the value stored inside it.)
  • Conditions are usually comparisons between two values (or two expressions) using a relational operator
  • The result of a comparison is always a Boolean value (True or False)

Relational operators in Python

Syntax <expression> <relational op> <expression>

  • > greater than
  • < less than
  • <= greater than or equal to
  • >= less than or equal to
  • != not equals to
  • == equals to

(Be careful! Equality in Python and in most other programming languages is ==. That's one of the most common bugs in programming.)

In [2]:
x = 6  # Assigns the value of 6 to the variable x -- or stores the value 6 into the memory space assigned to the variable x
print x == 6  # compares the value stored inside x to 6 -- should return True
print x != 6  # Since the value stored inside x is 6, this should be False
True
False

In [3]:
# We can use the result of an expression as a comparison:
year = 1980
if year%4 == 0:
    print "It's a leap year!"
It's a leap year!

Multi-way decisions

We can have multi-way conditions as well.

Syntax for Two-way if:

if condition1:
    do this if condition1 is True
else:
    do this if condition1 is not True
In [4]:
speed = 50
if speed > 55:
    print "Too Fast!"
else:
    print "You're not breaking the law!"
You're not breaking the law!

Flowchart
A tool for showing the flow of a program -- i.e. the order in which things are done in the program

Flowchart for 2-way if statement

We can also do multi-way if statements:

Syntax for Multi-way If:

if condition1:   
   do this if condition1 is True   
elif condition2:   
   do this if condition1 is False, but condition2 is True   
elif condition3:   
   do this if condition1 and condition2 are False, but condition3 is True   
else:   
   do this if none of the conditions are True

Note that a multi-way if is simply a nested if statement -- i.e. one if statement inside another one.
This means that the above multi-way statement is equivalent to saying:

if condition1:   
   do this if condition1 is True   
else:
   if condition2:   
        do this condition2 is True (and by implication, if condition 1 is False)
   else:
        if condition3:   
            do this if condition3 is True (and by implication, if condition1 and condition2 are False)   
        else:   
            do this if condition3 is False (and by implication, if condition1 and condition2 are also False)
In [5]:
my_speed = 35
if my_speed > 55:
    print "Too Fast!"
else:
    if my_speed < 40:
        print "Too Slow!"
    else:
        print "Just Right!"
Too Slow!

In [6]:
# This is equivalent to the above if-elif-else statement:

my_speed = 30
if my_speed > 55:
    print "Too Fast!"
elif my_speed < 40:
    print "Too Slow!"
else:
    print "Just Right!"
Too Slow!

Flowchart for multi-way if statement
In [7]:
# This also means that the order in which the comparisons happen matters!!
# As soon as the first one tests true, the rest will not be executed!
speed = 80
if speed > 55:
    print "You're above the speed limit"
elif speed > 70:
    print "You probably really need to slow down"
elif speed < 40:
    print "You're going too slow"
else:
    print "You're fine"
You're above the speed limit

In [8]:
# Compare with the example above
speed = 80
if speed > 75:
    print "You probably really need to slow down"
elif speed > 55:
    print "You're above the speed limit"
elif speed < 40:
    print "You're going too slow"
else:
    print "You're fine"
You probably really need to slow down

In [9]:
# It's probably easy to see what is wrong if we write the nested if statements instead of using an elif:

speed = 80
if speed > 55:
    print "You're above the speed limit"
else:
    # If we get here, then speed > 55 is False. Is it possible for speed < 55 and speed > 70 to both be true?
    if speed > 70:  
        print "You probably really need to slow down"
    else: 
        if speed < 40:
            print "You're going too slow"
        else:
            print "You're fine"
You're above the speed limit

One more common error -- nested ifs or if-elif, is NOT the same as multiple independent if statements!

In [10]:
speed = 80
if speed > 55:
    print "You're above the speed limit"

if speed > 70:  
    print "You probably really need to slow down"

if speed < 40:
    print "You're going too slow"
else:
    print "You're fine"
You're above the speed limit
You probably really need to slow down
You're fine

In [11]:
# we can compare strings as well as numbers. 
# string comparison goes lexicographically (i.e. the order in the alphabet)

a = "hello"
b = "hello"
c = "Hello"
d = "he"
print "a == b", a == b
print "a == c", a == c
print "a < d", a < d
print "d < a", d < a
a == b True
a == c False
a < d False
d < a True


Boolean Data Type

Booleans are another data type in Python. Boolean values are either True or False.
We don't often use Boolean values (or variables) directly in programs, but all conditional statements must contain an expression that evaluates to a Boolean value.

Boolean data types have three operators of their own:

  • and (conjunction)
  • or (disjunction)
  • not (negation)

They work on Boolean values, and their output is also a Boolean.
The result of Boolean operations is often shown using a Truth Table

x y x and y x or y not x
True True True True False
True False False True False
False True False True True
False False False False True

This lets us build more complicated comparison expressions:

if (score >= 0) and (score <= 100):
   print "This is a valid grade"
if ((quiz_score > 80) or (exam_score > 70)) and (attendance > 0.95):
    print "You get an "A"!

There are precedence rules with relational operators, too: not, then and, then or

So if we didn't have the parentheses:

(quiz_score > 80) or (exam_score > 70) and (attendance > 0.95)
would be evaluated as
(quiz_score > 80) or ((exam_score > 70) and (attendance > 0.95))
Which kind of has a very different meaning...

In any case, just use parentheses to make things clearer (to others and to yourself):

  • not x and y > 3 or 6 <= p or 5 != q and not t
  • (((not x) and (y > 3) ) or (6 <= p)) or ((5 != q) and (not t))

Example

Imagine we are writing a program to simulate a game of tennis:

  • We have two variables: playerA, storing the score of Player A
  • playerB, storing the score of Player B
  • Write a boolean expression that will return True if the set is not over.

(Reminder: In tennis, a player wins a set when he/she has scored (1) at least 6 games, and (2) is at least 2 games more than his/her opponent.)

Remember: break this down into small pieces -- and sometimes, it's easier to approach the problem from the opposite end

  • For playerA to win: (playerA >= 6) and (playerA - playerB >= 2)
  • For playerB to win: (playerB >= 6) and (playerB - playerA >= 2)
  • For the set to be over: ((playerA >= 6) and (playerA - playerB >= 2)) or ((playerB >= 6) and (playerB - playerA >= 2))
  • For the set to still be in progress: not (((playerA >= 6) and (playerA - playerB >= 2)) or ((playerB >= 6) and (playerB - playerA >= 2)))

Libraries

A library, in programming languages, is just a collection of functions that we can use. There are lots of libraries in Python that we can make use of. They are also sometimes called "modules". For example:

  • Random library: https://docs.python.org/2/library/random.html
  • Maths library: https://docs.python.org/2/library/math.html

To use a library, we have to import it. This tells Python to load in the library. We only need to import it once for every time we run Python. For programs, we usually do it at the beginning of the program:

import math
or import random

Once we do that, we can use the functions inside the libraries by appending the library name to the function:

  • math.sqrt(4) -- In the math library, use the sqrt function to calculate the square root of the integer 4
In [17]:
import random
x = random.randint(1, 10)  # random integer between 1 and 10, inclusive
print x
print random.random() # random floating point between 0 (inclusive) and 1 (exclusive)
6
0.550811254842


Practice Exercises

Fizz Buzz (easy)

The game fizzbuzz is played as a group game by children and it's a good way to get them to practice their division. Basically, the children name off the numbers one by one, with the exception that if they get to a number that's divisible by 3, they say "fizz" (instead of the number), if it's divisible by 5, they say "buzz", and if it's divisible by both 3 and 5, they say "fizzbuzz".

Write a program that asks the user for a number, and fizz-buzzes its way to that number. An example run is this:

Give me a number: 10
1
2
fizz
4
buzz
fizz
7
8
9
buzz

Factorial (easy)

The factorial of a number, which is written as the number with an exclamation point (3! is the factorial of 3) is defined as n(n-1)(n-2)...(1). For example, 3! = 3 x 2 x 1

Write a program that will ask the user for an integer. If the integer is positive, then it will print out the factorial formula and calculate the factorial. If not, then it will report an error and exit.

Example Run:

Give me an integer: 5
The factorial of 5 is 5 x 4 x 3 x 2 x 1 = 120

or:

Give me an integer: -2
That's not a positive number!

Maths Quiz (medium)

Write a program that will let kids practice their Maths. The program should generate two random integers and let the player input the product of those two integers. It should then check whether the player got the answer correct. It should also let the player pick how many questions he/she wants to play, and report the number of questions the user got right.

Example Run:

How many games do you want to play? 5
1. 3 x 5 = 15
That is correct!
2. 2 x 17 = 42
That is not correct!
3. 3 x 3 = 9
That is correct!
4. 5 x 12 = 55
That is not correct!
5. 7 x 9 = 62
That is not correct!
You got 2 out of 5! 
Practice harder!

Rock, Paper, Scissors (hard)

Write a program that plays the game "Rock, Paper, Scissors" between two players.
The program should generate two random numbers:

  • playerA, showing player A's hand
  • playerB, showing player B's hand

It should play 5 rounds of the game, and then report who won.

Example Run:

Round    PlayerA      PlayerB      Won
1        Rock         Rock         Draw
2        Rock         Paper        B
3        Scissors     Paper        A
4        Paper        Scissors     B
5        Paper        Paper        Draw
Player B wins.

Suggestions:

  • Let Rock = 0, Paper = 1, Scissors = 2
  • Store the possible player choices in a list: options = ["Rock", "Paper", "Scissors"]
  • Paper beats Rock (1 = 0+1), Scissors beats Paper (2 = 1+1), and Rock beats Scissors (0 = (2+1)%3).
  • (0+1)%3 and (1+1)%3 are the same as (0+1) and (1+1)
  • So, player A wins if playerA == (playerB+1)%3

Sample skeleton:

options = ["Rock", "Paper", "Scissors"]
scoreA =   ... # This is player A's score
scoreB =   ... # This is player B's score

# Now we play 5 rounds
for rounds in range(5):
    playerA = ...  # Generate Player A's "hand"
    playerB = ...  # Generate Player B's "hand"
    if (....): # condition for draw
       ...
    elif (...): # condition for Player A winning
       ...
    else:       # if it's not a draw, and player A didn't win, then Player B must have won!
       ...

... # Report the result
In []: