This is an example of some simple code for beginners to explore, to see how there are multiple ways to do something, and discuss what is better or worse about various solutions.

This task comes from Jeff Atwood's article FizzBuzz: the Programmer's Stairway to Heaven. It will be interesting if some beginner is asked to do FizzBuzz during an interview after exploring this.


In [1]:
# First code
# This code works, but the flag variable is terribly ugly.
# Also, the end='' argument in the print functions is ugly.
# Also, there are many print functions. Fewer would be prettier.

def fizzbuzz(n):
    for i in range(1, n + 1):
        is_a_multiple = False
        if i % 3 == 0:
            print('Fizz', end='')
            is_a_multiple = True
        if i % 5 == 0:
            print('Buzz', end='')
            is_a_multiple = True
        if is_a_multiple:
            print()
        else:
            print(i)
            
# The range is limited for ease of development.
# Needed to include 3 * 5 in that range.

n = 20
fizzbuzz(n)


1
2
Fizz
4
Buzz
Fizz
7
8
Fizz
Buzz
11
Fizz
13
14
FizzBuzz
16
17
Fizz
19
Buzz

In [2]:
# Simplified much.
# The ugly flag variable is gone,
# replaced by a list, which accretes 'Fizz', 'Buzz', and str(i) as needed.
# There is only one print function and it is at the end.

def fizzbuzz(n):
    for i in range(1, n + 1):
        s = []
        if i % 3 == 0:
            s.append('Fizz')
        if i % 5 == 0:
            s.append('Buzz')
        if not s:
            s.append(str(i))
        print(''.join(s))
        
n = 20
fizzbuzz(n)


1
2
Fizz
4
Buzz
Fizz
7
8
Fizz
Buzz
11
Fizz
13
14
FizzBuzz
16
17
Fizz
19
Buzz

In [3]:
# This plays with directly printing the number,
# instead of appending str(i) to s.
# I prefer the single print of the earlier cell.

def fizzbuzz(n):
    for i in range(1, n + 1):
        s = []
        if i % 3 == 0:
            s.append('Fizz')
        if i % 5 == 0:
            s.append('Buzz')
        if not s:
            print(i)
        else:
            print(''.join(s))
            
n = 20
fizzbuzz(n)


1
2
Fizz
4
Buzz
Fizz
7
8
Fizz
Buzz
11
Fizz
13
14
FizzBuzz
16
17
Fizz
19
Buzz

In [4]:
# Make the function, a pure function.
# That is:
#     The function has no I/O.
#     The function's return value depends only in the input value.
# A drawback is that it requires much RAM for large n.

def fizzbuzz(n):
    t = []
    for i in range(1, n + 1):
        s = []
        if i % 3 == 0:
            s.append('Fizz')
        if i % 5 == 0:
            s.append('Buzz')
        if not s:
            s.append(str(i))
        t.append(''.join(s))
    return '\n'.join(t)

n = 20
print(fizzbuzz(n))


1
2
Fizz
4
Buzz
Fizz
7
8
Fizz
Buzz
11
Fizz
13
14
FizzBuzz
16
17
Fizz
19
Buzz

In [5]:
# Give s and t meaningful names.

def fizzbuzz(n):
    lines = []
    for i in range(1, n + 1):
        terms = []
        if i % 3 == 0:
            terms.append('Fizz')
        if i % 5 == 0:
            terms.append('Buzz')
        if not terms:
            terms.append(str(i))
        lines.append(''.join(terms))
    return '\n'.join(lines)

n = 20
print(fizzbuzz(n))


1
2
Fizz
4
Buzz
Fizz
7
8
Fizz
Buzz
11
Fizz
13
14
FizzBuzz
16
17
Fizz
19
Buzz

In [6]:
# Should lines have a new line for each line?
# Let's try it.
# It works, but the code got a little uglier, so I am against this code.

def fizzbuzz(n):
    lines = []
    for i in range(1, n + 1):
        terms = []
        if i % 3 == 0:
            terms.append('Fizz')
        if i % 5 == 0:
            terms.append('Buzz')
        if not terms:
            terms.append(str(i))
        terms.append('\n')
        lines.append(''.join(terms))
    return ''.join(lines)

n = 20
print(fizzbuzz(n), end='')


1
2
Fizz
4
Buzz
Fizz
7
8
Fizz
Buzz
11
Fizz
13
14
FizzBuzz
16
17
Fizz
19
Buzz

In [7]:
# Let's convert an earlier version to a generator.

def fizzbuzz(n):
    for i in range(1, n + 1):
        terms = []
        if i % 3 == 0:
            terms.append('Fizz')
        if i % 5 == 0:
            terms.append('Buzz')
        if not terms:
            terms.append(str(i))
        yield ''.join(terms)

n = 20
for line in fizzbuzz(n):
    print(line)


1
2
Fizz
4
Buzz
Fizz
7
8
Fizz
Buzz
11
Fizz
13
14
FizzBuzz
16
17
Fizz
19
Buzz

In [8]:
# I can not think of more improvements,
# so run it for n specified by Jeff Atwood.

def fizzbuzz(n):
    lines = []
    for i in range(1, n + 1):
        terms = []
        if i % 3 == 0:
            terms.append('Fizz')
        if i % 5 == 0:
            terms.append('Buzz')
        if not terms:
            terms.append(str(i))
        lines.append(''.join(terms))
    return '\n'.join(lines)

n = 100
print(fizzbuzz(n))


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
Fizz
37
38
Fizz
Buzz
41
Fizz
43
44
FizzBuzz
46
47
Fizz
49
Buzz
Fizz
52
53
Fizz
Buzz
56
Fizz
58
59
FizzBuzz
61
62
Fizz
64
Buzz
Fizz
67
68
Fizz
Buzz
71
Fizz
73
74
FizzBuzz
76
77
Fizz
79
Buzz
Fizz
82
83
Fizz
Buzz
86
Fizz
88
89
FizzBuzz
91
92
Fizz
94
Buzz
Fizz
97
98
Fizz
Buzz