165 lines
4.6 KiB
Python
165 lines
4.6 KiB
Python
import unicodedata
|
|
import urllib
|
|
from collections import namedtuple as nt
|
|
from dataclasses import dataclass
|
|
from json import loads
|
|
import logging
|
|
|
|
import pygal
|
|
import pyrqlite.dbapi2 as dbapi2
|
|
import requests
|
|
|
|
connection = dbapi2.connect(
|
|
host="10.61.0.1",
|
|
user="root",
|
|
port=4001,
|
|
password="",
|
|
)
|
|
|
|
|
|
def remove_accents(input_str):
|
|
nfkd_form = unicodedata.normalize("NFKD", input_str)
|
|
return "".join([c for c in nfkd_form if not unicodedata.combining(c)])
|
|
|
|
|
|
def femininidad(nombre):
|
|
sql1 = """
|
|
SELECT COALESCE(frecuencia,0)
|
|
FROM mujeres WHERE nombre=:nombre
|
|
"""
|
|
sql2 = """
|
|
SELECT COALESCE(frecuencia,0)
|
|
FROM hombres WHERE nombre=:nombre
|
|
"""
|
|
with connection.cursor() as cursor:
|
|
nombre = nombre.strip().split()[0].strip().upper()
|
|
mujeres = cursor.execute(sql1, {"nombre": nombre}).fetchone()
|
|
mujeres = 0 if mujeres is None else mujeres[0]
|
|
hombres = cursor.execute(sql2, {"nombre": nombre}).fetchone()
|
|
hombres = 0 if hombres is None else hombres[0]
|
|
if hombres == mujeres == 0:
|
|
return 0.5
|
|
return mujeres / (hombres + mujeres)
|
|
|
|
|
|
def split_por_genero(nombres):
|
|
femeninos = []
|
|
masculinos = []
|
|
for n in nombres:
|
|
fem = femininidad(n[1])
|
|
if fem is None:
|
|
femeninos.append(n)
|
|
masculinos.append(n)
|
|
elif fem >= 0.5:
|
|
femeninos.append(n)
|
|
else:
|
|
masculinos.append(n)
|
|
return {"f": femeninos, "m": masculinos}
|
|
|
|
|
|
def handle(req):
|
|
"""handle a request to the function
|
|
Args:
|
|
req (str): request body
|
|
|
|
{
|
|
p: prefijo del nombre,
|
|
g: genero del nombre,
|
|
a: año de nacimiento
|
|
}
|
|
|
|
"""
|
|
|
|
try:
|
|
data = loads(req)
|
|
except Exception as e:
|
|
data = {}
|
|
|
|
try:
|
|
prefijo = data.get("p") or None
|
|
genero = data.get("g") or None
|
|
try:
|
|
año = int(data.get("a"))
|
|
except Exception:
|
|
año = None
|
|
except Exception as e:
|
|
prefijo = genero = año = None
|
|
return f"{req} -- {e}", 400
|
|
|
|
if prefijo is not None:
|
|
prefijo = prefijo.strip().lower()
|
|
|
|
if genero not in ("f", "m"):
|
|
genero = None
|
|
|
|
if prefijo is None and año is None: # Totales globales
|
|
with connection.cursor() as cursor:
|
|
sql = """
|
|
SELECT total, nombre
|
|
FROM totales
|
|
ORDER BY total DESC
|
|
LIMIT 50
|
|
"""
|
|
cursor.execute(sql)
|
|
datos = [(r["total"], r["nombre"]) for r in cursor.fetchall()]
|
|
|
|
elif prefijo is None and año is not None: # Totales por año
|
|
with connection.cursor() as cursor:
|
|
sql = """
|
|
SELECT contador, nombre
|
|
FROM nombres
|
|
WHERE
|
|
anio = :anio
|
|
ORDER BY contador DESC
|
|
LIMIT 50
|
|
"""
|
|
cursor.execute(sql, {"anio": año})
|
|
datos = [(r["contador"], r["nombre"]) for r in cursor.fetchall()]
|
|
|
|
elif prefijo is not None and año is None:
|
|
with connection.cursor() as cursor:
|
|
sql = """
|
|
SELECT total, nombre
|
|
FROM totales
|
|
WHERE
|
|
nombre LIKE :nombre
|
|
ORDER BY total DESC
|
|
LIMIT 50
|
|
"""
|
|
cursor.execute(sql, {"nombre": f"{prefijo}%"})
|
|
datos = [(r["total"], r["nombre"]) for r in cursor.fetchall()]
|
|
else:
|
|
with connection.cursor() as cursor:
|
|
sql = """
|
|
SELECT contador, nombre
|
|
FROM nombres
|
|
WHERE
|
|
anio = :anio AND
|
|
nombre LIKE :nombre
|
|
ORDER BY contador DESC
|
|
LIMIT 50
|
|
"""
|
|
cursor.execute(sql, {"anio": año, "nombre": f"{prefijo}%"})
|
|
datos = [(r["contador"], r["nombre"]) for r in cursor.fetchall()]
|
|
|
|
if genero:
|
|
datos = split_por_genero(datos)[genero]
|
|
|
|
datos = datos[:10]
|
|
|
|
chart = pygal.HorizontalBar(height=400, show_legend=False, show_y_labels=True)
|
|
chart.x_labels = [nombre.title() for _, nombre in datos[::-1]]
|
|
if len(datos) > 1:
|
|
chart.title = f"¿Puede ser ... {datos[0][1].title()}? ¿O capaz que {datos[1][1].title()}? ¡Contáme más!"
|
|
elif len(datos) == 1:
|
|
chart.title = f"¡Hola {datos[0][1].title()}!"
|
|
elif len(datos) < 1:
|
|
chart.title = "¡No esssistís!"
|
|
chart.add("", [contador for contador, _ in datos[::-1]])
|
|
|
|
return (
|
|
chart.render(is_unicode=True),
|
|
200,
|
|
{"Content-Type": "image/svg+xml"},
|
|
)
|