Instructions for debugMathPractice

(produced at 23:26 UTC on 2021-09-14)

This task is part of ps02 which is due at 23:59 EDT on 2021-09-21.

This is an individual task.

You can submit this task using this link.

Put all of your work for this task into the file mathPractice.py
(which is provided among the starter files)

Background

It is rarely the case that code works the first time you test it. It often contains one or more so-called bugs that cause it to behave incorrectly. Accordingly, much of the time you spend programming in the course will involve debugging, which is the process of finding and removing bugs.

Recall that in lab, we have shown you some tools including the debugger in Thonny and the optimism testing library for finding, removing, and preventing bugs.

Here's a simple example of a program that does not behave as expected:

username = input('What is your name? ')  # line 1
print('Hello, username')                 # line 2
n = input('Enter an integer n: ')        # line 3
print('n is', n, '; 2*n is', 2*n)        # line 4

For example:


What is your name? Wendy
Hello, username

Enter an integer n: 23
n is 23 ; 2*n is 2323

(Important Note: In this pset, we use blue text to highlight text entered by the user to distinguish it from text printed by the program, which is in black. When you actually run the program in Thonny, the text entered by the user will also appear in blue.)

This program misbehaves in two ways:

  1. Rather than displaying the name entered by the user (Wendy in this case), it always displays the string username.
  2. Rather than showing the double of the integer n for the expression 2*n (46 in this case) it shows the two-fold concatenation of the digits in the number ("2323" in this case).

The first bug is due to the fact that in line 2, the occurrence of username inside the printed string denotes the literal string U-S-E-R-N-A-M-E and not the value of the variable named username. This can be fixed by changing line 2 to be

print('Hello, ' +  username)       # fixed line 2, version 1, for 1st bug

or

print('Hello,', username)          # fixed line 2, version 2, for 1st bug

The second bug occurs because in the expresion 2*n the value of n is the string of digits entered by the user (e.g., the 2-digit string "23") rather than the integer 23. This can be fixed by using the int() function to convert the string of digits "23" to the integer 23. One way to apply this fix is to change line 4 to be:

print('n is', n, '; 2*n is', 2*int(n))     # fixed line 4 for 2nd bug

Alternatively, we could leave line 4 unchanged, and instead change line 3 to be

n = int(input('Enter an integer n: '))     # fixed line 3 for 2nd bug. 

With either combination of fixes, the program now works as expected:


What is your name? Wendy
Hello, Wendy

Enter an integer n: 23
n is 23 ; 2*n is 46

This example illustrates that (1) even a very short program can contain multiple bugs and (2) often there is more than one way to fix a bug.

A Note on print

Most examples involving print that you have seen in the course up to this point involve calling it with a single parenthesized argument that's a string. For example, suppose that:

  • i is a variable holding the integer 42
  • f is a variable holding the floating point number 6.023
  • s is a variable holding the string "bunny"

Then:

print('i is ' + str(i) + '; f is ' + str(f) + '; s is ' + s)

displays the characters

i is 42; f is 6.023; s is bunny

However, it turns out that the print function in Python is special in two ways:

  • print can accept any number of arguments.

  • Each argument to print is automatically converted to a string, and spaces are automatically inserted between them.

For example:

print('i is', i, '; f is', f, '; s is', s)

will also displays the characters

i is 42; f is 6.023; s is bunny

Passing multiple arguments with arbitrary types to print is often more convenient that having to convert the values to strings and concatenating them into one big string.

The mathPractice.py Program

For task 1, we will work with a Python program that quizzes the user on basic math operations (although it does not check their answers). This program is supposed behave as shown in the first and second examples below, where text highlighted in blue is entered by the user.

If you open the file mathPractice.py (which is included in the download folder for ps01) in Thonny, you will see an attempted implementation of this program.

Unfortunately, this example code has numerous bugs that prevent it from working properly. Your goal in this subtask is to fix the program so that it behaves as indicated by the above examples.

You should modify mathPractice.py by finding and fixing all the bugs it contains, so that ultimately it has the correct behavior as shown above. You may find it useful to make comment every time you fix a bug so that you can more easily review you progress against the rubric.

Notes:

  • Most changes require modifying/replacing existing lines in the program. It is never necessary to completely remove any lines from the program. It is not necessary to add any new lines to the program (although you might need to change a blank line).

  • You should use an incremental strategy for debugging. This means that, at every step, you should focus on the first line of the program that is incorrect (i.e., either it prints the wrong output or the program generates an error at that line). Then attempt to fix this line, and test your modified program to see if it improves the behavior of the program. If your bug fix doesn't work, try again. If it does work, focus on the next broken line. Keep doing this until the behavior is correct.

  • Thonny's assistant feature will give you tips about any errors that happen while running the code, as well as helping to point you at lines that may have bugs. But it does not always identify the best way to fix a bug, and sometimes an issue it identifies is actually caused by a problem that occurs earlier in the program. Try to really understand the cause of each problem before unthinkingly making changes.

  • There are some bugs in the program that don't cause it to crash with an error message, and which Thonny's assistant cannot detect. Make sure you actually check whether the output looks correct in addition to fixing any errors and warnings that Thonny displays. If you want to check your output carefully, you can use this difference checker website to compare the example outputs above with what your code actually produces and highlight any differences.

  • The tools we introduced in lab 2 may prove useful here: the Thonny debugger can help you understand why or where a problem occurs once you spot it, and if you want, you are welcome to add tests using optimism which specify the correct behavior (any testing output will not be counted as part of the program's normal output, so it won't mess up the correctness of your program).

Examples

Example #1

An example of exactly what the output should be if the user enters the numbers 15 and 7. Note that the other inputs after the first two don't affect the output at all, so they don't matter.

In []:
%run mathPractice.py
Prints
Let's practice some math! Enter an integer between 1 and 20: 15 Enter another integer between 1 and 20: 7 The numbers you entered are 15 and 7 The larger number is 15 The smaller number is 7 These bars show how big they are: =============== ======= [Addition] What is 15+7 ? 22 [Addition] The answer is: 22 [Subtraction] What is 15-7 ? 8 [Subtraction] The answer is: 8 [Multiplication] What is 15*7 ? 90 [Multiplication] The answer is: 105 [Division] What is 15/7 (rounded to an integer)? 2 [Division] The answer is: 2 [Remainder] What is the remainder of 15/7 ? I don't know. [Remainder] The answer is: 1

Example #2

An example of exactly what the output should be if the user enters the numbers 12 and 3. This uses more creative input values to demonstrate that the input from the user after the first two numbers is ignored.

In []:
%run mathPractice.py
Prints
Let's practice some math! Enter an integer between 1 and 20: 12 Enter another integer between 1 and 20: 3 The numbers you entered are 12 and 3 The larger number is 12 The smaller number is 3 These bars show how big they are: ============ === [Addition] What is 12+3 ? 15 [Addition] The answer is: 15 [Subtraction] What is 12-3 ? Nine [Subtraction] The answer is: 9 [Multiplication] What is 12*3 ? 36 [Multiplication] The answer is: 36 [Division] What is 12/3 (rounded to an integer)? Four [Division] The answer is: 4 [Remainder] What is the remainder of 12/3 ? nothing [Remainder] The answer is: 0

How to test using optimism

This example shows how you would define a test case using the optimism library. Note that you'd probably want to call expectOutputContains many more times to test that different parts of the output are correct. You'd include code like this at the very end of your file (and the made-up line numbers in the logs here reflect that).

In []:
# Import the testing library (note that there is no "from ... import *", # so in the code below, we always need to say "optimism.") import optimism # make sure we capture output for our test cases # Note: this MUST NOT be placed before all of the regular printing is # finished, or that output will be captured as part of testing. optimism.captureOutput() # first test uses 12 and 5 as the numbers # Note the "answer" lines are the "answers" to each practice question optimism.provideInput(''' 12 5 answer1 answer2 answer3 answer4 answer5 ''') # Here we define what we're testing (the whole file) optimism.testCase(optimism.runFile()) # These expectations ensure that parts of the output are correct optimism.expectOutputContains("The numbers you entered are 12 and 5") optimism.expectOutputContains("The larger number is 12")
Logs
✓ soln/mathPractice.py:97 ✓ soln/mathPractice.py:98

Rubric

 
unknown Procedure Requirements
What code you use to solve the problem.
 
unknown Extra goals
Complete all extra goals in addition to the core goals for a perfect score.
 
unknown Use int in exactly two places.
To minimize repetition, use the int function in exactly two places.
 
unknown Behavior Requirements
What your code does from the user's perspective.
 
unknown Core goals
Complete all core goals for core credit. Get partial credit for completing at least half, and more partial credit for completing at least 90%.
 
unknown bug #1
Hint Causes a SyntaxError
 
unknown bug #2
Hint: How does int() work?
 
unknown bug #3
Hint: Should show both numbers.
 
unknown bug #4
Hint: Is 12 larger than 5?
 
unknown bug #5
Hint: How are the bars created?
 
unknown bug #6
Hint: Can you add a number to a string?
 
unknown bug #7
Hint: gives away the answer.
 
unknown bug #8
Hint: What's the difference between '+' and ',' when printing?
 
unknown bug #10
Hint: Check the prompt variables.
 
unknown Extra goals
Complete all extra goals in addition to the core goals for a perfect score.
 
unknown bug #9
Hint: Are all the questions spaced out correctly?
 
unknown bug #11
Hint: Is the division answer always correct?
 
unknown bug #12
Hint: Is the remainder answer always correct?