Last active
September 22, 2021 01:56
-
-
Save duck57/79526f78479fafd5747ecbda88791096 to your computer and use it in GitHub Desktop.
User-configurable Fizz Buzz
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
#!/usr/bin/env python3 | |
import click | |
from typing import * | |
""" | |
Fizz Buzz Pow Pop Bang | |
Like your classic FizzBuzz but with more interactivity and control | |
of which numbers get replaced | |
""" | |
def make_strings( | |
freq_dict: Dict[int, str], start: int, stop: int | |
) -> Generator[str, None, None]: | |
""" | |
The method that does all the fizzbuzz hard work. | |
:param freq_dict: see get_dict() for how this is generated | |
:param start: starting number | |
:param stop: stop number (included in outupt) | |
:return a generator of strings with either the number or its phrase replacement | |
""" | |
for i in range(start, stop + 1): | |
x: str = "".join(freq_dict[n] for n in freq_dict.keys() if not i % n) | |
yield x if x else str(i) | |
def get_dict() -> Dict[int, str]: | |
""" | |
Generates the dictionary of numbers and phrases to feed to make_strings() | |
:return a dict in the form of {x: "something"} (which will output something every x) | |
""" | |
defaults: List[Tuple(int, str)] = [ | |
(5, "fizz"), | |
(3, "buzz"), | |
(7, "pow"), | |
(11, "pop"), | |
(17, "bang"), | |
] | |
i: int = 0 | |
d: Dict[int, str] = {} | |
cont: bool = True | |
def prompt(idx: int, num: int, phrase: str) -> bool: | |
""" | |
User-defined replacement definitions | |
:return whether to prompt for another replacement or not | |
""" | |
n: int = click.prompt( | |
"(0 to finish phrasebook creation)\n" + f"Chime in every n numbers", | |
default=num, | |
type=click.IntRange(0, None), | |
) | |
if not n: | |
return False | |
p: str = click.prompt( | |
"(negative number to treat these as normal numbers " | |
+ "and finish phrasebook creation)\n" | |
+ f"Say what every {n} numbers ", | |
default=phrase, | |
type=click.STRING, | |
) | |
if p[0] == "-": | |
return False | |
d[n] = p | |
return True | |
while cont: | |
ea: Tuple[int, str] = defaults[i] if i < len(defaults) else (0, f"-{i}") | |
cont = prompt(i, *ea) | |
i += 1 | |
return d | |
@click.command() | |
@click.option( | |
"-min", | |
type=click.INT, | |
help="Starting number", | |
default=1, | |
) | |
@click.option( | |
"-max", | |
type=click.INT, | |
default=100, | |
help="Stop number", | |
) | |
@click.option( | |
"-demo", | |
is_flag=True, | |
type=click.BOOL, | |
help="A normal fizzbuzz", | |
) | |
def main(min: int, max: int, demo: bool): | |
d: Dict[int, str] = {5: "fizz", 3: "buzz"} if demo else get_dict() | |
print("\n".join(make_strings(d, min, max))) | |
if __name__ == "__main__": | |
main() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Tonight's update: moved to using a generator and also improved the prompts.