Project FizzBuzz


#1

Hi everyone,

The challenge problem I gave myself (an oft-cited coding interview question), is the following:
“Directions: Write a program, FizzBuzz, that prints the numbers from 1 to 100.
If a number is a multiple of 3, print “Fizz”. If a number is a multiple of 5, print “Buzz”.
If a number is a multiple of both 3 and 5, print “FizzBuzz””

My working solution is below:

for i in range(0,101): if i % 3 == 0 and i % 5 == 0: print("FizzBuzz") elif i % 3 == 0: print("Fizz") elif i % 5 == 0: print("Buzz") else: print(i)

My question is that the first time I wrote this, it didn’t work because my first if statement was the following: “if i % 3 and i % 5 == 0: print (“FizzBuzz”)” … Why doesn’t that work?


#2
i % 3

will cast to True if it is non-zero, and False if it is zero.

Both operands need to be complete expressions, as you have correctly written above.


#3

OK … and according to the “rules” of Boolean logic, False AND True evaluates to False - so that if statement never executes.

However, if the statement is written completely i.e. if i % 3 == 0 and i % 5 == 0, for a number like 15, say, where both elements are True , then of course the statement executes.

Is there a reason for why the “incomplete” expression i % 3 casts to True if it is non-zero?
Following the logic, in that scenario True AND False evaluates to False so the statement doesn’t execute.


#4

Consider:

15 % 3 and 15 % 5
   0         0
 False and False

16 % 3 and 16 % 5
   1         1
  True and True

#5

OHHHHH… Got it now lol. Thank you :smiley:

For reference, I’ll also say that if you do a modulo on a number (or any mathematical operation, for that matter) and it gives you a number whose absolute value is greater than zero, the boolean value will be True.

Example: 17 % 3 = 2, and bool(2) is True. - Essentially the boolean value for any number whose absolute value is greater than 0 is True. (bool(-10000000000000) is True. Works for positive and negative decimals too.)


#6

All non-zero numbers cast to True. They as said to be truthy values. Only zero casts to False.

Something to bear in mind is that, False and True are not just booleans, they are also integers.

0 == False => True

and,

1 == True => True

To wit:

>>> isinstance(True, int)
True
>>> isinstance(False, int)
True
>>> 

Conversely, the same cannot be said for 0 and 1…

>>> isinstance(1, bool)
False
>>> isinstance(0, bool)
False

This came up in a small program I wrote over the past few days. Here is a snippet that will tell us how many days there are in February given a year.

def leap(y):
  """
  return 1 if y is a leap year else 0
  """
  return y % 4 == 0 and y % 100 != 0 or y % 400 == 0

It doesn’t actually return 1 or 0, but True or False, which can then be added to a number…

print (28 + leap(2016))    # 29

It’s because a boolean is also an integer that Python can do this.


#7

That’s a really handy fact to know. Thanks again for the explanation :slight_smile:


#8

Something else to consider while on the FizzBuzz topic…

Since you bring it up, 15 is the LCM of 3 and 5, so any number divisible by 15 will be FizzBuzz. That means we can replace the logic with a simple,

if not n % 15:
    print ("FizzBuzz")

Notice above that if n % 15 is non-zero it will be truthy. That means it still needs coercing to a boolean. not steps around that need by explicitly casting to a boolean. Put some time into studying this special operator so it becomes your friend and a real time saver (no comparison).

The key is the Least Common Multiple, which for problems like this is often applicable.


#9

I understand the LCM connection. The not and non-zero/truthy thing I’ll have to chew on a bit. It’ll click.

I appreciate the discussion :slight_smile:


#10

Regardless the object, not will cast it to a boolean, and negate it.

>>> not {}
True
>>> not []
True
>>> def foo():
	return 'foo'

>>> not foo
False
>>> not ''
True
>>> not 0
True
>>> not dict()
True
>>> 

The object proper doesn’t get changed, only a representation of the object in its changed state.


The thing to always keep in mind is that code is written from scratch, yes, but not from the ground, up. We sketch, and sketch some more. When the code starts doing what we want it to, we refactor. It’s a progressive process.

This program, for instance did not start out the way it finished up…

https://repl.it/@mtf/maxdatestr

You’ll get lots of zeros, but keep clicking Run.


#11

This topic was automatically closed 7 days after the last reply. New replies are no longer allowed.