Last active
June 4, 2022 09:55
-
-
Save Ramblurr/f4b1145cc42ad840f1b372e4619f055e to your computer and use it in GitHub Desktop.
a quick script to generate a reherseal schedule for a street band
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
from itertools import cycle | |
from datetime import date, timedelta | |
import random | |
import math | |
from tabulate import tabulate | |
# How many weeks should we generate a probenplan for? | |
weeks = 6 | |
# What date does the first probe start on? | |
start_date = date(2022, 6, 8) | |
plan_format = { | |
# How many intensive songs should there be per probe? | |
"intensive": 1, | |
# How many durchspielen songs should there be per probe? | |
"durchspielen": 6, | |
# How many of the intensive songs should repeat the next week? | |
"repeat_intensive": 1, | |
# Should the song order be shuffled after one full rotation? | |
"shuffle": True, | |
} | |
# What are the numbers? | |
songs = [ | |
"Asterix", | |
"Bella Ciao", | |
"Cumbia Sobre el Mar", | |
"Der Zug um 7.40", | |
"Grenzrenner", | |
"Inner Babylon", | |
"Kids Aren't Alright", | |
# "Klezma 34", | |
"Laisse Tomber Les Filles", | |
"L’estaca del pueblo", | |
"Metanioa", | |
"Monkeys Rally", | |
"Montserrat Serrat", | |
"Rasta Funk", | |
"Tammurriata Nera", | |
"Tschufittl Cocek", | |
"You Move You Lose", | |
] | |
def gen_probe(plan_format, song_cycle, last_plan): | |
""" | |
Generates a probenplan for a single probe | |
""" | |
number_intensive = plan_format["intensive"] | |
number_durchspielen = plan_format["durchspielen"] | |
repeat_intensive = plan_format["repeat_intensive"] | |
assert ( | |
repeat_intensive <= number_intensive | |
), "the number of intensive to repeat must be less than or equal to the number of intensive" | |
intensive = [] | |
durchspielen = [] | |
for n in range(number_intensive): | |
s = next(song_cycle) | |
intensive.append(s) | |
if repeat_intensive > 0 and last_plan is not None: | |
for n in range(repeat_intensive): | |
s = last_plan["intensive"][n] | |
durchspielen.append(s) | |
durchspielen_start = repeat_intensive | |
durchspielen_fresh = number_durchspielen - repeat_intensive | |
else: | |
durchspielen_fresh = number_durchspielen | |
durchspielen_start = 0 | |
for n in range(durchspielen_start, durchspielen_fresh): | |
s = next(song_cycle) | |
durchspielen.append(s) | |
return {"intensive": intensive, "durchspielen": durchspielen} | |
def generate_probenplan(plan_format, weeks, songs): | |
""" | |
Generates a probenplan for a certain number of weeks and a given | |
repertoire. | |
The plan will be generated according to the plan format. | |
""" | |
song_cycle = cycle(songs) | |
plans = [] | |
weeks_till_cycle = len(songs) / ( | |
plan_format["intensive"] | |
+ (plan_format["durchspielen"] - plan_format["repeat_intensive"]) | |
) | |
if plan_format["shuffle"]: | |
random.shuffle(songs) | |
# I always round up to ensure we play every song at least once per cycle | |
# we might play some more than once, but that's math | |
round_weeks_till_cycle = math.ceil(weeks_till_cycle) | |
for week in range(weeks): | |
if plan_format["shuffle"] and week > 0 and week % round_weeks_till_cycle == 0: | |
random.shuffle(songs) | |
song_cycle = cycle(songs) | |
# print(f"shuffling at week {week}") | |
if week > 0: | |
last_plan = plans[-1] | |
else: | |
last_plan = None | |
probe = gen_probe(plan_format, song_cycle, last_plan) | |
plans.append(probe) | |
return plans, weeks_till_cycle | |
def inc_playcount(play_counts, song): | |
return play_counts.get(song, 0) + 1 | |
def report_table(plan): | |
records = [] | |
for n, s in enumerate(plan["intensive"]): | |
records.append(["intensive", s]) | |
for n, s in enumerate(plan["durchspielen"]): | |
records.append(["durchspielen", s]) | |
headers = ["type", "song"] | |
return tabulate(records, headers, tablefmt="github") | |
def report_play_counts(play_counts): | |
records = [] | |
for song, count in play_counts.items(): | |
records.append([song, count]) | |
headers = ["song", "num times played"] | |
return tabulate(records, headers, tablefmt="github") | |
def report_probenplan(plans, songs, start_date, weeks_till_cycle): | |
weeks = len(plans) | |
print("─" * 100) | |
print( | |
f"## Probenplan for {len(songs)} songs for {len(plans)} weeks starting on {start_date}" | |
) | |
play_counts = {} | |
for i, plan in enumerate(plans): | |
probe_date = start_date + timedelta(days=i * 7) | |
print(f"### week {i+1} {probe_date}") | |
for n, s in enumerate(plan["intensive"]): | |
play_counts[s] = inc_playcount(play_counts, s) | |
for n, s in enumerate(plan["durchspielen"]): | |
play_counts[s] = inc_playcount(play_counts, s) | |
print() | |
print(report_table(plan)) | |
print() | |
print("### Play Counts") | |
print(report_play_counts(play_counts)) | |
if __name__ == "__main__": | |
plans, weeks_till_cycle = generate_probenplan(plan_format, weeks, songs) | |
report_probenplan(plans, songs, start_date, weeks_till_cycle) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment