Programming Assignment 1: Functions
Initial Due Date: 2024-09-19 8:00AM
Final Due Date: 2024-10-03 4:15PM
This assignment will walk you through the basics of using Thonny and writing your first functions in Python.
In general programming assignments are organized into several sections:
- Background/Introduction: An explanation of the overall goal of the assignment and any needed introduction to new features in Python, etc.
- Guide: A narrative guide to completing the assignment including suggestions, links to relevant documentation, etc.
- Specifications: The specific functionality you are expected to implement including suggestions for creativity points.
Background
This programming assignment gives you practice with defining functions, assigning to variables, returning values from functions, and printing.
As we will discuss further in class, we incorporate comments, i.e. notes that are not executed, into our programs to communicate our thinking to future users or readers of our code. Python has two kinds of comments, inline comments (any part of the line including and after a #
) and docstrings, which are comments between pairs of triple-quotes """
, e.g.,
"""
This is a docstring comment.
"""
We use docstrings to document our functions – what they do, what inputs the expect and what outputs they produce.
For reference, here are some simple example functions from class.
Guide
Warm-up
Start up Thonny (you may need to find it in the Applications folder). Download the linked starter file into a directory you have created for the course. Right-click on the above link, select “Save as…”, and save the file as “pa1_functions.py” for this assignment. Then open the saved file with Thonny and update the comment at the top with your name and section.
You will be compiling a single Python file with multiple function definitions for this assignment. Your future programming assignment submissions will be expected to follow a similar format (many programming assignments will not have a starter file). Note that the file name matters. The online submission system requires a specific filename.
Try a few commands in the interactive shell in the bottom half of Thonny. Recall that >>>
is the prompt, meaning Python is ready for a command; an indented line is a line continuation indicating that Python is waiting for you to finish the statement; and a line without anything in front of it is generally the response from the interpreter.
Try a few simple mathematical equations (e.g., 1 + 1
, 2 ** 3
, (100 // 20) + 45 * 7
). Play around with the idea that Python ignores whitespace within expressions (and notice that Python makes for a pretty effective calculator).
22/7 is an approximation for the mathematical value π. Type in both 22/7
and 22//7
and note the difference. Play around with assigning values to variables. For example, you could assign 22/7
to a variable, e.g., pi = 22/7
, and then use your newly-created variable to calculate the area of a circle with radius 10. Note that in the shell you can use the up and down arrow keys to revisit commands you typed previously.
So far, we’ve mostly been interacting with the Python Shell (interpreter). This is useful for doing short computations and trying out Python expressions. But usually we write and save programs, which allows us to write code that we can edit, re-run over time, and save. We write and edit our code in the editor window above the shell.
Remember the basic structure for defining a function is (though not all functions will have return statements):
def function_name(parameters):
"""Docstring explaining the function
Args:
parameters: Describe the function arguments
Returns:
Describe the return value (if the function returns a value)
"""
statement1
statement2
...return something
Recall that the way that Python can tell what is part of the function body is based on the indenting.
Section 1: Functions that return a value
Imagine you’re going on a semester abroad in Europe. To enhance your travels, you decide to write some functions to convert between currencies and units used in the United States to those used in European countries.
Write a function named euros_to_dollars
, that takes a single parameter, a price in euros represented as a floating point number, and returns the equivalent price in dollars also as a float
. Assume that 1€ is worth $1.21.
Run your program by clicking the green circle with the white arrow. Note that nothing appears to happen, because we have only defined a function, we haven’t yet called it. After you’ve run your program, you can interact with the interpreter/shell. For example, you can call your function and see the value returned:
>>> euros_to_dollars(35)
42.35
Make sure that you are using the return statement and are not printing the answer in your function. In particular, try running the following and make sure you get something printed at the same places (i.e., there should be no output until you manually invoke `print`` in the interpreter window):
>>> dollars = euros_to_dollars(35)
>>> print(dollars)
42.35
Write a function named welcome that doesn’t take any parameters and returns a translation of “welcome” in another language. For example:
>>> welcome()
'Willkommen'
Remember that you can create functions with zero parameters. To call a function without any parameters, you still need to put the matching (though empty) parentheses at the end (like shown above).
Write a function named kilometers_to_miles
, that takes a single parameter, the number of kilometers, and returns the equivalent distance in miles. [Note that for help, an appropriate online search query to seek the necessary information but not Python code would be “1 kilometer in miles”.] After running your program an example interaction could be:
>>> kilometers_to_miles(500)
310.6855
Write a function named celsius_to_fahrenheit
that takes a single parameter, the temperature in Celsius and returns the equivalent temperature in Fahrenheit. [Note that for help, an appropriate online search query would be something like “celsius to fahrenheit formula” or “formula to go from celsius to fahrenheit”.] After running your program an example interaction could be:
>>> celsius_to_fahrenheit(22)
71.6
Write a function named mpg_from_metric
that takes two parameters: (1) the number of kilometers and (2) the number of liters. The function returns the miles per gallon (i.e., miles divided by gallons) by converting the kilometers and liters appropriately. Remember, to have multiple parameters for functions, you separate them with commas in both the function definition and in the function invocation. Here is an example call (your answer should be close to this but may not be exactly the same):
>>> mpg_from_metric(400, 30)
31.358472666666668
You should not have any print statements inside any of the above functions. Rather, these functions return values that can be printed when the function is called. If you are not sure if you are returning values, try assigning the function call expression to an variable like shown above. There should not be any output until you manually invoke print
in the interpreter (shell).
Section 2: Functions that print
When you are running a program (rather than interacting with the shell) the intermediate results are not printed. Instead, if you want values to be displayed from the running program, you need to use the print
function. You can print any expression; for example, these are all valid lines of code you could have in a program:
print(10) # Printing a number
print(22/7) # Printing the result of a more complex expression
= 22/7 # Assign 22/7 to pi
pi print(pi) # Printing the value of a variable
print("Hello, world!") # Printing a string
Consider the program statement
print(kilometers_to_miles(500))
This statement has multiple parts. The kilometers_to_miles(500)
part calls or invokes a function you just created, which, in turn, will execute the statements inside that function. When your function returns its result, that result will be passed as a parameter to the print function, which will cause the value to be printed in the shell/interpreter.
Write a function four_fours
that expresses the values 0 through 9 using exactly four 4s and just the operators listed below. That is you must figure out and implement expressions that use exactly four 4s and one or more of the operators below to calculate the values 0-9. Even if you could compute a number with fewer than four 4s, you must use four 4s each time.
+
addition-
subtraction*
multiplication//
floor (integer) division**
exponentiation()
parentheses for grouping
Start with this code as a model, and complete it with similar statements for the numbers 1 through 9.
def four_fours():
"""
Express the values 0..9 using exactly four 4s.
Allowed operators are +, -, *, //, %, **, and parentheses.
Returns:
None
"""
print(4+4-4-4, "is 4+4-4-4") # 0
# FILL THIS IN with similar expressions for 1 through 9
In the above code, the mathematical expression 4+4-4-4
gets evaluated to the integer 0 and the value 0 is printed. But the string “is 4+4-4-4” is printed as is since it is enclosed in quotes. Your output should show each integer value 0 through 9 on its own line, along with the expression that produced the value; i.e., using the above code as a starting point the output will start like the following:
>>> four_fours()
0 is 4+4-4-4
1 is ...
Your output must match the formatting above exactly, i.e. a space on either side of “is” and no spaces in the expression.
Write a function convert_from_seconds
, which takes in a nonnegative integer number of seconds seconds
and reports the number of days, hours, minutes, and remaining seconds in seconds
seconds. There is no limit on the number of days, but you should be sure that 0 <= hours < 24, 0 <= minutes < 60, and 0 <= seconds < 60.
For instance,
>>> convert_from_seconds(3787)
0 days
1 hours
3 minutes
7 seconds
>>> convert_from_seconds(610)
0 days
0 hours
10 minutes
10 seconds
>>> convert_from_seconds(100000)
1 days
3 hours
46 minutes
40 seconds
You can start with this code as a model, and complete it with statements to compute and print the hours, minutes, and seconds.
def convert_from_seconds(seconds):
"""
Print number of days, hours, minutes, and seconds in a given number of seconds.
Args:
seconds: non-negative integer representing number of seconds
Returns:
None
"""
= seconds // (24 * 60 * 60) # Number of days
days = seconds % (24 * 60 * 60) # The leftover seconds
leftover_seconds # FILL THIS IN to compute hours and minutes
print(days, "days")
# FILL THIS IN to print number of hours, minutes, seconds like shown above
Specifications
Your submitted file for this assignment must be named “pa1_functions.py”. At a minimum your submission should have:
Section 1: Functions that return values
Implement the following functions as described in the Guide section:
- A function named
euros_to_dollars
, that takes a single parameter, a price in euros represented as a floating point number, and returns the equivalent price in dollars as afloat
. - A function named
welcome
that doesn’t take any parameters and returns “welcome” as a string in another language. - A function named
kilometers_to_miles
, that takes a single parameter, the number of kilometers, and returns the equivalent distance in miles as afloat
. - A function named
celsius_to_fahrenheit
that takes a single parameter, the temperature in Celsius and returns the equivalent temperature in Fahrenheit as afloat
. - A function named
mpg_from_metric
that takes two parameters: (1) the number of kilometers and (2) the number of liters. The function returns the miles per gallon (i.e., miles divided by gallons) as afloat
by converting the kilometers and liters appropriately.
Section 2: Functions that print
Implement the following functions as described in the Guide section:
- A function named
four_fours
that takes no parameters, and prints out the integer values 0 through 9 using four 4s and the operators +, -, *, //, %, **, and parentheses. Each line should show both the integer value and the corresponding mathematical expression using a print statement such asprint(4+4-4-4, "is 4+4-4-4")
. - A function named
convert_from_seconds
that takes a single parameter, a number of seconds, and prints the number of days, hours, minutes, and seconds that make up that number of seconds.
Creativity Suggestions
Here are some possible creativity additions, but you are encouraged to include your own ideas. The amount of creativity points awarded will be based on creativeness and difficulty of implementation.
- The “right way” to calculate the
mpg_from_metric
function is to utilize the other functions you write that do some of the work for you i.e. DRY it up. To calculate the mpg, write an additional functionliters_to_gallons
and then use this function and yourkilometers_to_miles
function to implement thempg_from_metric
function [0.5-1 point]. - Write a
dollars_to_euros
function that converts dollars using youreuros_to_dollars
function instead of explicitly incorporating the exchange rate [0.5-1 point]. - Write another function that will be useful while traveling in Europe. The amount of creativity points earned will be determined based on the usefulness of your function as well as the difficulty to implement.
It is OK to use Python features we haven’t yet discussed in class in your creativity features or elsewhere. There may be times in future programming assignments when I want you to use a specific feature or data structure in a problem; if so, I will explicitly indicate so in the assignment.
When you’re done
All your work should be in a single file (using the supplied starter file).
Update the comment at the very beginning of the file indicating the course and assignment number, your name, your section and a brief listing of your creativity features (so that the graders know what to look for).
Each function should have a docstring describing what it does. Also include other miscellaneous comments to make your thinking clear.
Submit your program via Gradescope. Your program file must be named pa1_functions.py. You can submit multiple times, with only the most recent submission (before the respective due date) graded. Note that the tests performed by Gradescope are limited. Passing all of the visible tests does not guarantee that your submission correctly satisfies all of the requirements of the assignment. Check out this guide to submitting programming assignments to Gradescope.
Grading
Assessment | Requirements |
---|---|
Revision needed | Some but not all tests are passing. |
Meets Expectations | All tests pass, the required functions are implemented correctly and your implementation uses satisfactory style. |
Exemplary | All requirements for Meets Expectations, 2 creativity points, and your implementation is clear, concise, readily understood, and maintainable. |
FAQ
How do I sign up for Gradescope?
Fortunately you shouldn’t need to sign up for Gradescope as I pre-populated the course roster (although you will need to create a password, etc. the first time you login). Apparently many of the Gradescope e-mails seem to be ending up in the junk mail folder, so check there first. Alternately you can choose the “Forgot my password” link on the login page to resend the e-mail to set your password (and log in the first time).
Returning the return value from the print function?
The return
in return print(...)
does nothing and will only confuse someone reading your code.
In the following code example the print
function returns None
, so myfunction
returns None
. But a Python function with no return
statement also returns None
so the explicit return
is unneeded here.
def myfunction(x):
return print(x)
When a function includes a return statement, you can think of that function like a mathematical function. For example, the function \(f(x)=2x\) would be defined in Python as:
def f(x):
return 2*x
The expression f(7)
evaluates to 14. This function (f
) does not print anything. The caller of the function could use the returned value (e.g., in a computation) or maybe print it, but the function itself does not print.
In general we only use print
when we want to communicate outside the program, e.g. with the user. Functions intended to be used by other parts of the program generally don’t invoke print
.
Running afoul of error tolerances in Gradescope tests
A common problem is failing a test with a result just outside the error tolerance specified in the test (e.g. for mpg_from_metric
). Generally the temperature conversion has an error tolerance of 0.1 and the distance/volume functions have a tolerance of 0.01. If you find yourself with this kind of failure, try making your conversion factors more precise. Don’t leave those tests as failing because the results seem “close enough”. Your program should pass all of the tests.
How do I format docstrings?
All of our functions should have Docstrings. Recall from class that Docstrings are special comments contained within triple quotes at the very beginning of a function that describe what the function does, its parameters and its return value (if any). We want to use standard format shown in class with a one sentence description of the function and explicit sections for the parameters and return value. For example:
def foo(x):
"""
Doubles input.
Args:
x: value to be doubled
Returns:
Doubled value
"""
return x * 2
If a function doesn’t have a return value (e.g., those in section 2), we don’t include a “Returns” section in the Docstring. For example:
def foo(x):
"""
Prints double the input.
Args:
x: value to be doubled
"""
print(x * 2)