|
| 1 | +# Ejercicios de práctica [Python] |
| 2 | +A esta altura del curso el alumno posee ya una serie de habilidades muy vinculadas entre si las cuales son: |
| 3 | +- Análisis, filtrado y trabajo de información. |
| 4 | +- Capacidad para utilizar formatos de datos de transacciones, APIs, Apps. |
| 5 | +- Poder mostrar los resultados en un gráfico y generar un reporte o un trablero de control. |
| 6 | + |
| 7 | +EL propósito de este ejercicio es que el alumno ponga a prueba estas facultades ya que este momento del curso es un momento bisagra, lo próximo que se verá de aquí en más son herramientas o procesos para mejorar estos 3 pilares (bases de datos, exponer una API, generar reportes web). |
| 8 | + |
| 9 | +# HackerRank [Python] |
| 10 | +Esta página posee ejercicios para poner a prueba a los programadores, muy utilizada en el ámbito profesional para evaluar posibles candidatos. En esta oportunidad hemos agarrado un ejercicio interesante de esta plataforma y almodado un poco para utilizar como ejercicio en esta oportunidad. |
| 11 | + |
| 12 | +# Enunciado |
| 13 | +El objetivo es consumir los datos que provee la siguiente URL:\ |
| 14 | +https://jsonmock.hackerrank.com/api/transactions/search?txnType=debit&page=1 |
| 15 | + |
| 16 | +Notar que al final de la URL aparece "__page=1__", en realidad esta URL admite que sea recorrida de la "__page=1__" hasta la page "__page=16__" ya que los datos están divididos en 16 consultas.\ |
| 17 | +En cada consulta recibiran datos como el siguiente (un extracto de ellos): |
| 18 | + |
| 19 | +``` |
| 20 | +{ |
| 21 | + "page":"1", |
| 22 | + "per_page":10, |
| 23 | + "total":155, |
| 24 | + "total_pages":16, |
| 25 | + "data":[{ |
| 26 | + "id":1, |
| 27 | + "userId":1, |
| 28 | + "userName":"John Oliver", |
| 29 | + "timestamp":1549536882071, |
| 30 | + "txnType":"debit", |
| 31 | + "amount":"$1,670.57", |
| 32 | + "location":{ |
| 33 | + "id":7, |
| 34 | + "address":"770, Deepends, Stockton Street","city":"Ripley", |
| 35 | + "zipCode":44139 |
| 36 | + }, |
| 37 | + "ip":"212.215.115.165" |
| 38 | + }, |
| 39 | + { |
| 40 | + "id":2, |
| 41 | + "userId":2, |
| 42 | + #..... |
| 43 | + } |
| 44 | + #..... |
| 45 | + ] |
| 46 | +} |
| 47 | +``` |
| 48 | + |
| 49 | +Lo que nos interesa de estos datos son el "__userId__", el consumo realizado en la variable "__amount__" y el location "__location__". |
| 50 | + |
| 51 | +## Primera etapa, el consumo de datos (fetch) |
| 52 | +Deben usar el módulo request como se vió en clase para consumir la URL provista en el enunciado. Recordar que la URL puede tener hasta 16 páginas, por lo que cuando realicen el request deben construir el string según la página que desean leer, un ejemplo para ello: |
| 53 | +``` |
| 54 | +url = https://jsonmock.hackerrank.com/api/transactions/search?txnType=debit&page={}.format(page_number) |
| 55 | +``` |
| 56 | +Deben crear una función llamada "fetch" que reciba como parámetro el número de la página que desean leer y el "location_id".\ |
| 57 | +``` |
| 58 | +dataset = fetch(page_number, location_id) |
| 59 | +``` |
| 60 | +La función fetch debe leer la página deseada y filtrar la información que les llega utilizando comprension de listas, ya que el dataset que retorna fetch debe ser aquellos "__userId__" cuyo "__location['id']__" coincida con el pasado como parámetro a la función.\ |
| 61 | +El dataset que retorna fetch debe ser una lista de diccionarios con la siguiente información por cada JSON: |
| 62 | +``` |
| 63 | +{"userId": ..., "amount": ...} |
| 64 | +``` |
| 65 | +dataset es una lista que contiene una fila como la anterior mostrada por cada conjunto de JSON que lea. Ejemplo: supongamos que el JSON que recibieron del request es (a modo de ejemplo resumido):\ |
| 66 | +``` |
| 67 | +{ |
| 68 | + "page":"5", |
| 69 | + "data":[{ |
| 70 | + "userId":3, |
| 71 | + "amount":"$1,670.57", |
| 72 | + "location":{ |
| 73 | + "id":7, |
| 74 | + }, |
| 75 | + }, |
| 76 | + { |
| 77 | + "userId":1, |
| 78 | + "amount":"$1,250.00", |
| 79 | + "location":{ |
| 80 | + "id":7, |
| 81 | + }, |
| 82 | + }, |
| 83 | + { |
| 84 | + "userId":3, |
| 85 | + "amount":"$100.00", |
| 86 | + "location":{ |
| 87 | + "id":7, |
| 88 | + }, |
| 89 | + }, |
| 90 | + |
| 91 | + #..... |
| 92 | + ] |
| 93 | +} |
| 94 | +``` |
| 95 | + |
| 96 | +Suponiendo que esos son los primeros 3 JSON contenidos en mi "data" retornado por request, donde en los 3 casos el location['id'] =7, si yo estaba buscando location_id = 7 mis primeras 3 filas de mi dataset serán: |
| 97 | +``` |
| 98 | +{"userId": 3, "amount": "$1,670.57"} |
| 99 | +{"userId": 1, "amount": "$1,250.00"} |
| 100 | +{"userId": 3, "amount": "$100.00"} |
| 101 | +``` |
| 102 | + |
| 103 | +## Transformación de la información (transform) |
| 104 | +Se debe realizar una función que reciba como parámetro el dataset creado en el punto anterior y transforme ese dataset (lista de diccionarios) en una lista con datos consolidados. Este función recibe como parámetro el dataset y retorna una lista "data": |
| 105 | +``` |
| 106 | +data = transform(dataset) |
| 107 | +``` |
| 108 | + |
| 109 | +La función transform realiza la contabilidad de cuanto monto total en débito realizó cada usuario (userID) en total. Por ejemplo, en el caso anterior donde nuestro dataset comenzaba con: |
| 110 | + |
| 111 | +``` |
| 112 | +{"userId": 3, "amount": "$1,670.57"} |
| 113 | +{"userId": 1, "amount": "$1,250.00"} |
| 114 | +{"userId": 3, "amount": "$100.00"} |
| 115 | +``` |
| 116 | + |
| 117 | +Si nuestro dataset solo tuviera esas 3 filas, debo sumar los dos débitos que realizó userID (consolidarlo) y mi lista final debe ser algo como la siguiente: |
| 118 | +``` |
| 119 | +[ |
| 120 | +[3, 1770.57] # 1770.57 = 1670.57 + 100 |
| 121 | +[1, 1250] |
| 122 | +] |
| 123 | +``` |
| 124 | + |
| 125 | +La lista que retorna "transform" como resultado es una lista de listas, en donde cada fila es la consolidación del débito de cada usuario. Difucultades para superar en este punto: |
| 126 | +- Los números están en texto y comienza con "$" y tienen puntos y comas, antes de poder sumarlos deben convertirlos a float con la siguiente línea: |
| 127 | +``` |
| 128 | +amount = float(re.sub(r'[^\d\-.]', '', amount_str)) # amount_str es el valor en string con el $ tomado del dataset |
| 129 | +``` |
| 130 | +- Deben poder consolidar la suma de cada usuario pero de buenas a primeras no saben cuantos usuarios existen o cuantos habrán. Les dejamos para que piensen como resolver esta problemática. |
| 131 | + |
| 132 | +## Reporte (report) |
| 133 | +Una vez que "transform" les haya transformado los datos en una lista de "[usuario, debito_total]", deben crear una función "report" que reciba como parámetro esos datos: |
| 134 | +``` |
| 135 | +report(data) |
| 136 | +``` |
| 137 | +Dentro de "report" deben utilizar comprension de listas para obtener una lista que represente a los valores de "X" como el ID de cada usuario, y una comprensión de listas que represente a los valores de "Y" como el valor de debito_total de cada uno: |
| 138 | +``` |
| 139 | +X = [ ... for x in data] |
| 140 | +Y = [ ... for x in data] |
| 141 | +``` |
| 142 | + |
| 143 | +Graficar los valores "X" e "Y" con el gráfico que más les parezca que puede representar que usuario ha realizado más consumo en débitos. |
| 144 | + |
| 145 | +## Esquema del ejercicio |
| 146 | +Deben crear su archivo de python y crear las funciones mencionadas en este documento. Deben crear la sección "if _name_ == "_main_" y ahí crear el flujo de prueba de este programa: |
| 147 | +``` |
| 148 | +if __name__ == "__main__": |
| 149 | + dataset = fetch(page_number, location_id) |
| 150 | + data = transform(dataset) |
| 151 | + report(data) |
| 152 | +
|
| 153 | +``` |
| 154 | + |
| 155 | + |
0 commit comments