Created
June 23, 2023 14:32
-
-
Save btknight/e36d8172ed5992b9238db7de0b7d44bb to your computer and use it in GitHub Desktop.
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
"""The truth is, I thought it mattered -- | |
I thought that music mattered. | |
But does it bollocks? | |
Not compared to how people matter. | |
""" | |
from itertools import cycle, repeat | |
from operator import methodcaller | |
from typing import List | |
# Here, we apply DRY to something so very, very not dry. (In a few different ways!) | |
spoken_intro = __doc__ | |
sing_when_we_win = cycle(["(We'll be singing)", "(When we're winning)"]) | |
knock = cycle(['I get knocked down', 'but I get up again', "You're never gonna keep me down"]) | |
piss = repeat('Pissing the night away') | |
thing_for_him_to_do = cycle(['He drinks a %s drink', 'He sings the songs that remind him of the %s times']) | |
drink = cycle(['whiskey', 'vodka', 'lager', 'cider']) | |
remind_him = cycle(['good', 'better']) | |
danny = repeat('Danny Boy') | |
girls_drinking = cycle(['Oh, ' + ', '.join([x for _, x in zip(range(3), danny)]), | |
"Don't cry for me, next door neighbor"]) | |
ooh = repeat('(ooh)') | |
def get_knocked_down_gen(): | |
"""Generate background lyrics in the refrain at the song's end. Generated in sets of three lines.""" | |
i = 0 | |
while True: | |
yield lc_first_letter(next(sing_when_we_win)) | |
if i >= 4: | |
yield parenthesize(lc_first_letter(next(piss)), add_lf=False) | |
else: | |
yield '' | |
third_vocal = next(sing_when_we_win) | |
if i % 2 == 0: | |
yield lc_first_letter(third_vocal) | |
else: | |
yield next(ooh) | |
i += 1 | |
get_knocked_down_bkgd = get_knocked_down_gen() | |
def do_thing_to_first_letter(s: str, method: str) -> str: | |
"""Call a method on the first alphaballistic character in a string. Used to capitalize or lower-case a string.""" | |
mc = methodcaller(method) | |
for i in range(len(s)): | |
if s[i].isalpha(): | |
s = s[:i] + mc(s[i]) + s[i + 1:] | |
return s | |
return s | |
def cap_first_letter(s: str) -> str: | |
"""Capitalize the first letter in a string.""" | |
# Python's str.capitalize method lower-cases the "I"s. | |
return do_thing_to_first_letter(s, 'upper') | |
def lc_first_letter(s: str) -> str: | |
"""Lower-case the first letter in a string.""" | |
return do_thing_to_first_letter(s, 'lower') | |
def parenthesize(s: str, add_lf: bool = True) -> str: | |
if s[0] == '(' and s[-1] == ')': | |
return s | |
return f'({s})' + ('\n' if add_lf else '') | |
def join_two_phrases(join_str: str, lines: List[str], add_lf: bool = True) -> str: | |
if len(lines) > 2 or len(lines) == 0: | |
raise IndexError("Need one or two phrases to join on the same line") | |
a = cap_first_letter(lines[0]) | |
if len(lines) == 1 or lines[1] == '' or lines[1] is None: | |
return a + ('\n' if add_lf else '') | |
b = lc_first_letter(lines[1]) | |
return join_str.join([a, b]) + ('\n' if add_lf else '') | |
def intro() -> str: | |
preface = spoken_intro + '\n' | |
for _ in range(3): | |
preface += next(sing_when_we_win) + '\n' | |
next(sing_when_we_win) # discard next "when we're winning" | |
return preface | |
def get_knocked_down(background_vocals: bool = False) -> str: | |
"""Generates the refrain. | |
If background_vocals is False, returns a full 4 set stanza of getting knocked down. | |
If background_vocals is True, returns a single refrain as a stanza.""" | |
stanza = '' | |
if background_vocals: | |
for _ in range(3): | |
stanza += join_two_phrases(' ', [next(knock), next(get_knocked_down_bkgd)]) | |
else: | |
for _ in range(4): | |
stanza += join_two_phrases(', ', [next(knock), next(knock)]) | |
stanza += next(knock) + '\n' | |
return stanza | |
def take_the_piss() -> str: | |
return parenthesize(join_two_phrases(', ', [next(piss), next(piss)], add_lf=False)) | |
def drink_and_sing() -> str: | |
stanza = '' | |
he_drinks = next(thing_for_him_to_do) | |
for i in range(2): | |
stanza += join_two_phrases(', ', [he_drinks % x for _, x in zip(range(2), drink)]) | |
he_sings = next(thing_for_him_to_do) | |
for i in range(2): | |
stanza += he_sings % next(remind_him) + '\n' | |
stanza += parenthesize(next(girls_drinking)) | |
return stanza | |
def hell(): | |
print(intro()) | |
while True: | |
print(get_knocked_down()) | |
print(take_the_piss()) | |
print(drink_and_sing()) | |
def thump_tub(): | |
print(intro()) | |
for _ in range(2): | |
print(get_knocked_down()) | |
print(take_the_piss()) | |
print(drink_and_sing()) | |
print(get_knocked_down()) | |
for _ in range(16): | |
print(get_knocked_down(background_vocals=True)) | |
if __name__ == '__main__': | |
thump_tub() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment