Last active
December 18, 2015 05:59
-
-
Save fcasco/5737125 to your computer and use it in GitHub Desktop.
FizzBuzz the Python way with a few magic tricks like decorators, unittest, doctest...
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/env python | |
# vim: set fileencoding=utf-8 : | |
""" | |
http://c2.com/cgi/wiki?FizzBuzzTest | |
The "Fizz-Buzz test" is an interview question designed to help filter out the 99.5% of programming job | |
candidates who can't seem to program their way out of a wet paper bag. The text of the programming assignment | |
is as follows:: | |
"Write a program that prints the numbers from 1 to 100. But for multiples of three print “Fizz” instead of | |
the number and for the multiples of five print “Buzz”. For numbers which are multiples of both three and five | |
print “FizzBuzz”." | |
Source: "Using FizzBuzz to Find Developers who Grok Coding" | |
http://tickletux.wordpress.com/2007/01/24/using-fizzbuzz-to-find-developers-who-grok-coding/ | |
""" | |
import unittest | |
from cStringIO import StringIO | |
import sys | |
functions = {} | |
def register(fn): | |
functions[fn.__name__] = fn | |
return fn | |
@register | |
def fzbz_base(s, e): | |
""" | |
>>> fzbz_base(10, 16) | |
Buzz | |
11 | |
Fizz | |
13 | |
14 | |
FizzBuzz | |
""" | |
for i in range(s, e): | |
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) | |
@register | |
def fzbz_ifs(s, e): | |
for i in range(s, e): | |
r = '' | |
if i % 3 == 0: | |
r += 'Fizz' | |
if i % 5 == 0: | |
r += 'Buzz' | |
if not r: | |
r = str(i) | |
print(r) | |
@register | |
def fzbz_listcomprehension(s, e): | |
print('\n'.join((('Fizz' if x % 3 == 0 else '') | |
+ ('Buzz' if x % 5 == 0 else '')) | |
or str(x) | |
for x in range(s, e))) | |
@register | |
def fzbz_getitem(s, e): | |
class FzBz(object): | |
def __getitem__(self, key): | |
return ((key % 3 == 0 and 'Fizz' or '') | |
+ (key % 5 == 0 and 'Buzz' or '')) \ | |
or str(key) | |
fzbz = FzBz() | |
print('\n'.join(fzbz[x] for x in range(s, e))) | |
@register | |
def fzbz_configurable(s, e): | |
fzbz = {3: 'Fizz', 5: 'Buzz'} | |
for i in range(s, e): | |
r = '' | |
for k, v in fzbz.items(): | |
if i % k == 0: | |
r += v | |
if not r: | |
r = str(i) | |
print(r) | |
class TestAllFunctions(unittest.TestCase): | |
def setUp(self): | |
self.out = StringIO() | |
sys.stdout = self.out | |
@staticmethod | |
def make_tst(fn): | |
def new_test(self): | |
fn(10, 16) | |
self.out.seek(0) | |
self.assertEqual(self.out.read(), 'Buzz\n11\nFizz\n13\n14\nFizzBuzz\n') | |
return new_test | |
def test(): | |
for name, fn in functions.items(): | |
setattr(TestAllFunctions, 'test_{}'.format(name), TestAllFunctions.make_tst(fn)) | |
unittest.main(argv=sys.argv[:1]) | |
def main(): | |
for i, name in enumerate(functions): | |
print('[{}] {}'.format(i, name)) | |
selection = int(raw_input('Function number: ')) | |
s = int(raw_input('First integer: ')) | |
e = int(raw_input('Last integer: ')) | |
functions.values()[selection](s, e) | |
if __name__ == '__main__': | |
actions = {'run': main, 'test': test} | |
try: | |
actions[sys.argv[1]]() | |
except (IndexError, KeyError): | |
print('Usage: fzbz.py [run|test]') | |
sys.exit() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment