Functions and Modules Answers

Module Exercises

Hint

If you get stuck for a minute or more, try searching Google or using help.

If you’re stuck for more than a few minutes, some of these links might be helpful for some of the exercises below:

Howdy

File: Create a file howdy.py in the modules sub-directory of the exercises directory.

Test: Run python test.py howdy.py from your exercises directory.

Exercise: Make a program howdy.py that prompts the user for their name and then prints Howdy <NAME>! where <NAME> is the user’s name.

$ cd modules
$ python howdy.py
What's your name? Trey
Howdy Trey!

The first line should prompt for input unchanged, and the second line should be the greeting with the user’s name.

Hint

You can get user input with the input() function. Don’t forget the exclamation mark and be mindful of spaces and capitalization.

Answers

name = input("What's your name? ")
print(f"Howdy {name}!")

Temperature Feedback

File: Create a file temp.py in the modules sub-directory of the exercises directory.

Test: Run python test.py temp.py from your exercises directory.

Exercise: Make a program temp.py that takes a temperature in Fahrenheit and prints “Too hot” if the temperature is above 80, “Too cold” if the temperature is below 65, and “Quite nice” if the temperature is between 65 and 80. You can assume the temperature is a positive two-digit number.

$ cd modules
$ python temp.py 80
Quite nice
$ python temp.py 82
Too hot
$ python temp.py 60
Too cold
$ python temp.py 70
Quite nice

Answers

This one only works with two-digit integer temperatures because we’re doing string comparisons:

import sys

temperature = sys.argv[1]
if temperature < '65':
    print("Too cold")
elif temperature > '80':
    print("Too hot")
else:
    print("Quite nice")

This one works with temperatures like 8, 100, and -50:

import sys

temperature = int(sys.argv[1])
if temperature < 65:
    print("Too cold")
elif temperature > 80:
    print("Too hot")
else:
    print("Quite nice")

This one also works with non-integer temperatures like 45.5 and 0.1:

import sys

temperature = float(sys.argv[1])
if temperature < 65:
    print("Too cold")
elif temperature > 80:
    print("Too hot")
else:
    print("Quite nice")

Dollars

File: Create a file dollars.py in the modules sub-directory of the exercises directory.

Test: Run python test.py dollars.py from your exercises directory.

Exercise: Make a program dollars.py that takes a number and returns that number written as US dollars with cents. See examples below.

$ cd modules
$ python dollars.py 80
$80.00
$ python dollars.py 5.5
$5.50
$ python dollars.py 3.048
$3.05
$ python dollars.py .05
$0.05

Hint

You’ll want to use Google for this one. You can use the string format method or f-strings.

Answers

import sys

amount = float(sys.argv[1])
print(f"${amount:.02f}")

Add

File: Create a file add.py in the modules sub-directory of the exercises directory.

Test: Run python test.py add.py from your exercises directory.

Exercise: Make a program add.py that takes two numbers and prints out the sum of these numbers. To run it without using the test framework:

$ cd modules
$ python add.py 3 5.2
8.2
$ python add.py -7 2
-5.0
$ python add.py -2 -1
-3.0

Answers

import sys

print(float(sys.argv[1]) + float(sys.argv[2]))

Mad Libs

File: Create a file madlib.py in the modules sub-directory of the exercises directory.

Test: Run python test.py madlib.py from your exercises directory.

Exercise: Create a program madlib.py that creates a phrasal template word game (Mad Libs). Your program should repeatedly prompt the user to enter words within different categories (noun, verb, adjective, etc.), then print out these words within one or more sentences.

Here’s an example:

$ cd modules
$ python madlib.py
Enter a verb: skip
Enter an adverb: merrily
Enter an adjective: mysterious
Enter a noun: dragon
Enter an adjective: purple

To write a Python program, you must first skip on your computer.
Then you'll merrily write some code.
Your code must be mysterious or Python will show you a dragon when you run it.
That's why Python is purple!

For your program to pass the tests, you must:

  1. Prompt the user for at least 3 words using input()

  2. Print out 1 or more sentences that use all of the given words

Focus on getting your program working first, then make it entertaining!

Hint

Use the input() function to prompt for user input and f-strings or string concatenation to build your sentences.

Answers

verb = input("Enter a verb: ")
adverb = input("Enter an adverb: ")
adjective = input("Enter an adjective: ")
noun = input("Enter a noun: ")
adjective2 = input("Enter an adjective: ")

print()
print(f"To write a Python program, you must first {verb} on your computer.")
print(f"Then you'll {adverb} write some code.")
print(f"Your code must be {adjective} or Python will show you a {noun} when you run it.")
print(f"That's why Python is {adjective2}!")

Difference Between

File: Create a file difference.py in the modules sub-directory of the exercises directory.

Test: Run python test.py difference.py from your exercises directory.

Exercise: Make a program difference.py that takes two numbers and prints the positive difference between these two numbers. To run it without using the test framework:

$ cd modules
$ python difference.py 3 5
2.0
$ python difference.py 6 3.5
2.5
$ python difference.py -7 2
9.0

Answers

import sys

print(abs(float(sys.argv[1]) - float(sys.argv[2])))

Silly Case

File: Create a file silly.py in the modules sub-directory of the exercises directory.

Test: Run python test.py silly.py from your exercises directory.

Exercise: Make a program silly.py that takes a string and returns a “silly case” string. A “silly case” string is a string which has the first letter of each word lowercased and every letter after it uppercased.

$ cd modules
$ python silly.py 'hello world!'
hELLO wORLD!
$ python silly.py 'Hiya world'
hIYA wORLD
$ python silly.py HEY.
hEY.

Hint

You’ll want to look through the methods that exist on strings for this one.

Answers

import sys

string = sys.argv[1]
print(string.title().swapcase())

Allow Zero Arguments

File: Create a file greetings.py in the modules sub-directory of the exercises directory.

Test: Run python test.py greetings.py from your exercises directory.

Exercise: Make a script like our greetings.py file example above, but allow it to take one or zero arguments. When one argument is given, it should print out “Hello <name>!” and when no arguments are given, it should say “Hello world!”. To run it without using the test framework:

$ cd modules
$ python greetings.py Trey
Hello Trey!
$ python greetings.py
Hello world!

Remember to move back to the exercises directory before running the test framework test!

$ cd ..
$ python test.py greetings.py
Testing greetings.py

..x
----------------------------------------------------------------------
Ran 3 tests in 0.001s

OK (expected failures=1)

Answers

import sys

arguments = sys.argv[1:]
if __name__ == "__main__":
    if arguments:
        name = arguments[0]
    else:
        name = "world"
    print(f"Hello {name}!")

CLI Only

File: Create a file hello.py in the modules sub-directory of the exercises directory.

Test: Run python test.py hello.py from your exercises directory.

Exercise: Make a module hello.py that prints “Hello world!” when you use it from the command-line, but prints an error message when you try to import it. To run it without using the test framework:

$ cd modules
$ python hello.py
Hello world!

Open the Python REPL and import the module:

>>> import hello
Error: This module can only be run from the command-line

Answers

if __name__ == "__main__":
    print("Hello world!")
else:
    print("Error: This module can only be run from the command-line")

Allow Unlimited Arguments

File: Edit the file greetings.py in the modules sub-directory of the exercises directory.

Test: Run python test.py greetings.py from your exercises directory.

Note

To run tests for this updated program, open modules_test.py, find the line that starts with class GreetingsTests. Look for the test named test_with_multiple_arguments and comment out the @unittest.skip line just above it. That line tells the Test Framework we don’t expect the test to pass, but now we are changing the program so the test should pass, therefore we comment the line out.

Exercise: Modify the greetings.py program so that it takes any number of arguments. All arguments should be joined together by spaces and printed out. To run it without using the test framework:

$ cd modules
$ python greetings.py
Hello world!
$ python greetings.py Kirk
Hello Kirk!
$ python greetings.py from planet Earth
Hello from planet Earth!

Tip

You may have noticed we did this in an example earlier, but you can get a list of all arguments with sys.argv[1:]. We’ll explain how this works in the next class.

Hint

Use str.join on the sys.argv list.

Answers

import sys

arguments = sys.argv[1:]
if __name__ == "__main__":
    if arguments:
        print(f'Hello {" ".join(arguments)}!')
    else:
        print("Hello world!")

Function Exercises

Hint

If you get stuck for a minute or more, try searching Google or using help.

If you’re stuck for more than a few minutes, some of these links might be helpful for some of the exercises below:

Hypotenuse

File: Edit the get_hypotenuse function in the file functions.py that is in the exercises directory.

Test: Run python test.py get_hypotenuse in your exercises directory.

Exercise: Edit the function get_hypotenuse so that it returns the hypotenuse of a right triangle given the other two sides. To test the function in the REPL, you can paste the function in from your text editor or import it as shown:

>>> from functions import get_hypotenuse
>>> get_hypotenuse(3, 4)
5.0
>>> get_hypotenuse(5, 12)
13.0

Hint: to get the square root of a number, raise it to the power of 0.5.

Note that if you change the code in the file after you import it, then to test the new code, you must exit the REPL, restart it and import the function again.

Note

Want to test this out manually (instead of using python test.py)?

You could could create a file called get_hypotenuse_test.py with your own test code:

from functions import get_hypotenuse

print("Calling get_hypotenuse(3, 4)")
print("Expected: 5.0")
print("  Actual:", get_hypotenuse(3, 4))

print()

print("Calling get_hypotenuse(5, 12)")
print("Expected: 13.0")
print("  Actual:", get_hypotenuse(5, 12))

Then you can run that file to test your code:

$ python get_hypotenuse_test.py

Answers

def get_hypotenuse(x, y):
    return (x ** 2 + y ** 2) ** 0.5
from math import sqrt

def get_hypotenuse(a, b):
    return sqrt(a**2 + b**2)

Parse Time

File: Edit the parse_time function in the file functions.py that is in the exercises directory.

Test: Run python test.py parse_time in your exercises directory.

Exercise: Edit the function parse_time so that it takes an input time string in the format of “minutes:seconds”. The function extracts the minutes and seconds, calculates and returns the total number of seconds. You can assume the string will contain at least one digit each for minutes and seconds.

>>> from functions import parse_time
>>> parse_time("4:03")
243
>>> parse_time("0:12")
12
>>> parse_time("1:10")
70

Note that if you change the code in the file after you import it, then to test the new code, you must exit the REPL, restart it and import the function again.

Answers

def parse_time(time_string):
    """Return total seconds from string of minutes:seconds."""
    sections = time_string.split(':')
    return int(sections[0]) * 60 + int(sections[1])

Format Time

File: Edit the format_time function in the file functions.py that is in the exercises directory.

Test: Run python test.py format_time in your exercises directory.

Exercise: Edit the function format_time so that it takes an integer value of seconds and calculates minutes and seconds, then returns a string of “minutes:seconds”. If the value of seconds is less than 10, a zero should be prefixed so the seconds are always 2 digits.

>>> from functions import format_time
>>> format_time(90061)
'1501:01'
>>> format_time(0)
'0:00'
>>> format_time(3600)
'60:00'
>>> format_time(301)
'5:01'
>>> format_time(3715)
'61:55'
>>> format_time(61)
'1:01'
>>> format_time(119)
'1:59'
>>> format_time(333)
'5:33'

Answers

def format_time(seconds):
    """Return a minutes:seconds string based on input seconds."""
    minutes = seconds // 60
    seconds = seconds % 60
    if seconds < 10:
        return f"{minutes}:0{seconds}"
    else:
        return f"{minutes}:{seconds}"

Or, you can use the built-in divmod function with string formatting:

def format_time(seconds):
    """Return a minutes:seconds string based on input seconds."""
    sections = divmod(seconds, 60)
    return f"{sections[0]}:{sections[1]:02d}"

Coalesce

File: Edit the coalesce function in the file functions.py that is in the exercises directory.

Test: Run python test.py coalesce in your exercises directory.

Exercise: Edit the function coalesce so that it takes a value and a default; returning default if value is None and returning value if it is not None. This is similar to the SQL coalesce operation. There was actually an idea to add a ?? coalesce operator to Python 3.8; that idea has been deferred. To test the function in the REPL, you can paste the function in from your text editor or import it as shown:

>>> from functions import coalesce
>>> name = "Trey"
>>> coalesce(name, "")
'Trey'
>>> name = None
>>> coalesce(name, "")
''

Note that if you change the code in the file after you import it, then to test the new code, you must exit the REPL, restart it and import the function again.

Answers

Here’s the simplest implementation of this function:

def coalesce(value, default):
    """Return value if given value is None, else return given default."""
    if value is None:
        return default
    return value

We could have made this more compact by using an inline if:

def coalesce(value, default):
    """Return value if given value is None, else return given default."""
    return value if value is not None else default

I don’t find this more readable though, and prefer the first implementation for readability.

To Percent

File: Edit the to_percent function in the file functions.py that is in the exercises directory.

Test: Run python test.py to_percent in your exercises directory.

Exercise: Edit the function to_percent so that it takes a number and returns a string of the percentage representation of the value with one decimal place. To test the function in the REPL, you can paste the function in from your text editor or import it as shown:

>>> from functions import to_percent
>>> to_percent(0.02534)
'2.5%'
>>> to_percent(1.5678)
'156.8%'

Note that if you change the code in the file after you import it, then to test the new code, you must exit the REPL, restart it and import the function again.

Answers

def to_percent(ratio):
    """Return a percentage string representing the given numeric ratio."""
    return f"{round(ratio*100, 1)}%"
def to_percent(ratio):
    """Return a percentage string representing the given numeric ratio."""
    return f"{ratio:.1%}"

To Celsius

File: Edit the to_celsius function in the file functions.py that is in the exercises directory.

Test: Run python test.py to_celsius in your exercises directory.

Exercise: Edit the function to_celsius that accepts a temperature in Fahrenheit as input and returns a temperature in Celsius. To test the function in the REPL, you can paste the function in from your text editor or import it as shown:

>>> from functions import to_celsius
>>> to_celsius(212)
100.0

Answers

def to_celsius(fahrenheit):
    return (fahrenheit - 32) * 5 / 9

Is Leap Year

File: Edit the is_leap_year function in the file functions.py that is in the exercises directory.

Test: Run python test.py is_leap_year in your exercises directory.

Exercise: Edit the function is_leap_year so that it takes a year as input and returns True if and only if the given year is a leap year.

  • Leap years are years that are divisible by 4

  • Exception: centennials (years divisible by 100) are not leap years

  • Exception to exception: years divisible by 400 are leap years

You may find this pseudocode from Wikipedia helpful.

>>> from functions import is_leap_year
>>> is_leap_year(1900)
False
>>> is_leap_year(2000)
True
>>> is_leap_year(2012)
True
>>> is_leap_year(2018)
False

Answers

def is_leap_year(year):
    if year % 4:
        return False
    elif year % 400 == 0:
        return True
    elif year % 100 == 0:
        return False
    else:
        return True

Perfect Square

File: Edit the is_perfect_square function in the file functions.py that is in the exercises directory.

Test: Run python test.py is_perfect_square in your exercises directory.

Exercise: Edit the function is_perfect_square so that it returns True if the given number is a perfect square.

A perfect square is a number which is the square of an integer. For example 25 (5 * 5), 49 (7 * 7) and 81 (9 * 9) are all perfect squares.

>>> from functions import is_perfect_square
>>> is_perfect_square(119025)
True
>>> is_perfect_square(81)
True
>>> is_perfect_square(33)
False
>>> is_perfect_square(1024)
True
>>> is_perfect_square(24)
False

Answers

from math import sqrt

def is_perfect_square(number):
    """Return True if given number is the square of an integer."""
    return sqrt(number).is_integer()