Skip to content

Instantly share code, notes, and snippets.

@whitmo
Created September 24, 2019 17:29
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save whitmo/bb626965321fab1f0c61d9eab0667ce7 to your computer and use it in GitHub Desktop.
Save whitmo/bb626965321fab1f0c61d9eab0667ce7 to your computer and use it in GitHub Desktop.
Crakkly Pop
"""
Write a program that prints out the numbers 1 to 100 (inclusive).
If the number is divisible by 3, print Crackle instead of the number.
If it's divisible by 5, print Pop. If it's divisible by both 3 and 5, print CracklePop.
"""
import sys
import io
import base64
def coroutine(func):
"from the beaz: http://www.dabeaz.com/coroutines/"
def start(*args,**kwargs):
cr = func(*args,**kwargs)
next(cr)
return cr
return start
@coroutine
def printer(template="({}) => {}".format, fh=sys.stdout):
"Receives input and 'prints' it to a file looking handle"
while True:
number, msg = (yield)
print(template(number, msg), file=fh)
@coroutine
def cracklepopper(outputter=printer(), tests={3:"Crackle", 5:"Pop"}):
"Receives integers and determines whether they crackle, pop, or both"
while True:
number = (yield)
outs = [tests[key] for key in sorted(tests.keys()) if number % key == 0]
msg = (number, "".join(outs))
if not outs:
msg = (number, number)
outputter.send(msg)
def main(howmany=101, cracklepopper=cracklepopper):
noisemaker = cracklepopper()
for num in range(1, howmany):
noisemaker.send(num)
# TEST STUFFS
expected_b64 = """
KDEpID0+IDEKKDIpID0+IDIKKDMpID0+IENyYWNrbGUKKDQpID0+IDQKKDUpID0+IFBvcAooNikgPT4gQ3JhY2tsZQooNykgPT4gNwooOCkgPT4gOAooOSkgPT4gQ3JhY2tsZQooMTApID0+IFBvcAooMTEpID0+IDExCigxMikgPT4gQ3JhY2tsZQooMTMpID0+IDEzCigxNCkgPT4gMTQKKDE1KSA9PiBDcmFja2xlUG9wCigxNikgPT4gMTYKKDE3KSA9PiAxNwooMTgpID0+IENyYWNrbGUKKDE5KSA9PiAxOQooMjApID0+IFBvcAooMjEpID0+IENyYWNrbGUKKDIyKSA9PiAyMgooMjMpID0+IDIzCigyNCkgPT4gQ3JhY2tsZQooMjUpID0+IFBvcAooMjYpID0+IDI2CigyNykgPT4gQ3JhY2tsZQooMjgpID0+IDI4CigyOSkgPT4gMjkKKDMwKSA9PiBDcmFja2xlUG9wCigzMSkgPT4gMzEKKDMyKSA9PiAzMgooMzMpID0+IENyYWNrbGUKKDM0KSA9PiAzNAooMzUpID0+IFBvcAooMzYpID0+IENyYWNrbGUKKDM3KSA9PiAzNwooMzgpID0+IDM4CigzOSkgPT4gQ3JhY2tsZQooNDApID0+IFBvcAooNDEpID0+IDQxCig0MikgPT4gQ3JhY2tsZQooNDMpID0+IDQzCig0NCkgPT4gNDQKKDQ1KSA9PiBDcmFja2xlUG9wCig0NikgPT4gNDYKKDQ3KSA9PiA0NwooNDgpID0+IENyYWNrbGUKKDQ5KSA9PiA0OQooNTApID0+IFBvcAooNTEpID0+IENyYWNrbGUKKDUyKSA9PiA1MgooNTMpID0+IDUzCig1NCkgPT4gQ3JhY2tsZQooNTUpID0+IFBvcAooNTYpID0+IDU2Cig1NykgPT4gQ3JhY2tsZQooNTgpID0+IDU4Cig1OSkgPT4gNTkKKDYwKSA9PiBDcmFja2xlUG9wCig2MSkgPT4gNjEKKDYyKSA9PiA2MgooNjMpID0+IENyYWNrbGUKKDY0KSA9PiA2NAooNjUpID0+IFBvcAooNjYpID0+IENyYWNrbGUKKDY3KSA9PiA2NwooNjgpID0+IDY4Cig2OSkgPT4gQ3JhY2tsZQooNzApID0+IFBvcAooNzEpID0+IDcxCig3MikgPT4gQ3JhY2tsZQooNzMpID0+IDczCig3NCkgPT4gNzQKKDc1KSA9PiBDcmFja2xlUG9wCig3NikgPT4gNzYKKDc3KSA9PiA3NwooNzgpID0+IENyYWNrbGUKKDc5KSA9PiA3OQooODApID0+IFBvcAooODEpID0+IENyYWNrbGUKKDgyKSA9PiA4MgooODMpID0+IDgzCig4NCkgPT4gQ3JhY2tsZQooODUpID0+IFBvcAooODYpID0+IDg2Cig4NykgPT4gQ3JhY2tsZQooODgpID0+IDg4Cig4OSkgPT4gODkKKDkwKSA9PiBDcmFja2xlUG9wCig5MSkgPT4gOTEKKDkyKSA9PiA5MgooOTMpID0+IENyYWNrbGUKKDk0KSA9PiA5NAooOTUpID0+IFBvcAooOTYpID0+IENyYWNrbGUKKDk3KSA9PiA5NwooOTgpID0+IDk4Cig5OSkgPT4gQ3JhY2tsZQooMTAwKSA9PiBQb3AK
"""
def test_main(
func,
cp=cracklepopper,
printer=printer,
expected=io.StringIO(base64.b64decode(expected_b64).decode('utf-8'))
):
"""Let's make sure main is outputting what we think it is
The big b64 blob above has the sequence of '(15) => CracklePop'
style statements in lines. We will assert they are the same as
those coming out of the main function.
"""
output = io.StringIO()
noisemaker = cp(printer(fh=output))
main(cracklepopper=cp)
for ex, actual in zip(expected.readlines(), output.readlines()):
assert ex == actual, "{} {}".format(ex, actual)
print("SEEMS GOOD OK")
if __name__ == "__main__":
main()
test_main(main)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment