Post on 29-Jul-2018
transcript
CS116 - Module 2 - Conditionals
Cameron Morland
Winter 2018
Reminder: if you have not already, ensure you:
Read Think Python, chapters 5, 6.
Cameron Morland CS116 - Module 2 - Conditionals
Variable assignment
Unlike in Racket, in Python we can change the value of variables as much as we like.Statements run in order, top to bottom.
width = 4
height = 3
area = width * height
# area is now 12
width = 5
# area is still 12
area = width * height
# now area is 15
Cameron Morland CS116 - Module 2 - Conditionals
Basic Conditional Statement
if test:true_block
# scale_positive(x): add half of x to positive x values.
def scale_positive(x):result = x
if x > 0:x = x // 2
result = result + x
return result
Cameron Morland CS116 - Module 2 - Conditionals
Another Conditional Statement
if test:true_block
else:false_block
# scale_unevenly(x): add half of x to positives , third to negatives.
def scale_unevenly(x):if x > 0:
result = x
x = x // 2
result = result + x
return resultelse:
return x + x // 3
Cameron Morland CS116 - Module 2 - Conditionals
Recursion: “Countdown” template in Python
def countdown_fn(n):if n == 0:
return base_answerelse:
answer = ... n ... countdown_fn(n-1)
return answer
Exercise: Use the countdown template to write a function sum_to(n) which sums allthe numbers from 0 to n.
Exercise: Modify your sum_to(n) function to make a new function sum3(n) which sumsthe numbers from 0 to n which are divisible by 3.
Cameron Morland CS116 - Module 2 - Conditionals
This could get ugly...
If there are multiple conditions to check, we can use nested if statements
# ticket_cost(age) return entry fee
# for a person age years old.
# ticket_cost: Nat -> Float
def ticket_cost(age):if age < 3: # infants are free.
cost = 0.00
else:if age < 18: # cheaper minors
cost = 5.50
else:if age < 65: # full price
cost = 9.25
else: # seniorscost = 8.00
return cost
Racket equivalent:;; (ticket_cost age) return entry fee
;; for a person age years old.
;; ticket_cost: Nat -> Num
(define (ticket-cost age)
(cond [(< age 3) 0.00][else
(cond [(< age 18) 5.50][else
(cond [(< age 65) 9.25][else 8.00])])]))
Cameron Morland CS116 - Module 2 - Conditionals
“Chained” conditionals to the rescue!
# ticket_cost2(age): return extry fee
# for a person age years old.
# ticket_cost: Nat -> Float
def ticket_cost2(age):if age < 3: # infants are free.
cost = 0.00
elif age < 18: # cheaper for minorscost = 5.50
elif age < 65: # full pricecost = 9.25
else: # seniors
cost = 8.00
return cost
Racket equivalent:;; (ticket_cost2 age) return entry fee
;; for a person age years old.
;; ticket_cost: Nat -> Num
(define (ticket-cost2 age)
(cond [(< age 3) 0.00][(< age 18) 5.50]
[(< age 65) 9.25]
[else 8.00]))
Exercise: Use elif to make sum3(n) easier to read.
Cameron Morland CS116 - Module 2 - Conditionals
Conversion to Boolean
a == b returns True if the values are equal. Note that a = b assigns a new value to a andreturns nothing. Beware.<, <=, > and >= return True or False as appropriate.a != b is True if the values are not equal, like a 6= b.
Cameron Morland CS116 - Module 2 - Conditionals
Evaluating if/elif/else
An if statement has one if followed by a code block. It may also have one or more elifstatements. Finally, it may have an else statement.
if conditionA:blockA
...
elif conditionB:blockB
...
elif conditionC:blockC
...
else: # no condition for else.
elseBlock
...
## This always runs after the if/elif/else,
## unless there was a return. It may be blank.
afterBlock...
You should think of a if/elif/else asa single statement.
If there is an else, exactly one of theblocks will run.
If there is no else, sometimes none ofthe blocks will run.Unlike in Racket, this is not an error.
Cameron Morland CS116 - Module 2 - Conditionals
if/elif/else versus if...if
Learn to keep each if/elif/else block separate in your mind.
x = 10
if x > 5: # This is True...
x = 7 # ...so this runs.
elif x > 0: # This is also True...x = 4 # ...but this does not run.
## now x == 7
x = 10
if x > 5: # This is True...
x = 7 # ...so this runs.
if x > 0: # This is still True...
x = 4 # ...so this does run.
## now x == 4
When you write your own code, I recommendyou leave a blank line any time an if block isfollowed by another if block.if x > 5: # This is True...
x = 7 # ...so this runs.
# Blank for clarity.
if x > 0: # This is still True...
x = 4 # ...so this does run
Cameron Morland CS116 - Module 2 - Conditionals
A recursive function
The two-argument Ackermann-Peter function is defined as follows for natural numbers m andn:
A(m, n) =
n + 1 if m = 0
A(m − 1, 1) if m 6= 0 and n = 0
A(m − 1,A(m, n − 1)) if m 6= 0 and n > 0.
Exercise: Write a Python function ackermann(m,n) which computes this function. Testyour function:check.expect('A(2,3)', ackermann(2,3), 9)check.expect('A(3,3)', ackermann(3,3), 61)
Cameron Morland CS116 - Module 2 - Conditionals
Some limitations to recursion
The Ackermann function blows up really fast! For example, Ackermann(4, 2) = 265536 − 3. Wecan’t do recursion this deep in Python.
Exercise: Revisit your sum_to(n) function. What is sum_to(900) ?What is sum_to(2000) ?
Python can’t recurse deeper than about 1000 function calls.We’ll see new approaches for bigger problems.
Cameron Morland CS116 - Module 2 - Conditionals
Global and Local variables
Variables defined inside a function are called local variables.Variables not defined inside a function are called global variables.This code works fine:foo = 3 # foo is a global variable
def func(x):baz = x + foo # baz and x are both local variables
return baz + foo
Inside a function you cannot change a global variable. So we will call them global constants.This code will not work:foo = 3 # foo is a global variable
def func(x):foo = x + foo # <-- attempting to change a global variable
return foo + foo
If you are in a situation where you feel it would be useful to change a global variable inside afunction, don’t. Try to approach the problem in a different way, or come ask for help.
Boolean arithmetic
In addition to Int and Float, Python has a Bool type. It can only be True or False.
v1 and v2 ⇒ True only if both values are True.
v1 or v2 ⇒ True if at least one value is True.
not v1 ⇒ True if v1 if False, otherwise False.
A Truth Table can be useful to describe combinations:
def baz(a, b):return a and not b
a b baz(a, b)
False False False
False True False
True False True
True True False
Exercise: Write a Python function quux(a, b)which has the following truth table:
a b quux(a, b)
False False False
False True True
True False True
True True False
Cameron Morland CS116 - Module 2 - Conditionals
Short Circuit Evaluation – Just like in Racket
Exercise: Type in this code, and crash it:## wrecktify(x) a bad function
## wrecktify: Float -> Float
import math
def wrecktify(x):if math.cos(1/x) > 0:
return math.cos(1/x)else:
return 0.0
A problem when x == 0. To fix it, we could add anextra if, or use short circuit evaluation:
A and B: B is evaluated only if A is True
A or B: B is evaluated only if A is False
One solution:def wrecktify2(x):
if x == 0:return 0.0
elif math.cos(1/x) > 0:return math.cos(1/x)
else:return 0.0
Another solution:def wrecktify3(x):
if x != 0 and math.cos(1/x) > 0:return math.cos(1/x)
else:return 0.0
Cameron Morland CS116 - Module 2 - Conditionals
Interpreting numbers as Booleans
0 and 0.0 are treated as False, while any other numeric value is treated as True.Generally it’s not a good idea to write code that does this, but you might see code that does.
def sum_to(n):if n:
return n + sum_to(n-1)else:
return 0
This program behaves the same as it would if I wrote if n != 0: ...
Cameron Morland CS116 - Module 2 - Conditionals
Sum of a series
Exercise: Use recursion to write a Python function sum_powers(b, n) which consumestwo Nat and returns the sum
S = 1 + b + b2 + b3 + · · ·+ bn−1 + bn
Hint:S = 1 + b (1 + b (1 + b (1 + . . . )))
Cameron Morland CS116 - Module 2 - Conditionals
Recursion Practice
Exercise: Complete digit_sum(n).## digit_sum(n) return the sum of the digits of n.
## digit_sum: Nat -> Nat
## Example:
## digit_sum(245) => 11
The nth Fibonacci number is the sum of the two previous Fibonacci numbers:
fn = fn−1 + fn−2
where f0 = 0, f1 = 1.
Exercise: Write a recursive function fib(n) that returns the nth Fibonacci number.fib(1) => 1
fib(6) => 8
Cameron Morland CS116 - Module 2 - Conditionals
Recursion Practice
Exercise: Write a function sum_squares_between(low, high) that returns the sum of thesquares of all the numbers between low and high, inclusive.sum_squares_between(3,5) => 3*3 + 4*4 + 5*5 => 50
Exercise: Write a function sum_multiples(n, d1, d2) that adds up all the numbers upto n that are multiples of d1 or d2.
Exercise: Write a function count_digits(n) that consumes a Nat and returns the numberof digits in it.count_digits(9) => 1
count_digits(245) => 3
count_digits(12345678901234567890) => 20
Cameron Morland CS116 - Module 2 - Conditionals
Recursion Practice
If r =√n, then r2 = n, so r = n
r . If r 6=√n, then one of r , n
r is greater than√n, and the
other is smaller.So if r is a “guess” of the square root of n, the average of r and n
r is a better guess.
Exercise: Use recursion to write a function sqrt(n, guess, threshold) which computes√n with an error less than threshold.
check.within('2 +- 0.1', sqrt(4.0, 1.0, 0.01), 2.0, 0.01)
Cameron Morland CS116 - Module 2 - Conditionals
Recursion Practice
The greatest common divisor (GCD) of two natural numbers is the largest natural number thatdivides evenly into both.
Exercise: Complete my_gcd_under.## my_gcd_under(a, b, t) return largest value t or less that divides a & b
## my_gcd_under: Nat Nat Nat -> Nat
## Example:
## my_gcd_under(60,40,100) => 20
## my_gcd_under(60,40,18) => 10
Exercise: Using my_gcd_under as a helper function, write my_gcd(a,b) that returns theGCD of two Nat values.
Cameron Morland CS116 - Module 2 - Conditionals
Goals of Module 2
Become comfortable with changing variables.
Understand local and global variables.
Write programs that use conditionals.
Get used to writing recursive functions in Python.
Before we begin the next module, please
Read Think Python, chapters 8, 10.
Cameron Morland CS116 - Module 2 - Conditionals