Chapter 10: Functions

60 Find the Bug exercises from Chapter 10 of Everyday Programming. Every program below is short, does something recognizable, and hides exactly one bug — syntax, runtime, or logical. Read it, predict what it does, then run it and find out.

Worked solutions for this chapter: Chapter 10 solutions. Every snippet is also available as a .py file — see Exercises & Solutions.

Exercises 10.1.1–10.1.5

Exercise 10.1.1 — Defining and calling

This program should define a function that prints a welcome message and then call it once.

def welcome():
    print("Welcome to the science club!")

welcome

Solution 10.1.1 · ex_10_1_1.py

Exercise 10.1.2 — The colon

This program defines a function that prints the boiling point of water and calls it.

def boiling_point()
    print("Water boils at 100 degrees Celsius.")

boiling_point()

Solution 10.1.2 · ex_10_1_2.py

Exercise 10.1.3 — The function body

This program should print the number of days in a week when called.

def days_in_week():
print("A week has 7 days.")

days_in_week()

Solution 10.1.3 · ex_10_1_3.py

Exercise 10.1.4 — Indenting the body

This program defines a function with two body lines and calls it once.

def study_plan():
    print("Read the chapter.")
  print("Solve five problems.")

study_plan()

Solution 10.1.4 · ex_10_1_4.py

Exercise 10.1.5 — Remember to call

This program should actually print the freezing point of water on screen.

def freezing_point():
    print("Water freezes at 0 degrees Celsius.")

Solution 10.1.5 · ex_10_1_5.py

Exercises 10.2.1–10.2.5

Exercise 10.2.1 — Passing an argument

This program should greet a student by name.

def greet_student(name):
    print("Hello,", name)

greet_student()

Solution 10.2.1 · ex_10_2_1.py

Exercise 10.2.2 — Parameter order

This program should print "Maya is 15 years old".

def describe(name, age):
    print(name, "is", age, "years old")

describe(15, "Maya")

Solution 10.2.2 · ex_10_2_2.py

Exercise 10.2.3 — Too many arguments

This program should print the area of a rectangle that is 4 by 6.

def rectangle_area(width, height):
    return width * height

print(rectangle_area(4, 6, 8))

Solution 10.2.3 · ex_10_2_3.py

Exercise 10.2.4 — Using the parameter

This program should double the number that is passed in and print 10.

def double(number):
    return number * 2

print(double(number))

Solution 10.2.4 · ex_10_2_4.py

Exercise 10.2.5 — Two parameters

This program should compute the perimeter of a rectangle (2 times width plus 2 times height) for a 3 by 5 rectangle, giving 16.

def perimeter(width, height):
    return 2 * width + 2 * width

print(perimeter(3, 5))  # 16

Solution 10.2.5 · ex_10_2_5.py

Exercises 10.3.1–10.3.5

Exercise 10.3.1 — Return, do not print

This program should store the sum of two numbers and then print 12.

def add(a, b):
    print(a + b)

total = add(5, 7)
print(total)  # 12

Solution 10.3.1 · ex_10_3_1.py

Exercise 10.3.2 — Return the right value

This function should return the average of three test scores.

def average_of_three(a, b, c):
    return a + b + c / 3

print(average_of_three(80, 90, 100))  # 90.0

Solution 10.3.2 · ex_10_3_2.py

Exercise 10.3.3 — Returning early

This program should convert Celsius to Fahrenheit and print 212.0 for 100 degrees.

def c_to_f(celsius):
    return
    celsius * 9 / 5 + 32

print(c_to_f(100))  # 212.0

Solution 10.3.3 · ex_10_3_3.py

Exercise 10.3.4 — Return what was asked

This function should return the larger of two numbers; here it should return 9.

def larger(a, b):
    if a > b:
        return a
    else:
        return a

print(larger(4, 9))  # 9

Solution 10.3.4 · ex_10_3_4.py

Exercise 10.3.5 — Use the returned value

This program should print the square of 6, which is 36.

def square(side):
    return side * side

square(6)
print(area)  # 36

Solution 10.3.5 · ex_10_3_5.py

Exercises 10.4.1–10.4.5

Exercise 10.4.1 — A default value

This program should print a greeting with the default name when called with no argument.

def greet(name="friend"):
    print("Hello,", name)

greet

Solution 10.4.1 · ex_10_4_1.py

Exercise 10.4.2 — Default tax rate

This function should add an 8 percent tax by default, so a 50 dollar bill becomes 54.0.

def with_tax(price, rate=0.08):
    return price + price * 0.8

print(with_tax(50))  # 54.0

Solution 10.4.2 · ex_10_4_2.py

Exercise 10.4.3 — Overriding the default

This program should print 200 by overriding the default step count.

def total_steps(days, per_day=100):
    return days * per_day

print(total_steps(2, 200))  # 200

Solution 10.4.3 · ex_10_4_3.py

Exercise 10.4.4 — Order of defaults

This function gives the area of a rectangle, using a default height of 1.

def area(height=1, width):
    return width * height

print(area(width=5))  # 5

Solution 10.4.4 · ex_10_4_4.py

Exercise 10.4.5 — The default is optional

This program should print 10 by relying on the default increment.

def increase(value, by=10):
    return value + by

print(increase())  # 10

Solution 10.4.5 · ex_10_4_5.py

Exercises 10.5.1–10.5.5

Exercise 10.5.1 — Calling by name

This program should print "Lina is 12 years old" using keyword arguments.

def introduce(name, age):
    print(name, "is", age, "years old")

introduce(name="Lina", age=12, grade=7)

Solution 10.5.1 · ex_10_5_1.py

Exercise 10.5.2 — Order independence

Keyword arguments let you reorder; this should print the speed as distance over time, 20.0.

def speed(distance, time):
    return distance / time

print(speed(time=100, distance=5))  # 20.0

Solution 10.5.2 · ex_10_5_2.py

Exercise 10.5.3 — Spelling the keyword

This program should print a labeled temperature using a keyword argument.

def report(city, temperature):
    print(city, "is at", temperature, "degrees")

report(city="Denver", temp=30)

Solution 10.5.3 · ex_10_5_3.py

Exercise 10.5.4 — Keyword after positional

This program should print "Sam scored 95" using one positional and one keyword argument.

def score_line(name, points):
    print(name, "scored", points)

score_line(name="Sam", 95)

Solution 10.5.4 · ex_10_5_4.py

Exercise 10.5.5 — Mixing names and positions

This should compute simple interest (principal times rate times years) as 60.0.

def interest(principal, rate, years):
    return principal * rate * years

print(interest(1000, years=3, rate=0.02, time=3))  # 60.0

Solution 10.5.5 · ex_10_5_5.py

Exercises 10.6.1–10.6.5

Exercise 10.6.1 — Returning a pair

This program should print the smallest and largest of three temperatures.

def min_max(a, b, c):
    return min(a, b, c)

low, high = min_max(31.0, 36.5, 33.0)
print(low, high)  # 31.0 36.5

Solution 10.6.1 · ex_10_6_1.py

Exercise 10.6.2 — Unpacking the result

This program should print the quotient and remainder of 17 divided by 5.

def divide(a, b):
    return a // b, a % b

quotient = divide(17, 5)
print(quotient, remainder)  # 3 2

Solution 10.6.2 · ex_10_6_2.py

Exercise 10.6.3 — Matching the count

This program should unpack a name and an age into two variables.

def person():
    return "Luis", 14, "grade 8"

name, age = person()
print(name, age)  # Luis 14

Solution 10.6.3 · ex_10_6_3.py

Exercise 10.6.4 — Order of the tuple

This should report width then height of a 8 by 3 rectangle, printing "width 8 height 3".

def dimensions():
    return 3, 8

width, height = dimensions()
print("width", width, "height", height)

Solution 10.6.4 · ex_10_6_4.py

Exercise 10.6.5 — Returning both values

This program should return and print both the sum and the product of 4 and 5.

def sum_and_product(a, b):
    return a + b
    return a * b

total, product = sum_and_product(4, 5)
print(total, product)  # 9 20

Solution 10.6.5 · ex_10_6_5.py

Exercises 10.7.1–10.7.5

Exercise 10.7.1 — No return means None

This program prints a message, and the returned value should be None.

def announce():
    print("The meeting starts now.")
    return "done"

result = announce()
print(result)  # None

Solution 10.7.1 · ex_10_7_1.py

Exercise 10.7.2 — Forgetting to return

This program should print the doubled value 14, using the function’s return value.

def double(number):
    answer = number * 2

print(double(7))  # 14

Solution 10.7.2 · ex_10_7_2.py

Exercise 10.7.3 — Printing is not returning

This should store the area of a circle approximation and print about 78.5, then use it again.

def circle_area(radius):
    print(3.14 * radius * radius)

area = circle_area(5)
print(area * 2)  # uses the area twice

Solution 10.7.3 · ex_10_7_3.py

Exercise 10.7.4 — None in arithmetic

This program should add 5 to the result of a function that returns a number.

def base_value():
    total = 10

print(base_value() + 5)  # 15

Solution 10.7.4 · ex_10_7_4.py

Exercise 10.7.5 — Expecting a value

This should check whether the helper returned a usable number and print it; it should print 42.

def lucky_number():
    chosen = 42

number = lucky_number()
print(number)  # 42

Solution 10.7.5 · ex_10_7_5.py

Exercises 10.8.1–10.8.5

Exercise 10.8.1 — Triple quotes

This function has a docstring describing what it does.

def add(a, b):
    "Return the sum of two numbers.'''
    return a + b

print(add(2, 3))  # 5

Solution 10.8.1 · ex_10_8_1.py

Exercise 10.8.2 — Docstring placement

The docstring should sit directly under the def line so it becomes the function’s documentation.

def to_meters(feet):
    result = feet * 0.3048
    """Convert feet to meters."""
    return result

print(to_meters.__doc__)  # Convert feet to meters.

Solution 10.8.2 · ex_10_8_2.py

Exercise 10.8.3 — Reading the docstring

This program should print the docstring of the function.

def half(number):
    """Return half of a number."""
    return number / 2

print(half.__docs__)

Solution 10.8.3 · ex_10_8_3.py

Exercise 10.8.4 — Closing the quotes

This function should have a one-line docstring and return a perimeter.

def square_perimeter(side):
    """Return the perimeter of a square.
    return side * 4

print(square_perimeter(3))  # 12

Solution 10.8.4 · ex_10_8_4.py

Exercise 10.8.5 — Docstring, then code

This program should print the function’s docstring.

def kelvin(celsius):
    """Convert Celsius to Kelvin.
    return celsius + 273.15

print(kelvin.__doc__)

Solution 10.8.5 · ex_10_8_5.py

Exercises 10.9.1–10.9.5

Exercise 10.9.1 — Collecting positionals

This program should sum any number of grades passed in; here the total should be 270.

def total(args):
    return sum(args)

print(total(90, 85, 95))  # 270

Solution 10.9.1 · ex_10_9_1.py

Exercise 10.9.2 — The star on args

This program should print all the extra numbers it receives as a tuple.

def show_numbers(args):
    print(args)

show_numbers(1, 2, 3)  # (1, 2, 3)

Solution 10.9.2 · ex_10_9_2.py

Exercise 10.9.3 — Keyword collection

This program should print the keyword arguments as a dictionary.

def show_options(*kwargs):
    print(kwargs)

show_options(color="blue", size="large")
# {'color': 'blue', 'size': 'large'}

Solution 10.9.3 · ex_10_9_3.py

Exercise 10.9.4 — Unpacking into a call

This program should pass the list as separate positional arguments and print 6.

def add_three(a, b, c):
    return a + b + c

numbers = [1, 2, 3]
print(add_three(numbers))  # 6

Solution 10.9.4 · ex_10_9_4.py

Exercise 10.9.5 — Order of args and kwargs

This should print both the positional tuple and the keyword dictionary.

def collect(**kwargs, *args):
    print(args)
    print(kwargs)

collect(1, 2, unit="cm")

Solution 10.9.5 · ex_10_9_5.py

Exercises 10.10.1–10.10.5

Exercise 10.10.1 — Lambda syntax

This program should make a one-line function that squares a number and print 25.

square = lambda x: return x * x

print(square(5))  # 25

Solution 10.10.1 · ex_10_10_1.py

Exercise 10.10.2 — Sorting with a key

This should sort the words from shortest to longest.

words = ["pear", "fig", "banana"]
print(sorted(words, key=lambda w: -len(w)))
# ['fig', 'pear', 'banana']

Solution 10.10.2 · ex_10_10_2.py

Exercise 10.10.3 — Lambda with map

This should double every number in the list, giving [2, 4, 6].

numbers = [1, 2, 3]
doubled = list(map(lambda n: n + 2, numbers))
print(doubled)  # [2, 4, 6]

Solution 10.10.3 · ex_10_10_3.py

Exercise 10.10.4 — Lambda with filter

This should keep only the even numbers, giving [2, 4].

numbers = [1, 2, 3, 4, 5]
evens = list(filter(lambda n: n % 2 == 1, numbers))
print(evens)  # [2, 4]

Solution 10.10.4 · ex_10_10_4.py

Exercise 10.10.5 — A lambda with two inputs

This should make a one-line function that adds two numbers and print 7.

add = lambda a b: a + b

print(add(3, 4))  # 7

Solution 10.10.5 · ex_10_10_5.py

Exercises 10.11.1–10.11.5

Exercise 10.11.1 — The shared default list

Each call should start with a fresh list, so both lines print a single-item list.

def collect(item, basket=[]):
    basket.append(item)
    return basket

print(collect("apple"))   # ['apple']
print(collect("bread"))   # ['bread']

Solution 10.11.1 · ex_10_11_1.py

Exercise 10.11.2 — A safe default

This should add a reading to a fresh list each call, printing a one-item list each time.

def add_reading(value, readings=[]):
    if readings is None:
        readings = []
    readings.append(value)
    return readings

print(add_reading(20))  # [20]
print(add_reading(22))  # [22]

Solution 10.11.2 · ex_10_11_2.py

Exercise 10.11.3 — Guarding the default

The guard should replace the shared default with a new list when none is given.

def add_score(score, scores=None):
    if scores is None:
        scores = scores
    scores.append(score)
    return scores

print(add_score(90))  # [90]

Solution 10.11.3 · ex_10_11_3.py

Exercise 10.11.4 — Fresh dictionary each time

Each call should return a dictionary with just one entry.

def tally(name, counts={}):
    counts[name] = 1
    return counts

print(tally("Maya"))   # {'Maya': 1}
print(tally("Luis"))   # {'Luis': 1}

Solution 10.11.4 · ex_10_11_4.py

Exercise 10.11.5 — Checking for None

The guard should run when no list is passed; both calls should print a one-item list.

def append_day(day, days=None):
    if days == []:
        days = []
    days.append(day)
    return days

print(append_day("Mon"))  # ['Mon']
print(append_day("Tue"))  # ['Tue']

Solution 10.11.5 · ex_10_11_5.py

Exercises 10.12.1–10.12.5

Exercise 10.12.1 — Mutating shares the change

Appending inside the function should change the caller’s list too.

def add_one(numbers):
    numbers = numbers + [1]

my_list = [10, 20]
add_one(my_list)
print(my_list)  # [10, 20, 1]

Solution 10.12.1 · ex_10_12_1.py

Exercise 10.12.2 — Rebinding stays local

Reassigning the parameter should not change the caller’s list, so this prints the original.

def replace(numbers):
    numbers.clear()
    numbers.extend([99, 100])

my_list = [10, 20]
replace(my_list)
print(my_list)  # [10, 20]

Solution 10.12.2 · ex_10_12_2.py

Exercise 10.12.3 — Integers are immutable

Changing the parameter inside the function should not affect the caller’s number, which stays 5.

def add_ten(value):
    global score
    score = value + 10

score = 5
add_ten(score)
print(score)   # expected: 5

Solution 10.12.3 · ex_10_12_3.py

Exercise 10.12.4 — Mutate in place

This should add a grade to the shared list in place, so the caller sees three items.

def record_grade(grades, grade):
    grades = grades + [grade]

scores = [80, 90]
record_grade(scores, 100)
print(scores)  # [80, 90, 100]

Solution 10.12.4 · ex_10_12_4.py

Exercise 10.12.5 — Sharing the same object

Both names point to the same list, so the append should be visible outside; this prints a 4-item list.

def append_value(items, value):
    items = list(items)
    items.append(value)

box = [1, 2, 3]
append_value(box, 4)
print(box)  # [1, 2, 3, 4]

Solution 10.12.5 · ex_10_12_5.py

results matching ""

    No results matching ""