diff --git a/generate_instrument_1.py b/generate_instrument_1.py new file mode 100644 index 0000000..093be87 --- /dev/null +++ b/generate_instrument_1.py @@ -0,0 +1,51 @@ +#!python3 +import random + +"""generates a musical instrument by choosing at random a hornbostel-sachs category. + +this version is uniformly distributed between the options at each level, but does not include suffxes.""" + + +strip_dashes_and_dots = lambda x: x.replace("-", "").replace(".", "").replace(" ", "") +def generate_instrument(listing): + """ listing contains a hornbostel-sachs dictionary; this steps through index-by-index + picking numbers at random one by one until it's gotta stop, so this has even chances + of every category, rather than an even chance to every listing.""" + + nice_from_stripped = {strip_dashes_and_dots(x): x for x in listing.keys()} + stripped_keys = [strip_dashes_and_dots(x) for x in listing.keys()] + + prefix = random.choice([x for x in stripped_keys if len(x) == 1]) + + final_code = pick_code(prefix, [x for x in stripped_keys if x.startswith(prefix)]) + return nice_from_stripped[final_code] + +# this defines a threshhold for quitting early dependent on the length of the code so far. +# so there's a 0% chance of stopping with a zero-length code, 0% with a 1-length code, 1% with 2-length... +chance_of_stopping = [0, 0, 0.01, 0.01, 0.01, 0.05, 0.05, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2] +def pick_code(prefix, keys): + if random.random() < chance_of_stopping[len(prefix)]: + return prefix + + # only look at keys that are one longer than the current key + next_keys = [x for x in keys if len(x) == len(prefix) + 1] + if len(next_keys) == 0: + return prefix # if we can't find any successors then stop + + next_prefix = random.choice(next_keys) + + return pick_code(next_prefix, [x for x in keys if x.startswith(next_prefix)]) + + + + +if __name__ == "__main__": + with open("Hornbostel-Sachs") as f: + hornbostelsachs = {line.split(" ")[0]: " ".join(line.split(" ")[1:]) for line in f.readlines()} + + val = generate_instrument(hornbostelsachs) + + parents = [val[0:x+1] for x in range(len(val)) if val[x].isdigit()] + + for x in parents: + print(x, " : ", hornbostelsachs[x].strip())