Last active
August 29, 2015 14:13
-
-
Save judy2k/0e3564c53b0ba954b4a2 to your computer and use it in GitHub Desktop.
A bunch of attempts to create a really horrible fizz buzz implementation in Python.
This file contains hidden or 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
#!/usr/bin/env python | |
# -*- coding: utf-8 -*- | |
from functools import wraps | |
def test(condition): | |
def test_decorator(f): | |
@wraps(f) | |
def test_wrapper(n): | |
if condition(n): | |
return f(n) | |
return test_wrapper | |
return test_decorator | |
@test(lambda n: n % 5 == 0 and n % 3 == 0) | |
def fizz_buzz(n): | |
return 'Fizz Buzz!' | |
def divisible_by(divisor, result): | |
@test(lambda n: n % divisor == 0) | |
def divisible(n): | |
return result | |
return divisible | |
def identity(n): | |
return n | |
def selector_factory(rules): | |
def selector(n): | |
for f in rules: | |
result = f(n) | |
if result: | |
return result | |
return selector | |
DEFAULT_RULES = [ | |
fizz_buzz, | |
divisible_by(3, "Fizz!"), | |
divisible_by(5, "Buzz!"), | |
identity | |
] | |
selector = selector_factory(DEFAULT_RULES) | |
for i in range(1, 16): | |
print selector(i) |
This file contains hidden or 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
#!/usr/bin/env python | |
# -*- coding: utf-8 -*- | |
import argparse | |
import logging | |
import re | |
def divisible_by(divisor): | |
def is_divisible(n): | |
return n % divisor == 0 | |
return is_divisible | |
def identity(n): | |
return n | |
def identifiericate(s): | |
return re.sub(r'[^a-z0-9]', '', re.sub(r' -', '_', s.lower())) | |
_returner_template = """ | |
def {funcname}(n): | |
return "{value}" | |
""" | |
def returner(val): | |
name = identifiericate(val) | |
funcname = "i_will_return_{name}".format(name=name) | |
code = _returner_template.format(funcname=funcname, value=val) | |
namespace = dict(__name__='returner_{}'.format(name)) | |
exec(code, namespace) | |
result = namespace[funcname] | |
return result | |
class UnFizzBuzzable(Exception): | |
def __init__(self, n): | |
msg = "I don't know what to do with {}".format(n) | |
super(UnFizzBuzzable, self).__init__(msg) | |
class FizzBuzz(object): | |
def __init__(self, tests, lookup): | |
self._tests = tests | |
self._lookup = lookup | |
def __call__(self, n): | |
key = tuple(test(n) for test in self._tests) | |
try: | |
handler = self._lookup[key] | |
logging.debug("Value {}, handled by {!s}".format(n, handler)) | |
return handler(n) | |
except KeyError: | |
raise UnFizzBuzzable() | |
def main(): | |
arg_parser = argparse.ArgumentParser() | |
arg_parser.add_argument('-v', '--verbose', action='store_true') | |
arguments = arg_parser.parse_args() | |
if arguments.verbose: | |
logging.getLogger().setLevel(logging.DEBUG) | |
fizz_buzz = FizzBuzz( | |
[divisible_by(3), divisible_by(5)], | |
{ | |
(False, False): identity, | |
(False, True): returner("Buzz!"), | |
(True, False): returner("Fizz!"), | |
(True, True): returner("Fizz Buzz!"), | |
} | |
) | |
for i in range(1, 16): | |
print fizz_buzz(i) | |
if __name__ == '__main__': | |
main() |
This file contains hidden or 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
#!/usr/bin/env python | |
# -*- coding: utf-8 -*- | |
""" | |
An abominably-implemented FizzBuzz implementation. | |
PEP-8 Compliant. | |
""" | |
import argparse | |
import logging | |
import re | |
def divisible_by(divisor): | |
""" | |
Return a function that tests if a number is divisible by `divisor`. | |
""" | |
def is_divisible(n): | |
""" Placeholder docstring. """ | |
return n % divisor == 0 | |
is_divisible.__doc__ = """ | |
Return True if `n` is divisible by {}. | |
""".format(divisor) | |
return is_divisible | |
def identity(n): | |
""" Return n """ | |
return n | |
def identifiericate(s): | |
""" | |
Convert a string to a valid Python identifier. | |
""" | |
return re.sub(r'[^a-z0-9_]', '', re.sub(r'[ \-]', '_', str(s).lower())) | |
def returner(val): | |
""" | |
Return a function that takes a parameter, but always returns `val`. | |
The function will have a clever name. | |
""" | |
name = identifiericate(val) | |
funcname = "i_will_return_{name}".format(name=name) | |
def i_will_return(n): | |
""" Placeholder docstring. """ | |
return val | |
i_will_return.__name__ = funcname | |
i_will_return.__doc__ = """ | |
A function that returns {!r} | |
""".strip().format(val) | |
return i_will_return | |
def fizz_buzz_elif_strategy(n): | |
""" | |
Return the correct FizzBuzz value for n by testing divisibility in | |
an if-elif. | |
""" | |
divisible_by_3 = n % 3 == 0 | |
divisible_by_5 = n % 5 == 0 | |
if divisible_by_3 and divisible_by_5: | |
return "Fizz Buzz!" | |
elif divisible_by_3: | |
return "Fizz!" | |
elif divisible_by_5: | |
return "Buzz!" | |
return n | |
class UnFizzBuzzable(Exception): | |
""" | |
An exception raised by a fizz-buzz strategy if it cannot resolve the | |
provided number. | |
""" | |
def __init__(self, n): | |
msg = "I don't know what to do with {}".format(n) | |
super(UnFizzBuzzable, self).__init__(msg) | |
class FizzBuzzLookupStrategy(object): | |
""" | |
A FizzBuzz strategy implemented by looking up handlers in a provided | |
truth-table. | |
""" | |
def __init__(self, tests, lookup): | |
self._tests = tests | |
self._lookup = lookup | |
def __call__(self, n): | |
""" | |
Generate a FizzBuzz result for `n`, using the lookup strategy. | |
""" | |
key = tuple(test(n) for test in self._tests) | |
try: | |
handler = self._lookup[key] | |
logging.debug("Value {}, handled by {!s}".format(n, handler)) | |
logging.debug("Handler doc: {}".format(handler.__doc__)) | |
return handler(n) | |
except KeyError: | |
raise UnFizzBuzzable(n) | |
class FizzBuzz(object): | |
""" | |
An infinite iterable (and callable) that executes a given | |
FizzBuzz strategy. | |
""" | |
def __init__(self, strategy): | |
self._strategy = strategy | |
def __call__(self, n): | |
""" | |
Generate a FizzBuzz result for `n`. | |
""" | |
return self._strategy(n) | |
def __iter__(self): | |
""" An infinite iterator over FizzBuzz values. """ | |
i = 0 | |
while True: | |
i += 1 | |
yield self(i) | |
def main(): | |
""" | |
Print out FizzBuzz values every quarter-second, forever. | |
""" | |
arg_parser = argparse.ArgumentParser() | |
arg_parser.add_argument('-v', '--verbose', action='store_true') | |
arguments = arg_parser.parse_args() | |
if arguments.verbose: | |
logging.getLogger().setLevel(logging.DEBUG) | |
# fizz_buzz_elif = FizzBuzz(fizz_buzz_elif_strategy) | |
fizz_buzz_lookup = FizzBuzz(FizzBuzzLookupStrategy( | |
[divisible_by(3), divisible_by(5)], | |
{ | |
(False, False): identity, | |
(False, True): returner("Buzz!"), | |
(True, False): returner("Fizz!"), | |
(True, True): returner("Fizz Buzz!"), | |
} | |
)) | |
import time | |
for n, v in enumerate(fizz_buzz_lookup, start=1): | |
print "{}: {}".format(n, v) | |
time.sleep(0.25) | |
if __name__ == '__main__': | |
main() |
This file contains hidden or 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
#!/usr/bin/env python | |
# -*- coding: utf-8 -*- | |
def divisible_by(divisor): | |
def is_divisible(n): | |
return n % divisor == 0 | |
return is_divisible | |
identity = lambda n: n | |
def fixed(val): | |
return lambda n: val | |
class UnFizzBuzzable(Exception): | |
def __init__(self, n): | |
super(UnFizzBuzzable, self).__init__("I don't know what to do with {}".format(n)) | |
class FizzBuzz(object): | |
def __init__(self, tests, lookup): | |
self._tests = tests | |
self._lookup = lookup | |
def __call__(self, n): | |
key = tuple(test(n) for test in self._tests) | |
solver = self._lookup[key] | |
if solver is not None: | |
return solver(n) | |
else: | |
raise UnFizzBuzzable() | |
fizz_buzz = FizzBuzz( | |
[divisible_by(3), divisible_by(5)], | |
{ | |
(False, False): identity, | |
(True, False): fixed("Fizz!"), | |
(False, True): fixed("Buzz!"), | |
(True, True): fixed("Fizz Buzz!"), | |
} | |
) | |
for i in range(1, 16): | |
print fizz_buzz(i) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment