Skip to content

Instantly share code, notes, and snippets.

@jonfazzaro
Last active February 28, 2022 21:05
Show Gist options
  • Save jonfazzaro/2e8abc6a6e39cc8cbc39a0e515bd8149 to your computer and use it in GitHub Desktop.
Save jonfazzaro/2e8abc6a6e39cc8cbc39a0e515bd8149 to your computer and use it in GitHub Desktop.
class Verse:
def create(bottles):
return {
0: UltimateVerse(),
1: PenultimateVerse()
}.get(bottles, Verse(bottles))
def __init__(self, bottles):
self.bottles = bottles
def sing(self):
return (
f"{self.bottlesOfBeer()} on the wall, {self.bottlesOfBeer()}. " +
f"{self._passOne()}, {self._next()} on the wall.")
def bottlesOfBeer(self):
return f"{self.bottles} bottles of beer"
def _passOne(self):
return "Take one down, pass it around"
def _next(self):
return Verse.create(self.bottles - 1).bottlesOfBeer()
class PenultimateVerse(Verse):
def __init__(self):
self.bottles = 1
def bottlesOfBeer(self):
return "1 bottle of beer"
class UltimateVerse(Verse):
def __init__(self):
self.bottles = 0
def bottlesOfBeer(self):
return "No bottles of beer"
def _passOne(self):
return "There are no more to pass around"
def _next(self):
return self.bottlesOfBeer()
class Song:
def sing(self):
return "\n".join(
map(lambda b: self.__verse(b), range(self.bottles, -1, -1)))
def __init__(self, bottles):
self.bottles = bottles
def __verse(self, bottles):
return Verse.create(bottles).sing()
# Testing
class Test:
def __init__(self, expected, actual):
self.expected = expected
self.actual = actual
def run(self):
if self.actual == self.expected:
self.__green(self.__class__.__name__)
else:
self.__red("FAIL: " + self.__class__.__name__)
print(f"\nExpected:\n{self.expected}\n\nActual:\n{self.actual}\n\n")
raise Exception("FAIL")
def __red(self, message):
print("\033[91m {}\033[00m".format(message))
def __green(self, message):
print("\033[92m {}\033[00m".format(message))
__verses = {
2:
"2 bottles of beer on the wall, 2 bottles of beer. Take one down, pass it around, 1 bottle of beer on the wall.",
1:
"1 bottle of beer on the wall, 1 bottle of beer. Take one down, pass it around, No bottles of beer on the wall.",
0:
"No bottles of beer on the wall, No bottles of beer. There are no more to pass around, No bottles of beer on the wall."
}
def lyrics(*verseNumbers):
return "\n".join(map(lambda i: __verses[i], verseNumbers))
class Given0_SingsTheLastRound(Test):
def __init__(self):
self.expected = lyrics(0)
self.actual = Song(0).sing()
class Given1_SingsVerseOneAndTheLastRound(Test):
def __init__(self):
self.expected = lyrics(1, 0)
self.actual = Song(1).sing()
class Given2_SingsThreeVerses(Test):
def __init__(self):
self.expected = lyrics(2, 1, 0)
self.actual = Song(2).sing()
Given0_SingsTheLastRound().run()
Given1_SingsVerseOneAndTheLastRound().run()
Given2_SingsThreeVerses().run()
print(Song(99).sing())
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment