BYU logo Computer Science

Functions and Booleans

Think of a function as a black box

function 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