class TemplateBank: def __init__(self, title_bank): self.markov = MarkovChain(3) for item in title_bank.values(): self.markov.add(item['title'].replace('—', '-')) def _random_template(self): title = self.markov.generate() replacements = {} tokens = [] doc = nlp(title) i = 0 for token in doc: # Consider named entities as single token. if token.ent_type_ in ('PERSON', 'FAC', 'GPE', 'LOC'): if token.ent_iob == 1: tokens[-2] += tokens[-1] + token.text tokens[-1] = token.whitespace_ else: tokens.append(token.text) tokens.append(token.whitespace_) replacements[i] = '[[PERSON]]' if token.ent_type_ == 'PERSON' else '[[LOC]]' i += 2 continue tokens.append(token.text) tokens.append(token.whitespace_) if token.tag_ in ("NN", "NNP"): replacements[i] = "[[NOUN]]" elif token.tag_ in ("NNS", "NNPS"): replacements[i] = "[[NOUNS]]" elif token.pos_ == "ADJ": replacements[i] = "[[ADJ]]" i += 2 if len(replacements) < 2: return None logger.debug('generated title: ' + ''.join(tokens)) # Create a template by replacing two random tokens with POS tags for i, replacement in random.sample(replacements.items(), 2): tokens[i] = replacement logger.debug('generated template: ' + ''.join(tokens)) return tokens def random_template(self): """Get random template from the bank.""" for i in range(0, 25): template = self._random_template() if template is not None: return template raise RecursionError("Title generation was unable to find fitting template.")
class MidiParser: def __init__(self, filename): self.filename = filename self.ticks = None self.tempo = get_tempo(filename) self.chain = MarkovChain() self.parse() def parse(self): """ reads midi and makes markov insertions """ midi = mido.MidiFile(self.filename) self.ticks = midi.ticks_per_beat prev = [] curr = [] for track in midi.tracks: for msg in track: if msg.type is 'note_on': if msg.time is 0: curr.append(msg.note) else: self.make_transition(prev, curr, msg.time) prev = curr curr = [] def make_transition(self, prev, curr, time): """ inserts all state transition possibilities into markov """ print(prev, curr, time) for i in prev: for j in curr: self.chain.add(i, j, self.millisecond(time)) def millisecond(self, ticks): """ tick to millisecond converter """ try: ms = ((ticks / self.ticks) * self.tempo) / 1000 return int(ms - (ms % 250) + 250) except TypeError: raise TypeError( "Could not read a tempo and ticks_per_beat from midi") def get_markov(self): return self.chain