Skip to content

Commit

Permalink
Merged changes
Browse files Browse the repository at this point in the history
  • Loading branch information
Pasha Sadikov committed Feb 9, 2014
1 parent 397903c commit 3793bc3
Show file tree
Hide file tree
Showing 14 changed files with 391 additions and 74 deletions.
57 changes: 57 additions & 0 deletions notes.org
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
Iambic Pentameter (10 syllables)

Pantoum
a1 b1 a2 b2
b1 c1 b2 c2
c1 d1 c2 d2
d1 e1 d2 e2
e1 f1 e2 f2
f1 a2 f2 a1

Sonnets
a b a b c d c d e f e f g g

Limericks
a a b b a (a: 8-10 syllables, b: 5-7 syllables)

Dodoitsu
7 7 7 5 (no rhyme

Rondeau
a a b b a a a b R
a a b b a R
(a: 8, b: 5, R: 2)

Something something normalizing syllable weights.

-----------------

GENERAL:

Remove single element families.

Cast odd -> even based on weights.

Since we're only dealing with even sets, maybe it makes sense to take the largest and start with that.

Alternative-merge:
Take largest
Alternate with second largest
When that's gone, return the poem.
Recur on the remainder.

If families don't rhyme (a b c d e ...), try haikus or dodoitsus.
Else, free form and sort by syllable.

Facebook: Tokenize by sentence.

TO-DO:::::
Form predicate functions.
General algorithm.
Alternative merging.
Free form cases.
Normalize weights.
-- FB Oauth bug
-- Tweet 0> Algorithm
-- Github...

104 changes: 104 additions & 0 deletions poemdao.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
import json
from poemline import PoemLine
from itertools import combinations

"""
General data access object for the poem
Handles individual lines and poem families
"""

class Poem:
def __init__(self,rhyme_families,lines, syls):
self.rhyme_families = rhyme_families
self.lines = lines
self.syllables = syls

def __init__(self):
# number of rhyme families in poem
self.rhyme_families = []
# array of poemline objects
self.lines = []
# syllables and lines count
self.syllables = {}

"""
sets the lines based on raw_json passed
makes the rhyme families
sets syllable counts
"""
def create_poem(self, raw_json):
data = json.loads(raw_json)
for i in data:
pline = PoemLine()
pline.create_poemline(data[i])
self.lines.append(pline)
self.make_fam()
for poem in self.lines:
try:
self.syllables[poem.syl].append(poem)
except Exception as e:
self.syllables[poem.syl] = [poem]


"""
Takes two sets, returns percentage of similiar words
"""
def match_percentage(self, listA, listB):
if (len(listA)+len(listB))==0:
return 0
else:
return (2.*len(listA&listB))/(len(listA)+len(listB))

"""
WORKS BUT DEPRECATED
"""
def make_families(self):
seen = {}
set_num = 0
families = {}
for s in self.lines:
seen[set_num]=[s.rhymes,False]
set_num+=1
combs = combinations(self.lines, 2)
q = 0
for i in combs:
if self.match_percentage(i[0].rhymes,i[1].rhymes) > .49:
families[q]=i[0].rhymes|i[1].rhymes
q+=1
self.mark_seen(i[0].rhymes,seen)
self.mark_seen(i[1].rhymes,seen)
elif (len(i[0].rhymes)+len(i[1].rhymes))==0:
self.mark_seen(i[0].rhymes,seen)
self.mark_seen(i[1].rhymes,seen)
for s in seen:
if (not seen[s][1]):
families[q]=seen[s][0]
q+=1
self.rhyme_families = families

def make_fam(self):
q=0
for line in self.lines:
for l2 in self.lines:
if (line != l2):
print line.rhymes
print l2.rhymes
print self.match_percentage(line.rhymes,l2.rhymes)
if (self.match_percentage(line.rhymes,l2.rhymes) > .01):
line.family.append(q)
l2.family.append(q)
q+=1
elif ((len(line.rhymes)+len(l2.rhymes))==0):
line.family.append(-1)
l2.family.append(-1)


"""
Helper function for make_families
"""
def mark_seen(self, setA, seen):
for s in seen:
if (seen[s][0]==setA):
seen[s][1]=True
seen[s][1]

31 changes: 22 additions & 9 deletions poemline.py
Original file line number Diff line number Diff line change
@@ -1,13 +1,26 @@
class PoemLine:
"""A line in the poem"""
"""A line in the poem"""

def __init__(self, syl, family, rhymes):
self.syl = syl
self.family = family
self.rhymes = rhymes
def __init__(self, syl, family, rhymes, originalString, cleanString):
self.syl = syl
self.family = family
self.rhymes = rhymes
self.originalString = originalString
self.cleanString = cleanString

def __init__(self):
self.syl = 0
self.family = ""
self.rhymes = {}
def __init__(self):
self.originalString = ""
self.cleanString = ""
self.syl = 0
self.family = []
self.rhymes = {}

def create_poemline(self, string):
# original text
self.originalString = string
# texts without symbols or urls
self.cleanString = remove_symbols(remove_urls(string))
# number of syllables in line
self.syl = line_syl(self.cleanString)
# rhymes against last word
self.rhymes = rhyme(string.split()[-1], self.RHYME_LEVEL)
1 change: 1 addition & 0 deletions poetification/cmudict_data.sql

Large diffs are not rendered by default.

18 changes: 18 additions & 0 deletions poetification/poetification/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,24 @@
'webpoet',
)

AUTHENTICATION_BACKENDS = (
'social_auth.backends.twitter.TwitterBackend',
'social_auth.backends.facebook.FacebookBackend',
'social_auth.backends.contrib.github.GithubBackend',
)

TWITTER_CONSUMER_KEY = os.environ['P_APP_KEY']
TWITTER_CONSUMER_SECRET = os.environ['P_APP_SECRET']
FACEBOOK_APP_ID = ''
FACEBOOK_API_SECRET = ''
LOGIN_URL = '/login-form/'
LOGIN_REDIRECT_URL = '/logged-in/'
LOGIN_ERROR_URL = '/login-error/'
SOCIAL_AUTH_COMPLETE_URL_NAME = 'socialauth_complete'
SOCIAL_AUTH_ASSOCIATE_URL_NAME = 'socialauth_associate_complete'
SOCIAL_AUTH_DEFAULT_USERNAME = 'new_social_auth_user'
SOCIAL_AUTH_FORCE_POST_DISCONNECT = True

MIDDLEWARE_CLASSES = (
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
Expand Down
7 changes: 7 additions & 0 deletions poetification/webpoet/lineutils.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import re

def remove_urls(string):
return re.sub(r'((https?):((//)|(\\\\))+([\w\d:#@%/;$()~_?\+-=\\\.&](#!)?)*)', ' ', string)

def remove_symbols(string):
return re.sub(r'[^\w]', ' ', string)
38 changes: 38 additions & 0 deletions poetification/webpoet/management/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
# from django.db.models.signals import post_syncdb
# from nltk.corpus import cmudict
# import webpoet.models as M
# import nltk
# import re

# def cmudict_callback(sender, **kwargs):
# # Match syllable inflection
# rc = re.compile(r'\d{1}')
# try:
# entries = cmudict.entries()

# except LookupError as le:
# # download cmudict package!
# nltk.download('cmudict')
# entries = cmudict.entries()

# finally:
# for entry in entries:
# phonemes = entry[1]
# vowels = filter(lambda x: rc.search(x[1]), enumerate(phonemes))
# syllables = len(vowels)
# try:
# lastphonemes = phonemes[vowels[-1][0]:]
# except: continue

# rhyme_phoneme = rc.sub('', ''.join(lastphonemes))
# try:
# rhymeword =\
# M.RhymeWord.objects.get(word=entry[0],
# syllables=syllables,
# rhyme_phoneme=rhyme_phoneme)
# except:
# M.RhymeWord(word=entry[0],
# syllables=syllables,
# rhyme_phoneme=rhyme_phoneme).save()

# post_syncdb.connect(cmudict_callback, sender=M)
67 changes: 64 additions & 3 deletions poetification/webpoet/models.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,71 @@
from django.db import models
from django.contrib.auth.models import User
import urllib, json
from lineutils import *
from collections import defaultdict

# Create your models here.
class Poem(models.Model):
created = models.DateTimeField()
created = models.DateTimeField(auto_now_add=True, blank=True)

# expects a list of phrases
@staticmethod
def getFamilies(phrases):
families = defaultdict(set)
for p in phrases:
words = remove_symbols(remove_urls(p)).split()

lastword = RhymeWord.findWord(words[-1])

if not lastword:
continue

families[lastword.rhyme_phoneme].append(one, two)

return families


class Line(models.Model):
poem = models.ForeignKey(Poem)
text = models.CharField(max_length=256, blank=True, null=False)
text = models.CharField(max_length=2048, blank=True, null=False)
syllables = models.IntegerField()


class RhymeWord(models.Model):
RBRAIN="http://rhymebrain.com/talk?function=getWordInfo&word="

word = models.CharField(max_length=128)
syllables = models.IntegerField(db_index=True, null=False)
rhyme_phoneme = models.CharField(max_length=32,
blank=False,
db_index=True,
null=False)
class Meta:
unique_together = ['word', 'syllables', 'rhyme_phoneme']


def rhymesWith(self, other):
return other.rhyme_phoneme == self.rhyme_phoneme


@staticmethod
def findWord(word):
try:
rw = RhymeWord.objects.get(word=word)
except:
f = urllib.urlopen(RhymeWord.RBRAIN + word)
phonemes = json.loads(f.read())['pron'].split()
rc = re.compile(r'\d{1}')
vowels = filter(lambda x: rc.search(x[1]), enumerate(phonemes))
syllables = len(vowels)
if syllables == 0:
rw = None
else:
lastphonemes = phonemes[vowels[-1][0]:]
rhyme_phoneme = rc.sub('', ''.join(lastphonemes))
rw = RhymeWord(word=word,
syllables=syllables,
rhyme_phoneme=rhyme_phoneme)
rw.save()
finally:
return rw

16 changes: 16 additions & 0 deletions poetification/webpoet/poemtypes.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
class Pantoum:

@staticmethod


class Sonnet:
pass

class Limerick:
pass

class Dodoitsu:
pass

class Rondeau:
pass
9 changes: 4 additions & 5 deletions poetification/webpoet/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,7 @@ def home(request):
poems = Poem.objects.all()
context = RequestContext(request, {'poems' : poems})
return HttpResponse(template.render(context))

def new(request):
template = loader.get_template('webpoet/new.html')
context = RequestContext(request, {})
return HttpResponse(template.render(context))
# def new(request):
# template = loader.get_template('webpoet/new.html')
# context = RequestContext(request, {})
# return HttpResponse(template.render(context))
1 change: 1 addition & 0 deletions requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,4 @@ requests-oauthlib==0.4.0
simplejson==3.3.2
twython==3.1.2
wsgiref==0.1.2
python-social-auth==0.1.21
Loading

0 comments on commit 3793bc3

Please sign in to comment.