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"}, )