drime

French rhyme dictionary with web and CLI interface
git clone https://a3nm.net/git/drime/
Log | Files | Refs | README

commit dff02edab89173f241cbc29f69a40ea18f5ce67e
parent 8389a003af377fa7a78387645956525d2f5a4d29
Author: Antoine Amarilli <a3nm@a3nm.net>
Date:   Sat, 26 Oct 2013 11:46:28 +0200

support classical constraints

Diffstat:
README | 4+++-
TODO | 1-
drime.py | 1+
query.py | 25++++++++++++++++++++-----
templates/about.html | 12++++++++++++
templates/index.html | 12++++++++++++
templates/page.html | 12++++++++++++
7 files changed, 60 insertions(+), 7 deletions(-)

diff --git a/README b/README @@ -13,7 +13,9 @@ frequency, syllable count, and rhyme gender. drime requires the haspirater module <http://gitorious.org/haspirater/>. Just place the "haspirater.py" and "haspirater.json" file in the same folder as the -other files. +other files. It also requires the "rhyme.py" module from plint +<http://gitorious.org/plint/> that you should put in the same folder, along with +plint's own dependencies. == 3. Generating the DB == diff --git a/TODO b/TODO @@ -1,2 +1 @@ -règles classiques juste avec la prononciation diff --git a/drime.py b/drime.py @@ -35,6 +35,7 @@ def q(): 'q': request.args.get('query'), 'nsyl': request.args.get('nsyl'), 'gender': request.args.get('gender'), + 'classical': request.args.get('classical'), 'page': request.args.get('page'), } if not d['page']: diff --git a/query.py b/query.py @@ -6,6 +6,7 @@ import codecs import operator from db_mysql import run_query from common import from_xsampa, to_xsampa +from rhyme import Rhyme, Constraint PAGESIZE = 500 @@ -21,8 +22,15 @@ def lcs(x, y): break return i - 1 +def convert(x): + d = {'true': True, 'false': False} + try: + return d[x.lower()] + except KeyError: + raise BadValues + -def query(q, nsyl='', gender=True, page=0): +def query(q, nsyl='', gender=True, classical=True, page=0): if not page: page = 0 else: @@ -67,9 +75,8 @@ def query(q, nsyl='', gender=True, page=0): except ValueError: raise BadValues - return do_query(word, phon, minsyll, maxsyll, elide, gender, + return do_query(word, phon, minsyll, maxsyll, elide, gender, classical, page*PAGESIZE, PAGESIZE) -pass def decode_all(x): for k in x.keys(): @@ -92,7 +99,7 @@ def render_orig(row): [a[0] + (' ('+a[1]+')' if row['word'] != a[1] else '') for a in row['orig']]) -def do_query(word, phon, minsyll, maxsyll, elide, gender, offset, size): +def do_query(word, phon, minsyll, maxsyll, elide, gender, classical, offset, size): cursor = run_query(''' SELECT word, phon, word_end, phon_end, feminine, orig FROM words @@ -101,6 +108,7 @@ def do_query(word, phon, minsyll, maxsyll, elide, gender, offset, size): ''', (word, word == None, phon, phon == None,)) result = {} keys = [] + constraint = Constraint(1, True) for x in cursor: decode_all(x) key = get_key(x) @@ -138,6 +146,11 @@ def do_query(word, phon, minsyll, maxsyll, elide, gender, offset, size): if (row['word'] == word and row['word'] == word and ',' not in row['orig']): continue # don't display the word if it has only one possible origin + if classical: + rhyme = Rhyme(word.encode('utf-8'), constraint, phon=[phon]) + rhyme.restrict(Rhyme(row['word'].encode('utf-8'), constraint, phon=[row['phon']])) + if not rhyme.satisfied(): + continue # discard words following classical rules row['freq'] = float(row['freq']) row['phon_rhyme'] = lcs(phon, row['phon']) row['word_rhyme'] = lcs(word, row['word']) @@ -185,8 +198,10 @@ if __name__ == '__main__': sys.stdout = codecs.getwriter('utf8')(sys.stdout) def usage(): - print ("Usage: %s QUERY [NSYL [GENDER]]" % sys.argv[0]) + print ("Usage: %s QUERY [NSYL [GENDER [CLASSICAL]]]" % sys.argv[0]) try: + for p in [3, 4]: + sys.argv[p] = convert(sys.argv[p]) r, c = query(*sys.argv[1:]) except BadValues: print ("Bad values passed as arguments.") diff --git a/templates/about.html b/templates/about.html @@ -41,6 +41,12 @@ sont les rimes masculines ou féminines, vous pouvez regarder. <a href="https://fr.wikipedia.org/wiki/Rime#Genre_des_rimes_:_rimes_f.C3.A9minines_et_masculines">la page Wikipédia à ce propos</a>.</p> +<p>En cochant la case <strong>classique</strong>, vous forcez les résultats à +être une rime classique. (Ce sont les contraintes classiques qui disent que +"rang" rime avec "sang" ou "flanc" mais pas avec "grand".) Cette option ne fait +pas grand-sens sans imposer également le respect du genre. (Désolé, je ne trouve +pas de bonne référence pour en savoir plus là-dessus.)</p> + <h2>Quels sont les résultats manquants&nbsp;? (faux négatifs)</h2> <ul> <li>Le système ne fournira que des mots de son dictionnaire comme rimes. En @@ -124,6 +130,12 @@ gender. If you're unsure about what this is, see <a href="https://fr.wikipedia.org/wiki/Rime#Genre_des_rimes_:_rimes_f.C3.A9minines_et_masculines">the relevant Wikipedia page (in French)</a>.</p> +<p>The <strong>classical</strong> checkbox restricts the rhymes to those that +are allowed by French classical poetry constraints (according to which, e.g., +"rang" rhymes with "sang" or "flanc" but not with "grand"). If you select this +option, you should probably also enable the "gender" option. (Sorry, I can't +find a reference online to explain more about how classical rhymes work.)</p> + <h2>Which results are missing? (false negatives)</h2> <ul> <li>The system will only provide words from its dictionary. No proper nouns, for diff --git a/templates/index.html b/templates/index.html @@ -44,6 +44,18 @@ Only rhymes of matching gender? {% endif %} </label><br /> + <label id="classical_label"> + <input type="checkbox" id="classical" name="classical" + {% if (mode != 'query') or classical == 'on' %} + checked="{{ classical }}" + {% endif %} + /> + {% if lang == 'fr' %} + Respecter les contraintes classiques&nbsp;? + {% else %} + Only classical rhymes? + {% endif %} + </label><br /> <input id="submit" type="submit" {% if lang == 'fr' %} value="Chercher" diff --git a/templates/page.html b/templates/page.html @@ -57,6 +57,18 @@ gender? {% endif %} </label> + <label id="classical_label"> + <input type="checkbox" id="classical" name="classical" + {% if (mode != 'query') or classical == 'on' %} + checked="{{ classical }}" + {% endif %} + /> + {% if lang == 'fr' %} + classique&nbsp;? + {% else %} + classical? + {% endif %} + </label> <input type="submit" {% if lang == 'fr' %} value="Chercher"