Compare commits

...

3 commits

2 changed files with 99 additions and 31 deletions

View file

@ -1,37 +1,72 @@
import secrets
from . import lexique
from . import word_db
lex = lexique.Lexique.parse()
wdb = word_db.WordDb.autoload()
def gen_phrase4():
out = []
out.append(secrets.choice(lex.most_common(lexique.CatGram.ADJECTIF)))
out.append(secrets.choice(lex.most_common(lexique.CatGram.NOM)))
out.append(secrets.choice(lex.most_common(lexique.CatGram.VERBE)))
out.append(secrets.choice(lex.most_common(lexique.CatGram.NOM)))
return " ".join(map(lambda x: x.word, out))
"""Generates a sentence with four words, of structure Adjective Noun Verb Adverb"""
nombre = word_db.Nombre.pick()
temps = word_db.Temps.pick()
adj = secrets.choice(wdb.adjectifs)
nom = secrets.choice(wdb.noms)
verbe = secrets.choice(wdb.verbes)
adverbe = secrets.choice(wdb.adverbes)
return " ".join(
[
adj.accord(nom.genre_or_pick, nombre),
nom.accord(nombre),
verbe.accord(temps, nombre),
adverbe.accord(),
]
)
def gen_phrase6():
"""Generates a sentence with six words, of structure Adjective Noun Verb Adjective
Noun Adverb"""
nombres = [word_db.Nombre.pick() for _ in range(2)]
temps = word_db.Temps.pick()
adj0 = secrets.choice(wdb.adjectifs)
nom0 = secrets.choice(wdb.noms)
verbe = secrets.choice(wdb.verbes)
adj1 = secrets.choice(wdb.adjectifs)
nom1 = secrets.choice(wdb.noms)
adverbe = secrets.choice(wdb.adverbes)
return " ".join(
[
adj0.accord(nom0.genre_or_pick, nombres[0]),
nom0.accord(nombres[0]),
verbe.accord(temps, nombres[0]),
adj1.accord(nom1.genre_or_pick, nombres[1]),
nom1.accord(nombres[1]),
adverbe.accord(),
]
)
def gen_rand(n=4):
"""Generates a fully random sequence of n words, without grammatical consistency"""
out = []
for _ in range(n):
cat = secrets.choice(
(
lexique.CatGram.ADJECTIF,
lexique.CatGram.NOM,
lexique.CatGram.VERBE,
lexique.CatGram.ADVERBE,
)
)
out.append(secrets.choice(lex.most_common(cat)))
return " ".join(map(lambda x: x.word, out))
word_cat = secrets.choice(list(wdb.CATEGORY_TO_ATTR))
if word_cat == word_db.Nom:
nombre = word_db.Nombre.pick()
out.append(secrets.choice(wdb.noms).accord(nombre))
elif word_cat == word_db.Adjectif:
genre = word_db.Genre.pick()
nombre = word_db.Nombre.pick()
out.append(secrets.choice(wdb.adjectifs).accord(genre, nombre))
elif word_cat == word_db.Verbe:
temps = word_db.Temps.pick()
nombre = word_db.Nombre.pick()
out.append(secrets.choice(wdb.verbes).accord(temps, nombre))
elif word_cat == word_db.Adverbe:
out.append(secrets.choice(wdb.adverbes).accord())
def gen_nom(n=4):
out = []
for _ in range(n):
cat = lexique.CatGram.NOM
out.append(secrets.choice(lex.most_common(cat)))
return " ".join(map(lambda x: x.word, out))
return " ".join(out)

View file

@ -1,8 +1,11 @@
""" A pre-processed database of words, independant of their source """
import gzip
import json
import secrets
import typing as t
from enum import Enum
import json
from pathlib import Path
class Genre(Enum):
@ -10,17 +13,32 @@ class Genre(Enum):
FEM = "féminin"
INV = "invariable" # pour les noms uniquement
@classmethod
def pick(cls) -> "Genre":
"""random-pick (avoids inv)"""
return secrets.choice([cls.masc, cls.fem])
class Nombre(Enum):
SING = "singulier"
PLUR = "pluriel"
@classmethod
def pick(cls) -> "Nombre":
"""random-pick"""
return secrets.choice(list(cls))
class Temps(Enum):
PRESENT = "present"
FUTUR = "futur"
IMPARFAIT = "imparfait"
@classmethod
def pick(cls) -> "Temps":
"""random-pick"""
return secrets.choice(list(cls))
class Nom(t.NamedTuple):
"""Nom commun"""
@ -36,13 +54,20 @@ class Nom(t.NamedTuple):
"""Accorde en nombre"""
return getattr(self, nombre.name.lower())
@property
def genre_or_pick(self) -> Genre:
"""Genre of the noun, or random-pick if invariable"""
if self.genre == Genre.INV:
return Genre.pick()
return self.genre
@property
def serialized(self):
return {"genre": self.genre.name, "sing": self.sing, "plur": self.plur}
@classmethod
def unserialized(cls, **kwargs):
genre = Genre(kwargs.pop("genre"))
def unserialized(cls, kwargs):
genre = Genre[kwargs.pop("genre")]
return cls(**kwargs, genre=genre)
@ -64,7 +89,7 @@ class Adjectif(t.NamedTuple):
return self._asdict()
@classmethod
def unserialized(cls, **kwargs):
def unserialized(cls, kwargs):
return cls(**kwargs)
@ -88,7 +113,7 @@ class Verbe(t.NamedTuple):
return self._asdict()
@classmethod
def unserialized(cls, **kwargs):
def unserialized(cls, kwargs):
return cls(**kwargs)
@ -109,13 +134,15 @@ class Adverbe(t.NamedTuple):
return self._asdict()
@classmethod
def unserialized(cls, **kwargs):
def unserialized(cls, kwargs):
return cls(**kwargs)
class WordDb:
"""Base de donnée de mots, sérialisable"""
SERIALIZED_GZ_LOCATION = Path(__file__).parent.parent / "morphalou_full.json.gz"
_serialize_data: dict[str, t.Type[t.NamedTuple]] = {
"noms": Nom,
"adjectifs": Adjectif,
@ -171,3 +198,9 @@ class WordDb:
def load(cls, fd) -> "WordDb":
"""Unserialize from this stream"""
return cls.unserialize(json.load(fd))
@classmethod
def autoload(cls) -> "WordDb":
"""Unserialize from default source"""
with gzip.open(cls.SERIALIZED_GZ_LOCATION) as h:
return cls.load(h)