cs116 - module 2 - conditionalscjmorlan/cs116/notes-02.pdf · cs116 - module 2 - conditionals...

22
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

Upload: dangmien

Post on 29-Jul-2018

238 views

Category:

Documents


1 download

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