Go to top, next, previous, or johnstachurski.net

Expressions and Conditional Execution

Controlling the flow of your program according to conditions

Epressions, True and False

Let's take a quick look at the if keyword:

>>> if 1 < 2: print 'foo'
... 
foo
>>> if 2 < 1: print 'bar'
... 
>>> 

Please ignore the ..., as we'll see what it means soon

What's important now is that

Here the code phrases 1 < 2 and 2 < 1 are called expressions

The expression 1 < 2 evaluates to True

>>> 1 < 2
True

While 2 < 1 evaluates to False

>>> 2 < 1
False

The code following the expression (here print 'foo' or print 'bar') is executed or ignored, depending on whether the expression evaluates to True or False

Testing Equality and Inequalty

Here are some more examples testing inequalty

>>> x, y = 1, 2
>>> x < y
True
>>> x > y
False
>>> 1 < 2 < 3   # We can 'chain' inequalities
True
>>> 1 <= 2 <= 3
True

How about testing for equality?

>>> 1 == 1
True
>>> x = y = 1
>>> x == y
True
>>> x == 2
False

Note that we use == to test for equality!

For "not equal" use !=

>>> 1 != 1
False
>>> 1 != 2
True

Combining Expressions

We can combine expressions using and, or, not

These are the standard logical operations from mathematics/set theory

Here's some quick examples

>>> a, b, c = 1, 2, 3
>>> a < b and b < c
True
>>> a < b and c < a
False
>>> a < b or c < a
True
>>> not a < b
False

Rules for the and operation: True if both are True, else False

>>> True and True   
True
>>> True and False
False
>>> False and True
False
>>> False and False
False

Rules for the or operation: False if both are False, else True

>>> True or True    
True
>>> True or False   
True
>>> False or True   
True
>>> False or False   
False

Finally, the not operation:

>>> not True       
False
>>> not False
True
>>> not not True
True

Boolean Operations on Sequences

Operations on sequences which return True or False

We have already met some of these

>>> s = 'foo'
>>> s.startswith('f')
True

Some other string methods which return boolean values:

>>> 'foo'.isdigit()
False
>>> '100'.isdigit()
True
>>> 'FOO'.isupper()
True

There are more, which we wont go into now

A general boolean operation on sequences using the in keyword:

>>> X = ['foo', 'bar']
>>> 'foo' in X
True
>>> 'fool' in X
False
>>> 'fool' not in X
True

What does this return?

>>> 'foo' in X or 'fool' in X

The in construct also works with strings:

>>> 'y' in 'yes'
True

If/Else

The following code is typed into a text file, not interpreter

Basics

Let's return to the if construct

if True:
    print 'foo' 

Not surprisingly, this prints 'foo'

Note the syntax:

if False:
    print 'foo' 

Of course this prints nothing

We can replace True or False with an expression that evaluates to True or False

if 1 < 2:
    print 'foo' 
if 2 < 1:
    print 'foo' 

Code Blocks and Indentation

The general syntax for the if construct is

if <expression>:
    <code block>

The code block can contain as many lines as we like

if True:
    print 'foo'
    print 'bar'
    print 'foobar'

All lines in the code block must have the same indentation

This gives an error

if True:
    print 'foo'
   print 'bar'
    print 'foobar'

As does this

if True:
    print 'foo'
    print 'bar'
     print 'foobar'

The Rules of Indentation

Code blocks are denoted by indentation

Note that internally, tabs and spaces are different things!

For example, in Gedit:



And in Geany



Correct Python settings for other text editors can be found by googling.

Else and Elif

Consider the following program

x = float(raw_input("Enter any number: "))
if x >= 0:
    print "The number is nonnegative."
else:
    print "The number is negative."

The 'else' clause only executed if condition is false

Don't forget the colon

If we need more conditions use 'elif'

x = float(raw_input("Enter any number: "))
if x > 0:
    print "The number is positive."
elif x == 0:
    print "The number is zero."
else:
    print "The number is negative."

Here's another example

username = raw_input("Enter username: ")
password = raw_input("Enter password: ")
if username == "john" and password == "loser":
    # Let john into the system
elif username == "hacker" and password == "winner":
    # Let hacker into the system
else:
    print "Invalid username or password"

Conditional Assignment

The conditional assignment

if x < 0:
    value = 'negative'
else:
    value = 'nonnegative'

can be done more succinctly as follows

value = 'negative' if x < 0 else 'nonnegative'

Problems

Recently I received the following chain email:


Don't tell me your age; your waiter may know!

  1. First of all, pick the number of times a week that you would like to go out to eat. (more than once but less than 10)
  2. Multiply this number by 2
  3. Add 5
  4. Multiply it by 50
  5. If you have already had your birthday this year add 1758...If you haven't, add 1757.
  6. Now subtract the four digit year that you were born.

You should have a three digit number

The first digit of this was your original number. (I.e., How many times you want to go out to restaurants in a week.) The next two numbers are YOUR AGE!


Write a program which asks the user to answer these questions, does the calculations and prints our their age.

Solution:

guess = int(raw_input("how many nights p/w do you eat out? (1 <= n < 10): "))
guess = (guess * 2 + 5) * 50
bday = raw_input("have you had your birthday this year? (y/n): ")

if 'y' in bday or 'Y' in bday:
    guess = guess + 1758
else:
    guess = guess + 1757

byear = int(raw_input("what year where you born? (4 digits): "))
guess = guess - byear

guess = str(guess)
print "your age is " + guess[1] + guess[2]

General Expressions

An expression is any code phrase which returns a value (object) when passed to the interpreter

Here are some examples

>>> 1 + 1
2
>>> 'foo' + 'bar'
'foobar'
>>> (1, 2) + (3, 4)
(1, 2, 3, 4)
>>> 1  # This is an expression too (a very simple one)
1

All of these are expressions

Often expressions come on the right hand side of equal signs

>>> x = 2 + 2  #  Expression evaluated, binds `x` to result (i.e., 4)
>>> x = 2      #  The right-hand side is also an expression

When testing conditions, we can use any expression

if 42:      # This is regarded as True
    print 'foo' 
if 0:       # This is regarded as False
    print 'foo' 
if 1 + 1:   # This is regarded as True
    print 'foo' 
if []:      # This is regarded as False
    print 'foo' 

The rule here is as follows

If you're not sure, you can use the function bool():

>>> bool(1)            # 1 is usually associated with 'true'
True
>>> bool(0)            # And 0 is usually associated with 'false'
False
>>> bool(10 + 10)      # We can put in any expression
True
>>> bool(42 - 42)      # This is False, because value is 0
False
>>> bool('hello')      # Nonempty string regarded as true
True
>>> bool('')           # Empty string regarded as false
False
>>> bool([1, 2])       # Nonempty list regarded as true
True
>>> bool([])           # Empty list regarded as false
False

Actually, bool is a data type, like a float or an int

>>> x = True
>>> type(x)
<type 'bool'>

The two possible values are True and False

The operator not applied to an expression returns the opposite bool:

>>> not 'foo' + 'bar'
False
>>> not 0 * 10
True

Boolean Arithmetic

In algebraic expressions,

>>> True + True
2
>>> True + False
1
>>> False + False
0
>>> True * False
0

This works for the built in sum() function too:

>>> sum([True, False, True, True])
3

Problems

The first three problems can be done at the prompt

Problem 1:

Problem 2:

Problem 3:

Problem 4:

The next problem is a bit harder, and requires you to write a script

Suppose that Y counts the number of successes in n trials with success probability p

Then Y is said to have the binomial distribution, and we write Y ~ Bin(n, p)

We can simulate one trial by with success probability p by

Your exercise is to

Simulate a draw of Y ~ Bin(n, p) using uniform random variables

Solutions

Solution to Problem 1:

>>> sum([x % 2 == 0 for x in range(100)])

Incidentally, this also works

>>> sum([not x % 2 for x in range(100)])

But try to be clear, not tricky.

We could also use count()

>>> [x % 2 == 0 for x in range(100)].count(True)

Solution to Problem 2:

>>> S = 'the good, the bad and the ugly'
>>> sum([letter == 'd' for letter in S])

Solution to Problem 3:

>>> X = ((2, 5), (4, 2), (9, 8))
>>> sum([x % 2 == 0 and y % 2 == 0 for x, y in X])

Solution to Problem 4:

from random import uniform
n = int(raw_input("Choose n: "))
p = float(raw_input("Choose p: "))
X = [uniform(0, 1) for i in range(n)]
Y = sum([U < p for U in X])
print Y