For this lab, you are going to be implementing a timed game where the user answers as many simple math questions as possible in a given time period.
Before you start working, make sure that you understand at a high-level how the game is supposed to be played. We’re going to build up the final version of this program one piece at a time. As you build each piece, make sure you understand where it fits into the larger program and make sure it’s working correctly before moving on.
Download the starter file. Right-click on the link, select “Save as…”, and save the file for this assignment. Then open the saved file with Thonny. Add your code in the places specified by the comments.
The first thing you will need is the ability to generate a random equation. Our
random equations will contain the operators
*. The following
pseudocode describes one way to generate a random equation. Pseudocode is a way
to describe an algorithm in detail without getting bogged down in language
syntax (recall “syntax vs. semantics”). It is a compromise between English and
generate a random number between 1 and 10 to start the equation for each operator that you want to add on: pick a random operator from +, -, * and add it to the equation pick a random number between 1 and 10 and add it to the equation
Using this approach, we can generate a random equation with as many operators as we would like.
Write a function called
random_equation that has a single parameter, the
number of operators to generate in the random equation, and returns a string
representing a random math equation involving the numbers 1-10 and operators
* (note that we don’t allow for 0 because it make multiplication
too easy, and we don’t allow division because it produces floating point
results that can be impossible to guess). Your function should work for zero
operators (see example below). Here are a few example runs:
>>> random_equation(4) '5 - 6 - 7 * 6 * 4' >>> random_equation(1) '3 * 7' >>> random_equation(2) '8 - 5 * 2' >>> random_equation(7) '8 + 7 + 4 - 7 - 2 * 3 * 2 * 4' >>> random_equation(0) '4'
Hints: You’ll likely need to use some sort of loop structure to get the
while). Think about which one is more appropriate
here. Also, notice that our equation is a string, so we’ll be building up a
string similar to how we did in the last assignment by appending additional
Now that you have an equation, you will need to have some way of repeatedly prompting the user for an answer until that answer is correct. Before writing any more code, read through this whole section since there are some hints/advice at the end.
There is a function named
eval built into Python that evaluates any
expression represented as a string and returns the value represented by that
expression. We’re going to use this function to figure out what the answer is
to our random equation. For example:
>>> eq = random_equation(4) >>> eq '7 * 5 - 2 - 4 * 8' >>> x = eval(eq) >>> x 1
Notice that the value that
eval returns is an int, which we would expect. If
eval can be used to evaluate more complicated string
expressions that include function calls, etc. Experiment with this if you’re curious!
Write a function called
query_equation that takes as a parameter a string
representing an equation (e.g., the return value from your
function). This function should prompt the user with the equation and then wait
for an answer from the user. If the user gets it wrong, then it will output a
message to the user indicating this and then prompt the user again with the
eval will be useful in figuring out if the user’s answer is
correct). The function should continue to prompt the user until they get the
answer right. When the user does finally get it right, the function should
print “Correct!”. The message the user gets if they answer incorrectly should
depend on how close there are:
There are many ways you can tackle this function, but I suggest an incremental approach:
Here is a quick example with
>>> eq = random_equation(2) >>> eq '5 + 9 + 7' >>> query_equation(eq) 5 + 9 + 7 = 25 Keep trying. 5 + 9 + 7 = 22 Close. Try again. 5 + 9 + 7 = 20 Close. Try again. 5 + 9 + 7 = 21 Correct!
We now have all of the pieces we need to put together our final program. Write
a function named
play_game that has two parameters, the game duration in
seconds and the number of operators. The function should use the
function in the
time module to time the user. As long as the elapsed time
hasn’t exceeded the specified game duration, you should present the user with
a new random equation and then keep track of how many they get correct (you should
be thinking about some kind of loop structure). When time runs out, you should
print out how many the user got correct and how long the game was actually
played for exactly as shown below (including punctuation).
10-9*7 = -53 Correct! You got 1 correct in 10.424232006072998 seconds.
This function should NOT be a lot of code, but should utilize the two previous
functions that you’ve written. The key responsibility of this function is
timing and keeping track of how many the player has gotten correct. Recall from
the prelab that we can measure how much time has elapsed by first recording a
starting time and then measuring the difference between the current time
time() and the initial start time.
As with the previous function, I would suggest an incremental approach. There are many ways you could tackle this, but one would be:
A note about timing: Because we are doing the timing outside of the
query_equation function, time will NOT expire until the user gets the answer
right. That is the actual time elapsed for the game will be longer than the
specified duration (and could be quite a bit longer). This is OK and how I
expect your implementation to work. That is keep presenting new questions to
the player as long as time has not “expired”. While there are mechanisms to
cutoff the game the moment time expires, doing so is outside the scope of this
A note about testing: Your game report
You got 1 correct in 10.424232006072998 seconds.
must match this format exactly, including the same words. Keep in mind that while “correct” and “right” are synonyms in this context, Python doesn’t know that.
play_game function is working, you can finish things up: Complete
your program by adding functionality to the main function, which gets called from the
if __name__ == "__main__" conditional that executes automatically when your program is run (we will learn
more about that statement later in the semester). You should ask the user if they want to
play a game. If they say “yes”, then you should prompt the user to see how long
they want to play for (in seconds) and then the game should start. If the user
does not say “yes”, just give the user a nice goodbye message.
A short instance of the game would look like:
Do you want to play a game [yes/no]? yes How long do you want to play for [seconds]? 10 10-9*7 = -53 Correct! You got 1 correct in 10.424232006072998 seconds.
At a minimum your submission should have:
random_equationwith one parameter, the number of operators, which returns a string with a random math equation with that number of operators (as described in the guide).
query_equationwith one parameter, a string representing an equation (e.g., the return value from your
random_equationfunction), which queries the user for the correct answer until they get it right.
query_equationshould not return anything.
play_gamewith two parameters, the game duration in seconds and the number of operators, which presents the user new equations to answer (via
query_equation) until time elapses.
play_gameshould print the number of correct answers and the actual time elapsed (not the specified duration) exactly as shown in the guide.
mainwith no parameters, which prompts the user and launches the game as described in the guide: ask the user if they want to play a game; if no, give a goodbye message; if yes, ask how long, and then call
play_gamewith the amount of time as an argument.
Make sure your implementation passes all Gradescope tests before adding creativity additions. When implementing your creativity additions, do not change the parameters to
the functions. In order to continue satisfying all Gradescope tests, you may need or want to make new copies of your functions, e.g.,
play_game_creativity so that your enhancements do not change the expected output, parameters and/or return values of the required functions. If you add additional information to the game summary do so outside of the required
play_game function, i.e., make sure to print the number of correct answers and the time elapsed from within play_game as shown in the guide, as the automated tests are looking for a line with that exact format. Do not add any additional questions (i.e. with
input) to the required
play_game functions other than specified. Any other input should occur outside of those functions. For example, if you want to add an option for the user to play again, implement that loop in the
main function not in
When you’re done you should have at least four functions (maybe more). Make sure that your program is properly commented:
In addition, make sure that you’ve used good coding style (including meaningful variable names, constants where relevant, vertical white space, etc.). There are numerous good candidates for constants in this lab including the range of numbers to include in the random equations, the allowed operators, etc.
Submit your program via Gradescope. Your program program file must be named lab4_math_wiz.py. You can submit multiple times, with only the most recent submission (before the 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.
|Correctly formed equations||4|
|All 3 operators randomly||1|
|Number varies based on input||1|
|Print correct/incorrect correctly||2|
|Loops until correct||3|
|Close answers get different feedback||1|
|Generates random equation and queries user||1|
|Loops until time expired||3|
|Prints out game summary||1|
|Correctly handles user input for game starting||2|
|Gets game duration||1|
|Code design and style||5|
As the labs get more complicated the Gradescope tests also get more complicated. A lot can go wrong in your programs and often the error message can be opaque. A couple of suggestions to help navigate Gradescope error messages:
The example shows an actual time elapsed (10.4s) that is greater than the specified duration (10s). This is expected. We can only check how much time has elapsed when the player successfully answers a question and so time may have “expired” while they were in the process of answering an equation, i.e. they started before time “expired”, but did not finish until afterwards. I want to point your attention this note in the lab: