Computer Science

# Functions and Booleans

## Think of a function as a black box

• the input to the box is a set of parameters
• the output from the box is a results
• the parameters may not be modified by the function

### Some function examples

``````def say_hello(name):
print(f"Hello, {name}.")

say_hello("Ammon")

def make_money():
return 1000

money = make_money()
print(f"I have {money} dollars!")

def multiply_money(money):
money = money * 2
print(f"In here, I have {money} dollars")

multiply_money(money)
print(f"Wait, I still have {money} dollars?!")``````
``````    Hello, Ammon.
I have 1000 dollars!
In here, I have 2000 dollars
Wait, I still have 1000 dollars?!``````

### If you need to modify a parameter, use return

• technically this creates a new variable and returns that variable
``````def multiply_money(money):
money = money*2
return money

stuff = make_money()
more_stuff = multiply_money(stuff)
print(f"Aha, now I have {more_stuff} dollars!")``````
``    Aha, now I have 2000 dollars!``

### Since an image is an object, we can modify its attributes

• pixels are attributes of an image, so we can modify them inside a function
``````from byuimage import Image

def darken(image):
for pixel in image:
pixel.red = pixel.red * 0.5
pixel.green = pixel.green * 0.5
pixel.blue = pixel.blue * 0.5

zion = Image("zion.jpg")
darken(zion)
zion.show()``````

## Divide and conquer

• This is a general problem-solving strategy
• Break a problem down into multiple, smaller parts
• Continue breaking parts down until you have a piece small enough for a function
• Each part gets its own, single-purpose function

## Functions and test cases

• we will write functions whose return value varies, depending on the parameters
• to test whether these functions work properly, we need to systematically test them

### Example function - bonus points

• look at student score and number of days it was submitted early
• for 1 or 2 early days, add 5%
• for 3 or more early days, add 10%
• can make a table of test cases
ScoreEarly DaysFinal Score
90090
90294.5
90599
80184
70377

### First try — which cases does it work for?

``````def bonus_points(score, early_days):
return score

print(bonus_points(90,0))
print(bonus_points(90,2))
print(bonus_points(90,5))
print(bonus_points(80,1))
print(bonus_points(80,3))``````
``````    90
90
90
80
80``````

### Second try — which cases does it work for?

``````
def bonus_points(score, early_days):
if early_days == 0:
return score
if early_days == 1 or early_days == 2:
return score*1.05

print(bonus_points(90,0))
print(bonus_points(90,2))
print(bonus_points(90,5))
print(bonus_points(80,1))
print(bonus_points(80,3))``````
``````    90
94.5
None
84.0
None``````
• notice that if you fail to return a value for a certain case, then the function returns None

### Third try — which cases does it work for?

``````def bonus_points(score, early_days):
if early_days == 0:
return score
if early_days == 1 or early_days == 2:
return score*1.05
if early_days >= 3:
return score*1.1

print(bonus_points(90,0))
print(bonus_points(90,2))
print(bonus_points(90,5))
print(bonus_points(80,1))
print(bonus_points(80,3))``````
``````    90
94.5
99.00000000000001
84.0
88.0``````
• due to the way computers represent floating-point numbers (like 90 x 1.1), there will be small differences due to approximations made with how numbers are stored in the computer.
• if you want to read about the details, see Floating Point Arithmetic: Issues and Limitations in the Python documentation

### What about negative early days (they turned it in late)?

``````def bonus_points(score, early_days):
if early_days == 0:
return score
if early_days == 1 or early_days == 2:
return score*1.05
if early_days >= 3:
return score*1.1

print(bonus_points(90,0))
print(bonus_points(90,2))
print(bonus_points(90,5))
print(bonus_points(80,1))
print(bonus_points(80,3))
print(bonus_points(80,-1))``````
``````    90
94.5
99.00000000000001
84.0
88.0
None``````
• you want to be systematic and be sure to catch all cases

### Fourth try — which cases does it work for?

• observe — if we get past the first two cases, then by default there is no bonus
• we call this a pick-off strategy — picking off cases and returning the result one-by-one
``````def bonus_points(score, early_days):
## small bonus
if early_days == 1 or early_days == 2:
return score*1.05
## big bonus
if early_days >= 3:
return score*1.1
## no bonus
return score

print(bonus_points(90,0))
print(bonus_points(90,2))
print(bonus_points(90,5))
print(bonus_points(80,1))
print(bonus_points(80,3))
print(bonus_points(80,-1))``````
``````    90
94.5
99.00000000000001
84.0
88.0
80``````

### Fifth try — what if we want to penalize for late days?

• 5% off per day
• where do we add this code?
``````def bonus_points(score, early_days):
## small bonus
if early_days == 1 or early_days == 2:
return score*1.05
## big bonus
if early_days >= 3:
return score*1.1
## no bonus
return score``````

### Fifth try — what if we want to penalize for late days?

• 5% off per day
• where do we add this code?
``````def bonus_points(score, early_days):
## penalty for late days
if early_days < 0:
return score - score*(-early_days*0.05)
## small bonus
if early_days == 1 or early_days == 2:
return score*1.05
## big bonus
if early_days >= 3:
return score*1.1
## no bonus
return score

print(bonus_points(90,0))
print(bonus_points(90,2))
print(bonus_points(90,5))
print(bonus_points(80,1))
print(bonus_points(80,3))
print(bonus_points(80,-1))
print(bonus_points(80,-4))``````
``````    90
94.5
99.00000000000001
84.0
88.0
76.0
64.0``````

## Boolean Values

• a boolean can be `True` or `False`
``````if bit.front_clear():
...

if early_days < 0:
...

while bit.get_color() == "red":
...``````

### Boolean operators

• `==`: compares two things and returns true if they are equal
• `!=`: compares two things and returns true if they are not equal
• `<`: returns true if the thing on the left is strictly less than the thing on the right
• `<=`: checks for less than or equal to
• `>`: checks for greater than
• `>=`: checks for greater than or equal to
``````if early_days >= 3:
...``````

### Boolean operators

• `and`: combines values (this and this are both true)
• `or`: this or this is true
• `not`: this is not true
``````if temp < 50 or is_raining:
print('not going outside!')

if temp < 32 and is_raining:
print('yay snow!')``````
``````
# what is the code to detect if the temp is over 70 and it's not raining?
temp = 80
is_raining = False
if temp > 70 and not is_raining:
print('Sunny and nice!')
``````
``    Sunny and nice!``

### don’t use `== True`

``````# do this
if is_raining:
print('raining')

# don't do this
if is_raining == True:
print('raining')``````

### write the `is_teen()` function

``````def is_teen(n):
""" return True if n is in the range 13..19, inclusive. Otherwise return False. """
if n >= 13 and n <= 19:
return True
return False

print(is_teen(13))
print(is_teen(17))
print(is_teen(22))``````
``````    True
True
False``````

## Using the Python Interpreter

You can open the `Python Console` in Pycharm to access the Python interpreter.

You should see:

``>>>``

You can type any valid Python commands here! Try:

• `n = 5`
• `n == 6`
• `n == 5`
• `n != 6`
• `n < 10`
• `n < 5`
• `n <= 5`
• `n > 0`
• and so forth

### You can even define functions

Try working with your `is_teen()` function:

``````def is_teen(n):
if n >= 13 and n <= 19:
return True

return False

is_teen(15)``````

### Another example

• write a function `guessing(a, b, c)`
• you have three people guess a number from 1 to 10 (secretly from each other)
• if all three match, they win 10
• if any two match, they win 5
• otherwise, they win nothing
``````def guessing(a, b, c):
# fix this code
return 0
``````