commit ef2bd441a1b6e0c08dea152114e9e30d2ec53155
parent b4c99425c0ddc4fb5349107e657bbb688d1a244a
Author: Antoine Amarilli <a3nm@a3nm.net>
Date: Sun, 12 Jun 2011 21:23:07 -0400
more generic version, add assonance, etc.
Diffstat:
rhyme.py | | | 122 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
1 file changed, 122 insertions(+), 0 deletions(-)
diff --git a/rhyme.py b/rhyme.py
@@ -0,0 +1,122 @@
+#!/usr/bin/python3 -u
+
+"""Determine if a French word starts by an aspirated 'h' or not, by a
+lookup in a precompiled trie"""
+
+import os
+import re
+import sys
+from pprint import pprint
+import pron
+import functools
+
+vowel = list("Eeaio592O#@y%u")
+
+def suffix(x, y):
+ bound = min(len(x), len(y))
+ for i in range(bound):
+ if x[-(1+i)] != y[-(1+i)]:
+ return i
+ return bound
+
+def rhyme(x, y):
+ print ("test: %s %s" % (x, y))
+ l = suffix(x, y)
+ for c in x[-l:]:
+ if c in vowel:
+ return l
+ return 0
+
+def strip_consonants(x):
+ return [a for a in x if a in vowel or a == 'j']
+
+def assonance_rhyme(x, y):
+ return rhyme(strip_consonants(x), strip_consonants(y))
+
+def eye_rhyme(x, y):
+ return suffix(x, y)
+
+def concat_couples(a, b):
+ pprint(a)
+ pprint(b)
+ l = set()
+ for x in a:
+ for y in b:
+ l.add(x + y)
+ return l
+
+def lookup(s):
+ #TODO split words
+ s = s.split(' ')[-3:]
+ sets = list(map((lambda a : set([x[1] for x in
+ pron.lookup(escape(a))])), s))
+ print("HERE")
+ pprint(sets)
+ return functools.reduce(concat_couples, sets, set(['']))
+
+
+def init_rhyme(line, constraint):
+ return (lookup(line), line, constraint)
+
+def max_constraints(a, b):
+ return (max(a[0], b[0]), max(a[1], b[1]), max(a[2], b[2]))
+
+def check_rhyme(current, new):
+ oldp, old, old_constraints = current
+ new, new_constraints = new
+ constraints = max_constraints(new_constraints, old_constraints)
+ newp = lookup(new)
+ newp_r, new_r = match(oldp, old, newp, new, constraints)
+ return (newp_r, new_r, constraints)
+
+def match(ap, a, bp, b, constraints):
+ # ap is the possible pronunciations, a the only possible writing
+ normalc, eyec, assonancec = constraints
+ rp = set()
+ for x in ap:
+ for y in bp:
+ val = rhyme(x, y)
+ #print ("%s = %s" % (x, y))
+ if val >= normalc:
+ rp.add(x[-val:])
+ val = assonance_rhyme(x, y)
+ #print ("%s = %s" % (x, y))
+ if val >= assonancec:
+ rp.add(x[-val:])
+ if a != None:
+ val = eye_rhyme(a, b)
+ if val < eyec:
+ r = None
+ else:
+ r = line[0][-val:]
+ else:
+ r = None
+ return rp, r
+
+#TODO lexique sucks
+def escape(t):
+ return re.sub('œ', 'oe', re.sub('æ', 'ae', t))
+
+if __name__ == '__main__':
+ while True:
+ line = sys.stdin.readline()
+ if not line:
+ break
+ line = line.lower().lstrip().rstrip().split(' ')
+ if len(line) < 1:
+ print("Usage: rimebot: WORD...")
+ continue
+ constraint = (99, 99, 3)
+ np, p, c = init_rhyme(line[0], constraint)
+ ok = True
+ for x in line[1:]:
+ pprint(np)
+ np, n, c = check_rhyme((np, p, c), (x, constraint))
+ pprint(np)
+ if n == None and len(np) == 0:
+ print("Non.")
+ ok = False
+ break
+ if ok:
+ print ("OK.")
+