Last active
December 26, 2015 12:09
-
-
Save freejoe76/7149133 to your computer and use it in GitHub Desktop.
This file contains hidden or 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
#!/usr/bin/env python | |
from pymarkov import markov | |
from random import choice | |
import doctest | |
import argparse | |
class Generate: | |
""" A song generator. Generate takes input (musician, album) and returns | |
a version of that musician's songs. | |
It expects songs in a text file, in a directory structure such as: | |
./music | |
/artist_name | |
album_title <-- that's the text-file, no extension | |
It requires pymarkov, via https://pypi.python.org/pypi/PyMarkov/0.1.0 | |
This version of pymarkov prints all input out, removing that print | |
statement increases sanity. | |
TODOs: | |
* Build out a whole song | |
* Build in song variance (self.attributes) | |
* How build a rhyme? | |
>>> generate = Generate('elliott_smith') | |
>>> song = generate.build_song('either_or') | |
>>> print song['title'] | |
Elliott Smith, Either Or | |
""" | |
def __init__(self, artist, phrase_length=2): | |
self.artist = artist | |
self.phrase_length = phrase_length | |
self.attributes = { | |
'song': ['no-rhyme', 'no-chorus'], | |
'stanza': [], | |
'chorus': ['one-line'], | |
'verse': [] | |
} | |
def build_line(self, markov_dict, length): | |
return markov.generate(markov_dict, length, self.phrase_length) | |
def build_stanza(self, markov_dict, lines): | |
i = 0 | |
line = [] | |
pattern_types = { | |
2: ['aa', 'ab'], | |
3: ['aaa', 'aba', 'aab', 'abb'], | |
4: ['aaaa', 'aaab', 'aabb', 'abbb', 'abba', 'aaba', 'abaa'] | |
} | |
#seed_lengths = [3, 4, 5, 6, 7, 8] | |
length_patterns = { | |
2: [[6, 6], [4,6], [4,8]], | |
3: [[6, 4, 6], [8, 4, 8]], | |
4: [[6, 4, 4, 6], [4, 4, 4, 4], [7, 2, 2, 7], [5, 5, 7, 7], [3, 3, 3, 3]] | |
} | |
length_pattern = choice(length_patterns[lines]) | |
while i < lines: | |
line += [self.build_line(markov_dict, length_pattern[i])] | |
i += 1 | |
return line | |
def build_song(self, album): | |
fp = 'music/%s/%s' % (self.artist, album) | |
try: | |
with open(fp, 'rb') as f: | |
text = f.read() | |
f.closed | |
except: | |
print 'Could not open album' | |
return False | |
markov_dict = markov.train([text], self.phrase_length) | |
return self.build_stanza(markov_dict, 4) | |
def main(args): | |
pass | |
def build_parser(): | |
""" This method handles command-line arguments. | |
""" | |
parser = argparse.ArgumentParser(usage='$ python generate.py', | |
description='', | |
epilog='') | |
parser.add_argument("-v", "--verbose", dest="verbose", default=False, action="store_true") | |
parser.add_argument("-a", "--artist", dest="artist", default="lana-del-rey") | |
parser.add_argument("-s", "--song", dest="song", default="all") | |
return parser | |
if __name__ == '__main__': | |
parser = build_parser() | |
args = parser.parse_args() | |
generate = Generate(args.artist, 3) | |
song = { 'body': generate.build_song(args.song) } | |
print '\n'.join(song['body']) |
This file contains hidden or 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
PyMarkov==0.1.0 | |
wsgiref==0.1.2 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Current example output:
separate from the victim of
images stuck in love with
nobody broke your heart you
throwing out now like it