# Exercise #5: Fizz Buzz

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/.