Skip to content

Instantly share code, notes, and snippets.

@judy2k
Last active August 29, 2015 14:13
Show Gist options
  • Save judy2k/0e3564c53b0ba954b4a2 to your computer and use it in GitHub Desktop.
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.
#!/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)
#!/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()
#!/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()
#!/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