</> Cómo funciona

masculinizar

GET
/v1/masculinizar

Función pura del español.

Parámetros

parámetrotipopor defectoqué hace
palabrastring— (obligatorio)la palabra en femenino
categoriastringopcional`Adjetivos` para respetar invariantes
singularbooleanTrue`false` si la entrada es plural

Cómo funciona (por dentro)

Mapa de funciones

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

El código

# -*- coding: utf-8 -*-
"""
masculinizador.py — saca el masculino de una palabra en femenino (la operación REVERSA).

Ir de femenino a masculino es a veces AMBIGUO (devuelve varias opciones separadas por
coma). Uso típico: normalizar una entrada a su forma canónica.

Algoritmo, en pasos: 1) excepciones curadas  2) adjetivo de número invariable (a→o)
3) ¿ya es masculino / invariante?  4) reglas por terminación (-ta / -na / -sa / -ra +
general a→o). Se apoya en el silabeador/acentuador algorítmico (upln).
"""
import json
import os
import upln
try:
    import genero as _genero
except Exception:
    _genero = None


class Masculinizador:
    def __init__(self, excepciones=None, mapa_aq0fn0=None, mapa_masculino=None,
                 usar_detector_genero=True):
        self.excepciones = excepciones or {}          # {femenino: masculino} curadas
        self.mapa_aq0fn0 = mapa_aq0fn0 or {}          # adjetivo femenino de número invariable -> a→o
        self.mapa_masculino = mapa_masculino or {}    # ya masculino / invariante -> se devuelve igual
        self.usar_detector_genero = usar_detector_genero and _genero is not None

    @classmethod
    def desde_dir(cls, d):
        """Construye el masculinizador cargando sus tablas de léxico."""
        # […carga de excepciones y mapas del repositorio léxico (ficheros y esquema, internos)…]
        return cls(excepciones=exc,
                   mapa_aq0fn0={w: True for w in aq},
                   mapa_masculino={w: True for w in invar})

    def masculinizar(self, femenino, es_singular=True, categoria=None):
        if femenino is None:
            return None
        femenino = femenino.lower().strip()
        if femenino == "":
            return ""

        if femenino in self.excepciones:                       # 1. excepciones curadas (reina→rey)
            return self.excepciones[femenino]
        if femenino in self.mapa_aq0fn0:                       # 2. adjetivo invariable de número: a→o
            return upln.remplace_last("a", "o", femenino)
        if femenino in self.mapa_masculino:                   # 3. ya masculino / invariante
            return femenino
        # adjetivos comunes (C) por terminación: no tienen masculino distinto
        if (self.usar_detector_genero and categoria
                and str(categoria).lower().startswith("adj")
                and _genero.es_invariable(femenino)):
            return femenino

        if es_singular:
            if not femenino.endswith("a"):                    # no acaba en 'a' -> ya es masculino
                return femenino
            # 4. acaba en 'a': reglas por terminación
            sil = upln.silabear(femenino)
            pos = upln.int_silaba_tonica(sil)
            if pos == 1:                                       # aguda -> misma palabra
                return femenino
            dos = femenino[-2:]
            if dos == "ta":
                # -eta/-anta/-enta/-ota admiten -e y -o (poeta→poete/poeto); resto a→o.
                if femenino.endswith(("eta", "anta", "enta", "ota")):
                    return upln.remplace_last("a", "e", femenino) + "," + upln.remplace_last("a", "o", femenino)
                return upln.remplace_last("a", "o", femenino)
            if dos == "na":
                # -ana/-ina/-ona/-una: a→o y además la variante en -n (leona→león).
                if femenino[-3:] in ("ana", "ina", "ona", "una"):
                    r = upln.remplace_last("a", "o", femenino)
                    sil2 = upln.remplace_last(upln.SEPARADOR + "na", "n", sil)
                    return r + "," + upln.acentuar_silabeada(sil2, pos - 1)
                return upln.remplace_last("a", "o", femenino)
            if dos == "sa":
                # -esa: a→o y variante en -s (condesa→condes / conde por excepción).
                if femenino[-3:] == "esa":
                    r = upln.remplace_last("a", "o", femenino)
                    sil2 = upln.remplace_last(upln.SEPARADOR + "sa", "s", sil)
                    return r + "," + upln.acentuar_silabeada(sil2, pos - 1)
                return upln.remplace_last("a", "o", femenino)
            if dos == "ra":
                # -dora/-ñora/-sora/-tora/-xora: se quita la 'a' (profesora→profesor).
                if femenino[-4:] in ("dora", "ñora", "sora", "tora", "xora"):
                    return upln.remplace_last("a", "", femenino)
                return upln.remplace_last("a", "o", femenino)
            return upln.remplace_last("a", "o", femenino)      # caso general a→o
        else:  # plural
            if femenino.endswith("zas"):
                return upln.remplace_last("zas", "ces", femenino) + "," + upln.remplace_last("zas", "zos", femenino)
            if femenino.endswith("as"):
                return upln.remplace_last("as", "es", femenino) + "," + upln.remplace_last("as", "os", femenino)
            return femenino


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/masculinizar" \
  -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