</> Cómo funciona

feminizar

GET
/v1/feminizar

Función pura del español.

Parámetros

parámetrotipopor defectoqué hace
palabrastring— (obligatorio)el adjetivo masculino a feminizar
categoriastringopcionalpon `Adjetivos` para respetar los invariantes (recomendado)
singularbooleanTrue`false` si la entrada es plural

Cómo funciona (por dentro)

Mapa de funciones

flowchart TD
  MOD[("repositorio")]
  __init__["__init__()"]
  desde_json["🔒 desde_json()"]
  desde_dir["🔒 desde_dir()"]
  feminizar["feminizar()"]
  _load["🔒 _load()"]
  desde_dir --> _load
  __init__ -. datos .-> MOD
  desde_json -. datos .-> MOD
  feminizar -. datos .-> MOD
  _load -. datos .-> MOD
  classDef red fill:#fde7f0,stroke:#c0397b,color:#7a1e4d;
  class desde_json,desde_dir,_load,MOD red;

El código

# -*- coding: utf-8 -*-
"""
feminizador.py — saca el femenino de un lema/palabra en masculino.

Algoritmo, en tres pasos: 1) excepciones curadas  2) ¿ya es femenino? (léxico)  3) reglas por sufijo.
La rama -n/-s usa el silabeador/acentuador algorítmico (upln.py), ya validado 100%.

Datos:
  - excepciones curadas masculino→femenino + mapas de invariantes (del repositorio léxico).
Uso:
  from feminizador import Feminizador
  fem = Feminizador.desde_dir(directorio)
  fem.feminizar("niño")      -> "niña"
  fem.feminizar("campeón")   -> "campeona"
  fem.feminizar("rey")       -> "reina"   (excepción)
"""
import json
import os
import upln
try:
    import genero as _genero
except Exception:
    _genero = None


class Feminizador:
    def __init__(self, excepciones=None, mapa_femenino=None, mapa_aq0mn0=None,
                 usar_detector_genero=True):
        # excepciones: {masculino: resultado}  (resultado puede llevar varias sep. por coma)
        self.excepciones = excepciones or {}
        # mapa_femenino: palabras que YA son femeninas (invariantes) -> se devuelven igual
        self.mapa_femenino = mapa_femenino or {}
        # mapa_aq0mn0: adjetivos masculinos de número invariable -> o→a
        self.mapa_aq0mn0 = mapa_aq0mn0 or {}
        # detector de género por terminación: si es común (C) -> invariante, no se feminiza
        self.usar_detector_genero = usar_detector_genero and _genero is not None

    @classmethod
    def desde_json(cls, ruta):
        # […lectura del repositorio de excepciones…]
        return cls(excepciones=exc)

    @classmethod
    def desde_dir(cls, directorio):
        """Carga excepciones + mapas de léxico (invariante / AQ0MN0) si existen."""
        # […carga de excepciones y mapas del repositorio léxico (ficheros y esquema, internos)…]
        return cls(
            excepciones=exc,
            mapa_femenino={w: True for w in invar},
            mapa_aq0mn0={w: True for w in aq0mn0},
        )

    def feminizar(self, masculino, es_singular=True, categoria=None):
        """Devuelve el femenino de `masculino`. Para un LEMA, es_singular=True.

        `categoria`: si es 'Adjetivos' (o adj...), se usa el detector de género por
        terminación para respetar los invariantes (masticable, cantante). En sustantivos
        NO se aplica (usan otra tabla de terminaciones)."""
        if masculino is None:
            return None
        masculino = masculino.lower().strip()
        if masculino == "":
            return ""

        # 1. excepciones curadas
        if masculino in self.excepciones:
            return self.excepciones[masculino]

        # 2. ya es femenino / invariante en el léxico
        if masculino in self.mapa_femenino:
            return masculino

        # 2bis. detector de género por terminación (SOLO adjetivos): común (C) -> invariante
        if (self.usar_detector_genero and categoria
                and str(categoria).lower().startswith("adj")
                and _genero.es_invariable(masculino)):
            return masculino

        # adjetivo masculino de número invariable -> o→a
        if masculino in self.mapa_aq0mn0:
            return upln.remplace_last("o", "a", masculino)

        # 3. reglas por sufijo
        if es_singular:
            if masculino.endswith("que"):
                return upln.remplace_last("que", "ca", masculino)
            if masculino.endswith("ge"):
                return upln.remplace_last("ge", "ja", masculino)
            if masculino.endswith("gue"):
                return upln.remplace_last("gue", "ga", masculino)
            if masculino.endswith("güe"):
                return upln.remplace_last("güe", "gua", masculino)
            if masculino.endswith("e") or masculino.endswith("o"):
                return masculino[:-1] + "a"
            if masculino.endswith(("r", "z", "l")):
                return masculino + "a"
            if masculino.endswith(("n", "s")):
                sil = upln.silabear(masculino)
                pos = upln.int_silaba_tonica(sil)
                last = masculino[-1]
                r = upln.remplace_last(last, upln.SEPARADOR + last + "a", sil)
                r = upln.desacentuar_palabra(r)
                try:
                    r = upln.acentuar_silabeada(r, pos + 1)
                except Exception:
                    r = r.replace(upln.SEPARADOR, "")
                return r
            return masculino  # invariante
        else:  # plural
            if masculino.endswith("ques"):
                return upln.remplace_last("ques", "cas", masculino)
            if masculino.endswith("ges"):
                return upln.remplace_last("ges", "jas", masculino)
            if masculino.endswith("gues"):
                return upln.remplace_last("gues", "guas", masculino)
            if masculino.endswith("gües"):
                return upln.remplace_last("gües", "gas", masculino)
            if masculino.endswith("ces"):
                return upln.remplace_last("ces", "zas", masculino)
            if masculino.endswith("es"):
                return upln.remplace_last("es", "as", masculino)
            if masculino.endswith("os"):
                return upln.remplace_last("os", "as", masculino)
            return masculino


if __name__ == "__main__":
    # […pruebas del módulo (casos de ejemplo y comprobación)…]

Pruébalo

Llámala con el código a la vista.

Ejemplos con el SDK

curl "https://api.wordkers.com/v1/feminizar" \
  -H "X-API-Key: TU_CLAVE"

Cómo empezar con el SDK →

¿Quieres que cambie algo, o copiar la lógica para lo tuyo? Sin problema — escríbeme. Lo que ves es el algoritmo; los datos y las claves se quedan en casa.

Wordkers · Catálogo · Empezar · Tu cuenta