Reorg repo
This commit is contained in:
0
busqueda/__init__.py
Normal file
0
busqueda/__init__.py
Normal file
164
busqueda/handler.py
Normal file
164
busqueda/handler.py
Normal file
@ -0,0 +1,164 @@
|
||||
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"},
|
||||
)
|
11
busqueda/handler_test.py
Normal file
11
busqueda/handler_test.py
Normal file
@ -0,0 +1,11 @@
|
||||
from .handler import handle
|
||||
|
||||
# Test your handler here
|
||||
|
||||
# To disable testing, you can set the build_arg `TEST_ENABLED=false` on the CLI or in your stack.yml
|
||||
# https://docs.openfaas.com/reference/yaml/#function-build-args-build-args
|
||||
|
||||
|
||||
def test_handle():
|
||||
# assert handle("input") == "input"
|
||||
pass
|
3
busqueda/requirements.txt
Normal file
3
busqueda/requirements.txt
Normal file
@ -0,0 +1,3 @@
|
||||
pygal
|
||||
requests
|
||||
pyrqlite
|
41
busqueda/tox.ini
Normal file
41
busqueda/tox.ini
Normal file
@ -0,0 +1,41 @@
|
||||
# If you would like to disable
|
||||
# automated testing during faas-cli build,
|
||||
|
||||
# Replace the content of this file with
|
||||
# [tox]
|
||||
# skipsdist = true
|
||||
|
||||
# You can also edit, remove, or add additional test steps
|
||||
# by editing, removing, or adding new testenv sections
|
||||
|
||||
|
||||
# find out more about tox: https://tox.readthedocs.io/en/latest/
|
||||
[tox]
|
||||
envlist = lint,test
|
||||
skipsdist = true
|
||||
|
||||
[testenv:test]
|
||||
deps =
|
||||
flask
|
||||
pytest
|
||||
-rrequirements.txt
|
||||
commands =
|
||||
# run unit tests with pytest
|
||||
# https://docs.pytest.org/en/stable/
|
||||
# configure by adding a pytest.ini to your handler
|
||||
pytest
|
||||
|
||||
[testenv:lint]
|
||||
deps =
|
||||
flake8
|
||||
commands =
|
||||
flake8 .
|
||||
|
||||
[flake8]
|
||||
count = true
|
||||
max-line-length = 127
|
||||
max-complexity = 10
|
||||
statistics = true
|
||||
# stop the build if there are Python syntax errors or undefined names
|
||||
select = E9,F63,F7,F82
|
||||
show-source = true
|
Reference in New Issue
Block a user