Prev - #4 Area & Volume | Table of Contents | Next - #6 Ordinal Suffix
fizzBuzz(5) → 1 2 Fizz 4 Buzz
Fizz buzz is a word game you can implement as a simple program. It became famous as a screening question in coding interviews to quickly determine if candidates had any programming ability whatsoever, so being able to solve it quickly leads to a good first impression.
This exercise continues our use of the modulo operator to determine if numbers are divisible by 3, 5, or both 3 and 5. “Divisible by n” means that it can be divided by a number n with no remainder. For example, 10 is divisible by 5, but 11 is not divisible by 5.
Exercise Description
Write a fizzBuzz()
function with a
single integer parameter named upTo
. For the numbers
1
up to and including upTo
,
the function prints one of four things:
·
Prints 'FizzBuzz'
if the number is divisible
by 3 and
5.
·
Prints 'Fizz'
if the number is only divisible
by 3.
·
Prints 'Buzz'
if the number is only divisible
by 5.
· Prints the number if the number is neither divisible by 3 nor 5.
Instead of printing each string or number on a separate line, print them without newlines. For example, your solution is correct if calling fizzBuzz(35) produces the following output:
1 2 Fizz 4 Buzz Fizz 7 8 Fizz Buzz 11 Fizz 13 14 FizzBuzz 16 17 Fizz 19 Buzz Fizz 22 23 Fizz Buzz 26 Fizz 28 29 FizzBuzz 31 32 Fizz 34 Buzz
Try to write a solution based on the information in this description. If you still have trouble solving this exercise, read the Solution Design and Special Cases and Gotchas sections for additional hints.
Prerequisite concepts: modulo operator, end
keyword argument for print()
, for loops, range() with two arguments
Solution Design
This function requires a loop covering the integers 1 up to and including the upTo
parameter. The %
modulo operator (which we used in Exercise
#3, “Odd & Even”) can check if a number is divisible by 3 or 5. If a number
mod 3 is 0, then the number is divisible by 3. If a number mod 5 is 0, then the
number is divisible by 5. For example, enter the following into the interactive
shell:
>>> 9 % 3
0
>>> 10 % 3
1
>>> 11 % 3
2
9 % 3
evaluates to 0, so 9 is divisible by 3. Meanwhile, 10
% 3 evaluates to 1
and 11
% 3 evaluates 2
, so 10 and 11 aren’t divisible
by 3. To see the pattern behind the modulo operator, enter the following code
into the interactive shell:
>>> for i in range(20):
... print(str(i).rjust(2), i % 3, i % 5)
...
0 0 0
1 1 1
2 2 2
3 0 3
4 1 4
5 2 0
6 0 1
7 1 2
8 2 3
9 0 4
10 1 0
11 2 1
12 0 2
13 1 3
14 2 4
15 0 0
16 1 1
17 2 2
18 0 3
19 1 4
The columns of three numbers are a number from 0 to 19, the number modulo 3, and the number modulo 5. Notice that the modulo 3 column cycles from 0 to 2 and the modulo 5 column cycles from 0 to 4. The modulo result is 0 every 3rd and 5th number, respectively. And they are both 0 every 15th number (more on this in the Special Cases and Gotchas section.)
Back to our solution, the code inside the loop checks if the
current number should cause the program to either display one of “Fizz”, “Buzz”,
“FizzBuzz”, or the number. This can be handled with a series of if-elif
-elif
-else statements.
To tell the print()
function to
automatically print a space instead of a newline character, pass the end=' ' keyword argument. For example, print('FizzBuzz', end=' ')
Special Cases and Gotchas
One common mistake when writing a Fizz Buzz program is checking
if the number is divisible by 3 or 5 before checking if it’s divisible by 3 and 5.
You’ll want to check if a number is divisible by 3 and 5 first, because these
numbers are also divisible by 3
and 5. But you want to be sure to display 'FizzBuzz'
rather than 'Fizz'
or 'Buzz'
.
Another way to determine if a number is divisible by 3 and 5 is to check if it is divisible by 15. This is because 15 is the least common multiple (LCM) of 3 and 5. You can either write the condition as number % 3 == 0 and number % 5 == 0 or write the condition as number % 15 == 0.
The range()
function tells for loops to go up to but not including their
argument. The code for i in range(10):
sets i to 0
through 9, not 0
through 10. You can specify two arguments to tell range() to start at a number besides 0
.
The code for i in range(1, 10):
sets i to 1
to 9
.
In our exercise, you want to include the number in upTo
,
so add 1
to it: range(1, upTo +
1)
Python’s list()
function can take a range object returned from range()
to produce a list of integers. For example, if you need a list of integers 1 to 10
, you can call list(range(1, 11)). If you need every even number between 150 up to and including 200
,
you can call list(range(150, 202, 2))
:
>>> list(range(1, 11))
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
>>> list(range(150, 202, 2))
[150, 152, 154, 156, 158, 160, 162, 164, 166, 168, 170, 172, 174, 176, 178, 180, 182, 184, 186, 188, 190, 192, 194, 196, 198, 200]
Now try to write a solution based on the information in the previous sections. If you still have trouble solving this exercise, read the Solution Template section for additional hints.
Solution Template
Try to first write a solution from scratch. But if you have difficulty, you can use the following partial program as a starting place. Copy the following code from https://invpy.com/fizzbuzz-template.py and paste it into your code editor. Replace the underscores with code to make a working program:
def fizzBuzz(upTo):
# Loop from 1 up to (and including) the upTo parameter:
for number in range(1, ____):
# If the loop number is divisible by 3 and 5, print 'FizzBuzz':
if number % 3 == ____ and number % 5 == ____:
____(____, end=' ')
# Otherwise the loop number is divisible by only 3, print 'Fizz':
elif ____ % 3 == 0:
____(____, end=' ')
# Otherwise the loop number is divisible by only 5, print 'Buzz':
elif number % 5 ____ 0:
____(____, end=' ')
# Otherwise, print the loop number:
else:
____(____, end=' ')
The complete solution for this exercise is given in Appendix A and https://invpy.com/fizzbuzz.py. You can view each step of this program as it runs under a debugger at https://invpy.com/fizzbuzz-debug/.
Prev - #4 Area & Volume | Table of Contents | Next - #6 Ordinal Suffix