frhyme

guess the last phonemes of a French word
git clone https://a3nm.net/git/frhyme/
Log | Files | Refs | README

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.") +