Skip to content

Instantly share code, notes, and snippets.

@mos3abof
Created January 3, 2025 15:47
Show Gist options
  • Save mos3abof/91f2fc48cee252befe1f502bb85dbfdb to your computer and use it in GitHub Desktop.
Save mos3abof/91f2fc48cee252befe1f502bb85dbfdb to your computer and use it in GitHub Desktop.
CracklePop
#!/usr/bin/env python
import argparse
import json
import unittest
from typing import List
def what_to_print(number: int) -> str:
"""
Takes in a number:
- prints "Crackle" if number is divisible by 3
- prints "Pop" if number is divisible by 5
- prints "CrackPop" if number is divisible by both 3 and 5
- prints the number itself otherwise
"""
if number % 5 == 0 and number % 3 == 0:
return "CracklePop"
elif number % 3 == 0:
return "Crackle"
elif number % 5 == 0:
return "Pop"
else:
return str(number)
def crackle_pop(start: int, end: int) -> List[str]:
"""
Takes a start and end numbers (inclusive), iterates through the range and
prints the result of crackle_pop() for the range.
"""
if end < start:
raise ValueError("end must be greater than or equal to start")
result = []
for number in range(start, end + 1):
result.append(what_to_print(number))
return result
class TestWhatToPrint(unittest.TestCase):
"""
Minimum required test cases
"""
def test_what_to_print(self):
"""
Tests that crackle_pop() resturns the correct result
"""
test_cases = [
# (input, expected_result)
# Prints the number itself
(1, "1"),
(7, "7"),
(91, "91"),
# divisible by 3 only, prints "Crackle"
(3, "Crackle"),
# divisible by 5 only, prints "Pop"
(5, "Pop"),
(100, "Pop"),
# divisible by 3 and 5, prints "CracklePop"
(15, "CracklePop"),
(30, "CracklePop"),
(60, "CracklePop"),
]
for number, result in test_cases:
self.assertEqual(what_to_print(number), result)
def test_crackle_pop(self):
"""
Tests the correct range is processed
"""
test_cases = [
# (start, end, expected_result_length)
(1, 2, 2),
(1, 100, 100),
(50, 100, 51),
(1, 1, 1),
]
for start, end, expected_result_length in test_cases:
self.assertEqual(len(crackle_pop(start, end)), expected_result_length)
def test_crackle_pop_boundary(self):
"""
crackle_pop should not accept end that is less than start
"""
with self.assertRaises(ValueError):
crackle_pop(2, 1)
if __name__ == "__main__":
"""
Executes the CracklePop solution for the range 1 - 100 inclusive.
"""
parser = argparse.ArgumentParser(description="CracklePop progam.")
# Define positional arguments and flags
parser.add_argument(
"sub_command",
help="subcommand to run [run, test], default is run",
default="run",
)
parser.add_argument(
"--start", "-s", help="start of the range to examine", default=1
)
parser.add_argument(
"--end", "-e", help="end of range to examine, inclusive", default=100
)
parser.add_argument(
"--output",
help="output format.",
default="text",
)
# Parse the arguments
args = parser.parse_args()
print(args)
if args.sub_command == "test":
unittest.main(argv=["first-arg-is-ignored"], exit=False)
if args.sub_command == "run":
result = crackle_pop(int(args.start), int(args.end))
if args.output == "json":
print(json.dumps(result))
else:
# default is to print text
print("\n".join(result))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment