├── Ayudantías ├── heroku-tutorial-app │ ├── Procfile │ ├── Pipfile │ ├── app.py │ ├── requirements.txt │ └── Pipfile.lock ├── Ay_examen.pdf ├── Ayudantía I1.pdf ├── Ayudantía I2.pdf ├── Ayudantía I3.pdf ├── Ayudantía 1 │ ├── banco.db │ ├── Ayudantía1.pdf │ └── Ayudantía1.pdf ├── AyudantiaAPI │ ├── release │ │ ├── Procfile │ │ ├── static │ │ │ └── plot.png │ │ ├── templates │ │ │ └── plot.html │ │ ├── Pipfile │ │ ├── README.md │ │ ├── usuarios.json │ │ ├── PostmanCollection.json │ │ ├── main.py │ │ └── Pipfile.lock │ └── Ayudantía_APIs.pdf ├── Solucion_AyudExamen │ ├── compras.csv │ ├── usuarios.csv │ ├── productos.csv │ └── neo4j.txt ├── Solución Ayudantía I3 (P4).pdf ├── AyudantiaPHP │ ├── app │ │ ├── config │ │ │ ├── data.php │ │ │ └── conexion.php │ │ ├── templates │ │ │ ├── footer.html │ │ │ └── header.html │ │ ├── consultas │ │ │ ├── consulta_altura.php │ │ │ ├── consulta_tipo_nombre.php │ │ │ └── consulta_tipo.php │ │ ├── index.php │ │ └── datos │ │ │ └── ejercicio_ayudantia.csv │ ├── Ayudantia_HTML_PHP.pdf │ ├── diagrama_arquitectura.png │ └── php_basico.php └── Solución Ayudantía I1 (C 6,7,9,10).pdf ├── Guías ├── Guía I1.pdf ├── Guía I2.pdf └── Guía I3.pdf ├── Slides ├── 03 - SQL.pdf ├── 06 - Vistas.pdf ├── 15 - TF-IDF.pdf ├── 01 - Motivación.pdf ├── 11 - Recursión.pdf ├── 04 - SQL Avanzado.pdf ├── 08 - Foreign Keys.pdf ├── 09 - Dependencias.pdf ├── 14 - JSON y NoSQL.pdf ├── 02 - Modelo Relacional.pdf ├── 05 - Algunas Consultas.pdf ├── 12 - Programación y SQL.pdf ├── 10 - Nulos y Outer Joins.pdf ├── 16 - Transacciones - 2PL.pdf ├── 17 - Recuperación de Fallas.pdf ├── 07 - Diseño de Bases de Datos.pdf └── 13 - Almacenamiento - Índices - Algorítmos.pdf ├── Programa └── Programa.pdf ├── Actividades ├── Neo4J │ └── Neo4J.pdf ├── Casen │ ├── Datos │ │ ├── casen.db │ │ └── comunas.csv │ └── Actividad Casen.pdf ├── Índices │ └── Índices.pdf ├── Álgebra Relacional │ ├── Álgebra Relacional.pdf │ └── Álgebra Relacional - Solución.pdf ├── Dependencias Funcionales │ └── Dependencias Funcionales.pdf ├── MongoDB │ ├── Datos │ │ ├── productos.json │ │ ├── usuarios.json │ │ └── mensajes.json │ └── MongoDB.ipynb ├── Psycopg2 │ └── Psycopg2.ipynb ├── Recursión │ └── Recursión.ipynb ├── Text Search │ └── Text Search.ipynb ├── Procedimientos Almacenados │ ├── Procedimientos Almacenados 1.ipynb │ ├── Procedimientos Almacenados 2.ipynb │ └── Procedimientos Almacenados - Guía.ipynb └── Pandas │ └── comunas.csv ├── Interrogaciones ├── I1 │ ├── I1.pdf │ └── I1 Rúbrica.pdf ├── I2 │ ├── I2.pdf │ └── I2 Rúbrica.pdf └── I3 │ ├── I3.pdf │ └── I3 Rúbrica.pdf ├── Proyecto ├── Datos SQL │ ├── Datos.zip │ └── readme.md ├── Entregas │ ├── Entrega 1.pdf │ ├── Entrega 2.pdf │ ├── Entrega 3.pdf │ ├── Entrega 4.pdf │ └── Entrega 5.pdf ├── Tests │ └── Entrega 2 │ │ └── Consultas.zip └── Tutoriales │ └── Tutorial SQLite y servidor.pdf ├── Interrogaciones Anteriores ├── I1 │ ├── I1 - 2017-2.pdf │ └── I1 - 2018-2.pdf ├── I2 │ ├── I2 - 2017-2.pdf │ └── I2 - 2018-2.pdf ├── I3 │ ├── I3 - 2017-2.pdf │ └── I3 - 2018-2.pdf └── Examen │ └── 2018-2 - Examen.pdf ├── .gitignore └── readme.md /Ayudantías/heroku-tutorial-app/Procfile: -------------------------------------------------------------------------------- 1 | web: gunicorn app:app -------------------------------------------------------------------------------- /Guías/Guía I1.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alanezz/Syllabus-2019-1/HEAD/Guías/Guía I1.pdf -------------------------------------------------------------------------------- /Guías/Guía I2.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alanezz/Syllabus-2019-1/HEAD/Guías/Guía I2.pdf -------------------------------------------------------------------------------- /Guías/Guía I3.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alanezz/Syllabus-2019-1/HEAD/Guías/Guía I3.pdf -------------------------------------------------------------------------------- /Slides/03 - SQL.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alanezz/Syllabus-2019-1/HEAD/Slides/03 - SQL.pdf -------------------------------------------------------------------------------- /Programa/Programa.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alanezz/Syllabus-2019-1/HEAD/Programa/Programa.pdf -------------------------------------------------------------------------------- /Slides/06 - Vistas.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alanezz/Syllabus-2019-1/HEAD/Slides/06 - Vistas.pdf -------------------------------------------------------------------------------- /Slides/15 - TF-IDF.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alanezz/Syllabus-2019-1/HEAD/Slides/15 - TF-IDF.pdf -------------------------------------------------------------------------------- /Ayudantías/Ay_examen.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alanezz/Syllabus-2019-1/HEAD/Ayudantías/Ay_examen.pdf -------------------------------------------------------------------------------- /Actividades/Neo4J/Neo4J.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alanezz/Syllabus-2019-1/HEAD/Actividades/Neo4J/Neo4J.pdf -------------------------------------------------------------------------------- /Ayudantías/Ayudantía I1.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alanezz/Syllabus-2019-1/HEAD/Ayudantías/Ayudantía I1.pdf -------------------------------------------------------------------------------- /Ayudantías/Ayudantía I2.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alanezz/Syllabus-2019-1/HEAD/Ayudantías/Ayudantía I2.pdf -------------------------------------------------------------------------------- /Ayudantías/Ayudantía I3.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alanezz/Syllabus-2019-1/HEAD/Ayudantías/Ayudantía I3.pdf -------------------------------------------------------------------------------- /Interrogaciones/I1/I1.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alanezz/Syllabus-2019-1/HEAD/Interrogaciones/I1/I1.pdf -------------------------------------------------------------------------------- /Interrogaciones/I2/I2.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alanezz/Syllabus-2019-1/HEAD/Interrogaciones/I2/I2.pdf -------------------------------------------------------------------------------- /Interrogaciones/I3/I3.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alanezz/Syllabus-2019-1/HEAD/Interrogaciones/I3/I3.pdf -------------------------------------------------------------------------------- /Slides/01 - Motivación.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alanezz/Syllabus-2019-1/HEAD/Slides/01 - Motivación.pdf -------------------------------------------------------------------------------- /Slides/11 - Recursión.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alanezz/Syllabus-2019-1/HEAD/Slides/11 - Recursión.pdf -------------------------------------------------------------------------------- /Proyecto/Datos SQL/Datos.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alanezz/Syllabus-2019-1/HEAD/Proyecto/Datos SQL/Datos.zip -------------------------------------------------------------------------------- /Slides/04 - SQL Avanzado.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alanezz/Syllabus-2019-1/HEAD/Slides/04 - SQL Avanzado.pdf -------------------------------------------------------------------------------- /Slides/08 - Foreign Keys.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alanezz/Syllabus-2019-1/HEAD/Slides/08 - Foreign Keys.pdf -------------------------------------------------------------------------------- /Slides/09 - Dependencias.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alanezz/Syllabus-2019-1/HEAD/Slides/09 - Dependencias.pdf -------------------------------------------------------------------------------- /Slides/14 - JSON y NoSQL.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alanezz/Syllabus-2019-1/HEAD/Slides/14 - JSON y NoSQL.pdf -------------------------------------------------------------------------------- /Actividades/Casen/Datos/casen.db: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alanezz/Syllabus-2019-1/HEAD/Actividades/Casen/Datos/casen.db -------------------------------------------------------------------------------- /Actividades/Índices/Índices.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alanezz/Syllabus-2019-1/HEAD/Actividades/Índices/Índices.pdf -------------------------------------------------------------------------------- /Ayudantías/Ayudantía 1/banco.db: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alanezz/Syllabus-2019-1/HEAD/Ayudantías/Ayudantía 1/banco.db -------------------------------------------------------------------------------- /Proyecto/Entregas/Entrega 1.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alanezz/Syllabus-2019-1/HEAD/Proyecto/Entregas/Entrega 1.pdf -------------------------------------------------------------------------------- /Proyecto/Entregas/Entrega 2.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alanezz/Syllabus-2019-1/HEAD/Proyecto/Entregas/Entrega 2.pdf -------------------------------------------------------------------------------- /Proyecto/Entregas/Entrega 3.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alanezz/Syllabus-2019-1/HEAD/Proyecto/Entregas/Entrega 3.pdf -------------------------------------------------------------------------------- /Proyecto/Entregas/Entrega 4.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alanezz/Syllabus-2019-1/HEAD/Proyecto/Entregas/Entrega 4.pdf -------------------------------------------------------------------------------- /Proyecto/Entregas/Entrega 5.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alanezz/Syllabus-2019-1/HEAD/Proyecto/Entregas/Entrega 5.pdf -------------------------------------------------------------------------------- /Ayudantías/AyudantiaAPI/release/Procfile: -------------------------------------------------------------------------------- 1 | # IMPORTANTE: NO NECESITAN ARCHIVO PARA LA ENTREGA 4 2 | web: gunicorn main:app 3 | -------------------------------------------------------------------------------- /Ayudantías/Solucion_AyudExamen/compras.csv: -------------------------------------------------------------------------------- 1 | uid,pid,cid,cantidad 2 | 1,1,1,2 3 | 3,2,2,5 4 | 2,3,3,1 5 | 3,1,4,2 6 | 1,4,5,3 7 | -------------------------------------------------------------------------------- /Interrogaciones/I1/I1 Rúbrica.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alanezz/Syllabus-2019-1/HEAD/Interrogaciones/I1/I1 Rúbrica.pdf -------------------------------------------------------------------------------- /Interrogaciones/I2/I2 Rúbrica.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alanezz/Syllabus-2019-1/HEAD/Interrogaciones/I2/I2 Rúbrica.pdf -------------------------------------------------------------------------------- /Interrogaciones/I3/I3 Rúbrica.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alanezz/Syllabus-2019-1/HEAD/Interrogaciones/I3/I3 Rúbrica.pdf -------------------------------------------------------------------------------- /Slides/02 - Modelo Relacional.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alanezz/Syllabus-2019-1/HEAD/Slides/02 - Modelo Relacional.pdf -------------------------------------------------------------------------------- /Slides/05 - Algunas Consultas.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alanezz/Syllabus-2019-1/HEAD/Slides/05 - Algunas Consultas.pdf -------------------------------------------------------------------------------- /Slides/12 - Programación y SQL.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alanezz/Syllabus-2019-1/HEAD/Slides/12 - Programación y SQL.pdf -------------------------------------------------------------------------------- /Actividades/Casen/Actividad Casen.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alanezz/Syllabus-2019-1/HEAD/Actividades/Casen/Actividad Casen.pdf -------------------------------------------------------------------------------- /Ayudantías/Ayudantía 1/Ayudantía1.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alanezz/Syllabus-2019-1/HEAD/Ayudantías/Ayudantía 1/Ayudantía1.pdf -------------------------------------------------------------------------------- /Slides/10 - Nulos y Outer Joins.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alanezz/Syllabus-2019-1/HEAD/Slides/10 - Nulos y Outer Joins.pdf -------------------------------------------------------------------------------- /Slides/16 - Transacciones - 2PL.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alanezz/Syllabus-2019-1/HEAD/Slides/16 - Transacciones - 2PL.pdf -------------------------------------------------------------------------------- /Ayudantías/Ayudantía 1/Ayudantía1.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alanezz/Syllabus-2019-1/HEAD/Ayudantías/Ayudantía 1/Ayudantía1.pdf -------------------------------------------------------------------------------- /Proyecto/Tests/Entrega 2/Consultas.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alanezz/Syllabus-2019-1/HEAD/Proyecto/Tests/Entrega 2/Consultas.zip -------------------------------------------------------------------------------- /Slides/17 - Recuperación de Fallas.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alanezz/Syllabus-2019-1/HEAD/Slides/17 - Recuperación de Fallas.pdf -------------------------------------------------------------------------------- /Ayudantías/AyudantiaAPI/Ayudantía_APIs.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alanezz/Syllabus-2019-1/HEAD/Ayudantías/AyudantiaAPI/Ayudantía_APIs.pdf -------------------------------------------------------------------------------- /Ayudantías/Solución Ayudantía I3 (P4).pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alanezz/Syllabus-2019-1/HEAD/Ayudantías/Solución Ayudantía I3 (P4).pdf -------------------------------------------------------------------------------- /Slides/07 - Diseño de Bases de Datos.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alanezz/Syllabus-2019-1/HEAD/Slides/07 - Diseño de Bases de Datos.pdf -------------------------------------------------------------------------------- /Ayudantías/AyudantiaPHP/app/config/data.php: -------------------------------------------------------------------------------- 1 | 6 | -------------------------------------------------------------------------------- /Ayudantías/Solucion_AyudExamen/usuarios.csv: -------------------------------------------------------------------------------- 1 | uid,nombre,edad 2 | 1,Tamara,25 3 | 2,Constanza,24 4 | 3,Adrián,26 5 | 4,Sebastián,70 6 | 5,Jaime,16 7 | -------------------------------------------------------------------------------- /Ayudantías/AyudantiaAPI/release/static/plot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alanezz/Syllabus-2019-1/HEAD/Ayudantías/AyudantiaAPI/release/static/plot.png -------------------------------------------------------------------------------- /Ayudantías/AyudantiaPHP/Ayudantia_HTML_PHP.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alanezz/Syllabus-2019-1/HEAD/Ayudantías/AyudantiaPHP/Ayudantia_HTML_PHP.pdf -------------------------------------------------------------------------------- /Interrogaciones Anteriores/I1/I1 - 2017-2.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alanezz/Syllabus-2019-1/HEAD/Interrogaciones Anteriores/I1/I1 - 2017-2.pdf -------------------------------------------------------------------------------- /Interrogaciones Anteriores/I1/I1 - 2018-2.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alanezz/Syllabus-2019-1/HEAD/Interrogaciones Anteriores/I1/I1 - 2018-2.pdf -------------------------------------------------------------------------------- /Interrogaciones Anteriores/I2/I2 - 2017-2.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alanezz/Syllabus-2019-1/HEAD/Interrogaciones Anteriores/I2/I2 - 2017-2.pdf -------------------------------------------------------------------------------- /Interrogaciones Anteriores/I2/I2 - 2018-2.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alanezz/Syllabus-2019-1/HEAD/Interrogaciones Anteriores/I2/I2 - 2018-2.pdf -------------------------------------------------------------------------------- /Interrogaciones Anteriores/I3/I3 - 2017-2.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alanezz/Syllabus-2019-1/HEAD/Interrogaciones Anteriores/I3/I3 - 2017-2.pdf -------------------------------------------------------------------------------- /Interrogaciones Anteriores/I3/I3 - 2018-2.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alanezz/Syllabus-2019-1/HEAD/Interrogaciones Anteriores/I3/I3 - 2018-2.pdf -------------------------------------------------------------------------------- /Ayudantías/AyudantiaPHP/diagrama_arquitectura.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alanezz/Syllabus-2019-1/HEAD/Ayudantías/AyudantiaPHP/diagrama_arquitectura.png -------------------------------------------------------------------------------- /Ayudantías/Solución Ayudantía I1 (C 6,7,9,10).pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alanezz/Syllabus-2019-1/HEAD/Ayudantías/Solución Ayudantía I1 (C 6,7,9,10).pdf -------------------------------------------------------------------------------- /Proyecto/Tutoriales/Tutorial SQLite y servidor.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alanezz/Syllabus-2019-1/HEAD/Proyecto/Tutoriales/Tutorial SQLite y servidor.pdf -------------------------------------------------------------------------------- /Actividades/Álgebra Relacional/Álgebra Relacional.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alanezz/Syllabus-2019-1/HEAD/Actividades/Álgebra Relacional/Álgebra Relacional.pdf -------------------------------------------------------------------------------- /Interrogaciones Anteriores/Examen/2018-2 - Examen.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alanezz/Syllabus-2019-1/HEAD/Interrogaciones Anteriores/Examen/2018-2 - Examen.pdf -------------------------------------------------------------------------------- /Slides/13 - Almacenamiento - Índices - Algorítmos.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alanezz/Syllabus-2019-1/HEAD/Slides/13 - Almacenamiento - Índices - Algorítmos.pdf -------------------------------------------------------------------------------- /Actividades/Álgebra Relacional/Álgebra Relacional - Solución.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alanezz/Syllabus-2019-1/HEAD/Actividades/Álgebra Relacional/Álgebra Relacional - Solución.pdf -------------------------------------------------------------------------------- /Actividades/Dependencias Funcionales/Dependencias Funcionales.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alanezz/Syllabus-2019-1/HEAD/Actividades/Dependencias Funcionales/Dependencias Funcionales.pdf -------------------------------------------------------------------------------- /Ayudantías/AyudantiaPHP/app/templates/footer.html: -------------------------------------------------------------------------------- 1 |

2 |
3 | 4 |
5 | 6 | 7 | -------------------------------------------------------------------------------- /Ayudantías/Solucion_AyudExamen/productos.csv: -------------------------------------------------------------------------------- 1 | pid,nombre,precio 2 | 1,Pack de Cervezas Premium,18990 3 | 2,Té Matcha,8990 4 | 3,Promo de Malpaso,7990 5 | 4,Vino Cartoné SuBidón 2L,1990 6 | 5,Hierbas saludables,10000 7 | -------------------------------------------------------------------------------- /Ayudantías/AyudantiaAPI/release/templates/plot.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Pandas Plot 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /Ayudantías/AyudantiaPHP/app/templates/header.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Consulta 6 | 7 | 8 | -------------------------------------------------------------------------------- /Ayudantías/heroku-tutorial-app/Pipfile: -------------------------------------------------------------------------------- 1 | [[source]] 2 | name = "pypi" 3 | url = "https://pypi.org/simple" 4 | verify_ssl = true 5 | 6 | [dev-packages] 7 | 8 | [packages] 9 | flask = "*" 10 | pandas = "*" 11 | pymongo = "*" 12 | gunicorn = "*" 13 | 14 | [requires] 15 | python_version = "3.6" 16 | -------------------------------------------------------------------------------- /Ayudantías/heroku-tutorial-app/app.py: -------------------------------------------------------------------------------- 1 | from flask import Flask 2 | import pymongo 3 | import json 4 | import pandas 5 | 6 | app = Flask(__name__) 7 | 8 | 9 | @app.route('/') 10 | def hello_world(): 11 | return 'Hello World!' 12 | 13 | 14 | if __name__ == '__main__': 15 | app.run() 16 | -------------------------------------------------------------------------------- /Ayudantías/heroku-tutorial-app/requirements.txt: -------------------------------------------------------------------------------- 1 | Click==7.0 2 | Flask==1.0.3 3 | gunicorn==19.9.0 4 | itsdangerous==1.1.0 5 | Jinja2==2.10.1 6 | MarkupSafe==1.1.1 7 | numpy==1.16.4 8 | pandas==0.24.2 9 | pymongo==3.8.0 10 | python-dateutil==2.8.0 11 | pytz==2019.1 12 | six==1.12.0 13 | Werkzeug==0.15.4 14 | -------------------------------------------------------------------------------- /Ayudantías/AyudantiaPHP/app/config/conexion.php: -------------------------------------------------------------------------------- 1 | 9 | -------------------------------------------------------------------------------- /Ayudantías/AyudantiaAPI/release/Pipfile: -------------------------------------------------------------------------------- 1 | [[source]] 2 | name = "pypi" 3 | url = "https://pypi.org/simple" 4 | verify_ssl = true 5 | # Estos son los paquetes que no se van instalar en los servidores o en "produccion" 6 | 7 | [dev-packages] 8 | # Estos son los paquetes que siempre se van instalar 9 | mypy = "*" 10 | flake8 = "*" 11 | 12 | [packages] 13 | matplotlib = "*" 14 | numpy = "*" 15 | pandas = "*" 16 | pymongo = "*" 17 | gunicorn = "*" 18 | Flask = "*" 19 | Jinja2 = "*" 20 | autopep8 = "*" 21 | 22 | [requires] 23 | python_version = "3.6" 24 | -------------------------------------------------------------------------------- /Actividades/MongoDB/Datos/productos.json: -------------------------------------------------------------------------------- 1 | [ 2 | { "pid": 1, 3 | "name": "Producto 1", 4 | "tags": ["Tag 1", "Tag 2"], 5 | "price": 100 6 | }, 7 | { "pid": 2, 8 | "name": "Producto 2", 9 | "tags": ["Tag 2", "Tag 3", "Tag 4"], 10 | "price": 200 11 | }, 12 | { "pid": 3, 13 | "name": "Producto 3", 14 | "tags": ["Tag 2"], 15 | "price": 300 16 | }, 17 | { "pid": 4, 18 | "name": "Producto 4", 19 | "tags": ["Tag 3", "Tag 5"], 20 | "price": 400 21 | }, 22 | { "pid": 5, 23 | "name": "Producto 5", 24 | "tags": ["Tag 6"], 25 | "price": 500 26 | } 27 | ] 28 | -------------------------------------------------------------------------------- /Ayudantías/AyudantiaAPI/release/README.md: -------------------------------------------------------------------------------- 1 | # gunicorn-flask-pipenv-sample 2 | 3 | ## Para correr 4 | 5 | ### Windows con una sola version de python, Ubuntu 18.04+ 6 | 7 | ```bash 8 | pip install pipenv 9 | ``` 10 | 11 | ### Otros 12 | 13 | ```bash 14 | pip3 install pipenv 15 | ``` 16 | 17 | Abrimos nuevamente la consola 18 | 19 | #### Crear entorno 20 | 21 | ```bash 22 | pipenv install 23 | ``` 24 | 25 | 26 | ### Correr 27 | ```bash 28 | pipenv shell 29 | ``` 30 | Si estas en windows 31 | ``` 32 | python main.py 33 | ``` 34 | 35 | Cualquier otro sistema operativo 36 | ``` 37 | gunicorn main:app --workers=3 --reload 38 | ``` -------------------------------------------------------------------------------- /Actividades/MongoDB/Datos/usuarios.json: -------------------------------------------------------------------------------- 1 | [ 2 | { "uid": 1, 3 | "name": "Adrian", 4 | "last_name": "Soto", 5 | "ocupation": "Delantero de Cobreloa", 6 | "follows": [2,3], 7 | "age": 24 8 | }, 9 | { "uid": 2, 10 | "name": "Florencia", 11 | "last_name": "Barrios", 12 | "ocupation": "Hacker de Pet Society", 13 | "follows": [1,4], 14 | "age": 22 15 | }, 16 | { "uid": 3, 17 | "name": "Devil", 18 | "last_name": "Sawak", 19 | "ocupation": "Dueño de Quik Devil", 20 | "follows": [4], 21 | "age": 40 22 | }, 23 | { "uid": 4, 24 | "name": "Nebil", 25 | "last_name": "Kawas", 26 | "ocupation": "DT de Palestino", 27 | "follows": [1,2,3], 28 | "age": 17 29 | }, 30 | { "uid": 5, 31 | "name": "Fernando", 32 | "last_name": "Pieressa", 33 | "ocupation": "Traductor", 34 | "follows": [], 35 | "age": 20 36 | } 37 | ] 38 | -------------------------------------------------------------------------------- /Ayudantías/AyudantiaAPI/release/usuarios.json: -------------------------------------------------------------------------------- 1 | [ 2 | { "uid": 1, 3 | "name": "Adrian", 4 | "last_name": "Soto", 5 | "ocupation": "Delantero de Cobreloa", 6 | "follows": [2,3], 7 | "age": 24 8 | }, 9 | { "uid": 2, 10 | "name": "Florencia", 11 | "last_name": "Barrios", 12 | "ocupation": "Hacker de Pet Society", 13 | "follows": [1,4], 14 | "age": 22 15 | }, 16 | { "uid": 3, 17 | "name": "Devil", 18 | "last_name": "Sawak", 19 | "ocupation": "Dueño de Quik Devil", 20 | "follows": [4], 21 | "age": 40 22 | }, 23 | { "uid": 4, 24 | "name": "Nebil", 25 | "last_name": "Kawas", 26 | "ocupation": "DT de Palestino", 27 | "follows": [1,2,3], 28 | "age": 17 29 | }, 30 | { "uid": 5, 31 | "name": "Fernando", 32 | "last_name": "Pieressa", 33 | "ocupation": "Traductor", 34 | "follows": [], 35 | "age": 20 36 | } 37 | ] 38 | 39 | -------------------------------------------------------------------------------- /Ayudantías/AyudantiaPHP/app/consultas/consulta_altura.php: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | =$altura order by altura desc;"; 12 | 13 | $result = $db -> prepare($query); 14 | $result -> execute(); 15 | $pokemones = $result -> fetchAll(); 16 | ?> 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | "; 27 | } 28 | ?> 29 |
IDNombreAltura
$p[0]$p[1]$p[2]
30 | 31 | 32 | -------------------------------------------------------------------------------- /Ayudantías/AyudantiaPHP/app/consultas/consulta_tipo_nombre.php: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | prepare($query); 13 | $result -> execute(); 14 | $pokemones = $result -> fetchAll(); 15 | ?> 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | "; 26 | } 27 | ?> 28 |
IDNombreTipo
$pokemon[0] $pokemon[1] $pokemon[2]
29 | 30 | 31 | -------------------------------------------------------------------------------- /Ayudantías/Solucion_AyudExamen/neo4j.txt: -------------------------------------------------------------------------------- 1 | ## Pregunta 1 2 | 3 | MATCH (a:Alumno)-[rel:Toma_Curso]->(c:Curso) 4 | WHERE a.Name="Tamara Cucumides" 5 | RETURN a, rel, c 6 | 7 | ## Pregunta 2 8 | 9 | MATCH (a:Alumno)-[rel:Toma_Curso]->(c:Curso) 10 | WHERE c.sigla="IIC2413" 11 | RETURN COUNT(a) 12 | 13 | MATCH (a:Alumno)-[rel:Toma_Curso]->(c:Curso) 14 | WHERE c.Name="Aplicaciones de EDP y analisis funcional" 15 | RETURN COUNT(a) 16 | 17 | ## Pregunta 3 18 | 19 | MATCH (a:Alumno)-[rel:Es_Ayudante]->(c:Curso)<-[rel2:Dicta_Curso]-(p:Profesor) 20 | WHERE p.Name="Adrián Soto" 21 | RETURN a, c, p 22 | 23 | ## Pregunta 4 24 | 25 | MATCH (a:Alumno)-[rel:Es_Ayudante]->(c:Curso)<-[rel2:Dicta_Curso]-(p:Profesor) 26 | WHERE p.Name="Adrián Soto" 27 | RETURN a, c, p 28 | 29 | 30 | ## Preunta 5 31 | 32 | MATCH (a:Alumno)-[rel:Es_ayudante]->(c:Curso)-[re:Es_ayudante]-(b:Alumno) 33 | WHERE a.Name <> b.Name AND exists((b)-[:Toma_Curso]-(:Curso)-[:Toma_Curso]-(a)) 34 | RETURN a,b,c 35 | 36 | 37 | 38 | 39 | -------------------------------------------------------------------------------- /Ayudantías/AyudantiaPHP/app/consultas/consulta_tipo.php: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | prepare($query); 11 | $result -> execute(); 12 | $dataCollected = $result -> fetchAll(); #Obtiene todos los resultados de la consulta en forma de un arreglo 13 | ?> 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | "; 27 | } 28 | ?> 29 |
IDNombreAlturaPesoExp BaseTipo
$p[0] $p[1] $p[2] $p[3] $p[4] $p[5]
30 | 31 | 32 | -------------------------------------------------------------------------------- /Ayudantías/AyudantiaPHP/php_basico.php: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 |

Hola

9 | 10 | Las variables son:
Var1: $var1
booleano: $booleano

"; 17 | 18 | #Control de flujo 19 | if ($booleano){ 20 | echo "

Dentro del if: la variable era TRUE.

"; 21 | } else { 22 | echo "

Dentro del if: la variable era FALSE.

"; 23 | } 24 | 25 | #Looping. Hay varios tipos de looping. Investigar! 26 | echo "

For Loop:

"; 27 | for($i = 0; $i<6; $i++) { 28 | echo "

i: $i

"; 29 | } 30 | 31 | echo "

Foreach Loop:

"; 32 | $array = array( 1, 2, 3, 4, 5); 33 | foreach( $array as $v ) { 34 | echo "

Value is: $v

"; 35 | } 36 | ?> 37 | 38 | 39 | 40 | -------------------------------------------------------------------------------- /Ayudantías/AyudantiaPHP/app/index.php: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 |

Biblioteca Pokemón

6 |

Aquí podran encontrar información sobre pokemones.

7 | 8 |
9 | 10 |

Consulta por tipo y nombre:

11 | 12 |
13 | Tipo: 14 | 15 |
16 | Nombre: 17 | 18 |

19 | 20 |
21 |
22 |
23 |
24 | 25 |

Consulta Pokemones mas altos que:

26 | 27 |
28 | Altura Mínima: 29 | 30 |

31 | 32 |
33 |
34 |
35 |
36 | 37 |

Consulta de selección por tipo:

38 | 39 | prepare("SELECT DISTINCT tipo FROM ejercicio_ayudantia;"); 43 | $result -> execute(); 44 | $dataCollected = $result -> fetchAll(); 45 | ?> 46 | 47 |
48 | Ingresar un tipo: 49 | 57 |

58 | 59 |
60 |



61 | 62 | 63 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | 2 | # Created by https://www.gitignore.io/api/osx,python 3 | 4 | ### OSX ### 5 | *.DS_Store 6 | .AppleDouble 7 | .LSOverride 8 | 9 | # Icon must end with two \r 10 | Icon 11 | 12 | # Thumbnails 13 | ._* 14 | 15 | # Files that might appear in the root of a volume 16 | .DocumentRevisions-V100 17 | .fseventsd 18 | .Spotlight-V100 19 | .TemporaryItems 20 | .Trashes 21 | .VolumeIcon.icns 22 | .com.apple.timemachine.donotpresent 23 | 24 | # Directories potentially created on remote AFP share 25 | .AppleDB 26 | .AppleDesktop 27 | Network Trash Folder 28 | Temporary Items 29 | .apdisk 30 | 31 | ### Python ### 32 | # Byte-compiled / optimized / DLL files 33 | __pycache__/ 34 | *.py[cod] 35 | *$py.class 36 | 37 | # C extensions 38 | *.so 39 | 40 | # Distribution / packaging 41 | .Python 42 | env/ 43 | build/ 44 | develop-eggs/ 45 | dist/ 46 | downloads/ 47 | eggs/ 48 | .eggs/ 49 | lib/ 50 | lib64/ 51 | parts/ 52 | sdist/ 53 | var/ 54 | wheels/ 55 | *.egg-info/ 56 | .installed.cfg 57 | *.egg 58 | 59 | # PyInstaller 60 | # Usually these files are written by a python script from a template 61 | # before PyInstaller builds the exe, so as to inject date/other infos into it. 62 | *.manifest 63 | *.spec 64 | 65 | # Installer logs 66 | pip-log.txt 67 | pip-delete-this-directory.txt 68 | 69 | # Unit test / coverage reports 70 | htmlcov/ 71 | .tox/ 72 | .coverage 73 | .coverage.* 74 | .cache 75 | nosetests.xml 76 | coverage.xml 77 | *,cover 78 | .hypothesis/ 79 | 80 | # Translations 81 | *.mo 82 | *.pot 83 | 84 | # Django stuff: 85 | *.log 86 | local_settings.py 87 | 88 | # Flask stuff: 89 | instance/ 90 | .webassets-cache 91 | 92 | # Scrapy stuff: 93 | .scrapy 94 | 95 | # Sphinx documentation 96 | docs/_build/ 97 | 98 | # PyBuilder 99 | target/ 100 | 101 | # Jupyter Notebook 102 | .ipynb_checkpoints 103 | 104 | # pyenv 105 | .python-version 106 | 107 | # celery beat schedule file 108 | celerybeat-schedule 109 | 110 | # SageMath parsed files 111 | *.sage.py 112 | 113 | # dotenv 114 | .env 115 | 116 | # virtualenv 117 | .venv 118 | venv/ 119 | ENV/ 120 | 121 | # Spyder project settings 122 | .spyderproject 123 | .spyproject 124 | 125 | # Rope project settings 126 | .ropeproject 127 | 128 | # mkdocs documentation 129 | /site 130 | 131 | # End of https://www.gitignore.io/api/osx,python 132 | -------------------------------------------------------------------------------- /Actividades/MongoDB/Datos/mensajes.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "mid": 1, 4 | "uid": 3, 5 | "msj": { 6 | "title": "Mensaje 1", 7 | "content": "Lorem ipsum dolor sit amet." 8 | }, 9 | "likes": 2 10 | }, 11 | { 12 | "mid": 2, 13 | "uid": 2, 14 | "msj": { 15 | "title": "Mensaje 2", 16 | "content": "Lorem ipsum dolor sit amet." 17 | }, 18 | "likes": 1 19 | }, 20 | { 21 | "mid": 3, 22 | "uid": 2, 23 | "msj": { 24 | "title": "Mensaje 3", 25 | "content": "Lorem ipsum dolor sit amet." 26 | }, 27 | "likes": 3 28 | }, 29 | { 30 | "mid": 4, 31 | "uid": 3, 32 | "msj": { 33 | "title": "Mensaje 4", 34 | "content": "Lorem ipsum dolor sit amet." 35 | }, 36 | "likes": 0 37 | }, 38 | { 39 | "mid": 5, 40 | "uid": 4, 41 | "msj": { 42 | "title": "Mensaje 5", 43 | "content": "Lorem ipsum dolor sit amet." 44 | }, 45 | "likes": 1 46 | }, 47 | { 48 | "mid": 6, 49 | "uid": 4, 50 | "msj": { 51 | "title": "Mensaje 6", 52 | "content": "Lorem ipsum dolor sit amet." 53 | }, 54 | "likes": 1 55 | }, 56 | { 57 | "mid": 7, 58 | "uid": 4, 59 | "msj": { 60 | "title": "Mensaje 7", 61 | "content": "Lorem ipsum dolor sit amet." 62 | }, 63 | "likes": 1 64 | }, 65 | { 66 | "mid": 8, 67 | "uid": 3, 68 | "msj": { 69 | "title": "Mensaje 8", 70 | "content": "Deseo leche con chocolate." 71 | }, 72 | "likes": 5 73 | }, 74 | { 75 | "mid": 9, 76 | "uid": 3, 77 | "msj": { 78 | "title": "Mensaje 9", 79 | "content": "Deseo comer un chocolate." 80 | }, 81 | "likes": 4 82 | }, 83 | { 84 | "mid": 10, 85 | "uid": 3, 86 | "msj": { 87 | "title": "Mensaje 10", 88 | "content": "Vi un ballet." 89 | }, 90 | "likes": 5 91 | }, 92 | { 93 | "mid": 11, 94 | "uid": 5, 95 | "msj": { 96 | "title": "Mensaje 11", 97 | "content": "Vi un ballet, eso me tiene mal." 98 | }, 99 | "likes": 2 100 | }, 101 | { 102 | "mid": 12, 103 | "uid": 4, 104 | "msj": { 105 | "title": "Mensaje 12", 106 | "content": "Vi un ballet, pero comí chocolate." 107 | }, 108 | "likes": 5 109 | }, 110 | { 111 | "mid": 13, 112 | "uid": 5, 113 | "msj": { 114 | "title": "Mensaje 13", 115 | "content": "Hola ke ase." 116 | }, 117 | "likes": 2 118 | }, 119 | { 120 | "mid": 14, 121 | "uid": 3, 122 | "msj": { 123 | "title": "Mensaje 14", 124 | "content": "Deseo escribir lorem ipsum." 125 | }, 126 | "likes": 3 127 | }, 128 | { 129 | "mid": 15, 130 | "uid": 5, 131 | "msj": { 132 | "title": "Mensaje 15", 133 | "content": "Comi demasiado chocolate, eso me tiene mal." 134 | }, 135 | "likes": 1 136 | } 137 | ] 138 | -------------------------------------------------------------------------------- /Ayudantías/AyudantiaAPI/release/PostmanCollection.json: -------------------------------------------------------------------------------- 1 | { 2 | "info": { 3 | "_postman_id": "cb853ebb-4413-4de2-85fc-15a893ac4355", 4 | "name": "Ayudantia", 5 | "schema": "https://schema.getpostman.com/json/collection/v2.1.0/collection.json" 6 | }, 7 | "item": [ 8 | { 9 | "name": "Get Users", 10 | "request": { 11 | "method": "GET", 12 | "header": [], 13 | "body": { 14 | "mode": "raw", 15 | "raw": "" 16 | }, 17 | "url": { 18 | "raw": "localhost:5000/users", 19 | "host": [ 20 | "localhost" 21 | ], 22 | "port": "5000", 23 | "path": [ 24 | "users" 25 | ] 26 | } 27 | }, 28 | "response": [] 29 | }, 30 | { 31 | "name": "Get User", 32 | "request": { 33 | "method": "GET", 34 | "header": [], 35 | "body": { 36 | "mode": "raw", 37 | "raw": "" 38 | }, 39 | "url": { 40 | "raw": "localhost:5000/users/3", 41 | "host": [ 42 | "localhost" 43 | ], 44 | "port": "5000", 45 | "path": [ 46 | "users", 47 | "3" 48 | ] 49 | } 50 | }, 51 | "response": [] 52 | }, 53 | { 54 | "name": "Get Plot", 55 | "request": { 56 | "method": "GET", 57 | "header": [], 58 | "body": { 59 | "mode": "raw", 60 | "raw": "" 61 | }, 62 | "url": { 63 | "raw": "localhost:5000/plot", 64 | "host": [ 65 | "localhost" 66 | ], 67 | "port": "5000", 68 | "path": [ 69 | "plot" 70 | ] 71 | } 72 | }, 73 | "response": [] 74 | }, 75 | { 76 | "name": "Delete User", 77 | "request": { 78 | "method": "DELETE", 79 | "header": [], 80 | "body": { 81 | "mode": "raw", 82 | "raw": "" 83 | }, 84 | "url": { 85 | "raw": "localhost:5000/users/3", 86 | "host": [ 87 | "localhost" 88 | ], 89 | "port": "5000", 90 | "path": [ 91 | "users", 92 | "3" 93 | ] 94 | } 95 | }, 96 | "response": [] 97 | }, 98 | { 99 | "name": "Create User", 100 | "request": { 101 | "method": "POST", 102 | "header": [ 103 | { 104 | "key": "Content-Type", 105 | "name": "Content-Type", 106 | "value": "application/json", 107 | "type": "text" 108 | } 109 | ], 110 | "body": { 111 | "mode": "raw", 112 | "raw": "{\n\t\"name\": \"Nicolas\", \n\t\"last_name\": \"Quiroz\", \n\t\"occupation\": \"estudiante\", \n\t\"follows\": [1,2,3], \n\t\"age\": 23\n}" 113 | }, 114 | "url": { 115 | "raw": "localhost:5000/users", 116 | "host": [ 117 | "localhost" 118 | ], 119 | "port": "5000", 120 | "path": [ 121 | "users" 122 | ] 123 | } 124 | }, 125 | "response": [] 126 | }, 127 | { 128 | "name": "Delete Many Users", 129 | "request": { 130 | "method": "DELETE", 131 | "header": [ 132 | { 133 | "key": "Content-Type", 134 | "name": "Content-Type", 135 | "value": "application/json", 136 | "type": "text" 137 | } 138 | ], 139 | "body": { 140 | "mode": "raw", 141 | "raw": "{\n\t\"uidBulk\":[1,2]\n}" 142 | }, 143 | "url": { 144 | "raw": "localhost:5000/users/many", 145 | "host": [ 146 | "localhost" 147 | ], 148 | "port": "5000", 149 | "path": [ 150 | "users", 151 | "many" 152 | ] 153 | } 154 | }, 155 | "response": [] 156 | }, 157 | { 158 | "name": "Test Parameters", 159 | "protocolProfileBehavior": { 160 | "disableBodyPruning": true 161 | }, 162 | "request": { 163 | "method": "GET", 164 | "header": [ 165 | { 166 | "key": "name", 167 | "value": "Kevin", 168 | "type": "text" 169 | } 170 | ], 171 | "body": { 172 | "mode": "raw", 173 | "raw": "hola soy el body" 174 | }, 175 | "url": { 176 | "raw": "localhost:5000/test?name=Kevin", 177 | "host": [ 178 | "localhost" 179 | ], 180 | "port": "5000", 181 | "path": [ 182 | "test" 183 | ], 184 | "query": [ 185 | { 186 | "key": "name", 187 | "value": "Kevin" 188 | } 189 | ] 190 | } 191 | }, 192 | "response": [] 193 | } 194 | ] 195 | } -------------------------------------------------------------------------------- /Proyecto/Datos SQL/readme.md: -------------------------------------------------------------------------------- 1 | # Datos Entrega 2 2 | En el `zip` se encuentran tres carpetas: 3 | 4 | - `comun` : Contiene todos los datos compartidos entre ambos grupos. Esto significa que ambos grupos deben importar estos datos a sus bases de datos correspondientes. Los archivos al interior son los siguientes: 5 | 6 | - `usuario.csv` : Contiene los usuarios de las aplicaciones correspondientes. Estos tienen `uid` que corresponde a un ID único que posee cada usuario de la aplicación. También poseen los siguientes datos (que pueden no ser únicos): `nombre`, `correo`, `nacimiento` y `nacionalidad` 7 | 8 | - `region.csv`: Corresponde a las regiones de Chile, cada una con un `rid` único, así como un `nombre` y `descripcion`. 9 | 10 | - `impar`: En esta carpeta se encuentran datos que deben importar sólo el grupo impar. Los archivos al interior son los siguientes: 11 | - `agencia_agenciaregion_tour.csv` : Contiene la información de las agencias, y regiones asociadas a cada tour. Los datos de las agencias son: `nombre` ,`direccion` y `telefono`. Cada agencia que existe en el sistema tiene un `aid` único, sin embrago el csv puede contener `aid` duplicados dado que hay al menos un tour por cada presencia de la agencia en una región. El archivo cuenta además con un `rid` por cada tour en el archivo. Se puede asumir que si existe un tour en una región, este va asociado a una agencia en la misma región. Luego está el `tid` que es un ID único por tour. El resto de las columnas son información asociada a cada tour. 12 | 13 | - `hotel_habitaciones.csv`: Corresponde a todas las habitaciones, asociadas a un hotel. Las primeras 6 columnas son información del hotel donde la habitación se encuentra. Sin embrago, `hid` es la única columna es la única que es única por hotel. El resto de las columnas son información de la habitación, `habid` es el ID único por habitación. Este es único independiente del hotel. 14 | 15 | - `reserva.csv`: corresponde a la información que hay en una reserva. Hay al menos una reserva por habitación. `resvid` es un id único por cada reserva. `fecha1` es la fecha donde comienza la reserva y `fecha2` cuando termina. Puedes asumir que `fecha2` siempre es después de `fecha1`. 16 | 17 | - `restaurante_platos.csv`: Corresponde a los platos asociados a cada restaurante. Las primeras 6 columnas son información del restaurante. `rid` corresponde al ID de la región donde se encuentra el restaurante. `restid` es un ID único por restaurante. El resto de las columnas es información de los platos, con `pid` siendo el ID de cada plato, independiente del restaurante. 18 | 19 | 20 | - `par`: En esta carpeta se encuentran datos que deben importar sólo el grupo par. Los archivos al interior son los siguientes: 21 | 22 | - `vina_enovina_enoturismo.csv`: Corresponde a la información de cada viña que hay por `enotour`. `rid` corresponde a el ID de la región donde se encuentra la viña recorrida en el tour. Las primeras 5 columnas son información de la viña. `vid` es el ID único por viña. El resto de la información es del tour asociado a la viña. `eid` es el ID único por tour. 23 | 24 | - `vino.csv`: Corresponde a la información de cada vino. `vinoid` es un ID único por vino, y `vid` es un id que relaciona cada vino a una viña. 25 | 26 | - `enovino.csv` : Corresponde a una archivo que indica los vinos degustados en cada enotour. Puedes asumir que la viña asociada al vino, es visitada. `eid` es el ID único del `enotour` asociado. `vinoid` es el ID del vino asociado. 27 | 28 | - `parques_nacionales_atractivos`: Corresponde a los atractivos en cada parque nacional. Hay al menos un parque nacional por región. Y al menos un atractivo por parque. `aid` es el ID único por atractivo, `pid` es el ID único por parque nacional. Las primeras 6 columnas están asociadas al parque, mientras que el resto es información del atractivo. 29 | 30 | - `parques_nacionales_senderos`: Corresponde a los senderos en cada parque nacional. Hay al menos un parque nacional por región. Y al menos un atractivo por parque. `sid` es el ID único por sendero, `pid` es el ID único por parque nacional. Las primeras 6 columnas están asociadas al parque, mientras que el resto es información del sendero. 31 | 32 | - `registro.csv`: Corresponde al registro de usuarios que han ingresado a casa sendero. Hay al menos un registro por sendero `regid` es el ID único por registro. 33 | 34 | 35 | -------------------------------------------------------------------------------- /Ayudantías/AyudantiaAPI/release/main.py: -------------------------------------------------------------------------------- 1 | from flask import Flask, render_template, request, abort, json 2 | from pymongo import MongoClient 3 | import pandas as pd 4 | import matplotlib.pyplot as plt 5 | import os 6 | import atexit 7 | import subprocess 8 | 9 | USER_KEYS = ['name', 'last_name', 'occupation', 'follows', 'age'] 10 | 11 | # Levantamos el servidor de mongo. Esto no es necesario, puede abrir 12 | # una terminal y correr mongod. El DEVNULL hace que no vemos el output 13 | mongod = subprocess.Popen('mongod', stdout=subprocess.DEVNULL) 14 | # Nos aseguramos que cuando el programa termine, mongod no quede corriendo 15 | atexit.register(mongod.kill) 16 | 17 | # El cliente se levanta en localhost:5432 18 | client = MongoClient('localhost') 19 | # Utilizamos la base de datos 'entidades' 20 | db = client["entidades"] 21 | # Seleccionamos la colección de usuarios 22 | usuarios = db.usuarios 23 | 24 | # Iniciamos la aplicación de flask 25 | app = Flask(__name__) 26 | 27 | 28 | @app.route("/") 29 | def home(): 30 | return "

HELLO

" 31 | 32 | # Mapeamos esta función a la ruta '/plot' con el método get. 33 | @app.route("/plot") 34 | def plot(): 35 | # Obtengo todos los usuarios 36 | users = usuarios.find({}, {"_id": 0}) 37 | 38 | # Hago un data frame (tabla poderosa) con la columna 'name' indexada 39 | df = pd.DataFrame(list(users)).set_index('name') 40 | 41 | # Hago un grafico de pi en base a la edad 42 | df.plot.pie(y='age') 43 | 44 | # Export la figura para usarla en el html 45 | pth = os.path.join('static', 'plot.png') 46 | plt.savefig(pth) 47 | 48 | # Retorna un html "rendereado" 49 | return render_template('plot.html') 50 | 51 | 52 | @app.route("/users") 53 | def get_users(): 54 | resultados = [u for u in usuarios.find({}, {"_id": 0})] 55 | # Omitir el _id porque no es json serializable 56 | 57 | return json.jsonify(resultados) 58 | 59 | 60 | @app.route("/users/") 61 | def get_user(uid): 62 | users = list(usuarios.find({"uid": uid}, {"_id": 0})) 63 | 64 | return json.jsonify(users) 65 | 66 | 67 | @app.route("/users", methods=['POST']) 68 | def create_user(): 69 | ''' 70 | Crea un nuevo usuario en la base de datos 71 | Se necesitan todos los atributos de model, a excepcion de _id 72 | ''' 73 | 74 | # Si los parámetros son enviados con una request de tipo application/json: 75 | data = {key: request.json[key] for key in USER_KEYS} 76 | 77 | # Se genera el uid 78 | count = usuarios.count_documents({}) 79 | data["uid"] = count + 1 80 | 81 | # Insertar retorna un objeto 82 | result = usuarios.insert_one(data) 83 | 84 | # Creo el mensaje resultado 85 | if (result): 86 | message = "1 usuario creado" 87 | success = True 88 | else: 89 | message = "No se pudo crear el usuario" 90 | success = False 91 | 92 | # Retorno el texto plano de un json 93 | return json.jsonify({'success': success, 'message': message}) 94 | 95 | 96 | @app.route('/users/', methods=['DELETE']) 97 | def delete_user(uid): 98 | ''' 99 | Elimina un usuario de la db. 100 | Se requiere llave uid 101 | ''' 102 | 103 | # esto borra el primer resultado. si hay mas, no los borra 104 | usuarios.delete_one({"uid": uid}) 105 | 106 | message = f'Usuario con id={uid} ha sido eliminado.' 107 | 108 | # Retorno el texto plano de un json 109 | return json.jsonify({'result': 'success', 'message': message}) 110 | 111 | 112 | @app.route('/users/many', methods=['DELETE']) 113 | def delete_many_user(): 114 | ''' 115 | Elimina un varios usuarios de la db. 116 | - Se requiere llave idBulk en el body de la request application/json 117 | ''' 118 | 119 | if not request.json: 120 | # Solicitud faltan parametros. Codigo 400: Bad request 121 | abort(400) # Arrojar error 122 | 123 | all_uids = request.json['uidBulk'] 124 | 125 | if not all_uids: 126 | # Solicitud faltan parametros. Codigo 400: Bad request 127 | abort(400) # Arrojar error 128 | 129 | # Esto borra todos los usuarios con el id dentro de la lista 130 | result = usuarios.delete_many({"uid": {"$in": all_uids}}) 131 | 132 | # Creo el mensaje resultado 133 | message = f'{result.deleted_count} usuarios eliminados.' 134 | 135 | # Retorno el texto plano de un json 136 | return json.jsonify({'result': 'success', 'message': message}) 137 | 138 | 139 | @app.route("/test") 140 | def test(): 141 | # Obtener un parámero de la URL 142 | param = request.args.get('name', False) 143 | print("URL param:", param) 144 | 145 | # Obtener un header 146 | param2 = request.headers.get('name', False) 147 | print("Header:", param2) 148 | 149 | # Obtener el body 150 | body = request.data 151 | print("Body:", body) 152 | 153 | return "OK" 154 | 155 | 156 | if os.name == 'nt': 157 | app.run() 158 | -------------------------------------------------------------------------------- /Actividades/Psycopg2/Psycopg2.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "# Psycopg2\n", 8 | "\n", 9 | "En este clase vamos a usar la librería `psycopg2`, la que nos permite conectar una base de datos PSQL con Python. Primero tenemos que conectarnos a la base de datos. Luego vamos a crear tablas e insertar valores." 10 | ] 11 | }, 12 | { 13 | "cell_type": "code", 14 | "execution_count": 8, 15 | "metadata": {}, 16 | "outputs": [], 17 | "source": [ 18 | "import psycopg2\n", 19 | "\n", 20 | "conn = psycopg2.connect(\"dbname=progsql user=adriansotosuarez\")\n", 21 | "cur = conn.cursor()\n", 22 | "\n", 23 | "cur.execute(\"DROP TABLE IF EXISTS R;\")\n", 24 | "cur.execute(\"CREATE TABLE R (a int, b int, PRIMARY KEY(a, b));\")\n", 25 | "\n", 26 | "cur.execute(\"DROP TABLE IF EXISTS S;\")\n", 27 | "cur.execute(\"CREATE TABLE S (b int, c int, PRIMARY KEY(b, c));\")\n", 28 | "\n", 29 | "cur.execute(\"INSERT INTO R VALUES(1, 1);\")\n", 30 | "cur.execute(\"INSERT INTO R VALUES(2, 1);\")\n", 31 | "cur.execute(\"INSERT INTO R VALUES(3, 1);\")\n", 32 | "cur.execute(\"INSERT INTO R VALUES(1, 2);\")\n", 33 | "cur.execute(\"INSERT INTO R VALUES(2, 2);\")\n", 34 | "cur.execute(\"INSERT INTO R VALUES(1, 3);\")\n", 35 | "cur.execute(\"INSERT INTO R VALUES(1, 4);\")\n", 36 | "\n", 37 | "cur.execute(\"INSERT INTO S VALUES(1, 1);\")\n", 38 | "cur.execute(\"INSERT INTO S VALUES(1, 2);\")\n", 39 | "cur.execute(\"INSERT INTO S VALUES(3, 1);\")\n", 40 | "cur.execute(\"INSERT INTO S VALUES(4, 1);\")\n", 41 | "cur.execute(\"INSERT INTO S VALUES(4, 2);\")\n", 42 | "cur.execute(\"INSERT INTO S VALUES(4, 3);\")\n", 43 | "cur.execute(\"INSERT INTO S VALUES(5, 1);\")\n", 44 | "\n", 45 | "conn.commit()" 46 | ] 47 | }, 48 | { 49 | "cell_type": "markdown", 50 | "metadata": {}, 51 | "source": [ 52 | "Si queremos hacer una consulta y mostrar los resultados:" 53 | ] 54 | }, 55 | { 56 | "cell_type": "code", 57 | "execution_count": 10, 58 | "metadata": {}, 59 | "outputs": [ 60 | { 61 | "name": "stdout", 62 | "output_type": "stream", 63 | "text": [ 64 | "(1, 1)\n", 65 | "(2, 1)\n", 66 | "(3, 1)\n" 67 | ] 68 | } 69 | ], 70 | "source": [ 71 | "cur.execute(\"SELECT * FROM R WHERE R.b=1;\")\n", 72 | "\n", 73 | "t = cur.fetchone()\n", 74 | "while t:\n", 75 | " print(t)\n", 76 | " t = cur.fetchone()\n", 77 | " \n", 78 | "cur.close()" 79 | ] 80 | }, 81 | { 82 | "cell_type": "markdown", 83 | "metadata": {}, 84 | "source": [ 85 | "Vamos a ver un ejemplo más complejo. Vamos a hacer la consulta $R \\bowtie S$ suponiendo que sólo podemos hacer las consultas:\n", 86 | "\n", 87 | "- `SELECT * FROM R`;\n", 88 | "- `SELECT * FROM S`;" 89 | ] 90 | }, 91 | { 92 | "cell_type": "code", 93 | "execution_count": 18, 94 | "metadata": {}, 95 | "outputs": [ 96 | { 97 | "name": "stdout", 98 | "output_type": "stream", 99 | "text": [ 100 | "(1, 1) - (1, 1)\n", 101 | "(1, 1) - (1, 2)\n", 102 | "(2, 1) - (1, 1)\n", 103 | "(2, 1) - (1, 2)\n", 104 | "(3, 1) - (1, 1)\n", 105 | "(3, 1) - (1, 2)\n", 106 | "(1, 3) - (3, 1)\n", 107 | "(1, 4) - (4, 1)\n", 108 | "(1, 4) - (4, 2)\n", 109 | "(1, 4) - (4, 3)\n" 110 | ] 111 | } 112 | ], 113 | "source": [ 114 | "cur_r = conn.cursor()\n", 115 | "cur_s = conn.cursor()\n", 116 | "\n", 117 | "cur_r.execute(\"SELECT * FROM R\")\n", 118 | "cur_s.execute(\"SELECT * FROM S\")\n", 119 | "\n", 120 | "t_r = cur_r.fetchone()\n", 121 | "while t_r:\n", 122 | " \n", 123 | " t_s = cur_s.fetchone()\n", 124 | " while t_s:\n", 125 | " if t_r[1] == t_s[0]:\n", 126 | " print(\"{} - {}\".format(t_r, t_s))\n", 127 | " t_s = cur_s.fetchone()\n", 128 | " cur_s.execute(\"SELECT * FROM S\")\n", 129 | " \n", 130 | " t_r = cur_r.fetchone()\n", 131 | " \n", 132 | "cur_r.close()\n", 133 | "cur_s.close()" 134 | ] 135 | }, 136 | { 137 | "cell_type": "markdown", 138 | "metadata": {}, 139 | "source": [ 140 | "Finalmente, siempre es muy importante cerrar la conexión." 141 | ] 142 | }, 143 | { 144 | "cell_type": "code", 145 | "execution_count": 19, 146 | "metadata": {}, 147 | "outputs": [], 148 | "source": [ 149 | "conn.close()" 150 | ] 151 | } 152 | ], 153 | "metadata": { 154 | "kernelspec": { 155 | "display_name": "Python 3", 156 | "language": "python", 157 | "name": "python3" 158 | }, 159 | "language_info": { 160 | "codemirror_mode": { 161 | "name": "ipython", 162 | "version": 3 163 | }, 164 | "file_extension": ".py", 165 | "mimetype": "text/x-python", 166 | "name": "python", 167 | "nbconvert_exporter": "python", 168 | "pygments_lexer": "ipython3", 169 | "version": "3.7.1" 170 | } 171 | }, 172 | "nbformat": 4, 173 | "nbformat_minor": 2 174 | } 175 | -------------------------------------------------------------------------------- /Ayudantías/AyudantiaPHP/app/datos/ejercicio_ayudantia.csv: -------------------------------------------------------------------------------- 1 | id;nombre;altura;peso;experiencia_base;tipo 2 | 1;bulbasaur;7;69;64;planta-veneno 3 | 2;ivysaur;10;130;142;planta-veneno 4 | 3;venusaur;20;1000;236;planta-veneno 5 | 4;charmander;6;85;62;fuego 6 | 5;charmeleon;11;190;142;fuego 7 | 6;charizard;17;905;240;fuego-volador 8 | 7;squirtle;5;90;63;agua 9 | 8;wartortle;10;225;142;agua 10 | 9;blastoise;16;855;239;agua 11 | 10;caterpie;3;29;39;insecto 12 | 11;metapod;7;99;72;insecto 13 | 12;butterfree;11;320;178;insecto-volador 14 | 13;weedle;3;32;39;insecto-veneno 15 | 14;kakuna;6;100;72;insecto-veneno 16 | 15;beedrill;10;295;178;insecto-veneno 17 | 16;pidgey;3;18;50;normal-volador 18 | 17;pidgeotto;11;300;122;normal-volador 19 | 18;pidgeot;15;395;216;normal-volador 20 | 19;rattata;3;35;51;normal 21 | 20;raticate;7;185;145;normal 22 | 21;spearow;3;20;52;normal-volador 23 | 22;fearow;12;380;155;normal-volador 24 | 23;ekans;20;69;58;veneno 25 | 24;arbok;35;650;153;veneno 26 | 25;pikachu;4;60;112;electrico 27 | 26;raichu;8;300;218;electrico 28 | 27;sandshrew;6;120;60;tierra 29 | 28;sandslash;10;295;158;tierra 30 | 29;nidoran-f;4;70;55;veneno 31 | 30;nidorina;8;200;128;veneno 32 | 31;nidoqueen;13;600;227;veneno-tierra 33 | 32;nidoran-m;5;90;55;veneno 34 | 33;nidorino;9;195;128;veneno 35 | 34;nidoking;14;620;227;veneno-tierra 36 | 35;clefairy;6;75;113;normal 37 | 36;clefable;13;400;217;normal 38 | 37;vulpix;6;99;60;fuego 39 | 38;ninetales;11;199;177;fuego 40 | 39;jigglypuff;5;55;95;normal 41 | 40;wigglytuff;10;120;196;normal 42 | 41;zubat;8;75;49;veneno-volador 43 | 42;golbat;16;550;159;veneno-volador 44 | 43;oddish;5;54;64;planta-veneno 45 | 44;gloom;8;86;138;planta-veneno 46 | 45;vileplume;12;186;221;planta-veneno 47 | 46;paras;3;54;57;planta-insecto 48 | 47;parasect;10;295;142;planta-insecto 49 | 48;venonat;10;300;61;insecto-veneno 50 | 49;venomoth;15;125;158;insecto-veneno 51 | 50;diglett;2;8;53;tierra 52 | 51;dugtrio;7;333;142;tierra 53 | 52;meowth;4;42;58;normal 54 | 53;persian;10;320;154;normal 55 | 54;psyduck;8;196;64;agua 56 | 55;golduck;17;766;175;agua 57 | 56;mankey;5;280;61;lucha 58 | 57;primeape;10;320;159;lucha 59 | 58;growlithe;7;190;70;fuego 60 | 59;arcanine;19;1550;194;fuego 61 | 60;poliwag;6;124;60;agua 62 | 61;poliwhirl;10;200;135;agua 63 | 62;poliwrath;13;540;230;agua-lucha 64 | 63;abra;9;195;62;psiquico 65 | 64;kadabra;13;565;140;psiquico 66 | 65;alakazam;15;480;225;psiquico 67 | 66;machop;8;195;61;lucha 68 | 67;machoke;15;705;142;lucha 69 | 68;machamp;16;1300;227;lucha 70 | 69;bellsprout;7;40;60;planta-veneno 71 | 70;weepinbell;10;64;137;planta-veneno 72 | 71;victreebel;17;155;221;planta-veneno 73 | 72;tentacool;9;455;67;agua-veneno 74 | 73;tentacruel;16;550;180;agua-veneno 75 | 74;geodude;4;200;60;tierra-roca 76 | 75;graveler;10;1050;137;tierra-roca 77 | 76;golem;14;3000;223;tierra-roca 78 | 77;ponyta;10;300;82;fuego 79 | 78;rapidash;17;950;175;fuego 80 | 79;slowpoke;12;360;63;agua-psiquico 81 | 80;slowbro;16;785;172;agua-psiquico 82 | 81;magnemite;3;60;65;electrico 83 | 82;magneton;10;600;163;electrico 84 | 83;farfetchd;8;150;123;normal-volador 85 | 84;doduo;14;392;62;normal-volador 86 | 85;dodrio;18;852;161;normal-volador 87 | 86;seel;11;900;65;agua 88 | 87;dewgong;17;1200;166;agua-hielo 89 | 88;grimer;9;300;65;veneno 90 | 89;muk;12;300;175;veneno 91 | 90;shellder;3;40;61;agua 92 | 91;cloyster;15;1325;184;agua-hielo 93 | 92;gastly;13;1;62;fantasma-veneno 94 | 93;haunter;16;1;142;fantasma-veneno 95 | 94;gengar;15;405;225;fantasma-veneno 96 | 95;onix;88;2100;77;tierra-roca 97 | 96;drowzee;10;324;66;psiquico 98 | 97;hypno;16;756;169;psiquico 99 | 98;krabby;4;65;65;agua 100 | 99;kingler;13;600;166;agua 101 | 100;voltorb;5;104;66;electrico 102 | 101;electrode;12;666;168;electrico 103 | 102;exeggcute;4;25;65;psiquico-planta 104 | 103;exeggutor;20;1200;182;psiquico-planta 105 | 104;cubone;4;65;64;tierra 106 | 105;marowak;10;450;149;tierra 107 | 106;hitmonlee;15;498;159;lucha 108 | 107;hitmonchan;14;502;159;lucha 109 | 108;lickitung;12;655;77;normal 110 | 109;koffing;6;10;68;veneno 111 | 110;weezing;12;95;172;veneno 112 | 111;rhyhorn;10;1150;69;tierra-roca 113 | 112;rhydon;19;1200;170;tierra-roca 114 | 113;chansey;11;346;395;normal 115 | 114;tangela;10;350;87;planta 116 | 115;kangaskhan;22;800;172;normal 117 | 116;horsea;4;80;59;agua 118 | 117;seadra;12;250;154;agua 119 | 118;goldeen;6;150;64;agua 120 | 119;seaking;13;390;158;agua 121 | 120;staryu;8;345;68;agua 122 | 121;starmie;11;800;182;agua-psiquico 123 | 122;mr-mime;13;545;161;psiquico 124 | 123;scyther;15;560;100;insecto-volador 125 | 124;jynx;14;406;159;hielo-psiquico 126 | 125;electabuzz;11;300;172;electrico 127 | 126;magmar;13;445;173;fuego 128 | 127;pinsir;15;550;175;insecto 129 | 128;tauros;14;884;172;normal 130 | 129;magikarp;9;100;40;agua 131 | 130;gyarados;65;2350;189;agua-volador 132 | 131;lapras;25;2200;187;agua-hielo 133 | 132;ditto;3;40;101;normal 134 | 133;eevee;3;65;65;normal 135 | 134;vaporeon;10;290;184;agua 136 | 135;jolteon;8;245;184;electrico 137 | 136;flareon;9;250;184;fuego 138 | 137;porygon;8;365;79;normal 139 | 138;omanyte;4;75;71;roca-agua 140 | 139;omastar;10;350;173;roca-agua 141 | 140;kabuto;5;115;71;roca-agua 142 | 141;kabutops;13;405;173;roca-agua 143 | 142;aerodactyl;18;590;180;roca-volador 144 | 143;snorlax;21;4600;189;normal 145 | 144;articuno;17;554;261;hielo-volador 146 | 145;zapdos;16;526;261;electrico-volador 147 | 146;moltres;20;600;261;fuego-volador 148 | 147;dratini;18;33;60;dragon 149 | 148;dragonair;40;165;147;dragon 150 | 149;dragonite;22;2100;270;dragon-volador 151 | 150;mewtwo;20;1220;306;psiquico 152 | 151;mew;4;40;270;psiquico 153 | -------------------------------------------------------------------------------- /Actividades/Casen/Datos/comunas.csv: -------------------------------------------------------------------------------- 1 | Código Comuna|Nombre Comuna 2 | 15101|ARICA 3 | 15102|CAMARONES 4 | 15201|PUTRE 5 | 15202|GENERAL LAGOS 6 | 1101|IQUIQUE 7 | 1107|ALTO HOSPICIO 8 | 1401|POZO ALMONTE 9 | 1402|CAMIÑA 10 | 1403|COLCHANE 11 | 1404|HUARA 12 | 1405|PICA 13 | 2101|ANTOFAGASTA 14 | 2102|MEJILLONES 15 | 2103|SIERRA GORDA 16 | 2104|TALTAL 17 | 2201|CALAMA 18 | 2202|OLLAGÜE 19 | 2203|SAN PEDRO DE ATACAMA 20 | 2301|TOCOPILLA 21 | 2302|MARIA ELENA 22 | 3101|COPIAPÓ 23 | 3102|CALDERA 24 | 3103|TIERRA AMARILLA 25 | 3201|CHAÑARAL 26 | 3202|DIEGO DE ALMAGRO 27 | 3301|VALLENAR 28 | 3302|ALTO DEL CARMEN 29 | 3303|FREIRINA 30 | 3304|HUASCO 31 | 4101|LA SERENA 32 | 4102|COQUIMBO 33 | 4103|ANDACOLLO 34 | 4104|LA HIGUERA 35 | 4105|PAIGUANO 36 | 4106|VICUÑA 37 | 4201|ILLAPEL 38 | 4202|CANELA 39 | 4203|LOS VILOS 40 | 4204|SALAMANCA 41 | 4301|OVALLE 42 | 4302|COMBARBALÁ 43 | 4303|MONTE PATRIA 44 | 4304|PUNITAQUI 45 | 4305|RÍO HURTADO 46 | 5101|VALPARAÍSO 47 | 5102|CASABLANCA 48 | 5103|CON CON 49 | 5104|JUAN FERNÁNDEZ 50 | 5105|PUCHUNCAVÍ 51 | 5107|QUINTERO 52 | 5109|VIÑA DEL MAR 53 | 5201|ISLA DE PASCUA 54 | 5301|LOS ANDES 55 | 5302|CALLE LARGA 56 | 5303|RINCONADA 57 | 5304|SAN ESTEBAN 58 | 5401|LA LIGUA 59 | 5402|CABILDO 60 | 5403|PAPUDO 61 | 5404|PETORCA 62 | 5405|ZAPALLAR 63 | 5501|QUILLOTA 64 | 5502|CALERA 65 | 5503|HIJUELAS 66 | 5504|LA CRUZ 67 | 5506|NOGALES 68 | 5601|SAN ANTONIO 69 | 5602|ALGARROBO 70 | 5603|CARTAGENA 71 | 5604|EL QUISCO 72 | 5605|EL TABO 73 | 5606|SANTO DOMINGO 74 | 5701|SAN FELIPE 75 | 5702|CATEMU 76 | 5703|LLAILLAY 77 | 5704|PANQUEHUE 78 | 5705|PUTAENDO 79 | 5706|SANTA MARÍA 80 | 5801|QUILPUÉ 81 | 5802|LIMACHE 82 | 5803|OLMUÉ 83 | 5804|VILLA ALEMANA 84 | 6101|RANCAGUA 85 | 6102|CODEGUA 86 | 6103|COINCO 87 | 6104|COLTAUCO 88 | 6105|DOÑIHUE 89 | 6106|GRANEROS 90 | 6107|LAS CABRAS 91 | 6108|MACHALÍ 92 | 6109|MALLOA 93 | 6110|MOSTAZAL 94 | 6111|EL OLIVAR 95 | 6112|PEUMO 96 | 6113|PICHIDEGUA 97 | 6114|QUINTA DE TILCOCO 98 | 6115|RENGO 99 | 6116|REQUINOA 100 | 6117|SAN VICENTE 101 | 6201|PICHILEMU 102 | 6202|LA ESTRELLA 103 | 6203|LITUECHE 104 | 6204|MARCHIHUE 105 | 6205|NAVIDAD 106 | 6206|PAREDONES 107 | 6301|SAN FERNANDO 108 | 6302|CHÉPICA 109 | 6303|CHIMBARONGO 110 | 6304|LOLOL 111 | 6305|NANCAGUA 112 | 6306|PALMILLA 113 | 6307|PERALILLO 114 | 6308|PLACILLA 115 | 6309|PUMANQUE 116 | 6310|SANTA CRUZ 117 | 7101|TALCA 118 | 7102|CONSTITUCIÓN 119 | 7103|CUREPTO 120 | 7104|EMPEDRADO 121 | 7105|MAULE 122 | 7106|PELARCO 123 | 7107|PENCAHUE 124 | 7108|RÍO CLARO 125 | 7109|SAN CLEMENTE 126 | 7110|SAN RAFAEL 127 | 7201|CAUQUENES 128 | 7202|CHANCO 129 | 7203|PELLUHUE 130 | 7301|CURICÓ 131 | 7302|HUALAÑÉ 132 | 7303|LICANTÉN 133 | 7304|MOLINA 134 | 7305|RAUCO 135 | 7306|ROMERAL 136 | 7307|SAGRADA FAMILIA 137 | 7308|TENO 138 | 7309|VICHUQUÉN 139 | 7401|LINARES 140 | 7402|COLBÚN 141 | 7403|LONGAVÍ 142 | 7404|PARRAL 143 | 7405|RETIRO 144 | 7406|SAN JAVIER 145 | 7407|VILLA ALEGRE 146 | 7408|YERBAS BUENAS 147 | 8102|CORONEL 148 | 8103|CHIGUAYANTE 149 | 8104|FLORIDA 150 | 8105|HUALQUI 151 | 8107|PENCO 152 | 8108|SAN PEDRO DE LA PAZ 153 | 8109|SANTA JUANA 154 | 8111|TOMÉ 155 | 8112|HUALPÉN 156 | 8101|CONCEPCIÓN 157 | 8106|LOTA 158 | 8110|TALCAHUANO 159 | 8201|LEBU 160 | 8203|CAÑETE 161 | 8205|CURANILAHUE 162 | 8206|LOS ALAMOS 163 | 8207|TIRÚA 164 | 8202|ARAUCO 165 | 8204|CONTULMO 166 | 8301|LOS ANGELES 167 | 8302|ANTUCO 168 | 8303|CABRERO 169 | 8304|LAJA 170 | 8305|MULCHÉN 171 | 8306|NACIMIENTO 172 | 8307|NEGRETE 173 | 8308|QUILACO 174 | 8309|QUILLECO 175 | 8310|SAN ROSENDO 176 | 8311|SANTA BÁRBARA 177 | 8312|TUCAPEL 178 | 8313|YUMBEL 179 | 8314|ALTO BIO BIO 180 | 8401|CHILLÁN 181 | 8402|BULNES 182 | 8403|COBQUECURA 183 | 8404|COELEMU 184 | 8405|COIHUECO 185 | 8406|CHILLÁN VIEJO 186 | 8407|EL CARMEN 187 | 8408|NINHUE 188 | 8409|ÑIQUEN 189 | 8410|PEMUCO 190 | 8411|PINTO 191 | 8412|PORTEZUELO 192 | 8413|QUILLÓN 193 | 8414|QUIRIHUE 194 | 8415|RÁNQUIL 195 | 8416|SAN CARLOS 196 | 8417|SAN FABIÁN 197 | 8418|SAN IGNACIO 198 | 8419|SAN NICOLÁS 199 | 8420|TREGUACO 200 | 8421|YUNGAY 201 | 9101|TEMUCO 202 | 9102|CARAHUE 203 | 9103|CUNCO 204 | 9104|CURARREHUE 205 | 9105|FREIRE 206 | 9106|GALVARINO 207 | 9107|GORBEA 208 | 9108|LAUTARO 209 | 9109|LONCOCHE 210 | 9110|MELIPEUCO 211 | 9111|NUEVA IMPERIAL 212 | 9112|PADRE LAS CASAS 213 | 9113|PERQUENCO 214 | 9114|PITRUFQUEN 215 | 9116|SAAVEDRA 216 | 9117|TEODORO SCHMIDT 217 | 9118|TOLTÉN 218 | 9119|VILCÚN 219 | 9121|CHOL CHOL 220 | 9120|VILLARRICA 221 | 9115|PUCÓN 222 | 9201|ANGOL 223 | 9202|COLLIPULLI 224 | 9203|CURACAUTÍN 225 | 9204|ERCILLA 226 | 9205|LONQUIMAY 227 | 9206|LOS SAUCES 228 | 9207|LUMACO 229 | 9208|PURÉN 230 | 9209|RENAICO 231 | 9210|TRAIGUÉN 232 | 9211|VICTORIA 233 | 14103|LANCO 234 | 14104|LOS LAGOS 235 | 14107|PAILLACO 236 | 14108|PANGUIPULLI 237 | 14101|VALDIVIA 238 | 14102|CORRAL 239 | 14105|MÁFIL 240 | 14106|MARIQUINA 241 | 14202|FUTRONO 242 | 14203|LAGO RANCO 243 | 14204|RÍO BUENO 244 | 14201|LA UNIÓN 245 | 10103|COCHAMÓ 246 | 10105|FRUTILLAR 247 | 10107|LLANQUIHUE 248 | 10109|PUERTO VARAS 249 | 10101|PUERTO MONTT 250 | 10102|CALBUCO 251 | 10104|FRESIA 252 | 10106|LOS MUERMOS 253 | 10108|MAULLÍN 254 | 10302|PUERTO OCTAY 255 | 10303|PURRANQUE 256 | 10304|PUYEHUE 257 | 10305|RÍO NEGRO 258 | 10307|SAN PABLO 259 | 10301|OSORNO 260 | 10306|SAN JUAN DE LA COSTA 261 | 10204|CURACO DE VELEZ 262 | 10205|DALCAHUE 263 | 10206|PUQUELDÓN 264 | 10201|CASTRO 265 | 10202|ANCUD 266 | 10203|CHONCHI 267 | 10207|QUEILÉN 268 | 10208|QUELLÓN 269 | 10209|QUEMCHI 270 | 10210|QUINCHAO 271 | 10402|FUTALEUFÚ 272 | 10404|PALENA 273 | 10401|CHAITÉN 274 | 10403|HUALAIHUÉ 275 | 11101|COYHAIQUE 276 | 11102|LAGO VERDE 277 | 11201|AYSÉN 278 | 11202|CISNES 279 | 11203|GUAITECAS 280 | 11301|COCHRANE 281 | 11302|O'HIGGINS 282 | 11303|TORTEL 283 | 11401|CHILE CHICO 284 | 11402|RÍO IBAÑEZ 285 | 12101|PUNTA ARENAS 286 | 12102|LAGUNA BLANCA 287 | 12103|RÍO VERDE 288 | 12104|SAN GREGORIO 289 | 12201|CABO DE HORNOS 290 | 12301|PORVENIR 291 | 12302|PRIMAVERA 292 | 12303|TIMAUKEL 293 | 12401|NATALES 294 | 12402|TORRES DEL PAINE 295 | 13102|CERRILLOS 296 | 13103|CERRO NAVIA 297 | 13104|CONCHALÍ 298 | 13105|EL BOSQUE 299 | 13106|ESTACIÓN CENTRAL 300 | 13107|HUECHURABA 301 | 13108|INDEPENDENCIA 302 | 13109|LA CISTERNA 303 | 13110|LA FLORIDA 304 | 13111|LA GRANJA 305 | 13112|LA PINTANA 306 | 13113|LA REINA 307 | 13114|LAS CONDES 308 | 13115|LO BARNECHEA 309 | 13116|LO ESPEJO 310 | 13117|LO PRADO 311 | 13118|MACUL 312 | 13119|MAIPÚ 313 | 13120|ÑUÑOA 314 | 13122|PEÑALOLÉN 315 | 13123|PROVIDENCIA 316 | 13124|PUDAHUEL 317 | 13125|QUILICURA 318 | 13126|QUINTA NORMAL 319 | 13127|RECOLETA 320 | 13128|RENCA 321 | 13129|SAN JOAQUÍN 322 | 13130|SAN MIGUEL 323 | 13131|SAN RAMÓN 324 | 13132|VITACURA 325 | 13101|SANTIAGO 326 | 13121|PEDRO AGUIRRE CERDA 327 | 13201|PUENTE ALTO 328 | 13202|PIRQUE 329 | 13203|SAN JOSE DE MAIPO 330 | 13303|TIL TIL 331 | 13301|COLINA 332 | 13302|LAMPA 333 | 13401|SAN BERNARDO 334 | 13402|BUIN 335 | 13403|CALERA DE TANGO 336 | 13404|PAINE 337 | 13501|MELIPILLA 338 | 13502|ALHUÉ 339 | 13503|CURACAVÍ 340 | 13504|MARIA PINTO 341 | 13505|SAN PEDRO 342 | 13601|TALAGANTE 343 | 13602|EL MONTE 344 | 13603|ISLA DE MAIPO 345 | 13604|PADRE HURTADO 346 | 13605|PEÑAFLOR 347 | -------------------------------------------------------------------------------- /readme.md: -------------------------------------------------------------------------------- 1 | # IIC2413 - Bases de Datos 2 | 3 | ## Tabla de contenidos 4 | 5 | - [Equipo](#equipo) 6 | - [Profesor](#profesor) 7 | - [Ayudantes](#ayudantes) 8 | - [Evaluación](#evaluación) 9 | - [Nota de Cátedra](#nota-de-cátedra) 10 | - [Nota de Proyecto](#nota-de-proyecto) 11 | - [Nota Final](#nota-final) 12 | - [Foro](#foro) 13 | - [Política de integridad académica](#política-de-integridad-académica) 14 | 15 | --- 16 | 17 | ## Equipo 18 | 19 | ### Profesor 20 | 21 | Nombre | Sección | Email 22 | -------------- | ------- | --------------------- 23 | Adrián Soto | 1 | [assoto@uc.cl] 24 | 25 | ### Ayudantes de cátedra 26 | 27 | Nombre | Email 28 | ---------------------- | ---------------- 29 | **Isidora Vizcaya** | [isvizcaya@uc.cl] 30 | Romano Fenzo | [rfenzo@uc.cl] 31 | Tamara Cucumides | [tacucumides@uc.cl] 32 | Constanza Gaínza | [cmgainza@uc.cl] 33 | María Ignacia Sánchez | [mcsanchez@uc.cl] 34 | Marcelo Saldías | [misaldias@uc.cl] 35 | Daniela Concha | [daconcha@uc.cl] 36 | Patricio de Solminihac | [pdesolminihac@uc.cl] 37 | 38 | 39 | ### Ayudantes de proyecto 40 | 41 | Nombre | Email 42 | ------------------- | ---------------- 43 | **Felipe Silva** | [lfsilva1@uc.cl] 44 | Wenyi He Yang | [whe1@uc.cl] 45 | Kevin Johnson | [kjjohnson@uc.cl] 46 | Nicolás Quiroz | [naquiroz@uc.cl] 47 | Philippe Potin | [papotin@uc.cl] 48 | Fernanda Durán | [frduran@uc.cl] 49 | Valentina Álvarez | [vjalvarez@uc.cl] 50 | Valentina Rojas | [varojasm@uc.cl] 51 | 52 | 53 | [assoto@uc.cl]: mailto:assoto@uc.cl 54 | [isvizcaya@uc.cl]: mailto:isvizcaya@uc.cl 55 | [lfsilva1@uc.cl]: mailto:lfsilva1@uc.cl 56 | [rfenzo@uc.cl]: mailto:rfenzo@uc.cl 57 | [whe1@uc.cl]: mailto:whe1@uc.cl 58 | [kjjohnson@uc.cl]: mailto:kjjohnson@uc.cl 59 | [tacucumides@uc.cl]: mailto:tacucumides@uc.cl 60 | [cmgainza@uc.cl]: mailto:cmgainza@uc.cl 61 | [mcsanchez@uc.cl]: mailto:mcsanchez@uc.cl 62 | [misaldias@uc.cl]: mailto:misaldias@uc.cl 63 | [naquiroz@uc.cl]: mailto:naquiroz@uc.cl 64 | [papotin@uc.cl]: mailto:papotin@uc.cl 65 | [frduran@uc.cl]: mailto:frduran@uc.cl 66 | [vjalvarez@uc.cl]: mailto:vjalvarez@uc.cl 67 | [daconcha@uc.cl]: mailto:daconcha@uc.cl 68 | [pdesolminihac@uc.cl]: mailto:pdesolminihac@uc.cl 69 | [varojasm@uc.cl]: mailto:varojasm@uc.cl 70 | 71 | 72 | --- 73 | 74 | ## Evaluación 75 | 76 | ### Nota de Cátedra 77 | 78 | El curso contará con 3 interrogaciones y un examen a lo largo del semestre. El contenido de estas será el material visto en clases, ayudantías y en las actividades del curso. La hora de inicio de las interrogaciones será a las 18:30, mientras que el examen comenzará a las 9:00. Las fechas son las siguientes: 79 | 80 | Interrogación | Fecha 81 | ----------------- | ----------------------- 82 | Interrogación \#1 | lunes 08 de abril 83 | Interrogación \#2 | miércoles 08 de mayo 84 | Interrogación \#3 | miércoles 05 de junio 85 | Examen | martes 02 de julio 86 | 87 | La nota de cátedra (_NC_) corresponde a: 88 | 89 | _NC = I1 + I2 + I3 + 2·EX - min(I1, I2, I3, Ex)_ 90 | 91 | ### Nota de Proyecto 92 | 93 | El curso contará con un proyecto que tiene 5 entregas. Las fechas y el método de entrega será anunciado durante el semestre, para cada entrega. 94 | 95 | La nota de proyecto (_NP_) corresponde a: 96 | 97 | _NP = 0.05·E1 + 0.20·E2 + 0.3·E3 + 0.20·E4 + 0.25·E5_ 98 | 99 | **Importante:** La nota de las entregas 3, 4 y 5 estarán sujetas a una evaluación de pares que puede alterar la nota del alumno. Si el profesor lo considera necesario, citará a a los alumnos cuyas evaluaciones de pares indican un comportamiento irregular en las entregas. 100 | 101 | ### Nota Final 102 | 103 | Si _NC > 4.0 y NP > 4.0_ la nota final (_NF_) del curso se calcula como: 104 | 105 | _NF = 0.5·NC + 0.5·NP_ 106 | 107 | En otro caso, la nota se calcula como: 108 | 109 | _NF = min(3.9, 0.5·NC + 0.5·NP)_ 110 | 111 | --- 112 | 113 | ## Foro 114 | 115 | La página de [_Issues_](https://github.com/IIC2413/Syllabus-2018-2/issues) se utilizará como foro para preguntas. Notar que las etiquetas ya se encuentran definidas. **Este es el único canal oficial para formular preguntas**. 116 | 117 | Tanto al publicar como comentar, debes atenerte a las **normas del curso**. Además, debes utilizar **[_Markdown_](https://github.com/adam-p/markdown-here/wiki/Markdown-Cheatsheet#code)** cuando sea necesario. Por ejemplo, cuando se necesita mostrar código o mensajes de error. 118 | 119 | Una vez resuelto el problema, da las **gracias** y **cierra el issue**. 120 | 121 | **Importante**: El equipo docente puede tardar hasta 24 horas en contestar una _issue_, aunque normalmente el tiempo de respuesta debería ser menor. Por lo mismo, se recomienda **no publicar _issues_ el mismo día de alguna entrega o interrogación**. 122 | 123 | 124 | --- 125 | 126 | ## Política de integridad académica 127 | 128 | Los alumnos de la Escuela de Ingeniería de la Pontificia Universidad Católica de Chile deben mantener un comportamiento acorde a la Declaración de Principios de la Universidad. En particular, se espera que **mantengan altos estándares de honestidad académica**. Cualquier acto deshonesto o fraude académico está prohibido; los alumnos que incurran en este tipo de acciones se exponen a un Procedimiento Sumario. Es responsabilidad de cada alumno conocer y respetar el documento sobre Integridad Académica publicado por la Dirección de Docencia de la Escuela de Ingeniería (disponible en SIDING). 129 | 130 | Específicamente, para los cursos del Departamento de Ciencia de la Computación, rige obligatoriamente la siguiente política de integridad académica. Todo trabajo presentado por un alumno para los efectos de la evaluación de un curso debe ser hecho individualmente por el alumno, sin apoyo en material de terceros. Por _trabajo_ se entiende en general las interrogaciones escritas, las tareas de programación u otras, los trabajos de laboratorio, los proyectos, el examen, entre otros. 131 | 132 | **En particular, si un alumno copia un trabajo, o si a un alumno se le prueba que compró o intentó comprar un trabajo, obtendrá nota final 1.1 en el curso y se solicitará a la Dirección de Docencia de la Escuela de Ingeniería que no le permita retirar el curso de la carga académica semestral.** 133 | 134 | Por _copia_ se entiende incluir en el trabajo presentado como propio, partes hechas por otra persona. **En caso que corresponda a _copia_ a otros alumnos, la sanción anterior se aplicará a todos los involucrados**. En todos los casos, se informará a la Dirección de Docencia de la Escuela de Ingeniería para que tome sanciones adicionales si lo estima conveniente. 135 | 136 | Obviamente, está permitido usar material disponible públicamente, por ejemplo, libros o contenidos tomados de Internet, siempre y cuando se incluya la referencia correspondiente. 137 | 138 | Lo anterior se entiende como complemento al [Reglamento del Alumno de la Pontificia Universidad Católica de Chile]. Por ello, es posible pedir a la Universidad la aplicación de sanciones adicionales especificadas en dicho reglamento. 139 | 140 | [Reglamento del Alumno de la Pontificia Universidad Católica de Chile]: http://admisionyregistros.uc.cl/alumnos/informacion-academica/reglamentos-estudiantiles 141 | -------------------------------------------------------------------------------- /Actividades/Recursión/Recursión.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "# Recursión\n", 8 | "\n", 9 | "En este notebook vamos a ver un ejemplo de recursión en SQL. Para esto vamos a usar PSQL." 10 | ] 11 | }, 12 | { 13 | "cell_type": "code", 14 | "execution_count": 2, 15 | "metadata": {}, 16 | "outputs": [ 17 | { 18 | "name": "stdout", 19 | "output_type": "stream", 20 | "text": [ 21 | "The sql extension is already loaded. To reload it, use:\n", 22 | " %reload_ext sql\n" 23 | ] 24 | } 25 | ], 26 | "source": [ 27 | "%load_ext sql" 28 | ] 29 | }, 30 | { 31 | "cell_type": "code", 32 | "execution_count": 3, 33 | "metadata": {}, 34 | "outputs": [ 35 | { 36 | "name": "stderr", 37 | "output_type": "stream", 38 | "text": [ 39 | "/usr/local/lib/python3.7/site-packages/psycopg2/__init__.py:144: UserWarning: The psycopg2 wheel package will be renamed from release 2.8; in order to keep installing from binary please use \"pip install psycopg2-binary\" instead. For details see: .\n", 40 | " \"\"\")\n" 41 | ] 42 | }, 43 | { 44 | "data": { 45 | "text/plain": [ 46 | "'Connected: adriansotosuarez@recursion'" 47 | ] 48 | }, 49 | "execution_count": 3, 50 | "metadata": {}, 51 | "output_type": "execute_result" 52 | } 53 | ], 54 | "source": [ 55 | "%sql postgresql://adriansotosuarez:@localhost/recursion" 56 | ] 57 | }, 58 | { 59 | "cell_type": "code", 60 | "execution_count": 8, 61 | "metadata": {}, 62 | "outputs": [ 63 | { 64 | "name": "stdout", 65 | "output_type": "stream", 66 | "text": [ 67 | " * postgresql://adriansotosuarez:***@localhost/recursion\n", 68 | "Done.\n" 69 | ] 70 | }, 71 | { 72 | "data": { 73 | "text/plain": [ 74 | "[]" 75 | ] 76 | }, 77 | "execution_count": 8, 78 | "metadata": {}, 79 | "output_type": "execute_result" 80 | } 81 | ], 82 | "source": [ 83 | "%%sql\n", 84 | "\n", 85 | "CREATE TABLE Vuelos(ciudad_origen VARCHAR(100), ciudad_destino VARCHAR(100), \n", 86 | " PRIMARY KEY(ciudad_origen, ciudad_destino))" 87 | ] 88 | }, 89 | { 90 | "cell_type": "code", 91 | "execution_count": 9, 92 | "metadata": {}, 93 | "outputs": [ 94 | { 95 | "name": "stdout", 96 | "output_type": "stream", 97 | "text": [ 98 | " * postgresql://adriansotosuarez:***@localhost/recursion\n", 99 | "1 rows affected.\n", 100 | "1 rows affected.\n", 101 | "1 rows affected.\n", 102 | "1 rows affected.\n", 103 | "1 rows affected.\n", 104 | "1 rows affected.\n" 105 | ] 106 | }, 107 | { 108 | "data": { 109 | "text/plain": [ 110 | "[]" 111 | ] 112 | }, 113 | "execution_count": 9, 114 | "metadata": {}, 115 | "output_type": "execute_result" 116 | } 117 | ], 118 | "source": [ 119 | "%%sql\n", 120 | "INSERT INTO Vuelos VALUES('Santiago', 'Buenos Aires');\n", 121 | "INSERT INTO Vuelos VALUES('Buenos Aires', 'Madrid');\n", 122 | "INSERT INTO Vuelos VALUES('Madrid', 'Doha');\n", 123 | "INSERT INTO Vuelos VALUES('Doha', 'Katmandú');\n", 124 | "INSERT INTO Vuelos VALUES('Santiago', 'Lima');\n", 125 | "INSERT INTO Vuelos VALUES('Lima', 'Miami');" 126 | ] 127 | }, 128 | { 129 | "cell_type": "code", 130 | "execution_count": 10, 131 | "metadata": {}, 132 | "outputs": [ 133 | { 134 | "name": "stdout", 135 | "output_type": "stream", 136 | "text": [ 137 | " * postgresql://adriansotosuarez:***@localhost/recursion\n", 138 | "13 rows affected.\n" 139 | ] 140 | }, 141 | { 142 | "data": { 143 | "text/html": [ 144 | "\n", 145 | " \n", 146 | " \n", 147 | " \n", 148 | " \n", 149 | " \n", 150 | " \n", 151 | " \n", 152 | " \n", 153 | " \n", 154 | " \n", 155 | " \n", 156 | " \n", 157 | " \n", 158 | " \n", 159 | " \n", 160 | " \n", 161 | " \n", 162 | " \n", 163 | " \n", 164 | " \n", 165 | " \n", 166 | " \n", 167 | " \n", 168 | " \n", 169 | " \n", 170 | " \n", 171 | " \n", 172 | " \n", 173 | " \n", 174 | " \n", 175 | " \n", 176 | " \n", 177 | " \n", 178 | " \n", 179 | " \n", 180 | " \n", 181 | " \n", 182 | " \n", 183 | " \n", 184 | " \n", 185 | " \n", 186 | " \n", 187 | " \n", 188 | " \n", 189 | " \n", 190 | " \n", 191 | " \n", 192 | " \n", 193 | " \n", 194 | " \n", 195 | " \n", 196 | " \n", 197 | " \n", 198 | " \n", 199 | " \n", 200 | " \n", 201 | "
ciudad_origenciudad_destino
SantiagoBuenos Aires
Buenos AiresMadrid
MadridDoha
DohaKatmandú
SantiagoLima
LimaMiami
SantiagoMadrid
Buenos AiresDoha
MadridKatmandú
SantiagoMiami
SantiagoDoha
Buenos AiresKatmandú
SantiagoKatmandú
" 202 | ], 203 | "text/plain": [ 204 | "[('Santiago', 'Buenos Aires'),\n", 205 | " ('Buenos Aires', 'Madrid'),\n", 206 | " ('Madrid', 'Doha'),\n", 207 | " ('Doha', 'Katmandú'),\n", 208 | " ('Santiago', 'Lima'),\n", 209 | " ('Lima', 'Miami'),\n", 210 | " ('Santiago', 'Madrid'),\n", 211 | " ('Buenos Aires', 'Doha'),\n", 212 | " ('Madrid', 'Katmandú'),\n", 213 | " ('Santiago', 'Miami'),\n", 214 | " ('Santiago', 'Doha'),\n", 215 | " ('Buenos Aires', 'Katmandú'),\n", 216 | " ('Santiago', 'Katmandú')]" 217 | ] 218 | }, 219 | "execution_count": 10, 220 | "metadata": {}, 221 | "output_type": "execute_result" 222 | } 223 | ], 224 | "source": [ 225 | "%%sql\n", 226 | "WITH RECURSIVE R(ciudad_origen, ciudad_destino) AS (\n", 227 | " SELECT * FROM\n", 228 | " Vuelos\n", 229 | " UNION\n", 230 | " SELECT V.ciudad_origen, R.ciudad_destino\n", 231 | " FROM Vuelos V, R\n", 232 | " WHERE V.ciudad_destino = R.ciudad_origen\n", 233 | ")\n", 234 | "SELECT * FROM R" 235 | ] 236 | }, 237 | { 238 | "cell_type": "code", 239 | "execution_count": null, 240 | "metadata": {}, 241 | "outputs": [], 242 | "source": [] 243 | } 244 | ], 245 | "metadata": { 246 | "kernelspec": { 247 | "display_name": "Python 3", 248 | "language": "python", 249 | "name": "python3" 250 | }, 251 | "language_info": { 252 | "codemirror_mode": { 253 | "name": "ipython", 254 | "version": 3 255 | }, 256 | "file_extension": ".py", 257 | "mimetype": "text/x-python", 258 | "name": "python", 259 | "nbconvert_exporter": "python", 260 | "pygments_lexer": "ipython3", 261 | "version": "3.7.1" 262 | } 263 | }, 264 | "nbformat": 4, 265 | "nbformat_minor": 2 266 | } 267 | -------------------------------------------------------------------------------- /Actividades/Text Search/Text Search.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "# Búsqueda en textos\n", 8 | "\n", 9 | "### Outline:\n", 10 | " - Búsqueda básica\n", 11 | " - Text Search\n", 12 | " - ¿Cómo funciona?\n", 13 | " - Otras ventajas: Stemming, Stop Words\n", 14 | " - Índices compuestos\n", 15 | " - Búsqueda con rankeo\n", 16 | "\n", 17 | "---\n", 18 | " \n", 19 | "Para esta actividad es mejor que trabajes con el pedazo grande de Wikidata, wiki\\_500000.josn. Impórtalo \n", 20 | "igual que antes, ingresa lo siguiente en la consola: \n", 21 | "`> mongoimport --db test --collection entidades --drop --file wiki_5000.json --jsonArray`\n", 22 | "\n", 23 | "__Ojo:__ Este archivo pesa 2,3 GB " 24 | ] 25 | }, 26 | { 27 | "cell_type": "markdown", 28 | "metadata": {}, 29 | "source": [ 30 | "## Búsqueda básica\n", 31 | "\n", 32 | "Imagina que quieres todas las entidades de Wikidata en donde aparece *\"Chile\"* en la descripción. La forma más obvia (y la única que sabríamos hacer hasta el momento) sería usar el equivalente MongoDB para el operador `LIKE` en SQL. Corre el servidor de mongo, como lo hicimos en la guía de MongoDB, y corre mongo. La consulta que __obtiene las descripciones__ en inglés que contienen *\"Chile\"* se ve así: \n", 33 | "\n", 34 | "`> db.entidades.find({\"descriptions.en.value\":{$regex:\"Chile\"}}, {\"descriptions.en.value\":1});`\n" 35 | ] 36 | }, 37 | { 38 | "cell_type": "markdown", 39 | "metadata": {}, 40 | "source": [ 41 | " - Corre esta consulta y espera los resultados. Quizás se demore un poco, así que ahora tienes unos minutos sin computador para hacer lo que quieras (Ver memes siempre es una buena opción :) )\n", 42 | " - Discute con tu compañera o compañero de al lado: ¿por qué se demora tanto esta consulta? ¿Cómo se podría mejorar el rendimiento?\n", 43 | "\n", 44 | "#### __Notas:__ \n", 45 | "- Recuerda que para que esta consulta funcione, la base de datos que debes estar usando en MongoDB es la llamada _test_. Esta tiene la tabla de _entidades_ que cargaste anteriormente. Para esto, ejecuta el comando `use test`.\n", 46 | "- Como recordarás de la guía de MongoDB, lo que hace el primer argumento es la selección. En este caso, selecciona aquellos datos cuya descripción, en inglés, contenga la palabra _\"Chile\"_. Lo que hace el segundo argumento es la proyección, y en este caso, le estás pidiendo al programa que te entregue la descripción en inglés. \n", 47 | "- El operador `$regex` es el equivalente a `LIKE`\n", 48 | "- __No olvides__ poner `;` al final de la sentencia ;)\n", 49 | "\n", 50 | "### Text Search\n", 51 | "\n", 52 | "Como lo han discutido, no hay una forma evidente de indexar el campo `descriptions.en.value` para que retorne las descripciones que contienen ciertas palabras clave. Antes de ver cómo funciona, veamos cómo hacerlo en mongo. \n", 53 | "\n", 54 | "##### 1 . Crea un índice de texto en ese campo (el valor `\"text\"` indica que el índice es de texto): \n", 55 | "\n", 56 | "`> db.entidades.createIndex({\"descriptions.en.value\":\"text\"});`\n", 57 | "\n", 58 | "##### 2 . ¡Ahora puedes hacer consultas! La siguiente consulta busca todas las descripciones que tengan `\"Chile\"` (esta si que funciona rápido) \n", 59 | "\n", 60 | "`> db.entidades.find({$text: {$search: \"Chile\"}},{\"descriptions.en.value\":1});`\n", 61 | "\n", 62 | "##### 3 . Existen varias otras cosas que hacer, como hacer un `OR` (en este caso entre `chile` y `town`):\n", 63 | "\n", 64 | "`> db.entidades.find({$text: {$search: \"Chile town\"}},{\"descriptions.en.value\":1});`\n", 65 | "\n", 66 | "##### 4 . Buscar frases enteras (en este caso la frase `\"in Chile\"`) poniéndolas entre comillas (la comilla debe ir acompañada del comando de escape, así: `\\\"`): \n", 67 | "\n", 68 | "`> db.entidades.find({$text: {$search: \"\\\"in Chile\\\"\"}},{\"descriptions.en.value\":1});`\n", 69 | "##### 5 .Combinar más de una frase para hacer un `AND` (en este caso todo lo que contenga `\"Chile\"` y `\"town\"`): \n", 70 | "\n", 71 | "`> db.entidades.find({$text: {$search: \"\\\"Chile\\\" \\\"town\\\"\"}}, {\"descriptions.en.value\":1});`\n", 72 | "\n", 73 | "##### 6 . Y hacer `NOT` (en este caso todo lo que contiene `\"Chile\"` y no contenga `\"war\"`): \n", 74 | "\n", 75 | "`> db.entidades.find({$text: {$search: \"Chile -war\"}},{\"descriptions.en.value\":1});`\n", 76 | "\n", 77 | "\n", 78 | "### ¿Cómo funciona? \n", 79 | "\n", 80 | "Limitémonos a pensar solo en las descripciones de los documentos de Wikidata. Llamemos $D$ al conjunto de descripciones. \n", 81 | "Asume también que tenemos un índice en el campo `id` de los documentos, por lo que, dado un `id`, podemos encontrar rápidamente la descripción que corresponde a ese `id`.\n", 82 | "\n", 83 | "- Imagina que $P$ es el conjunto de todas las palabras que aparecen en $D$. ¿Cómo podríamos crear una estructura que nos permita \n", 84 | "acceder rápidamente a todos los `id` de descripciones que tienen una palabra en $P$?\n", 85 | "\n", 86 | "Acá hay una idea: Hacer una matriz de $|P|$ por $|D|$ entradas: las columnas son los documentos y las filas son las palabras, y hay un $1$ en la entrada $[i,j]$ si la palabra $i$ aparece en el documento $j$. \n", 87 | "- Discute las ventajas y desventajas de la idea. ¿Qué tamaño tiene esta matriz? ¿Qué tan rápido es conseguir todos los documentos que mencionan Chile? \n", 88 | "- Piensa en cómo hacer algo más eficiente que permita recuperar información igual de rápido.\n", 89 | "\n", 90 | "### Consultas booleanas \n", 91 | "\n", 92 | "Imagina que tienes un índice invertido sobre las descripciones de artículos en wikidata. \n", 93 | "\n", 94 | "1. Explica como buscar todos los documentos que mencionan la palabra $p$ y la palabra $q$\n", 95 | "- Explica como buscar todos los documentos que mencionan a la palabra $p$ y no a la palabra $q$\n", 96 | "- Explica como buscar todos los documentos que mencionan a la palabra $p$ pero no a la palabra $q$\n", 97 | "- Explica como buscar todos los documentos que mencionan a la frase $``p\\ q\\ r\"$\n", 98 | "- Explica por que es problemático buscar todos los documentos que no contengan la palabra $p$\n", 99 | "\n", 100 | "### Otras ventajas: Stemming, Stop Words\n", 101 | "\n", 102 | "Ejecuta esta consulta. Le estás pidiendo a MongoDB que te explique cómo fue procesada. \n", 103 | "\n", 104 | "`> db.entidades.find({$text: {$search: \"\\\"Chile\\\" Town -war\"}}, {\"descriptions.en.value\":1}).explain(true);`\n", 105 | "\n", 106 | "Mira `parsedTextQuery`, y el objeto `terms`. Verás que está buscando, entre otras cosas, por la palabra `town` (sin mayúscula). Esto es común en los buscadores de texto, y se conoce como __Stemming__: tratamos de reducir las palabras complicadas a sus raíces, lo que incluye eliminar signos de puntuación, pasar a minúsculas, y transformar cosas como _\"Chiles\"_ a _\"Chile\"_.\n", 107 | "\n", 108 | "Ejecuta ahora esta consulta, y fíjate qué pasa con la palabra `\"in\"`:\n", 109 | "\n", 110 | "`> db.entidades.find({$text: {$search: \"towns in Chile\"}}, {\"descriptions.en.value\":1}).explain(true);`\n", 111 | "\n", 112 | "Las palabras que no se incluyen (por ser muy comunes) se llaman **Stop Words**.\n", 113 | "\n", 114 | "1. Encuentra otro ejemplo de stemming en inglés, y otra Stop Word que no sea `in`. \n", 115 | "- Imagina ahora ejemplos de stemming en español. ¿Hay alguno que cambie entre \n", 116 | "español e inglés? ¿qué stop words hay en español? \n", 117 | "- Mira la diferencia entre `\"towns\"`(cómo término) y `\"\\\"towns\\\"\"` (como frase). \n", 118 | "\n", 119 | "### Indices compuestos\n", 120 | "\n", 121 | "Quizá queremos buscar tanto en el título como en el contenido del documento. A esta idea se le llama un _índice compuesto_. Para indexar las descripciones y los labels en wikidata (inglés), ingresa lo siguiente (ojo que mongo solo admite un índice invertido por collection, así que tienes que [borrar el anterior](https://docs.mongodb.com/manual/reference/method/db.collection.dropIndex/)): \n", 122 | "\n", 123 | "`> db.entidades.createIndex({\"descriptions.en.value\":\"text\",\"labels.en.value\":\"text\"})`\n", 124 | "\n", 125 | "Listo! \n", 126 | "- Busca todos los documentos que contienen Chile, ahora usando el índice compuesto. Busca otras consultas donde quede claro que se usa también el label\n", 127 | "\n", 128 | "#### Bonus (pesos a distintos campos):\n", 129 | "Averigua como hacer que el label sea más importante que la descripción a la hora de buscar en índices compuestos. \n", 130 | "__Ayuda:__ Lo que puedes hacer es asignar pesos (weights) distintos a cada campo, y ordenar por su puntaje (mira más abajo).\n", 131 | "\n", 132 | "### Búsqueda con rankeo\n", 133 | "\n", 134 | "Imagina que quieres información sobre todos los mamíferos de Chile. Ejecutas la siguiente consulta: \n", 135 | "\n", 136 | "`> db.entidades.find({$text: {$search: \"Chilean mammal\"}},{\"descriptions.en.value\":1});`\n", 137 | "\n", 138 | "Tienes una mezcla de mamíferos y de cosas relacionadas en Chile. ¿Cómo decide MongoDB qué resultados entregar? \n", 139 | "Internamente, MongoDB asigna un puntaje de relevancia a las distintas descripciones que hacen match. \n", 140 | "Hay una manera más explícita de ordenar los resultados por relevancia. Ejecuta primero la consulta que muestra el puntaje. \n", 141 | "\n", 142 | "`> db.entidades.find({$text: {$search: \"Chilean mammal\"}},{\"descriptions.en.value\":1, score: {$meta: \"textScore\"}});`\n", 143 | "\n", 144 | "Como ves, el resultado tiene resultados de descripciones que contienen `\"Chilean\"` o `\"mammal\"`, y a cada uno se le asigna un puntaje de acuerdo a la relevancia. Para ordenar los resultados por su relevancia, ejecuta en vez lo siguiente:\n", 145 | "\n", 146 | "\n", 147 | "`> db.entidades.find({$text: {$search: \"Chilean mammal\"}},\n", 148 | " {\"descriptions.en.value\":1,\n", 149 | " score: { $meta: \"textScore\" }}).sort( { score: { $meta: \"textScore\" }});`\n", 150 | "\n", 151 | "- 1. Averigua de qué depende el puntaje de MongoDB. Para esto, crea una nueva collection con unos 5-10 documentos (que sean puro texto), y anda modificando a medida que vas investigando. \n", 152 | "\n", 153 | "__Ayuda:__ generalmente el puntaje es proporcional a la cantidad de veces que aparece en el documento, e inversamente proporcional a la cantidad de documentos en los que aparece. ¿Es esto cierto en MongoDB? \n", 154 | "\n", 155 | "\n" 156 | ] 157 | } 158 | ], 159 | "metadata": { 160 | "kernelspec": { 161 | "display_name": "Python 3", 162 | "language": "python", 163 | "name": "python3" 164 | }, 165 | "language_info": { 166 | "codemirror_mode": { 167 | "name": "ipython", 168 | "version": 3 169 | }, 170 | "file_extension": ".py", 171 | "mimetype": "text/x-python", 172 | "name": "python", 173 | "nbconvert_exporter": "python", 174 | "pygments_lexer": "ipython3", 175 | "version": "3.7.1" 176 | } 177 | }, 178 | "nbformat": 4, 179 | "nbformat_minor": 2 180 | } 181 | -------------------------------------------------------------------------------- /Ayudantías/heroku-tutorial-app/Pipfile.lock: -------------------------------------------------------------------------------- 1 | { 2 | "_meta": { 3 | "hash": { 4 | "sha256": "2ba874eea7dd00b4a6a52552c55e428eef5a3107ec4f4d9f332077d7e6025d9c" 5 | }, 6 | "pipfile-spec": 6, 7 | "requires": { 8 | "python_version": "3.6" 9 | }, 10 | "sources": [ 11 | { 12 | "name": "pypi", 13 | "url": "https://pypi.org/simple", 14 | "verify_ssl": true 15 | } 16 | ] 17 | }, 18 | "default": { 19 | "click": { 20 | "hashes": [ 21 | "sha256:2335065e6395b9e67ca716de5f7526736bfa6ceead690adf616d925bdc622b13", 22 | "sha256:5b94b49521f6456670fdb30cd82a4eca9412788a93fa6dd6df72c94d5a8ff2d7" 23 | ], 24 | "version": "==7.0" 25 | }, 26 | "flask": { 27 | "hashes": [ 28 | "sha256:ad7c6d841e64296b962296c2c2dabc6543752985727af86a975072dea984b6f3", 29 | "sha256:e7d32475d1de5facaa55e3958bc4ec66d3762076b074296aa50ef8fdc5b9df61" 30 | ], 31 | "index": "pypi", 32 | "version": "==1.0.3" 33 | }, 34 | "gunicorn": { 35 | "hashes": [ 36 | "sha256:aa8e0b40b4157b36a5df5e599f45c9c76d6af43845ba3b3b0efe2c70473c2471", 37 | "sha256:fa2662097c66f920f53f70621c6c58ca4a3c4d3434205e608e121b5b3b71f4f3" 38 | ], 39 | "index": "pypi", 40 | "version": "==19.9.0" 41 | }, 42 | "itsdangerous": { 43 | "hashes": [ 44 | "sha256:321b033d07f2a4136d3ec762eac9f16a10ccd60f53c0c91af90217ace7ba1f19", 45 | "sha256:b12271b2047cb23eeb98c8b5622e2e5c5e9abd9784a153e9d8ef9cb4dd09d749" 46 | ], 47 | "version": "==1.1.0" 48 | }, 49 | "jinja2": { 50 | "hashes": [ 51 | "sha256:065c4f02ebe7f7cf559e49ee5a95fb800a9e4528727aec6f24402a5374c65013", 52 | "sha256:14dd6caf1527abb21f08f86c784eac40853ba93edb79552aa1e4b8aef1b61c7b" 53 | ], 54 | "version": "==2.10.1" 55 | }, 56 | "markupsafe": { 57 | "hashes": [ 58 | "sha256:00bc623926325b26bb9605ae9eae8a215691f33cae5df11ca5424f06f2d1f473", 59 | "sha256:09027a7803a62ca78792ad89403b1b7a73a01c8cb65909cd876f7fcebd79b161", 60 | "sha256:09c4b7f37d6c648cb13f9230d847adf22f8171b1ccc4d5682398e77f40309235", 61 | "sha256:1027c282dad077d0bae18be6794e6b6b8c91d58ed8a8d89a89d59693b9131db5", 62 | "sha256:24982cc2533820871eba85ba648cd53d8623687ff11cbb805be4ff7b4c971aff", 63 | "sha256:29872e92839765e546828bb7754a68c418d927cd064fd4708fab9fe9c8bb116b", 64 | "sha256:43a55c2930bbc139570ac2452adf3d70cdbb3cfe5912c71cdce1c2c6bbd9c5d1", 65 | "sha256:46c99d2de99945ec5cb54f23c8cd5689f6d7177305ebff350a58ce5f8de1669e", 66 | "sha256:500d4957e52ddc3351cabf489e79c91c17f6e0899158447047588650b5e69183", 67 | "sha256:535f6fc4d397c1563d08b88e485c3496cf5784e927af890fb3c3aac7f933ec66", 68 | "sha256:62fe6c95e3ec8a7fad637b7f3d372c15ec1caa01ab47926cfdf7a75b40e0eac1", 69 | "sha256:6dd73240d2af64df90aa7c4e7481e23825ea70af4b4922f8ede5b9e35f78a3b1", 70 | "sha256:717ba8fe3ae9cc0006d7c451f0bb265ee07739daf76355d06366154ee68d221e", 71 | "sha256:79855e1c5b8da654cf486b830bd42c06e8780cea587384cf6545b7d9ac013a0b", 72 | "sha256:7c1699dfe0cf8ff607dbdcc1e9b9af1755371f92a68f706051cc8c37d447c905", 73 | "sha256:88e5fcfb52ee7b911e8bb6d6aa2fd21fbecc674eadd44118a9cc3863f938e735", 74 | "sha256:8defac2f2ccd6805ebf65f5eeb132adcf2ab57aa11fdf4c0dd5169a004710e7d", 75 | "sha256:98c7086708b163d425c67c7a91bad6e466bb99d797aa64f965e9d25c12111a5e", 76 | "sha256:9add70b36c5666a2ed02b43b335fe19002ee5235efd4b8a89bfcf9005bebac0d", 77 | "sha256:9bf40443012702a1d2070043cb6291650a0841ece432556f784f004937f0f32c", 78 | "sha256:ade5e387d2ad0d7ebf59146cc00c8044acbd863725f887353a10df825fc8ae21", 79 | "sha256:b00c1de48212e4cc9603895652c5c410df699856a2853135b3967591e4beebc2", 80 | "sha256:b1282f8c00509d99fef04d8ba936b156d419be841854fe901d8ae224c59f0be5", 81 | "sha256:b2051432115498d3562c084a49bba65d97cf251f5a331c64a12ee7e04dacc51b", 82 | "sha256:ba59edeaa2fc6114428f1637ffff42da1e311e29382d81b339c1817d37ec93c6", 83 | "sha256:c8716a48d94b06bb3b2524c2b77e055fb313aeb4ea620c8dd03a105574ba704f", 84 | "sha256:cd5df75523866410809ca100dc9681e301e3c27567cf498077e8551b6d20e42f", 85 | "sha256:e249096428b3ae81b08327a63a485ad0878de3fb939049038579ac0ef61e17e7" 86 | ], 87 | "version": "==1.1.1" 88 | }, 89 | "numpy": { 90 | "hashes": [ 91 | "sha256:0778076e764e146d3078b17c24c4d89e0ecd4ac5401beff8e1c87879043a0633", 92 | "sha256:141c7102f20abe6cf0d54c4ced8d565b86df4d3077ba2343b61a6db996cefec7", 93 | "sha256:14270a1ee8917d11e7753fb54fc7ffd1934f4d529235beec0b275e2ccf00333b", 94 | "sha256:27e11c7a8ec9d5838bc59f809bfa86efc8a4fd02e58960fa9c49d998e14332d5", 95 | "sha256:2a04dda79606f3d2f760384c38ccd3d5b9bb79d4c8126b67aff5eb09a253763e", 96 | "sha256:3c26010c1b51e1224a3ca6b8df807de6e95128b0908c7e34f190e7775455b0ca", 97 | "sha256:52c40f1a4262c896420c6ea1c6fda62cf67070e3947e3307f5562bd783a90336", 98 | "sha256:6e4f8d9e8aa79321657079b9ac03f3cf3fd067bf31c1cca4f56d49543f4356a5", 99 | "sha256:7242be12a58fec245ee9734e625964b97cf7e3f2f7d016603f9e56660ce479c7", 100 | "sha256:7dc253b542bfd4b4eb88d9dbae4ca079e7bf2e2afd819ee18891a43db66c60c7", 101 | "sha256:94f5bd885f67bbb25c82d80184abbf7ce4f6c3c3a41fbaa4182f034bba803e69", 102 | "sha256:a89e188daa119ffa0d03ce5123dee3f8ffd5115c896c2a9d4f0dbb3d8b95bfa3", 103 | "sha256:ad3399da9b0ca36e2f24de72f67ab2854a62e623274607e37e0ce5f5d5fa9166", 104 | "sha256:b0348be89275fd1d4c44ffa39530c41a21062f52299b1e3ee7d1c61f060044b8", 105 | "sha256:b5554368e4ede1856121b0dfa35ce71768102e4aa55e526cb8de7f374ff78722", 106 | "sha256:cbddc56b2502d3f87fda4f98d948eb5b11f36ff3902e17cb6cc44727f2200525", 107 | "sha256:d79f18f41751725c56eceab2a886f021d70fd70a6188fd386e29a045945ffc10", 108 | "sha256:dc2ca26a19ab32dc475dbad9dfe723d3a64c835f4c23f625c2b6566ca32b9f29", 109 | "sha256:dd9bcd4f294eb0633bb33d1a74febdd2b9018b8b8ed325f861fffcd2c7660bb8", 110 | "sha256:e8baab1bc7c9152715844f1faca6744f2416929de10d7639ed49555a85549f52", 111 | "sha256:ec31fe12668af687b99acf1567399632a7c47b0e17cfb9ae47c098644ef36797", 112 | "sha256:f12b4f7e2d8f9da3141564e6737d79016fe5336cc92de6814eba579744f65b0a", 113 | "sha256:f58ac38d5ca045a377b3b377c84df8175ab992c970a53332fa8ac2373df44ff7" 114 | ], 115 | "version": "==1.16.4" 116 | }, 117 | "pandas": { 118 | "hashes": [ 119 | "sha256:071e42b89b57baa17031af8c6b6bbd2e9a5c68c595bc6bf9adabd7a9ed125d3b", 120 | "sha256:17450e25ae69e2e6b303817bdf26b2cd57f69595d8550a77c308be0cd0fd58fa", 121 | "sha256:17916d818592c9ec891cbef2e90f98cc85e0f1e89ed0924c9b5220dc3209c846", 122 | "sha256:2538f099ab0e9f9c9d09bbcd94b47fd889bad06dc7ae96b1ed583f1dc1a7a822", 123 | "sha256:366f30710172cb45a6b4f43b66c220653b1ea50303fbbd94e50571637ffb9167", 124 | "sha256:42e5ad741a0d09232efbc7fc648226ed93306551772fc8aecc6dce9f0e676794", 125 | "sha256:4e718e7f395ba5bfe8b6f6aaf2ff1c65a09bb77a36af6394621434e7cc813204", 126 | "sha256:4f919f409c433577a501e023943e582c57355d50a724c589e78bc1d551a535a2", 127 | "sha256:4fe0d7e6438212e839fc5010c78b822664f1a824c0d263fd858f44131d9166e2", 128 | "sha256:5149a6db3e74f23dc3f5a216c2c9ae2e12920aa2d4a5b77e44e5b804a5f93248", 129 | "sha256:627594338d6dd995cfc0bacd8e654cd9e1252d2a7c959449228df6740d737eb8", 130 | "sha256:83c702615052f2a0a7fb1dd289726e29ec87a27272d775cb77affe749cca28f8", 131 | "sha256:8c872f7fdf3018b7891e1e3e86c55b190e6c5cee70cab771e8f246c855001296", 132 | "sha256:90f116086063934afd51e61a802a943826d2aac572b2f7d55caaac51c13db5b5", 133 | "sha256:a3352bacac12e1fc646213b998bce586f965c9d431773d9e91db27c7c48a1f7d", 134 | "sha256:bcdd06007cca02d51350f96debe51331dec429ac8f93930a43eb8fb5639e3eb5", 135 | "sha256:c1bd07ebc15285535f61ddd8c0c75d0d6293e80e1ee6d9a8d73f3f36954342d0", 136 | "sha256:c9a4b7c55115eb278c19aa14b34fcf5920c8fe7797a09b7b053ddd6195ea89b3", 137 | "sha256:cc8fc0c7a8d5951dc738f1c1447f71c43734244453616f32b8aa0ef6013a5dfb", 138 | "sha256:d7b460bc316064540ce0c41c1438c416a40746fd8a4fb2999668bf18f3c4acf1" 139 | ], 140 | "index": "pypi", 141 | "version": "==0.24.2" 142 | }, 143 | "pymongo": { 144 | "hashes": [ 145 | "sha256:32421df60d06f479d71b6b539642e410ece3006e8910688e68df962c8eb40a21", 146 | "sha256:324b22a8443e11faca44c96b20e7ec8a9e59a1e664457edeeb4f796080b31cde", 147 | "sha256:4505ff8b7923dd7a8bed1bf25c9c4d0df5ab0b8b2821f2296533f2149a55f401", 148 | "sha256:460b224681ea711e48e3638d15be2249024031b7dcb9622ba19c2e85bd5a26cc", 149 | "sha256:47473b70c5f3cd5ddd2c49ab3b9ceafdafbbed5bc963f147df22a9343d7978f5", 150 | "sha256:49375839af76834e9c5c3cc78c78386873fd0b2ad9a0860a7dc4ec9fe73af9dd", 151 | "sha256:4a65f0f71ece86c860d30a1436b646db8ea32aec518845ef2903ca569faec32e", 152 | "sha256:530621906c5dd6d27305b39c4e017701e5f4299aa68b93cde70eb985f94ca26f", 153 | "sha256:54f4770b5810e8dc3cbeed675874195f02bb2bc4e95a9d665068edfb3baff4f7", 154 | "sha256:5ed9382410e938b0ff76041c34018210504729a83bcf4f6a70c7092c28169f6f", 155 | "sha256:61cad83637ae12c1c825130d7f9325cd6c162e3a64e8747a8144866020be3ff4", 156 | "sha256:61e8e1c58b4fdf47ab79b7c7db8bb022c1e40b3b5fcbbaeea5fc94dc5c75638d", 157 | "sha256:6e04e496af7d156b66cce70460011c621ecbadf5dcdce325c7acbb3cd6ea245d", 158 | "sha256:7ef89ec435e89da902451dde6845066fe2770befaf0301fe2a1ac426b51fced3", 159 | "sha256:854e8425e5eb775ccfffad04ecd094c99923d60a2c2d49babb5c435e836a91fa", 160 | "sha256:9569796d48498e4db4e1d56284b626a8ed15f641ce3a8b2085f06bb03f4c2c88", 161 | "sha256:9d50c99c6388863cbfdc5db9bad62e3a7c2e5fc151554a07c7f3c2530334a34f", 162 | "sha256:9ea016c2c011df21f77c1f806ce45129a344ba2d414bd50f9e065b13a4a134be", 163 | "sha256:a8421f0823174888fb12a5fa675322e756499d71e77ff712b4412d4b8f3c6503", 164 | "sha256:aef7d88384ada699976350a285c7a333f96ebc959e98e7d2c98589f47bbf3b7f", 165 | "sha256:b4d7ff9957ee770cf03bd7156a68a2f2e838e60712d9608eadc8741c15d01e72", 166 | "sha256:c1db85c39e6a60588f855dbc7bd68fb0dab796096148ab5aa4abecaff19e1c6e", 167 | "sha256:cee2fc0b94e66e7230da12fc4b3d34793c49957e16ee04f6468a94e264a1e41d", 168 | "sha256:cf1dea28379a16b23e47db312883f07b3ba8d9d6abc1c59e51d4c8ae1820ab43", 169 | "sha256:d1cd175df7c8b5fc976bade78bf4d9fb5aa7ab465c0f59931e380bbe188ef8fc", 170 | "sha256:d48a94edf3cdd34524936a72ea01b352682b337f33a42db10ba29a96c37147d3", 171 | "sha256:d9cc103a4e97f78bc77a1d72759ab3722f6cdf0374ad4fb4b0c53bd3238bdf98", 172 | "sha256:fcb9ae8aa9158106c5d98a4349ec0d90b68f052d620b2d24622ba03b91e4d81d" 173 | ], 174 | "index": "pypi", 175 | "version": "==3.8.0" 176 | }, 177 | "python-dateutil": { 178 | "hashes": [ 179 | "sha256:7e6584c74aeed623791615e26efd690f29817a27c73085b78e4bad02493df2fb", 180 | "sha256:c89805f6f4d64db21ed966fda138f8a5ed7a4fdbc1a8ee329ce1b74e3c74da9e" 181 | ], 182 | "version": "==2.8.0" 183 | }, 184 | "pytz": { 185 | "hashes": [ 186 | "sha256:303879e36b721603cc54604edcac9d20401bdbe31e1e4fdee5b9f98d5d31dfda", 187 | "sha256:d747dd3d23d77ef44c6a3526e274af6efeb0a6f1afd5a69ba4d5be4098c8e141" 188 | ], 189 | "version": "==2019.1" 190 | }, 191 | "six": { 192 | "hashes": [ 193 | "sha256:3350809f0555b11f552448330d0b52d5f24c91a322ea4a15ef22629740f3761c", 194 | "sha256:d16a0141ec1a18405cd4ce8b4613101da75da0e9a7aec5bdd4fa804d0e0eba73" 195 | ], 196 | "version": "==1.12.0" 197 | }, 198 | "werkzeug": { 199 | "hashes": [ 200 | "sha256:865856ebb55c4dcd0630cdd8f3331a1847a819dda7e8c750d3db6f2aa6c0209c", 201 | "sha256:a0b915f0815982fb2a09161cb8f31708052d0951c3ba433ccc5e1aa276507ca6" 202 | ], 203 | "version": "==0.15.4" 204 | } 205 | }, 206 | "develop": {} 207 | } 208 | -------------------------------------------------------------------------------- /Actividades/Procedimientos Almacenados/Procedimientos Almacenados 1.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "# Procedimientos Almacenados - PL/pgSQL\n", 8 | "\n", 9 | "La mayoría de los DBMS ofrecen la posibilidad de programar funciones o procedimientos almacenados en el mismo DBMS. Estos procedimientos permiten tomar ventaja de todas las bondades de los DBMS. Esta semana vamos a aprender a programar estos procedimientos. Sqlite3 no soporta esta funcionalidad, así que vamos a tener que recurrir nuevamente a **PostgreSQL**.\n", 10 | "\n", 11 | "Gracias a la magia de los Jupyter Notebooks, utilizaremos la libreria ipython-sql para acceder a la base de datos PostgreSQL que tenemos instalada en nuestro computador." 12 | ] 13 | }, 14 | { 15 | "cell_type": "code", 16 | "execution_count": null, 17 | "metadata": {}, 18 | "outputs": [], 19 | "source": [ 20 | "%load_ext sql" 21 | ] 22 | }, 23 | { 24 | "cell_type": "markdown", 25 | "metadata": {}, 26 | "source": [ 27 | "Debes modificar la siguiente celda para que tenga los datos correctos para conectarse la instancia de PostgreSQL que corre en tu computador.\n", 28 | "\n", 29 | "``postgresql://:@localhost/``" 30 | ] 31 | }, 32 | { 33 | "cell_type": "code", 34 | "execution_count": null, 35 | "metadata": {}, 36 | "outputs": [], 37 | "source": [ 38 | "%%sql \n", 39 | "postgresql://adriansotosuarez:@localhost/almacenados" 40 | ] 41 | }, 42 | { 43 | "cell_type": "markdown", 44 | "metadata": {}, 45 | "source": [ 46 | "Antes de comenzar, en la siguiente celda, crea una relación:\n", 47 | "\n", 48 | "Personas(__run:varchar__, nombre:varchar, apellido:varchar)" 49 | ] 50 | }, 51 | { 52 | "cell_type": "code", 53 | "execution_count": null, 54 | "metadata": {}, 55 | "outputs": [], 56 | "source": [ 57 | "%%sql \n", 58 | "DROP TABLE IF EXISTS Personas;\n", 59 | "CREATE TABLE Personas (run varchar, nombre varchar, apellido varchar, PRIMARY KEY(run))" 60 | ] 61 | }, 62 | { 63 | "cell_type": "markdown", 64 | "metadata": {}, 65 | "source": [ 66 | "### Agradecimientos\n", 67 | "\n", 68 | "Este notebook fue escrito principalmente por el ayudante **Marcelo Saldías González**." 69 | ] 70 | }, 71 | { 72 | "cell_type": "markdown", 73 | "metadata": {}, 74 | "source": [ 75 | "## Funciones Básicas\n", 76 | "\n", 77 | "La forma básica de las funciones es:\n", 78 | "\n", 79 | "```SQL\n", 80 | "CREATE OR REPLACE FUNCTION ()\n", 81 | "RETURNS AS\n", 82 | "$$\n", 83 | "DECLARE\n", 84 | "   \n", 85 | "BEGIN\n", 86 | " \n", 87 | "END\n", 88 | "$$ language plpgsql;\n", 89 | "```\n", 90 | "\n", 91 | "Acá tenemos:\n", 92 | "+ **nombre_función**: Es el nombre que le quieras dar a la función.\n", 93 | "\n", 94 | "+ **atributos_de_input**: Es una lista de atributos que recibe la función como input, de acuerdo a la sintáxis (input_1 tipo_1, input_2 tipo_2, ..., input_n tipo_n).\n", 95 | "+ **declaración_de_variables**:Es una lista de variables a declarar. Los tipos comunes son integer, numeric, varchar y record.\n", 96 | "+ **sentencias_SQL**: Contiene una lista de instrucciones SQL, cada una terminando en un punto y coma (;).\n", 97 | "\n", 98 | "Hagamos entonces nuestra primera función." 99 | ] 100 | }, 101 | { 102 | "cell_type": "code", 103 | "execution_count": null, 104 | "metadata": {}, 105 | "outputs": [], 106 | "source": [ 107 | "%%sql\n", 108 | "CREATE OR REPLACE FUNCTION insertar_persona (rut varchar, nombre varchar, apellido varchar)\n", 109 | "RETURNS void AS\n", 110 | "$$\n", 111 | "BEGIN\n", 112 | " INSERT INTO Personas VALUES (rut, nombre, apellido);\n", 113 | "END\n", 114 | "$$ language plpgsql" 115 | ] 116 | }, 117 | { 118 | "cell_type": "markdown", 119 | "metadata": {}, 120 | "source": [ 121 | "Otra opción es escribir el código anterior en un editor de texto y guardarlo como **insertar_persona.sql**. Luego en postgres ejecutar:\n", 122 | "\n", 123 | "```\\i insertar_persona.sql```\n", 124 | "\n", 125 | "Con cualquiera de las opciones anteriores, le estás diciendo a postgreSQL que ejecute el comando que tenías guardado. PostgreSQL va a crear la función, que ya esta lista para ser usada. Con esto podemos poblar la base de datos de forma más rápida. \n", 126 | "\n", 127 | "Para ejecutar nuestra nueva función, ejecuta lo siguiente:" 128 | ] 129 | }, 130 | { 131 | "cell_type": "code", 132 | "execution_count": null, 133 | "metadata": {}, 134 | "outputs": [], 135 | "source": [ 136 | "%%sql\n", 137 | "SELECT insertar_persona('unerut','unnombre','unapellido');" 138 | ] 139 | }, 140 | { 141 | "cell_type": "markdown", 142 | "metadata": {}, 143 | "source": [ 144 | "Ahora vamos a verificar que la inserción se realizó correctamente mostrando todos las tuplas de la tabla Persona" 145 | ] 146 | }, 147 | { 148 | "cell_type": "code", 149 | "execution_count": null, 150 | "metadata": {}, 151 | "outputs": [], 152 | "source": [ 153 | "%%sql\n", 154 | "SELECT * FROM Personas;" 155 | ] 156 | }, 157 | { 158 | "cell_type": "markdown", 159 | "metadata": {}, 160 | "source": [ 161 | "Ahora intentaremos algo más radical:" 162 | ] 163 | }, 164 | { 165 | "cell_type": "code", 166 | "execution_count": null, 167 | "metadata": {}, 168 | "outputs": [], 169 | "source": [ 170 | "%%sql\n", 171 | "\n", 172 | "CREATE OR REPLACE FUNCTION insercion_radical (numero integer)\n", 173 | "RETURNS void AS\n", 174 | "$$\n", 175 | "DECLARE\n", 176 | " temp varchar;\n", 177 | "BEGIN\n", 178 | " FOR i IN 1..numero LOOP\n", 179 | " temp := to_char(i,'99999999');\n", 180 | " INSERT INTO Personas VALUES (temp, temp, temp);\n", 181 | " END LOOP;\n", 182 | "END\n", 183 | "$$ language plpgsql;" 184 | ] 185 | }, 186 | { 187 | "cell_type": "markdown", 188 | "metadata": {}, 189 | "source": [ 190 | "Ahora estamos listos! Ejecuta lo siguiente para tener tu primera tabla con 10000 tuplas" 191 | ] 192 | }, 193 | { 194 | "cell_type": "code", 195 | "execution_count": null, 196 | "metadata": {}, 197 | "outputs": [], 198 | "source": [ 199 | "%%sql\n", 200 | "\n", 201 | "SELECT insercion_radical(10000);\n", 202 | "SELECT * FROM Personas;" 203 | ] 204 | }, 205 | { 206 | "cell_type": "markdown", 207 | "metadata": {}, 208 | "source": [ 209 | "Hay un par de elementos por explicar acá:\n", 210 | "\n", 211 | "+ El control de flujo en esta función está dado por:\n", 212 | "\n", 213 | "```SQL\n", 214 | "FOR IN ... LOOP\n", 215 | " \n", 216 | "END LOOP;\n", 217 | "```\n", 218 | "No necesitas haber declarado var, pero solo es válida dentro del loop (de hecho, al entrar al loop ingnoras la declaración anterior, si existiese). En general `x` e `y` pueden ser números, variables numéricas o expresiones.\n", 219 | "\n", 220 | "+ Existen otras formas de iteración, como `WHILE` y `LOOP`.\n", 221 | "+ La linea `temp := to_char(i, '999999999');` dice que la variable `temp` ahora corresponde a loa que retorna la funcion `to_char`. Esta función toma un número _n_ y un string _f_, y devuelve el número _n_ como un string, en el formato que indicaste con _f_. En general postgreSQL tiene miles de funciones como ésta, que ya están hechas. ¡Consulta la documentación!" 222 | ] 223 | }, 224 | { 225 | "cell_type": "markdown", 226 | "metadata": {}, 227 | "source": [ 228 | "Como control de lujo puedes escribir:\n", 229 | "\n", 230 | "```SQL\n", 231 | "IF THEN\n", 232 | " \n", 233 | "ELSE\n", 234 | " \n", 235 | "END IF;\n", 236 | "```\n", 237 | "\n", 238 | "En este caso, la condicion booleana es cualquier comparación que puedas escribir en SQL." 239 | ] 240 | }, 241 | { 242 | "cell_type": "markdown", 243 | "metadata": {}, 244 | "source": [ 245 | "## Recorriendo los resultados de una consulta\n", 246 | "\n", 247 | "La capacidad para recorrer, en el entorno mismo del DBMS, los resultados de las consultas es quizá lo más importante en las funciones.\n", 248 | "\n", 249 | "Para eso necesitamos una variable de tip ```RECORD```. Este es un tipo abstracto que sirve para contener los resultados de una tupla.\n", 250 | "\n", 251 | "La forma básica de recorrer los resultados de una consulta es entonces:\n", 252 | "\n", 253 | "```sql\n", 254 | "FOR IN LOOP\n", 255 | " \n", 256 | "END LOOP;\n", 257 | "```\n", 258 | "\n", 259 | "Esto funcion de la siguiente manera: El sistema ejecuta la `````` y va iterando tupla a tupla la respuesta: la primera tupla de la respuesta queda guardada en la variable ``````, cuando se terminan de ejecutar las `````` se pasa a la segunda iteración, donde la segunda tupla de la respuesta a `````` pasa a la variable `````` y así sucesivamente.\n", 260 | "\n", 261 | "A modo de ejemplo, en la siguiente celda crea la siguiente tabla en postgres:\n", 262 | "\n", 263 | "PersonasCompleto(**run:varchar**, nombrecompleto:varchar)" 264 | ] 265 | }, 266 | { 267 | "cell_type": "code", 268 | "execution_count": null, 269 | "metadata": {}, 270 | "outputs": [], 271 | "source": [ 272 | "%%sql\n", 273 | "DROP TABLE IF EXISTS PersonasCompleto;\n", 274 | "CREATE TABLE PersonasCompleto (run varchar, nombrecompleto varchar, PRIMARY KEY(run));" 275 | ] 276 | }, 277 | { 278 | "cell_type": "markdown", 279 | "metadata": {}, 280 | "source": [ 281 | "La siguiente función se usa para copiar a `PersonasCompleto` el rut y la concatenación del nombre y el apellido de cada persona almacenado en la tabla Persona." 282 | ] 283 | }, 284 | { 285 | "cell_type": "code", 286 | "execution_count": null, 287 | "metadata": {}, 288 | "outputs": [], 289 | "source": [ 290 | "%%sql\n", 291 | "\n", 292 | "CREATE OR REPLACE FUNCTION transferencia()\n", 293 | "RETURNS void AS $$\n", 294 | "DECLARE\n", 295 | " tupla RECORD;\n", 296 | " concat varchar;\n", 297 | "BEGIN\n", 298 | " FOR tupla IN SELECT * FROM Personas LOOP\n", 299 | " concat = tupla.nombre || tupla.apellido;\n", 300 | " INSERT INTO PersonasCompleto VALUES (tupla.run, concat);\n", 301 | " END LOOP;\n", 302 | "END\n", 303 | "$$ language plpgsql" 304 | ] 305 | }, 306 | { 307 | "cell_type": "markdown", 308 | "metadata": {}, 309 | "source": [ 310 | "Ahora ejecutemos nuestra nueva funcion!" 311 | ] 312 | }, 313 | { 314 | "cell_type": "code", 315 | "execution_count": null, 316 | "metadata": {}, 317 | "outputs": [], 318 | "source": [ 319 | "%%sql\n", 320 | "SELECT transferencia();\n", 321 | "SELECT * FROM PersonasCompleto;" 322 | ] 323 | }, 324 | { 325 | "cell_type": "markdown", 326 | "metadata": {}, 327 | "source": [ 328 | "# Ejercicios\n", 329 | "\n", 330 | "+ Escribe una función que reciba un número $i$, y retorne la $i$-ésima potencia de 2 (no tiene que ver con base de datos, pero es bueno para revisar que entiendes el entorno de programación!)" 331 | ] 332 | }, 333 | { 334 | "cell_type": "code", 335 | "execution_count": null, 336 | "metadata": {}, 337 | "outputs": [], 338 | "source": [ 339 | "%%sql\n", 340 | "\n", 341 | "# Escribe tu código aquí!" 342 | ] 343 | }, 344 | { 345 | "cell_type": "markdown", 346 | "metadata": {}, 347 | "source": [ 348 | "+ Escribe una función que retorne el número de tuplas en la tabla Personas" 349 | ] 350 | }, 351 | { 352 | "cell_type": "code", 353 | "execution_count": null, 354 | "metadata": {}, 355 | "outputs": [], 356 | "source": [ 357 | "%%sql\n", 358 | "\n", 359 | "#Escribe tu código aquí!" 360 | ] 361 | }, 362 | { 363 | "cell_type": "markdown", 364 | "metadata": {}, 365 | "source": [ 366 | "+ Escribe una función ```contar_K()``` que entregue el número de ruts en la tabla personas que terminan con K (recuerda que puedes usar el operador ```LIKE```)" 367 | ] 368 | }, 369 | { 370 | "cell_type": "code", 371 | "execution_count": null, 372 | "metadata": {}, 373 | "outputs": [], 374 | "source": [ 375 | "%%sql\n", 376 | "\n", 377 | "#Escribe tu código aquí!" 378 | ] 379 | } 380 | ], 381 | "metadata": { 382 | "kernelspec": { 383 | "display_name": "Python 3", 384 | "language": "python", 385 | "name": "python3" 386 | }, 387 | "language_info": { 388 | "codemirror_mode": { 389 | "name": "ipython", 390 | "version": 3 391 | }, 392 | "file_extension": ".py", 393 | "mimetype": "text/x-python", 394 | "name": "python", 395 | "nbconvert_exporter": "python", 396 | "pygments_lexer": "ipython3", 397 | "version": "3.7.1" 398 | } 399 | }, 400 | "nbformat": 4, 401 | "nbformat_minor": 2 402 | } 403 | -------------------------------------------------------------------------------- /Actividades/Procedimientos Almacenados/Procedimientos Almacenados 2.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "# Procedimientos Almacenados 2 - PL/pgSQL\n", 8 | "\n", 9 | "Importamos la librería para ejecutar código SQL en este jupyter notebook antes de empezar:" 10 | ] 11 | }, 12 | { 13 | "cell_type": "code", 14 | "execution_count": null, 15 | "metadata": {}, 16 | "outputs": [], 17 | "source": [ 18 | "%load_ext sql" 19 | ] 20 | }, 21 | { 22 | "cell_type": "markdown", 23 | "metadata": {}, 24 | "source": [ 25 | "Debes modificar la siguiente celda para que tenga los datos correctos para conectarse la instancia de PostgreSQL que corre en tu computador.\n", 26 | "\n", 27 | "``postgresql://:@localhost/``" 28 | ] 29 | }, 30 | { 31 | "cell_type": "code", 32 | "execution_count": null, 33 | "metadata": {}, 34 | "outputs": [], 35 | "source": [ 36 | "%%sql \n", 37 | "postgresql://adriansotosuarez:@localhost/almacenados" 38 | ] 39 | }, 40 | { 41 | "cell_type": "markdown", 42 | "metadata": {}, 43 | "source": [ 44 | "### Agradecimientos\n", 45 | "\n", 46 | "Este notebook fue escrito principalmente por el ayudante **Marcelo Saldías González**." 47 | ] 48 | }, 49 | { 50 | "cell_type": "markdown", 51 | "metadata": {}, 52 | "source": [ 53 | "# 1. Trucos Avanzados" 54 | ] 55 | }, 56 | { 57 | "cell_type": "markdown", 58 | "metadata": {}, 59 | "source": [ 60 | "¿Puedes adivinar que computa esta función?" 61 | ] 62 | }, 63 | { 64 | "cell_type": "code", 65 | "execution_count": null, 66 | "metadata": {}, 67 | "outputs": [], 68 | "source": [ 69 | "%%sql\n", 70 | "\n", 71 | "CREATE OR REPLACE FUNCTION fib (\n", 72 | "numero INTEGER\n", 73 | ") RETURNS INTEGER AS $$\n", 74 | "BEGIN\n", 75 | "IF numero < 2 THEN\n", 76 | "RETURN numero;\n", 77 | "END IF;\n", 78 | "RETURN fib(numero - 2) + fib(numero - 1);\n", 79 | "END;\n", 80 | "$$ LANGUAGE plpgsql;" 81 | ] 82 | }, 83 | { 84 | "cell_type": "code", 85 | "execution_count": null, 86 | "metadata": {}, 87 | "outputs": [], 88 | "source": [ 89 | "%sql SELECT fib(10);" 90 | ] 91 | }, 92 | { 93 | "cell_type": "markdown", 94 | "metadata": {}, 95 | "source": [ 96 | "Exacto! Son los números de Fibonacci! Esto no tiene nada que ver con las bases de datos, dices. Pero ahora trata de ejecutar esta función en tu computador. Utiliza la celda anterior para probar con ```n = 10```, ```n = 20```, y ```n = 30```... Se demora muchísimo, y si te acuerdas de introducción a la programación, tiene toda la razón de demorarse, porque nuestro algoritmo recursivo está mal escrito. Por ejemplo, para n = 30 tenemos que llamar a ```fib(28)``` y ```fib(29)```, pero ambas requieren el cómputo de ```fib(27)```, y por lo tanto las ejecuciones de ```fib``` para números menores terminan ejecutándose miles de veces.\n", 97 | "\n", 98 | "Bueno, aprovechémonos de que tenemos una base de datos, y tratemos de guardar en una tabla temporal los resultados de fibonacci. No debería tomar mucho espacio.\n", 99 | "\n", 100 | "En la siguiente celda, crea una relación\n", 101 | "\n", 102 | "`Fib_cache(num INTEGER, fib INTEGER)`" 103 | ] 104 | }, 105 | { 106 | "cell_type": "code", 107 | "execution_count": null, 108 | "metadata": {}, 109 | "outputs": [], 110 | "source": [ 111 | "%%sql\n", 112 | "DROP TABLE IF EXISTS Fib_cache;\n", 113 | "CREATE TABLE Fib_cache(num integer, fib integer, PRIMARY KEY(num));" 114 | ] 115 | }, 116 | { 117 | "cell_type": "markdown", 118 | "metadata": {}, 119 | "source": [ 120 | "La relación anterior almacenará cada número ```num``` junto al número Fibonacci correspondiente a ```num``` (es decir, ```fib(num)```).\n", 121 | "\n", 122 | "Ahora observa" 123 | ] 124 | }, 125 | { 126 | "cell_type": "code", 127 | "execution_count": null, 128 | "metadata": {}, 129 | "outputs": [], 130 | "source": [ 131 | "%%sql\n", 132 | "\n", 133 | "CREATE OR REPLACE FUNCTION fib_cacheando(\n", 134 | " numero INTEGER\n", 135 | ") RETURNS INTEGER AS $$\n", 136 | "DECLARE\n", 137 | "ret INTEGER;\n", 138 | "BEGIN\n", 139 | "IF numero < 2 THEN\n", 140 | " RETURN numero;\n", 141 | "END IF;\n", 142 | "SELECT INTO ret fib\n", 143 | "FROM fib_cache\n", 144 | "WHERE num = numero;\n", 145 | "IF ret IS NULL THEN\n", 146 | " ret := fib_cacheando(numero - 2) + fib_cacheando(numero - 1);\n", 147 | " INSERT INTO fib_cache (num, fib)\n", 148 | " VALUES (numero, ret);\n", 149 | "END IF;\n", 150 | "RETURN ret;\n", 151 | "END;\n", 152 | "$$ language plpgsql;" 153 | ] 154 | }, 155 | { 156 | "cell_type": "markdown", 157 | "metadata": {}, 158 | "source": [ 159 | "### ¿Que crees que esta pasando? Vamos paso por paso:" 160 | ] 161 | }, 162 | { 163 | "cell_type": "markdown", 164 | "metadata": {}, 165 | "source": [ 166 | "```SQL\n", 167 | "CREATE OR REPLACE FUNCTION fib_cacheando(\n", 168 | " numero INTEGER\n", 169 | ") RETURNS INTEGER AS $$\n", 170 | "DECLARE\n", 171 | "ret INTEGER;\n", 172 | "BEGIN\n", 173 | "IF numero < 2 THEN\n", 174 | " RETURN numero;\n", 175 | "END IF;\n", 176 | "```" 177 | ] 178 | }, 179 | { 180 | "cell_type": "markdown", 181 | "metadata": {}, 182 | "source": [ 183 | "Todo bien hasta acá, tomamos los casos bases 0 y 1" 184 | ] 185 | }, 186 | { 187 | "cell_type": "markdown", 188 | "metadata": {}, 189 | "source": [ 190 | "```SQL\n", 191 | "SELECT INTO ret fib\n", 192 | "FROM fib_cache\n", 193 | "WHERE num = numero;\n", 194 | "```" 195 | ] 196 | }, 197 | { 198 | "cell_type": "markdown", 199 | "metadata": {}, 200 | "source": [ 201 | "Usamos ```SELECT INTO FROM...``` para guardar en `````` el valor de la consulta ```SELECT FROM...```. En este caso, buscamos en la tabla ```fib_cache``` si acaso tenemos la tupla del número de Fibonacci correspondiente a ```num```.\n", 202 | "\n", 203 | "```SQL\n", 204 | "IF ret IS NULL THEN\n", 205 | " ret := fib_cacheando(numero - 2) + fib_cacheando(numero - 1);\n", 206 | " INSERT INTO fib_cache (num, fib)\n", 207 | " VALUES (numero, ret);\n", 208 | "END IF;\n", 209 | "```\n", 210 | "\n", 211 | "Si ```ret``` es nulo, significa que no tenemos esevalor, y hay que obtenerlo utilizando una llamada recursiva. Si ```ret``` no es nulo, significa que ya lo tenemos, y no tenemos que hacer nada más.\n", 212 | "\n", 213 | "```sql\n", 214 | "RETURN ret;\n", 215 | "END;\n", 216 | "$$ LANGUAGE plpsgsql\n", 217 | "```\n", 218 | "\n", 219 | "Finalmente retornamos el valor de ```ret```. Prueba ahora calcular ```fib_cacheando(30)```. ¡Mira lo rápido que funciona ahora!" 220 | ] 221 | }, 222 | { 223 | "cell_type": "code", 224 | "execution_count": null, 225 | "metadata": {}, 226 | "outputs": [], 227 | "source": [ 228 | "%sql SELECT fib_cacheando(30);" 229 | ] 230 | }, 231 | { 232 | "cell_type": "markdown", 233 | "metadata": {}, 234 | "source": [ 235 | "# 2. Retornando Tablas" 236 | ] 237 | }, 238 | { 239 | "cell_type": "markdown", 240 | "metadata": {}, 241 | "source": [ 242 | "En la siguiente celda, crea la sigiuente relación:\n", 243 | "\n", 244 | "Vuelo(**ciudad_origen:varchar, ciudad_destino:varchar**, horas:integer)" 245 | ] 246 | }, 247 | { 248 | "cell_type": "code", 249 | "execution_count": null, 250 | "metadata": {}, 251 | "outputs": [], 252 | "source": [ 253 | "%%sql\n", 254 | "DROP TABLE IF EXISTS Vuelo;\n", 255 | "CREATE TABLE Vuelo (ciudad_origen varchar, ciudad_destino varchar, horas integer, PRIMARY KEY(ciudad_origen, ciudad_destino));" 256 | ] 257 | }, 258 | { 259 | "cell_type": "markdown", 260 | "metadata": {}, 261 | "source": [ 262 | "La idea de esta relación es que una tupla `(ciudad origen, ciudad destino, N)` indique que existe al menos un vuelo directo desde la ciudad origen a la ciudad destino, y que el vuelo más corto demora $N$ horas. Con la siguiente celda, llenaremos esta tabla con unas cuantas tuplas para ir probando las funciones que debes hacer." 263 | ] 264 | }, 265 | { 266 | "cell_type": "code", 267 | "execution_count": null, 268 | "metadata": {}, 269 | "outputs": [], 270 | "source": [ 271 | "%%sql\n", 272 | "INSERT INTO Vuelo VALUES ('Santiago', 'Concepción', 2);\n", 273 | "INSERT INTO Vuelo VALUES ('Santiago', 'Seoul', 23);\n", 274 | "INSERT INTO Vuelo VALUES ('Concepción', 'Dallas', 24);\n", 275 | "INSERT INTO Vuelo VALUES ('Santiago', 'Shanghai', 10);\n", 276 | "INSERT INTO Vuelo VALUES ('New York', 'Los Angeles', 12);\n", 277 | "INSERT INTO Vuelo VALUES ('New York', 'London', 20);\n", 278 | "INSERT INTO Vuelo VALUES ('Dallas', 'Houston', 10);\n", 279 | "INSERT INTO Vuelo VALUES ('Dallas', 'Toronto', 15);\n", 280 | "INSERT INTO Vuelo VALUES ('Toronto', 'Chengdu', 12);\n", 281 | "INSERT INTO Vuelo VALUES ('Toronto', 'Huangzhou', 20);" 282 | ] 283 | }, 284 | { 285 | "cell_type": "markdown", 286 | "metadata": {}, 287 | "source": [ 288 | "Queremos crear una función que reciba una ciudad C y retorne una tabla con todas las ciudades en las que existe un vuelo directo desde C, junto con el tiempo. Para esto, tenemos que decirle a la función que debe retornar una tabla (si, esto se puede hacer en SQL, pero lo hacemos acá porque es un buen ejercicio para empezar).\n", 289 | "\n", 290 | "Veamos primero como retornar una tabla cualquiera:" 291 | ] 292 | }, 293 | { 294 | "cell_type": "code", 295 | "execution_count": null, 296 | "metadata": {}, 297 | "outputs": [], 298 | "source": [ 299 | "%%sql\n", 300 | "\n", 301 | "CREATE OR REPLACE FUNCTION\n", 302 | "retornar_vuelos ()\n", 303 | "RETURNS TABLE (ciudad_origen varchar(50), ciudad_destino varchar(50), \n", 304 | " horas integer) AS $$\n", 305 | "BEGIN\n", 306 | "RETURN QUERY SELECT * FROM Vuelo;\n", 307 | "RETURN;\n", 308 | "END;\n", 309 | "$$ language plpgsql" 310 | ] 311 | }, 312 | { 313 | "cell_type": "markdown", 314 | "metadata": {}, 315 | "source": [ 316 | "Nada muy impactante... lo único que hay que tomar en cuenta es que ```RETURN QUERY``` no retorna una función, solo asigna el valor de retorno a la tabla en cuestión (por eso retornamos explícitamente después).\n", 317 | "\n", 318 | "Una vez que cargues esta funcion en PostgreSQL, prueba llamándola como hemos hecho hasta ahora:" 319 | ] 320 | }, 321 | { 322 | "cell_type": "code", 323 | "execution_count": null, 324 | "metadata": {}, 325 | "outputs": [], 326 | "source": [ 327 | "%sql SELECT retornar_vuelos();" 328 | ] 329 | }, 330 | { 331 | "cell_type": "markdown", 332 | "metadata": {}, 333 | "source": [ 334 | "¿Algún Problema? ¿No se supone que retornaba una tabla? Efectivamente, y por eso es que si queremos que la seleccion haga explícito todos sus atributos, tenemos que consultar lo que retorna la función como si fuera una tabla!" 335 | ] 336 | }, 337 | { 338 | "cell_type": "code", 339 | "execution_count": null, 340 | "metadata": {}, 341 | "outputs": [], 342 | "source": [ 343 | "%sql SELECT * from retornar_vuelos();" 344 | ] 345 | }, 346 | { 347 | "cell_type": "markdown", 348 | "metadata": {}, 349 | "source": [ 350 | "# 2.1 SQL Dinámico\n", 351 | "\n", 352 | "¿Qué pasa cuando quiero que mi consulta se vea modificada de acuerdo al input de la función?\n", 353 | "\n", 354 | "En ese caso tenemos dos opciones:\n", 355 | "\n", 356 | "+ Generar la consulta como una concatenación de strings (alternativa mala)\n", 357 | "+ Usar SQL Dinámico (alternativa decente)\n", 358 | "\n", 359 | "Por qué es mejor SQL dinámico lo discutiremos en clases. Pero veamos en que consiste.\n", 360 | "\n", 361 | "La idea de SQL dinámico es \"preparar\" una consulta antes de saber los parámetros, y una vez que tengamos el valor de los parámetros, ejecutar la consulta, mediante el comando ```EXECUTE```.\n", 362 | "\n", 363 | "Veamos el ejemplo de los vuelos directos:" 364 | ] 365 | }, 366 | { 367 | "cell_type": "code", 368 | "execution_count": null, 369 | "metadata": {}, 370 | "outputs": [], 371 | "source": [ 372 | "%%sql\n", 373 | "\n", 374 | "CREATE OR REPLACE FUNCTION\n", 375 | "vuelos_directos (c_origen varchar)\n", 376 | "RETURNS TABLE (ciudad_destino varchar(50), horas integer) AS $$\n", 377 | "BEGIN\n", 378 | "RETURN QUERY EXECUTE 'SELECT ciudad_destino, horas\n", 379 | " FROM VUELO\n", 380 | " WHERE ciudad_origen = $1'\n", 381 | " USING c_origen;\n", 382 | "RETURN;\n", 383 | "END;\n", 384 | "$$ language plpgsql;\n" 385 | ] 386 | }, 387 | { 388 | "cell_type": "markdown", 389 | "metadata": {}, 390 | "source": [ 391 | "La idea es almacenar en variables `($1, $2, etc)` los valores que necesitamos, y luego especificar las variables de donde sacamos estos valores con ```USING```." 392 | ] 393 | }, 394 | { 395 | "cell_type": "code", 396 | "execution_count": null, 397 | "metadata": {}, 398 | "outputs": [], 399 | "source": [ 400 | "%sql SELECT * FROM vuelos_directos('Dallas');" 401 | ] 402 | }, 403 | { 404 | "cell_type": "markdown", 405 | "metadata": {}, 406 | "source": [ 407 | "# 2.2 Ejercicio\n", 408 | "\n", 409 | "Imagina ahora que tienes una instancia de la tabla Vuelo con miles de datos, y te interesan todos los lugares a los que puedes llegar volando desde Santiago, sin importar el número de escalas. ¿Puedes pensar en un algoritmo para implementar esto usando una funcion?\n", 410 | "\n", 411 | "Escríbelo como una función en PLpgSQL. Puede que te sea útil pensar en como reutilizábamos una base de datos temporal para computar los números de Fibonacci." 412 | ] 413 | }, 414 | { 415 | "cell_type": "code", 416 | "execution_count": null, 417 | "metadata": {}, 418 | "outputs": [], 419 | "source": [ 420 | "%%sql\n", 421 | "#Esribe tu respuesta aqui!" 422 | ] 423 | } 424 | ], 425 | "metadata": { 426 | "kernelspec": { 427 | "display_name": "Python 3", 428 | "language": "python", 429 | "name": "python3" 430 | }, 431 | "language_info": { 432 | "codemirror_mode": { 433 | "name": "ipython", 434 | "version": 3 435 | }, 436 | "file_extension": ".py", 437 | "mimetype": "text/x-python", 438 | "name": "python", 439 | "nbconvert_exporter": "python", 440 | "pygments_lexer": "ipython3", 441 | "version": "3.7.1" 442 | } 443 | }, 444 | "nbformat": 4, 445 | "nbformat_minor": 2 446 | } 447 | -------------------------------------------------------------------------------- /Actividades/Procedimientos Almacenados/Procedimientos Almacenados - Guía.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "# Guía Procedimientos Almacenados - PL/pgSQL" 8 | ] 9 | }, 10 | { 11 | "cell_type": "code", 12 | "execution_count": null, 13 | "metadata": {}, 14 | "outputs": [], 15 | "source": [ 16 | "%load_ext sql" 17 | ] 18 | }, 19 | { 20 | "cell_type": "markdown", 21 | "metadata": {}, 22 | "source": [ 23 | "Debes modificar la siguiente celda para que tenga los datos correctos para conectarse la instancia de PostgreSQL que corre en tu computador.\n", 24 | "\n", 25 | "``postgresql://:@localhost/``" 26 | ] 27 | }, 28 | { 29 | "cell_type": "code", 30 | "execution_count": null, 31 | "metadata": {}, 32 | "outputs": [], 33 | "source": [ 34 | "%%sql \n", 35 | "postgresql://adriansotosuarez:@localhost/almacenados" 36 | ] 37 | }, 38 | { 39 | "cell_type": "markdown", 40 | "metadata": {}, 41 | "source": [ 42 | "# Problema 1: Secuencia\n", 43 | "\n", 44 | "En el siguiente ejercicio mostraremos un ejemplo de creación de tablas auxiliares para lo que encontremos necesario. Eventualmente podríamos necesitar números ascendentes en forma de secuencia, pero en forma de tabla...\n", 45 | "\n", 46 | "Por ejemplo, para crear índices haciendo producto cruz con otra tabla. Pero la secuencia puede ser de largo variable. Podríamos optar por tener una tabla en nuestra base de datos que solo contenga números para este uso, pero esto complica el límite de cuántos números usar al tener que específicar en un ```WHERE``` cada vez que queramos utilizarla.\n", 47 | "\n", 48 | "Esto es mucho trabajo, la alternativa es crear una función capaz de generar esta tabla automáticamente, es decir buscamos una función ```seq(n)``` que retorne una tabla de una sola columna con enteros del 1 a n. Por ejemplo:\n", 49 | "\n", 50 | "```sql\n", 51 | "SELECT * FROM seq(5);\n", 52 | "\n", 53 | "1\n", 54 | "2\n", 55 | "3\n", 56 | "4\n", 57 | "5\n", 58 | "```" 59 | ] 60 | }, 61 | { 62 | "cell_type": "markdown", 63 | "metadata": {}, 64 | "source": [ 65 | "Ahora deja de leer esto e intenta hacerlo tu mismo. Ten en cuenta lo siguiente: recuerda que la idea es crear una tabla auxiliar que aparece al llamado de ```seq```, es decir, si revisáramos las tablas de la base de datos luego de ejecutar ```seq```, no debería haber nuevas tablas." 66 | ] 67 | }, 68 | { 69 | "cell_type": "code", 70 | "execution_count": null, 71 | "metadata": {}, 72 | "outputs": [], 73 | "source": [ 74 | "%%sql\n", 75 | "\n", 76 | "#Intenta resolver el ejercicio aqui!\n", 77 | "\n", 78 | "\n", 79 | "\n", 80 | "\n", 81 | "\n", 82 | "\n", 83 | "\n", 84 | "\n", 85 | "# Filtro Anti Spoilers!" 86 | ] 87 | }, 88 | { 89 | "cell_type": "markdown", 90 | "metadata": {}, 91 | "source": [ 92 | "### Solución:" 93 | ] 94 | }, 95 | { 96 | "cell_type": "code", 97 | "execution_count": null, 98 | "metadata": {}, 99 | "outputs": [], 100 | "source": [ 101 | "%%sql\n", 102 | "\n", 103 | "CREATE OR REPLACE FUNCTION seq(n integer)\n", 104 | "RETURNS TABLE (number integer) AS $$\n", 105 | "DECLARE\n", 106 | "i INTEGER;\n", 107 | "BEGIN\n", 108 | " CREATE TABLE SEQ(number integer);\n", 109 | " FOR i in 1 .. n LOOP\n", 110 | " INSERT INTO SEQ VALUES(i);\n", 111 | " END LOOP;\n", 112 | " RETURN QUERY SELECT * FROM SEQ;\n", 113 | " DROP TABLE SEQ;\n", 114 | " RETURN;\n", 115 | "END;\n", 116 | "$$ language plpgsql;" 117 | ] 118 | }, 119 | { 120 | "cell_type": "markdown", 121 | "metadata": {}, 122 | "source": [ 123 | "Si la vemos, es bastante directo. El parámetro de entrada como dijimos es un ```integer``` n, y la función retorna una tabla con una sola columna de tipo ```integer``` tambien (que llamamos ```number```). Luego creamos una tabla auxiliar para luego retornar ```SEQ``` e insertamos los números 1 a n mediante un ```FOR``` en nuestra tabla.\n", 124 | "\n", 125 | "Especificamos el valor de retorno con ```RETURN QUERY```, eliminamos la tabla auxiliar para no dejar rastro de tu creación, y luego retornamos la función con ```RETURN```." 126 | ] 127 | }, 128 | { 129 | "cell_type": "markdown", 130 | "metadata": {}, 131 | "source": [ 132 | "### Propuesto\n", 133 | "\n", 134 | "Ahora intente expandir nuestra definición de ```seq```. Tendrá 3 parámetros, el inicio de la secuencia, el final y un incremento. Es decir, entrega una secuencia que parte en cierto valor, luego aumenta el valor segun el incremento hasta superar el valor final. Lo anterior es para el caso en que el incremento sea positivo, en caso contrario, debe iniciar en la posición final y disminuir hasta pasar el valor inicial. Con ejemplos:\n", 135 | "\n", 136 | "```sql\n", 137 | "SELECT * FROM seq(1,5,1);\n", 138 | "\n", 139 | "1\n", 140 | "2\n", 141 | "3\n", 142 | "4\n", 143 | "5\n", 144 | "\n", 145 | "SELECT * FROM seq(3,8,2);\n", 146 | "\n", 147 | "3\n", 148 | "5\n", 149 | "7\n", 150 | "\n", 151 | "SELECT * FROM seq(2,4,-1);\n", 152 | "\n", 153 | "4\n", 154 | "3\n", 155 | "2\n", 156 | "\n", 157 | "SELECT * FROM seq(3,2,-1);\n", 158 | "\n", 159 | "```\n", 160 | "\n", 161 | "Ojo con el caso final. Como en este caso la secuencia disminuye y comenzamos con 2 que ya es menor a 3, entrega la tabla vacía" 162 | ] 163 | }, 164 | { 165 | "cell_type": "code", 166 | "execution_count": null, 167 | "metadata": {}, 168 | "outputs": [], 169 | "source": [ 170 | "%%sql\n", 171 | "\n", 172 | "# Intenta resolver el ejercicio aquí!" 173 | ] 174 | }, 175 | { 176 | "cell_type": "markdown", 177 | "metadata": {}, 178 | "source": [ 179 | "# Problema 2: Resta Casera\n", 180 | "\n", 181 | "Otro buen ejercicio es realizar a mano operaciones nativas de SQL con procedimientos almacenados. En el siguiente realizamos la operación resta que conocimos en álgebra relacional y que existe como ```EXCEPT``` en SQL. Para recordar, esta recibe 2 tablas unión-compatibles (mismo número de columnas y de mismos tipos) y retorna aquella tabla que contiene todas las tuplas de la primera que no se encuentran en la segunda.\n", 182 | "\n", 183 | "Para simplificar, supongamos que existen 2 tablas **A** y **B** con columnas *a* y *b* cada una, y que la única consulta SQL que podemos realizar sobre estas tablas es obtener todos los elementos (```SELECT * FROM A``` o ```SELECT * FROM B```). Realizar un procedimiento almacenado que calcule la resta de estas dos tablas." 184 | ] 185 | }, 186 | { 187 | "cell_type": "markdown", 188 | "metadata": {}, 189 | "source": [ 190 | "Deje de leer, inténtelo en la siguiente celda, y vuelva:" 191 | ] 192 | }, 193 | { 194 | "cell_type": "code", 195 | "execution_count": null, 196 | "metadata": {}, 197 | "outputs": [], 198 | "source": [ 199 | "%%sql\n", 200 | "\n", 201 | "# Intenta resolver el ejercicio aquí\n", 202 | "\n", 203 | "\n", 204 | "\n", 205 | "\n", 206 | "\n", 207 | "\n", 208 | "\n", 209 | "\n", 210 | "# Filtro anti spoilers!" 211 | ] 212 | }, 213 | { 214 | "cell_type": "markdown", 215 | "metadata": {}, 216 | "source": [ 217 | "### Solución:" 218 | ] 219 | }, 220 | { 221 | "cell_type": "code", 222 | "execution_count": null, 223 | "metadata": {}, 224 | "outputs": [], 225 | "source": [ 226 | "%%sql\n", 227 | "\n", 228 | "CREATE OR REPLACE FUNCTION restar()\n", 229 | "RETURNS TABLE (number1 integer, numer2 integer) as $$\n", 230 | "DECLARE\n", 231 | " r1 record;\n", 232 | " r2 record;\n", 233 | " se_restan bool;\n", 234 | "BEGIN\n", 235 | " CREATE TABLE resta(number1 integer, number2 integer);\n", 236 | " FOR r1 IN SELECT * FROM A LOOP\n", 237 | " se_restan := FALSE;\n", 238 | " FOR r2 IN SELECT * FROM B LOOP\n", 239 | " IF r1 = r2 THEN\n", 240 | " se_restan := TRUE;\n", 241 | " END IF;\n", 242 | " END LOOP;\n", 243 | " IF NOT se_restan THEN\n", 244 | " INSERT INTO resta VALUES(r1.a, r1.b);\n", 245 | " END IF;\n", 246 | " END LOOP;\n", 247 | " RETURN QUERY SELECT * FROM resta;\n", 248 | " DROP TABLE resta;\n", 249 | " RETURN;\n", 250 | "END;\n", 251 | "$$ language plpgsql;" 252 | ] 253 | }, 254 | { 255 | "cell_type": "markdown", 256 | "metadata": {}, 257 | "source": [ 258 | "Nuevamente, bastante directo. Iteramos sobre los elementos de A creando para cada uno una variable booleana ```se_restan``` con la cual vereificamos si se encuentra el elemento de A en B. En caso de no estar, lo agregamos tranquilamente a nuestra tabla auxiliar ```resta```.\n", 259 | "\n", 260 | "### Propuesto\n", 261 | "\n", 262 | "Teniendo los mismos supuestos de antes, es decir, dos tablas A y B con columnas *a* y *b* cada una. Escriba un procedimiento almacenado que calcule el producto cruz de A y B." 263 | ] 264 | }, 265 | { 266 | "cell_type": "code", 267 | "execution_count": null, 268 | "metadata": {}, 269 | "outputs": [], 270 | "source": [ 271 | "%%sql\n", 272 | "\n", 273 | "# Intenta resolver el ejercicio aquí!" 274 | ] 275 | }, 276 | { 277 | "cell_type": "markdown", 278 | "metadata": {}, 279 | "source": [ 280 | "# Problema 3: Calcular Distancias\n", 281 | "\n", 282 | "Otro ejercicio útil, sobre todo cuando se trabaja con bases de datos de lugares que contienen coordenadas geográficas, es calcular la distancia entre un punto dado y los lugares de la base de datos y filtrar por una distancia dada. De esta forma, se obtienen todos los lugares que se encuentren, por ejemplo, a menos de 10 Km del Campus San Joaquín.\n", 283 | "\n", 284 | "Para esto, resulta muy útil crear una función capaz de generar esta tabla de resultados utilizando procedimientos almacenados. Para calcular la distancia entre dos lugres podemos usar la fórmula de Haversine:\n", 285 | "\n", 286 | "+ ```Lugar1 = (lat1, lng1)```\n", 287 | "+ ```Lugar2 = (lat2, lng2)```\n", 288 | "\n", 289 | "$distancia = 6371 * acos(cos(radians(lat1)) * cos(radians(lat2)) * cos(radians(lng2)) - radians(lng1) + sin(radians(lat1)) * sin(radians(lat2)))$" 290 | ] 291 | }, 292 | { 293 | "cell_type": "markdown", 294 | "metadata": {}, 295 | "source": [ 296 | "En donde ```Lugar1``` es nuestro punto de refencia/comparación. Realizar un procedimiento almacenado que dado un punto de referencia y una distancia, entregue una tabla con todos los lugares que se encuentran a una distancia menor al valor entregado. *Hint: Revisar SQL Dinámico*.\n", 297 | "\n", 298 | "Para esto tienen la tabla:\n", 299 | "\n", 300 | "Lugares(**id integer**, nombre varchar(50), lat float, lng float)." 301 | ] 302 | }, 303 | { 304 | "cell_type": "code", 305 | "execution_count": null, 306 | "metadata": {}, 307 | "outputs": [], 308 | "source": [ 309 | "%%sql\n", 310 | "DROP TABLE IF EXISTS Lugares;\n", 311 | "CREATE TABLE Lugares (id integer, nombre varchar(50), lat float, lng float, PRIMARY KEY(id));\n", 312 | "INSERT INTO Lugares VALUES (1, 'Casa Central', -33.4409096,-70.6421587);\n", 313 | "INSERT INTO Lugares VALUES (2, 'Concepción', 36.8261411,-73.1032568);\n", 314 | "SELECT * FROM Lugares;" 315 | ] 316 | }, 317 | { 318 | "cell_type": "markdown", 319 | "metadata": {}, 320 | "source": [ 321 | "Ahora deja de leer e inténtalo!" 322 | ] 323 | }, 324 | { 325 | "cell_type": "code", 326 | "execution_count": null, 327 | "metadata": {}, 328 | "outputs": [], 329 | "source": [ 330 | "%%sql\n", 331 | "\n", 332 | "# Intenta resolver el ejercicio aquí\n", 333 | "\n", 334 | "\n", 335 | "\n", 336 | "\n", 337 | "\n", 338 | "\n", 339 | "\n", 340 | "\n", 341 | "# Filtro anti spoilers!" 342 | ] 343 | }, 344 | { 345 | "cell_type": "markdown", 346 | "metadata": {}, 347 | "source": [ 348 | "## Solución" 349 | ] 350 | }, 351 | { 352 | "cell_type": "code", 353 | "execution_count": null, 354 | "metadata": {}, 355 | "outputs": [], 356 | "source": [ 357 | "%%sql\n", 358 | "DROP FUNCTION IF EXISTS HaversineDistance(double precision, double precision, integer);\n", 359 | "\n", 360 | "CREATE OR REPLACE FUNCTION\n", 361 | "HaversineDistance(lat1 float, lng1 float, distance integer)\n", 362 | "RETURNS TABLE (id integer, nombre varchar(50), distancia float) AS $$\n", 363 | "BEGIN\n", 364 | "RETURN QUERY EXECUTE 'SELECT id, nombre, 6371 * ACOS(least(greatest((COS(RADIANS($1)) * COS(RADIANS(lat)) * COS(RADIANS(lng)) - RADIANS($2) + SIN(RADIANS($1)) * SIN(RADIANS(lat))), -1), 1)) AS distancia FROM Lugares'\n", 365 | " USING lat1, lng1, distance;\n", 366 | " RETURN;\n", 367 | "END\n", 368 | "$$ language plpgsql" 369 | ] 370 | }, 371 | { 372 | "cell_type": "markdown", 373 | "metadata": {}, 374 | "source": [ 375 | "Si lo vemos, es bastante directo. El procedimiento recibe 3 parámetros de entrada y se genera la consulta en SQL que filtra a través del ```HAVING``` los lugares cuya distancia al lugar de referencia sea menor a ```distance``` (en [km]).\n", 376 | "\n", 377 | "Finalmente, para ejecutar el procedimiento se debe llamar a ```SELECT * FROM HaversineDistance(-33.497579, -70.612246, 10);```, que nos entregará todos los lugares que se encuentran a menos de 10 km del Campus San Joaquín.\n", 378 | "\n", 379 | "**Observación**: Existe un *bug* en la función `ACOS` que nos obliga a usar `greatest` y `least`." 380 | ] 381 | }, 382 | { 383 | "cell_type": "code", 384 | "execution_count": null, 385 | "metadata": {}, 386 | "outputs": [], 387 | "source": [ 388 | "%sql SELECT * FROM HaversineDistance(-33.497579, -70.612246, 10);" 389 | ] 390 | }, 391 | { 392 | "cell_type": "markdown", 393 | "metadata": {}, 394 | "source": [ 395 | "## Propuesto\n", 396 | "\n", 397 | "Supongamos que existe la tabla ```Lugares``` como en el ejercicio anterior. Escriba un procedimiento almacenado que utilizando esta tabla, cree las siguientes dos tablas en la base de datos:\n", 398 | "\n", 399 | "+ ```Distancia(idlugar1 int, idlugar2 int, distancia float)```\n", 400 | "+ ```VecinoMasCercano(idlugar int, idvecino int)```\n", 401 | "\n", 402 | "Como los nombres sugieren, ```Distancia``` indica la distancia entre cada par de ulgares de la tabla ```Lugares``` y ```VecinoMasCercano``` contiene para cada lugar, su id y el id del lugar más cercano (que no es si mismo).\n", 403 | "\n", 404 | "A diferencia de casos anteriores, este procedimiento no debe entregar las tablas si no simplemente dejarlas almacenadas en la base de datos donde se trabaja y asume la existencia de la tabla ```Lugares```, no es necesario ingresar su nombre como parámetro." 405 | ] 406 | }, 407 | { 408 | "cell_type": "code", 409 | "execution_count": null, 410 | "metadata": {}, 411 | "outputs": [], 412 | "source": [ 413 | "%%sql\n", 414 | "\n", 415 | "# Intenta resolver el ejercicio aquí!" 416 | ] 417 | } 418 | ], 419 | "metadata": { 420 | "kernelspec": { 421 | "display_name": "Python 3", 422 | "language": "python", 423 | "name": "python3" 424 | }, 425 | "language_info": { 426 | "codemirror_mode": { 427 | "name": "ipython", 428 | "version": 3 429 | }, 430 | "file_extension": ".py", 431 | "mimetype": "text/x-python", 432 | "name": "python", 433 | "nbconvert_exporter": "python", 434 | "pygments_lexer": "ipython3", 435 | "version": "3.7.1" 436 | } 437 | }, 438 | "nbformat": 4, 439 | "nbformat_minor": 2 440 | } 441 | -------------------------------------------------------------------------------- /Actividades/MongoDB/MongoDB.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "# Resumen MongoDB\n", 8 | "\n", 9 | "### Outline\n", 10 | "\n", 11 | "1. Datos\n", 12 | "2. Importando Datos\n", 13 | "3. Utilizando la consola de MongoDB\n", 14 | "4. Consultando en MongoDB\n", 15 | " + Filtros\n", 16 | " + Proyección\n", 17 | "5. Algunas consultas\n", 18 | "6. Python y MongoDB\n", 19 | "7. JavaScript y MongoDB\n" 20 | ] 21 | }, 22 | { 23 | "cell_type": "markdown", 24 | "metadata": {}, 25 | "source": [ 26 | "## Datos \n", 27 | "\n", 28 | "Trabajaremos en el contexto de una red social, con una colección de **usuarios**, otra colección de **mensajes** y una colección de productos. Los datos se ven así:\n", 29 | "\n", 30 | "#### Usuarios\n", 31 | "\n", 32 | "```\n", 33 | " \"mid\": ,\n", 34 | " \"uid\": ,\n", 35 | " \"msj\": {\"title\": ,\n", 36 | " \"content\": },\n", 37 | " \"likes\": \n", 38 | "\n", 39 | "```\n", 40 | "#### Mensajes \n", 41 | "\n", 42 | "```\n", 43 | " \"mid\": ,\n", 44 | " \"uid\": ,\n", 45 | " \"msj\": {\"title\": ,\n", 46 | " \"content\": },\n", 47 | " \"likes\": \n", 48 | "```\n", 49 | "\n", 50 | "#### Productos\n", 51 | "```\n", 52 | " \"pid\": ,\n", 53 | " \"name\": ,\n", 54 | " \"tags\": [, ..., ],\n", 55 | " \"price\": \n", 56 | "```\n", 57 | "\n", 58 | "---\n", 59 | "\n", 60 | "## Importando Datos \n", 61 | "\n", 62 | "Luego de haber **instalado mongo en tu Computador**, ingresa desde la consola a la carpeta donde tengas los archivos de los datos en formato `json`. Ingresa el comando `sudo service mongod start`. Luego, para importar los datos de `usuarios.json` en la colección `usuarios`, ejecuta en la consola:\n", 63 | "\n", 64 | "\n", 65 | "`mongoimport --db test --collection usuarios --drop --file usuarios.json --jsonArray`\n", 66 | "\n", 67 | "\n", 68 | "Para importar los datos de `mensajes.json` en la colección `mensajes`:\n", 69 | "\n", 70 | "\n", 71 | "`mongoimport --db test --collection mensajes --drop --file mensajes.json --jsonArray`\n", 72 | "\n", 73 | "\n", 74 | "Para importar los datos de `productos.json` en la colección `productos`:\n", 75 | "\n", 76 | "`mongoimport --db test --collection productos --drop --file productos.json --jsonArray`\n", 77 | "\n", 78 | "---\n", 79 | "\n", 80 | "## Utilizando la consola de MongoDB\n", 81 | "\n", 82 | "### Consultando en MongoDB\n", 83 | "\n", 84 | "Para utilizar MongoDB **debes tener un servidor corriendo**. Para iniciar un servidor de mongo en la consola, utiliza el comando `mongo`. Debería aparecer la consola de MongoDB, en la que puedes hacer consultas. Ahora ejecuta las siguientes instrucciones: \n", 85 | "```\n", 86 | "> use test\n", 87 | "> db.usuarios.find()\n", 88 | "```\n", 89 | "Con la primera línea nos conectamos a la base de datos `test`, y con la segunda deberías obtener a todos los usuarios. \n", 90 | "\n", 91 | "La consulta básica se realiza mediante la función `find()`. Opcionalmente puedes ejecutar `find` con dos parámetros que también son documentos JSON. El primer parámetro corresponde a filtros (selección) y el segundo a proyección. Ahora ejecuta la misma consulta anterior pero usando el comando `pretty()` para hacer que aparezcan los documentos de una forma un poco más legible:\n", 92 | "\n", 93 | "```\n", 94 | "> db.usuarios.find({}, {}).pretty()\n", 95 | "```\n", 96 | "\n", 97 | "**Pro Tip:** Usa el comando `help` en la consola para obtener comandos útiles para manejar MongoDB en esta ;)\n", 98 | "\n", 99 | "### Filtros \n", 100 | "\n", 101 | "El primer parámetro del comando `find()` son los filtros, o selección. La selección por igualdad es simple: la siguiente consulta busca el usuario con `uid` igual a 2:\n", 102 | "\n", 103 | "`> db.usuarios.find({uid: 2}, {}).pretty()`\n", 104 | "\n", 105 | "\n", 106 | "Ahora vamos a buscar todos los productos con precio mayor a 300:\n", 107 | "\n", 108 | "`> db.productos.find({price: {$gt: 300}}, {}).pretty()`\n", 109 | "\n", 110 | "Si te fijas, usamos `price: {$gt: 300}`. Esto nos exige que debemos buscar todos los elementos donde la key `price` sea mayor que 300. Tienes los siguientes comandos a disposición:\n", 111 | "\n", 112 | "\n", 113 | "+ `$gt`: mayor que.\n", 114 | "+ `$lt`: menor que.\n", 115 | "+ `$gte`: mayor o igual que.\n", 116 | "+ `$lte`: menor o igual que.\n", 117 | "\n", 118 | "\n", 119 | "Ahora busquemos los productos con precio entre 200 y 400. Para esto vamos a utilizar la instrucción `$and`:\n", 120 | "\n", 121 | "`> db.productos.find({$and: [{price: {$gte: 200}}, {price: {$lte: 400}}]}, {}).pretty()`\n", 122 | "\n", 123 | "Como ves, esto se empieza a complicar. Vamos a escribir la consulta anterior en más de una línea para hacerla más legible:\n", 124 | "\n", 125 | "```\n", 126 | "db.productos.find(\n", 127 | " {\n", 128 | " $and: [\n", 129 | " {price: {$gte: 200}}, \n", 130 | " {price: {$lte: 400}}\n", 131 | " ]\n", 132 | " }, {}).pretty();\n", 133 | "```\n", 134 | "\n", 135 | "\n", 136 | "La instrucción `$and` recibe un arreglo de selecciones. Se van a retornar los documentos que cumplan todas las condiciones. También existe un comando `\\$or. Finalmente, también tenemos acceso a desigualdades con la instrucción `$ne`:\n", 137 | "\n", 138 | "`> db.usuarios.find({price: {$ne: 2}}, {}).pretty()`\n", 139 | "\n", 140 | "En general las consultas no se ven tan amigables o legibles. Puedes ver la documentación de MongoDB para ver qué otros filtros se pueden usar. \n", 141 | "\n", 142 | "\n", 143 | "### Proyección\n", 144 | "\n", 145 | "El segundo parámetro de `find()` corresponde a los campos a proyectar. Ahora proyectaremos solamente los nombres de los usuarios:\n", 146 | "\n", 147 | "`> db.usuarios.find({}, {name: 1})`\n", 148 | "\n", 149 | "También podemos excluir en la proyección, usando un 0 en vez de un 1:\n", 150 | "\n", 151 | "El segundo parámetro de `find()` corresponde a los campos a proyectar. Ahora proyectaremos solamente los nombres de los usuarios:\n", 152 | "\n", 153 | "`> db.productos.find({}, {tags: 0})`\n", 154 | "\n", 155 | "En el caso anterior, estamos excluyendo el arreglo de tags de los productos.\n", 156 | "\n", 157 | "---\n" 158 | ] 159 | }, 160 | { 161 | "cell_type": "markdown", 162 | "metadata": {}, 163 | "source": [ 164 | "## Ejemplos de consultas\n", 165 | "Aquí hay algunos ejemplos breves de consultas que se pueden hacer en MongoDB.\n", 166 | "\n", 167 | "##### Todos los mensajes:\n", 168 | "\n", 169 | "`> db.mensajes.find({}, {}).pretty()`\n", 170 | "\n", 171 | "##### El contenido de todos los mensajes:\n", 172 | "\n", 173 | "`> db.mensajes.find({}, {\"msj.content\": 1})`\n", 174 | "\n", 175 | "En el ejemplo anterior estamos accediendo a una key dentro de un JSON dentro de los documentos.\n", 176 | "\n", 177 | "##### El contenido de todos los mensajes del usuario con id $i$:\n", 178 | "\n", 179 | "`> db.mensajes.find({\"uid\": i}, {\"msj.content\": 1})`\n", 180 | "\n", 181 | "\n", 182 | "##### El contenido de todos los mensajes del usuario con id $i$ o $j$:\n", 183 | "\n", 184 | "`> db.mensajes.find({$or: [{\"uid\": i}, { \"uid\": j }]}, {\"msj.content\": 1})`\n", 185 | "\n", 186 | "En este ejemplo estamos usando la instrucción `$or`.\n", 187 | "\n", 188 | "##### Los usuarios mayores a 18 años ordenados por nombre:\n", 189 | "\n", 190 | "`> db.usuarios.find({age: {$gt: 18}}, {}).sort({\"name\": 1})`\n", 191 | "\n", 192 | "Aquí estamos haciendo uso de la función `sort()`.\n", 193 | "\n", 194 | "##### Todos los productos cuyos tags sean exactamente el arreglo `[\"Tag 1\", \"Tag 2\"]`, en ese orden:\n", 195 | "\n", 196 | "`> db.productos.find({tags: [\"Tag 1\", \"Tag 2\"]}, {})`\n", 197 | "\n", 198 | "##### Todos los productos que en sus tags contengan los elementos `\"Tag 4\"` y `\"Tag 3\"`:\n", 199 | "\n", 200 | "`> db.productos.find({tags: {$all: [\"Tag 4\", \"Tag 3\"]}}, {})`\n", 201 | "\n", 202 | "##### Todos los productos que en sus tags contengan los elementos `\"Tag 4\"` Y `\"Tag 3\"`:\n", 203 | "\n", 204 | "`> db.productos.find({tags: {$all: [\"Tag 4\", \"Tag 3\"]}}, {})`\n", 205 | "\n", 206 | "##### Todos los productos que en sus tags contengan el elemento `\"Tag 5\"`:\n", 207 | "\n", 208 | "`> db.productos.find({tags: \"Tag 5\"}, {})`\n", 209 | "\n", 210 | "##### Todos los productos que en sus tags contengan el elemento `\"Tag 5\"` o `\"Tag 1\"`:\n", 211 | "\n", 212 | "`> db.productos.find({tags: {$in: [\"Tag 5\", \"Tag 1\"]}}, {})`\n", 213 | "\n", 214 | "##### Todos los productos que en sus tags NO contengan el elemento`\"Tag 5\"` o `\"Tag 1\"`:\n", 215 | "\n", 216 | "`> db.productos.find({tags: {$nin: [\"Tag 5\", \"Tag 1\"]}}, {})`\n", 217 | "\n", 218 | "##### El promedio del precio de los productos:\n", 219 | "\n", 220 | "```\n", 221 | "> db.productos.aggregate(\n", 222 | " [\n", 223 | " {$group: {_id: null, total: {$avg: \"$price\"}}}\n", 224 | " ]\n", 225 | ")\n", 226 | "```\n", 227 | "\n", 228 | "##### La suma del precio de todos los productos que contengan la etiqueta `\"Tag 3\"`:\n", 229 | "\n", 230 | "```\n", 231 | "> db.productos.aggregate(\n", 232 | " [\n", 233 | " {$match: {tags: \"Tag 3\"}}, \n", 234 | " {$group: {_id: null, total: {$sum: \"$price\"}}}\n", 235 | " ]\n", 236 | ");\n", 237 | "```\n", 238 | "\n", 239 | "##### La suma de todos los `likes` agrupadas por usuario:\n", 240 | "\n", 241 | "```\n", 242 | "> db.mensajes.aggregate(\n", 243 | " [\n", 244 | " {$group: {_id: \"$uid\", total: {$sum: \"$likes\"}}}\n", 245 | " ]\n", 246 | ")\n", 247 | "```\n", 248 | "\n", 249 | "---" 250 | ] 251 | }, 252 | { 253 | "cell_type": "markdown", 254 | "metadata": {}, 255 | "source": [ 256 | "## Javascript + MongoDB\n", 257 | "\n", 258 | "Aquí hay algunos ejemplos de consultas más complejas que se pueden hacer en MongoDB con la ayuda de __Javascript__. Para correr estos ejemplos, si tu solución está en el archivo `ejemplo.js`, entonces debes correr el comando:\n", 259 | "\n", 260 | "`mongo ejemplo.js`\n", 261 | "\n", 262 | "Las consultas de ejemplo son:\n", 263 | "\n", 264 | "###### Cada id de usuario junto al nombre de la gente a la que sigue:\n", 265 | "\n", 266 | "```Javascript\n", 267 | "var cursor = db.usuarios.find({}, {});\n", 268 | "cursor.forEach(\n", 269 | " (element) => {\n", 270 | " try {\n", 271 | " var follows = element[\"follows\"];\n", 272 | " print(\"## User ID: \" + element[\"uid\"]);\n", 273 | " for (var followed in follows) {\n", 274 | " var user_cursor = db.usuarios.find({\"uid\": follows[followed]},{});\n", 275 | " user_cursor.forEach(\n", 276 | " (user_element) => {\n", 277 | " print(user_element[\"name\"]);\n", 278 | " }\n", 279 | " )\n", 280 | " }\n", 281 | " print(\"##\");\n", 282 | " }\n", 283 | " catch(e) {\n", 284 | " print(\"GG\", e);\n", 285 | " }\n", 286 | " }\n", 287 | ");\n", 288 | "```\n", 289 | "\n", 290 | "\n", 291 | "\n", 292 | "##### Cada id de usuario, junto a su nombre y la cantidad de likes total de sus mensajes:\n", 293 | "\n", 294 | "```Javascript\n", 295 | "var cursor = db.usuarios.find({}, {});\n", 296 | "cursor.forEach(\n", 297 | " (element) => {\n", 298 | " try {\n", 299 | " var msj_cursor = db.mensajes.find({\"uid\": element[\"uid\"]}, {})\n", 300 | " var likes = 0;\n", 301 | " msj_cursor.forEach(\n", 302 | " (msj_element) => {\n", 303 | " likes += msj_element[\"likes\"];\n", 304 | " }\n", 305 | " )\n", 306 | " print(\"User ID: \" + element[\"uid\"] +\n", 307 | " \" - Name: \" + element[\"name\"] +\n", 308 | " \" - Likes: \" + likes);\n", 309 | " }\n", 310 | " catch(e) {\n", 311 | " print(\"GG\", e);\n", 312 | " }\n", 313 | " }\n", 314 | ");\n", 315 | "```" 316 | ] 317 | }, 318 | { 319 | "cell_type": "markdown", 320 | "metadata": {}, 321 | "source": [ 322 | "## Python + MongoDB = Pymongo\n", 323 | "\n", 324 | "Para utilizar MongoDB con python deberás descargar `pymongo` y utilizar `MongoClient` para correr el servidor. \n", 325 | "\n", 326 | "```Python\n", 327 | "from pymongo import MongoClient\n", 328 | "\n", 329 | "MONGODATABASE = \"test\"\n", 330 | "MONGOSERVER = \"localhost\"\n", 331 | "MONGOPORT = 27017\n", 332 | "client = MongoClient(MONGOSERVER, MONGOPORT)\n", 333 | "mongodb = client[MONGODATABASE]\n", 334 | "\n", 335 | "usuarios = mongodb.usuarios\n", 336 | "mensajes = mondodb.mensajes\n", 337 | "productos = mongodb.productos\n", 338 | "\n", 339 | "```\n", 340 | "\n", 341 | "Intenta el siguiente comando para mostrar todos los mensajes de la base de datos:\n", 342 | "\n", 343 | "```Python\n", 344 | "qfilter = mensajes.find({}, {'_id': 0})\n", 345 | "for mensaje in qfilter:\n", 346 | " print(mensaje)\n", 347 | "```\n", 348 | "**Ojo:** Esto funciona porque en la base de datos `test` se cargaron previamente los 3 archivos indicados. \n", 349 | "\n", 350 | "\n", 351 | "---" 352 | ] 353 | }, 354 | { 355 | "cell_type": "markdown", 356 | "metadata": {}, 357 | "source": [ 358 | "Si bien los procedimientos en Javascript se pueden correr desde la terminal de mongo, vamos a realizar la primera consulta utilizando `pymongo`.\n", 359 | "\n", 360 | "##### Cada id de usuario junto al nombre de la gente a la que sigue:" 361 | ] 362 | }, 363 | { 364 | "cell_type": "code", 365 | "execution_count": 8, 366 | "metadata": {}, 367 | "outputs": [ 368 | { 369 | "name": "stdout", 370 | "output_type": "stream", 371 | "text": [ 372 | "El usuario Devil sigue a: \n", 373 | "\tNebil\n", 374 | "El usuario Florencia sigue a: \n", 375 | "\tAdrian\n", 376 | "\tNebil\n", 377 | "El usuario Nebil sigue a: \n", 378 | "\tAdrian\n", 379 | "\tFlorencia\n", 380 | "\tDevil\n", 381 | "El usuario Adrian sigue a: \n", 382 | "\tFlorencia\n", 383 | "\tDevil\n", 384 | "El usuario Fernando sigue a: \n" 385 | ] 386 | } 387 | ], 388 | "source": [ 389 | "from pymongo import MongoClient\n", 390 | "\n", 391 | "MONGODATABASE = \"test\"\n", 392 | "MONGOSERVER = \"localhost\"\n", 393 | "MONGOPORT = 27017\n", 394 | "client = MongoClient(MONGOSERVER, MONGOPORT)\n", 395 | "mongodb = client[MONGODATABASE]\n", 396 | "\n", 397 | "usuarios = mongodb.usuarios\n", 398 | "mensajes = mongodb.mensajes\n", 399 | "productos = mongodb.productos\n", 400 | "\n", 401 | "qusers = usuarios.find()\n", 402 | "\n", 403 | "for user in qusers:\n", 404 | " print('El usuario {} sigue a: '.format(user['name']))\n", 405 | " for uid in user['follows']:\n", 406 | " ufollows = usuarios.find({'uid': uid})\n", 407 | " for user2 in ufollows:\n", 408 | " print(\"\\t{}\".format(user2['name']))\n", 409 | " " 410 | ] 411 | }, 412 | { 413 | "cell_type": "code", 414 | "execution_count": null, 415 | "metadata": {}, 416 | "outputs": [], 417 | "source": [] 418 | } 419 | ], 420 | "metadata": { 421 | "kernelspec": { 422 | "display_name": "Python 3", 423 | "language": "python", 424 | "name": "python3" 425 | }, 426 | "language_info": { 427 | "codemirror_mode": { 428 | "name": "ipython", 429 | "version": 3 430 | }, 431 | "file_extension": ".py", 432 | "mimetype": "text/x-python", 433 | "name": "python", 434 | "nbconvert_exporter": "python", 435 | "pygments_lexer": "ipython3", 436 | "version": "3.7.1" 437 | } 438 | }, 439 | "nbformat": 4, 440 | "nbformat_minor": 2 441 | } 442 | -------------------------------------------------------------------------------- /Actividades/Pandas/comunas.csv: -------------------------------------------------------------------------------- 1 | 15101,Arica,Arica,Arica y Parinacota,4799.4,210936,736,38.4 2 | 15102,Camarones,Arica,Arica y Parinacota,3927,679,0.3,751 3 | 15201,Putre,Parinacota,Arica y Parinacota,5902.5,1462,0.2,707 4 | 15202,General Lagos,Parinacota,Arica y Parinacota,2244.4,739,0.5,0.67 5 | 1101,Iquique,Iquique,Tarapacá,2242.1,184953,82.4,766 6 | 1107,Alto Hospicio,Iquique,Tarapacá,572.9,94455,87.6, 7 | 1401,Pozo Almonte,Tamarugal,Tarapacá,13765.8,11519,0.7,722 8 | 1402,Camiña,Tamarugal,Tarapacá,2200.2,1156,0.5,619 9 | 1403,Colchane,Tamarugal,Tarapacá,4015.6,1384,0.4,603 10 | 1404,Huara,Tamarugal,Tarapacá,10474.6,2360,0.2,676 11 | 1405,Pica,Tamarugal,Tarapacá,8934.3,4194,0.6,793 12 | 2101,Antofagasta,Antofagasta,Antofagasta,30718.1,348669,9.7,734 13 | 2102,Mejillones,Antofagasta,Antofagasta,3803.9,9752,2.2,0.73 14 | 2103,Sierra Gorda,Antofagasta,Antofagasta,12886,1206,0.1,789 15 | 2104,Taltal,Antofagasta,Antofagasta,20405.1,13493,0.5,716 16 | 2201,Calama,El Loa,Antofagasta,15596.9,147886,9.1,757 17 | 2202,Ollagüe,El Loa,Antofagasta,2964,332,0.1,679 18 | 2203,San Pedro de Atacama,El Loa,Antofagasta,23439,5605,0.2,711 19 | 2301,Tocopilla,Tocopilla,Antofagasta,4038.8,20091,5.9,0.69 20 | 2302,María Elena,Tocopilla,Antofagasta,12197,4593,0.6,779 21 | 3101,Copiapó,Copiapó,Atacama,16681.3,158261,11.9,725 22 | 3102,Caldera,Copiapó,Atacama,4666.6,16150,2.9,741 23 | 3103,Tierra Amarilla,Copiapó,Atacama,11191,13912,1.1,686 24 | 3201,Chañaral,Chañaral,Atacama,5772,14146,2.2,714 25 | 3202,Diego de Almagro,Chañaral,Atacama,18664,16452,1,789 26 | 3301,Vallenar,Huasco,Atacama,7084,52099,6.7,731 27 | 3302,Alto del Carmen,Huasco,Atacama,5939,5488,0.8,664 28 | 3303,Freirina,Huasco,Atacama,3207.9,6531,1.7,693 29 | 3304,Huasco,Huasco,Atacama,1601.4,9015,5.6,695 30 | 4101,La Serena,Elqui,Coquimbo,1892.8,211275,132.5,781 31 | 4102,Coquimbo,Elqui,Coquimbo,1429,202441,141.6,731 32 | 4103,Andacollo,Elqui,Coquimbo,310,11116,33.1,675 33 | 4104,La Higuera,Elqui,Coquimbo,4158.2,4331,0.8,0.67 34 | 4105,Paihuano,Elqui,Coquimbo,1495,4252,2.8,734 35 | 4106,Vicuña,Elqui,Coquimbo,7610,26029,3.2,716 36 | 4201,Illapel,Choapa,Coquimbo,2629,30598,11.6,667 37 | 4202,Canela,Choapa,Coquimbo,2196.6,9182,4.2,644 38 | 4203,Los Vilos,Choapa,Coquimbo,1823.8,18483,9.6,675 39 | 4204,Salamanca,Choapa,Coquimbo,3445,25671,7.1,676 40 | 4301,Ovalle,Limarí,Coquimbo,3835,112956,28.1,725 41 | 4302,Combarbalá,Limarí,Coquimbo,2257.5,13818,7.7,661 42 | 4303,Monte Patria,Limarí,Coquimbo,4366.9,30137,6.9,653 43 | 4304,Punitaqui,Limarí,Coquimbo,1339,10418,7.1,653 44 | 4305,Río Hurtado,Limarí,Coquimbo,2180,4149,1.9,653 45 | 5101,Valparaíso,Valparaíso,Valparaíso,401.6,308137,687.2,701 46 | 5102,Casablanca,Valparaíso,Valparaíso,953,25165,22.9,712 47 | 5103,Concón,Valparaíso,Valparaíso,76,63210,424.6,781 48 | 5104,Juan Fernández,Valparaíso,Valparaíso,149.4,792,4,744 49 | 5105,Puchuncaví,Valparaíso,Valparaíso,300,16371,43.1,734 50 | 5107,Quintero,Valparaíso,Valparaíso,148,28066,143.5,733 51 | 5109,Viña del Mar,Valparaíso,Valparaíso,121.6,311399,2560.8,766 52 | 5201,Isla de Pascua,Isla de Pascua,Valparaíso,163.6,5761,23.1,715 53 | 5301,Los Andes,Los Andes,Valparaíso,1248,110866,48.2,756 54 | 5302,Calle Larga,Los Andes,Valparaíso,321.7,11110,34.3,706 55 | 5303,Rinconada,Los Andes,Valparaíso,122.5,8097,63.8,691 56 | 5304,San Esteban,Los Andes,Valparaíso,681,17371,12.5,732 57 | 5401,La Ligua,Petorca,Valparaíso,1163,38524,27.5,708 58 | 5402,Cabildo,Petorca,Valparaíso,1455,21094,13,671 59 | 5403,Papudo,Petorca,Valparaíso,64.2,5643,71.7,734 60 | 5404,Petorca,Petorca,Valparaíso,11.6,10074,390.5,696 61 | 5405,Zapallar,Petorca,Valparaíso,288,6726,22.1,743 62 | 5501,Quillota,Quillota,Valparaíso,302,88803,288.5,726 63 | 5502,La Calera,Quillota,Valparaíso,60.5,55207,830,0.7 64 | 5503,Hijuelas,Quillota,Valparaíso,267,19132,71.6,672 65 | 5504,La Cruz,Quillota,Valparaíso,78,17346,164.3,763 66 | 5506,Nogales,Quillota,Valparaíso,405,26385,53.3,689 67 | 5601,San Antonio,San Antonio,Valparaíso,405,87697,215.3,697 68 | 5602,Algarrobo,San Antonio,Valparaíso,176,13472,48.9,722 69 | 5603,Cartagena,San Antonio,Valparaíso,246,17029,68.6,708 70 | 5604,El Quisco,San Antonio,Valparaíso,51,15829,185.6,745 71 | 5605,El Tabo,San Antonio,Valparaíso,99,11861,71,747 72 | 5606,Santo Domingo,San Antonio,Valparaíso,536,9205,34.5,751 73 | 5701,San Felipe,San Felipe de Aconcagua,Valparaíso,186,72121,344.9,0.73 74 | 5702,Catemu,San Felipe de Aconcagua,Valparaíso,361.6,13902,33.5,669 75 | 5703,Llaillay,San Felipe de Aconcagua,Valparaíso,349.1,23680,62,676 76 | 5704,Panquehue,San Felipe de Aconcagua,Valparaíso,121.9,7569,53.8,696 77 | 5705,Putaendo,San Felipe de Aconcagua,Valparaíso,7.68,17369,1938.8,674 78 | 5706,Santa María,San Felipe de Aconcagua,Valparaíso,166.3,14504,9.2,699 79 | 5801,Quilpué,Marga Marga,Valparaíso,537,162320,280.7,752 80 | 5802,Limache,Marga Marga,Valparaíso,294,45864,133.4,722 81 | 5803,Olmué,Marga Marga,Valparaíso,232,16243,70.5,701 82 | 5804,Villa Alemana,Marga Marga,Valparaíso,97,135368,1225.6,755 83 | 6101,Rancagua,Cachapoal,Lib. Gral. Bernardo O'Higgins,260.3,250638,823.4,732 84 | 6102,Codegua,Cachapoal,Lib. Gral. Bernardo O'Higgins,287,12725,37.6,706 85 | 6103,Coinco,Cachapoal,Lib. Gral. Bernardo O'Higgins,98,7248,65.1,678 86 | 6104,Coltauco,Cachapoal,Lib. Gral. Bernardo O'Higgins,225,17620,72.1,644 87 | 6105,Doñihue,Cachapoal,Lib. Gral. Bernardo O'Higgins,78,21023,86.7,685 88 | 6106,Graneros,Cachapoal,Lib. Gral. Bernardo O'Higgins,113,30372,252.2,691 89 | 6107,Las Cabras,Cachapoal,Lib. Gral. Bernardo O'Higgins,749,23857,27,661 90 | 6108,Machalí,Cachapoal,Lib. Gral. Bernardo O'Higgins,2597,44566,11.1,0.73 91 | 6109,Malloa,Cachapoal,Lib. Gral. Bernardo O'Higgins,113,14972,113.9,649 92 | 6110,Mostazal,Cachapoal,Lib. Gral. Bernardo O'Higgins,524,23430,44.7,691 93 | 6111,Olivar,Cachapoal,Lib. Gral. Bernardo O'Higgins,45,13483,256.5,661 94 | 6112,Peumo,Cachapoal,Lib. Gral. Bernardo O'Higgins,153.1,14158,92.1,674 95 | 6113,Pichidegua,Cachapoal,Lib. Gral. Bernardo O'Higgins,320,18637,55.5,652 96 | 6114,Quinta de Tilcoco,Cachapoal,Lib. Gral. Bernardo O'Higgins,93,12144,122.4,678 97 | 6115,Rengo,Cachapoal,Lib. Gral. Bernardo O'Higgins,755,56188,66.8,0.68 98 | 6116,Requínoa,Cachapoal,Lib. Gral. Bernardo O'Higgins,673,26235,33,668 99 | 6117,San Vicente,Cachapoal,Lib. Gral. Bernardo O'Higgins,497.8,47716,66.6,694 100 | 6201,Pichilemu,Cardenal Caro,Lib. Gral. Bernardo O'Higgins,749.1,13916,16.5,677 101 | 6202,La Estrella,Cardenal Caro,Lib. Gral. Bernardo O'Higgins,435,4821,9.7,696 102 | 6203,Litueche,Cardenal Caro,Lib. Gral. Bernardo O'Higgins,619,5591,8.9,645 103 | 6204,Marchihue,Cardenal Caro,Lib. Gral. Bernardo O'Higgins,660,7557,10.4,0.67 104 | 6205,Navidad,Cardenal Caro,Lib. Gral. Bernardo O'Higgins,300,5650,18,651 105 | 6206,Paredones,Cardenal Caro,Lib. Gral. Bernardo O'Higgins,562,6802,11.9,628 106 | 6301,San Fernando,Colchagua,Lib. Gral. Bernardo O'Higgins,2441,75221,30.8,725 107 | 6302,Chépica,Colchagua,Lib. Gral. Bernardo O'Higgins,503,15820,27.5,637 108 | 6303,Chimbarongo,Colchagua,Lib. Gral. Bernardo O'Higgins,498,35664,64.9,674 109 | 6304,Lolol,Colchagua,Lib. Gral. Bernardo O'Higgins,597,6630,10.4,628 110 | 6305,Nancagua,Colchagua,Lib. Gral. Bernardo O'Higgins,111,18921,140.9,665 111 | 6306,Palmilla,Colchagua,Lib. Gral. Bernardo O'Higgins,237,12373,47.3,676 112 | 6307,Peralillo,Colchagua,Lib. Gral. Bernardo O'Higgins,282.6,10933,38.6,653 113 | 6308,Placilla,Colchagua,Lib. Gral. Bernardo O'Higgins,146.9,9624,65.5,621 114 | 6309,Pumanque,Colchagua,Lib. Gral. Bernardo O'Higgins,441,3458,7.8,635 115 | 6310,Santa Cruz,Colchagua,Lib. Gral. Bernardo O'Higgins,419.5,35255,77.2,719 116 | 7101,Talca,Talca,Maule,232,264842,928.5,731 117 | 7102,Constitución,Talca,Maule,1344,41416,34.3,715 118 | 7103,Curepto,Talca,Maule,1073.8,9714,9.7,644 119 | 7104,Empedrado,Talca,Maule,565,4250,7.4,637 120 | 7105,Maule,Talca,Maule,190,21957,88.6,681 121 | 7106,Pelarco,Talca,Maule,332,7959,21.8,653 122 | 7107,Pencahue,Talca,Maule,956.8,9187,8.6,649 123 | 7108,Río Claro,Talca,Maule,431,13020,30.2,671 124 | 7109,San Clemente,Talca,Maule,4504,39554,9.5,659 125 | 7110,San Rafael,Talca,Maule,263.5,8512,29.1,629 126 | 7201,Cauquenes,Cauquenes,Maule,2216,40245,19.4,656 127 | 7202,Chanco,Cauquenes,Maule,530,9571,17.8,612 128 | 7203,Pelluhue,Cauquenes,Maule,371,6636,17.2,694 129 | 7301,Curicó,Curicó,Maule,1328,177766,133.8,0.71 130 | 7302,Hualañé,Curicó,Maule,629,9977,15.4,631 131 | 7303,Licantén,Curicó,Maule,273,6689,25.2,705 132 | 7304,Molina,Curicó,Maule,1552,40329,25.8,663 133 | 7305,Rauco,Curicó,Maule,309,9878,27.7,659 134 | 7306,Romeral,Curicó,Maule,1597,14460,7.9,668 135 | 7307,Sagrada Familia,Curicó,Maule,548.8,17839,31.9,672 136 | 7308,Teno,Curicó,Maule,618.4,28228,45.6,648 137 | 7309,Vichuquén,Curicó,Maule,426,4335,11.5,678 138 | 7401,Linares,Linares,Maule,1466,107311,73.1,0.71 139 | 7402,Colbún,Linares,Maule,2900,19361,6,638 140 | 7403,Longaví,Linares,Maule,1454,28968,19.3,626 141 | 7404,Parral,Linares,Maule,1638,39404,23.2,656 142 | 7405,Retiro,Linares,Maule,827,18760,22,649 143 | 7406,San Javier,Linares,Maule,1313,40881,31,654 144 | 7407,Villa Alegre,Linares,Maule,190,15428,77.5,648 145 | 7408,Yerbas Buenas,Linares,Maule,262,17158,61.5,0.64 146 | 8416,San Carlos,Punilla,Ñuble,874,51335,58.7,653 147 | 8417,San Fabián,Punilla,Ñuble,1568.3,3503,2.2,618 148 | 8405,Coihueco,Punilla,Ñuble,1776.6,24714,13.9,639 149 | 8409,Ñiquén,Punilla,Ñuble,493.1,10063,20.4,629 150 | 8419,San Nicolás,Punilla,Ñuble,490.5,10051,20.5,625 151 | 8402,Bulnes,Diguillín,Ñuble,425.4,21542,50.6,626 152 | 8401,Chillán,Diguillín,Ñuble,511.2,175585,343.5,714 153 | 8406,Chillán Viejo,Diguillín,Ñuble,291.8,29199,100.1,732 154 | 8407,El Carmen,Diguillín,Ñuble,664.3,11830,17.8,611 155 | 8410,Pemuco,Diguillín,Ñuble,562.7,9120,16.2,631 156 | 8411,Pinto,Diguillín,Ñuble,1164,10883,9.3,618 157 | 8413,Quillón,Diguillín,Ñuble,423,15525,36.7,0.59 158 | 8418,San Ignacio,Diguillín,Ñuble,363.6,15770,43.4,618 159 | 8421,Yungay,Diguillín,Ñuble,823.5,18234,22.1,669 160 | 8414,Quirihue,Itata,Ñuble,589,11851,20.1,594 161 | 8403,Cobquecura,Itata,Ñuble,570.3,5173,9.1,633 162 | 8404,Coelemu,Itata,Ñuble,342.3,15461,45.2,611 163 | 8408,Ninhue,Itata,Ñuble,401.2,5278,13.2,569 164 | 8412,Portezuelo,Itata,Ñuble,282.3,5061,17.9,599 165 | 8415,Ránquil,Itata,Ñuble,248.3,4983,20.1,586 166 | 8420,Treguaco,Itata,Ñuble,313.1,4995,16,562 167 | 8101,Concepción,Concepción,Biobío,221.6,227768,1027.8,757 168 | 8102,Coronel,Concepción,Biobío,279.4,107508,384.8,682 169 | 8103,Chiguayante,Concepción,Biobío,71.5,115366,1613.5,764 170 | 8104,Florida,Concepción,Biobío,608.6,9867,16.2,604 171 | 8105,Hualqui,Concepción,Biobío,530.5,21934,41.3,666 172 | 8106,Lota,Concepción,Biobío,135.8,48045,353.8,643 173 | 8107,Penco,Concepción,Biobío,107.6,52389,486.9,689 174 | 8108,San Pedro de La Paz,Concepción,Biobío,112.5,94827,842.9,787 175 | 8109,Santa Juana,Concepción,Biobío,731.2,13331,18.2,626 176 | 8110,Talcahuano,Concepción,Biobío,92.3,171673,1859.9,731 177 | 8111,Tomé,Concepción,Biobío,494.5,55764,112.8,668 178 | 8112,Hualpén,Concepción,Biobío,53.5,86176,1610.8, 179 | 8201,Lebu,Arauco,Biobío,561.4,25790,45.9,633 180 | 8202,Arauco,Arauco,Biobío,956.1,41153,43,704 181 | 8203,Cañete,Arauco,Biobío,1089.2,33535,30.8,641 182 | 8204,Contulmo,Arauco,Biobío,638.8,5188,8.1,603 183 | 8205,Curanilahue,Arauco,Biobío,994.3,33855,31,643 184 | 8206,Los Álamos,Arauco,Biobío,599.1,20723,34.6,645 185 | 8207,Tirúa,Arauco,Biobío,624.4,10859,17.4,584 186 | 8301,Los Ángeles,Biobío,Biobío,1748.2,195813,112,696 187 | 8302,Antuco,Biobío,Biobío,1884.1,3774,2,662 188 | 8303,Cabrero,Biobío,Biobío,639.8,29532,46.2,635 189 | 8304,Laja,Biobío,Biobío,339.8,20964,61.7,665 190 | 8305,Mulchén,Biobío,Biobío,1925.3,28517,14.8,639 191 | 8306,Nacimiento,Biobío,Biobío,934.9,26145,28,656 192 | 8307,Negrete,Biobío,Biobío,156.5,8933,57.1,629 193 | 8308,Quilaco,Biobío,Biobío,1123.7,3722,3.3,635 194 | 8309,Quilleco,Biobío,Biobío,1121.8,10396,9.3,641 195 | 8310,San Rosendo,Biobío,Biobío,92.4,3627,39.3,647 196 | 8311,Santa Bárbara,Biobío,Biobío,1254.9,14612,11.6,637 197 | 8312,Tucapel,Biobío,Biobío,914.9,13442,14.7,655 198 | 8313,Yumbel,Biobío,Biobío,727,20572,28.3,597 199 | 8314,Alto Biobío,Biobío,Biobío,2124.6,10039,4.7, 200 | 9101,Temuco,Cautín,La Araucanía,464,269992,8039,763 201 | 9102,Carahue,Cautín,La Araucanía,1340.6,25718,19.2,604 202 | 9103,Cunco,Cautín,La Araucanía,1906.5,19024,10,659 203 | 9104,Curarrehue,Cautín,La Araucanía,1170.7,7540,6.4,603 204 | 9105,Freire,Cautín,La Araucanía,935.2,27616,29.5,614 205 | 9106,Galvarino,Cautín,La Araucanía,568.2,11324,19.9,611 206 | 9107,Gorbea,Cautín,La Araucanía,694.5,15481,22.3,644 207 | 9108,Lautaro,Cautín,La Araucanía,901.1,35451,39.3,669 208 | 9109,Loncoche,Cautín,La Araucanía,976.8,22191,22.7,652 209 | 9110,Melipeuco,Cautín,La Araucanía,1107.3,5451,4.9,629 210 | 9111,Nueva Imperial,Cautín,La Araucanía,732.5,32109,43.8,629 211 | 9112,Padre Las Casas,Cautín,La Araucanía,400.7,72135,180,662 212 | 9113,Perquenco,Cautín,La Araucanía,330.7,6911,20.9,0.63 213 | 9114,Pitrufquén,Cautín,La Araucanía,580.7,23776,40.9,663 214 | 9115,Pucón,Cautín,La Araucanía,1248.5,29987,24,767 215 | 9116,Saavedra,Cautín,La Araucanía,400.8,13481,33.6,574 216 | 9117,Teodoro Schmidt,Cautín,La Araucanía,649.9,15793,24.3,607 217 | 9118,Toltén,Cautín,La Araucanía,860.4,10403,12.1,617 218 | 9119,Vilcún,Cautín,La Araucanía,1420.9,23823,16.8,643 219 | 9120,Villarrica,Cautín,La Araucanía,1291.1,56178,43.5,698 220 | 9121,Cholchol,Cautín,La Araucanía,427.9,10825,25.3, 221 | 9201,Angol,Malleco,La Araucanía,1194.4,51136,42.8,707 222 | 9202,Collipulli,Malleco,La Araucanía,1295.9,21705,16.7,633 223 | 9203,Curacautín,Malleco,La Araucanía,1664,15728,9.5,657 224 | 9204,Ercilla,Malleco,La Araucanía,499.7,9148,18.3,609 225 | 9205,Lonquimay,Malleco,La Araucanía,3914.2,11341,2.9,629 226 | 9206,Los Sauces,Malleco,La Araucanía,849.8,6490,7.6,602 227 | 9207,Lumaco,Malleco,La Araucanía,1119,10479,9.4,603 228 | 9208,Purén,Malleco,La Araucanía,464.9,11789,25.4,594 229 | 9209,Renaico,Malleco,La Araucanía,267.4,9028,33.8,615 230 | 9210,Traiguén,Malleco,La Araucanía,908,18357,20.2,657 231 | 9211,Victoria,Malleco,La Araucanía,1256,33127,26.4,686 232 | 14101,Valdivia,Valdivia,Los Ríos,1016,163148,138.4,754 233 | 14102,Corral,Valdivia,Los Ríos,767,5084,7.1,658 234 | 14103,Lanco,Valdivia,Los Ríos,532.4,16663,28.4,648 235 | 14104,Los Lagos,Valdivia,Los Ríos,1791.2,18733,11.3,658 236 | 14105,Máfil,Valdivia,Los Ríos,583,7006,12.3,655 237 | 14106,Mariquina,Valdivia,Los Ríos,1320.5,19823,15.1,653 238 | 14107,Paillaco,Valdivia,Los Ríos,896,19898,22,647 239 | 14108,Panguipulli,Valdivia,Los Ríos,3292,35185,10.1,627 240 | 14201,La Unión,Ranco,Los Ríos,2137,38544,18.4,687 241 | 14202,Futrono,Ranco,Los Ríos,2267.5,15811,6.6,637 242 | 14203,Lago Ranco,Ranco,Los Ríos,1763.3,9380,5.7,606 243 | 14204,Río Bueno,Ranco,Los Ríos,2211.7,31343,15.5,624 244 | 10101,Puerto Montt,Llanquihue,Los Lagos,1673,248945,142.5,718 245 | 10102,Calbuco,Llanquihue,Los Lagos,590.8,34902,59.1,642 246 | 10103,Cochamó,Llanquihue,Los Lagos,3910.8,4326,1.1,0.69 247 | 10104,Fresia,Llanquihue,Los Lagos,1278.1,12454,9.7,657 248 | 10105,Frutillar,Llanquihue,Los Lagos,831.4,17756,21.4,669 249 | 10106,Los Muermos,Llanquihue,Los Lagos,1245.8,16522,13.3,648 250 | 10107,Llanquihue,Llanquihue,Los Lagos,420.8,18151,43.1,695 251 | 10108,Maullín,Llanquihue,Los Lagos,860.8,13914,16.2,691 252 | 10109,Puerto Varas,Llanquihue,Los Lagos,4064.9,39414,9.7,748 253 | 10201,Castro,Chiloé,Los Lagos,472.5,50764,107.4,0.72 254 | 10202,Ancud,Chiloé,Los Lagos,1752.4,41960,23.9,705 255 | 10203,Chonchi,Chiloé,Los Lagos,1362.1,14639,10.7,641 256 | 10204,Curaco de Vélez,Chiloé,Los Lagos,80,3884,48.6,702 257 | 10205,Dalcahue,Chiloé,Los Lagos,1239.4,14548,11.7,0.69 258 | 10206,Puqueldón,Chiloé,Los Lagos,97.3,4097,42.1,628 259 | 10207,Queilén,Chiloé,Los Lagos,332.9,5319,16,646 260 | 10208,Quellón,Chiloé,Los Lagos,3244,30964,9.5,0.67 261 | 10209,Quemchi,Chiloé,Los Lagos,440.3,9191,20.9,656 262 | 10210,Quinchao,Chiloé,Los Lagos,160.7,9043,56.3,648 263 | 10301,Osorno,Osorno,Los Lagos,951,153797,152.9,0.7 264 | 10302,Puerto Octay,Osorno,Los Lagos,1795.7,9480,5.3,679 265 | 10303,Purranque,Osorno,Los Lagos,1458.8,20768,14.2,627 266 | 10304,Puyehue,Osorno,Los Lagos,1597.9,11370,7.1,675 267 | 10305,Río Negro,Osorno,Los Lagos,1265.7,13425,10.6,633 268 | 10306,San Juan de la Costa,Osorno,Los Lagos,1517,7997,5.3,0.51 269 | 10307,San Pablo,Osorno,Los Lagos,637.3,9150,14.4,625 270 | 10401,Chaitén,Palena,Los Lagos,8470.5,7122,0.8,704 271 | 10402,Futaleufú,Palena,Los Lagos,1280,1836,1.4,665 272 | 10403,Hualaihué,Palena,Los Lagos,2787.7,8426,3,659 273 | 10404,Palena,Palena,Los Lagos,2763.7,1665,0.6,667 274 | 11101,Coyhaique,Coyhaique,Aysén del Gral. C. Ibáñez del Campo,7290.2,59221,6.8,751 275 | 11102,Lago Verde,Coyhaique,Aysén del Gral. C. Ibáñez del Campo,5422.3,925,0.2,637 276 | 11201,Aysén,Aysén,Aysén del Gral. C. Ibáñez del Campo,29796.4,27187,0.9,674 277 | 11202,Cisnes,Aysén,Aysén del Gral. C. Ibáñez del Campo,16093,6166,0.3,725 278 | 11203,Guaitecas,Aysén,Aysén del Gral. C. Ibáñez del Campo,620.6,1862,2.4,654 279 | 11301,Cochrane,Capitán Prat,Aysén del Gral. C. Ibáñez del Campo,8599.5,2759,0.3,668 280 | 11302,O'Higgins,Capitán Prat,Aysén del Gral. C. Ibáñez del Campo,8182.5,700,0.1,572 281 | 11303,Tortel,Capitán Prat,Aysén del Gral. C. Ibáñez del Campo,19710.6,531,0,655 282 | 11401,Chile Chico,General Carrera,Aysén del Gral. C. Ibáñez del Campo,5737.1,5334,0.8,707 283 | 11402,Río Ibáñez,General Carrera,Aysén del Gral. C. Ibáñez del Campo,5997.2,2208,0.4,654 284 | 12101,Punta Arenas,Magallanes,Magallanes y Antártica Chilena,17846.3,125483,6.8,748 285 | 12102,Laguna Blanca,Magallanes,Magallanes y Antártica Chilena,3695.6,631,0,785 286 | 12103,Río Verde,Magallanes,Magallanes y Antártica Chilena,17248,363,0,784 287 | 12104,San Gregorio,Magallanes,Magallanes y Antártica Chilena,6883.7,731,0.1,823 288 | 12201,Cabo de Hornos,Antártica Chilena,Magallanes y Antártica Chilena,15578.7,1677,0.1,806 289 | 12202,Antártica,Antártica Chilena,Magallanes y Antártica Chilena,1250257.6,127,0, 290 | 12301,Porvenir,Tierra del Fuego,Magallanes y Antártica Chilena,9707.4,5650,0.8,731 291 | 12302,Primavera,Tierra del Fuego,Magallanes y Antártica Chilena,4253.4,803,0.2,774 292 | 12303,Timaukel,Tierra del Fuego,Magallanes y Antártica Chilena,10758.9,873,0.1,717 293 | 12401,Natales,Última Esperanza,Magallanes y Antártica Chilena,49924.1,21327,0.4,699 294 | 12402,Torres del Paine,Última Esperanza,Magallanes y Antártica Chilena,6630,1163,0.1,0.73 295 | 13101,Santiago,Santiago,Metropolitana de Santiago,22,237369,8654.8,807 296 | 13102,Cerrillos,Santiago,Metropolitana de Santiago,21,79195,3422.1,743 297 | 13103,Cerro Navia,Santiago,Metropolitana de Santiago,11,128090,13361.4,683 298 | 13104,Conchalí,Santiago,Metropolitana de Santiago,10.7,121118,11229,707 299 | 13105,El Bosque,Santiago,Metropolitana de Santiago,14.2,162671,12365,711 300 | 13106,Estación Central,Santiago,Metropolitana de Santiago,15,119292,8601.5,735 301 | 13107,Huechuraba,Santiago,Metropolitana de Santiago,44.8,87667,1886.6,737 302 | 13108,Independencia,Santiago,Metropolitana de Santiago,7,73874,9354.1,709 303 | 13109,La Cisterna,Santiago,Metropolitana de Santiago,10,80910,8511.8,775 304 | 13110,La Florida,Santiago,Metropolitana de Santiago,70.2,397497,5209,804 305 | 13111,La Granja,Santiago,Metropolitana de Santiago,10,121214,13252,689 306 | 13112,La Pintana,Santiago,Metropolitana de Santiago,30.6,202146,8511.8,679 307 | 13113,La Reina,Santiago,Metropolitana de Santiago,23,91927,9618.3,883 308 | 13114,Las Condes,Santiago,Metropolitana de Santiago,99,289949,2524.2,933 309 | 13115,Lo Barnechea,Santiago,Metropolitana de Santiago,1024,97230,73,912 310 | 13116,Lo Espejo,Santiago,Metropolitana de Santiago,7,99527,15667,657 311 | 13117,Lo Prado,Santiago,Metropolitana de Santiago,7,94766,13100.4,715 312 | 13118,Macul,Santiago,Metropolitana de Santiago,12.9,111436,8656.5,806 313 | 13119,Maipú,Santiago,Metropolitana de Santiago,135.5,805000,3876.2,902 314 | 13120,Ñuñoa,Santiago,Metropolitana de Santiago,16.9,195410,8937.5,0.86 315 | 13121,Pedro Aguirre Cerda,Santiago,Metropolitana de Santiago,10,104018,11456,708 316 | 13122,Peñalolén,Santiago,Metropolitana de Santiago,54,249621,4001.1,743 317 | 13123,Providencia,Santiago,Metropolitana de Santiago,14.3,126487,8429.1,911 318 | 13124,Pudahuel,Santiago,Metropolitana de Santiago,197,225509,993.7,735 319 | 13125,Quilicura,Santiago,Metropolitana de Santiago,58,203946,3486.6,782 320 | 13126,Quinta Normal,Santiago,Metropolitana de Santiago,13,101737,8388,723 321 | 13127,Recoleta,Santiago,Metropolitana de Santiago,16,152985,9273.8,697 322 | 13128,Renca,Santiago,Metropolitana de Santiago,24,142136,8388.1,709 323 | 13129,San Joaquín,Santiago,Metropolitana de Santiago,9.7,94255,10064.4,719 324 | 13130,San Miguel,Santiago,Metropolitana de Santiago,10.0,90846,7787.2,765 325 | 13131,San Ramón,Santiago,Metropolitana de Santiago,7,85195,14600.9,679 326 | 13132,Vitacura,Santiago,Metropolitana de Santiago,28.3,84195,2910.7,949 327 | 13201,Puente Alto,Cordillera,Metropolitana de Santiago,88,757721,6664.8,773 328 | 13202,Pirque,Cordillera,Metropolitana de Santiago,445.3,20732,37.2,807 329 | 13203,San José de Maipo,Cordillera,Metropolitana de Santiago,4994.8,14455,0.3,759 330 | 13301,Colina,Chacabuco,Metropolitana de Santiago,971.2,113340,80.1,726 331 | 13302,Lampa,Chacabuco,Metropolitana de Santiago,452,79421,89.9,697 332 | 13303,Til Til,Chacabuco,Metropolitana de Santiago,653,16405,22.6,706 333 | 13401,San Bernardo,Maipo,Metropolitana de Santiago,155,277802,1974,712 334 | 13402,Buin,Maipo,Metropolitana de Santiago,214,74232,296.2,731 335 | 13403,Calera de Tango,Maipo,Metropolitana de Santiago,73.3,27781,782.6,792 336 | 13404,Paine,Maipo,Metropolitana de Santiago,820,6612,73.7,718 337 | 13501,Melipilla,Melipilla,Metropolitana de Santiago,1345,107698,70.3,735 338 | 13502,Alhué,Melipilla,Metropolitana de Santiago,845,4646,5.2,0.7 339 | 13503,Curacaví,Melipilla,Metropolitana de Santiago,693,28439,35.1,0.71 340 | 13504,María Pinto,Melipilla,Metropolitana de Santiago,393.5,12501,115.6,698 341 | 13505,San Pedro,Melipilla,Metropolitana de Santiago,788,8062,9.6,701 342 | 13601,Talagante,Talagante,Metropolitana de Santiago,126,78887,474.6,749 343 | 13602,El Monte,Talagante,Metropolitana de Santiago,118,32468,224.2,688 344 | 13603,Isla de Maipo,Talagante,Metropolitana de Santiago,189,33723,136.5,724 345 | 13604,Padre Hurtado,Talagante,Metropolitana de Santiago,80.8,50696,626.2,728 346 | 13605,Peñaflor,Talagante,Metropolitana de Santiago,69,87741,965.5,753 -------------------------------------------------------------------------------- /Ayudantías/AyudantiaAPI/release/Pipfile.lock: -------------------------------------------------------------------------------- 1 | { 2 | "_meta": { 3 | "hash": { 4 | "sha256": "96a7498890be7f8162f7bd37d3777436de99599774748f6aa89f307df6885f58" 5 | }, 6 | "pipfile-spec": 6, 7 | "requires": { 8 | "python_version": "3.6" 9 | }, 10 | "sources": [ 11 | { 12 | "name": "pypi", 13 | "url": "https://pypi.org/simple", 14 | "verify_ssl": true 15 | } 16 | ] 17 | }, 18 | "default": { 19 | "autopep8": { 20 | "hashes": [ 21 | "sha256:4d8eec30cc81bc5617dbf1218201d770dc35629363547f17577c61683ccfb3ee" 22 | ], 23 | "index": "pypi", 24 | "version": "==1.4.4" 25 | }, 26 | "click": { 27 | "hashes": [ 28 | "sha256:2335065e6395b9e67ca716de5f7526736bfa6ceead690adf616d925bdc622b13", 29 | "sha256:5b94b49521f6456670fdb30cd82a4eca9412788a93fa6dd6df72c94d5a8ff2d7" 30 | ], 31 | "version": "==7.0" 32 | }, 33 | "cycler": { 34 | "hashes": [ 35 | "sha256:1d8a5ae1ff6c5cf9b93e8811e581232ad8920aeec647c37316ceac982b08cb2d", 36 | "sha256:cd7b2d1018258d7247a71425e9f26463dfb444d411c39569972f4ce586b0c9d8" 37 | ], 38 | "version": "==0.10.0" 39 | }, 40 | "flask": { 41 | "hashes": [ 42 | "sha256:ad7c6d841e64296b962296c2c2dabc6543752985727af86a975072dea984b6f3", 43 | "sha256:e7d32475d1de5facaa55e3958bc4ec66d3762076b074296aa50ef8fdc5b9df61" 44 | ], 45 | "index": "pypi", 46 | "version": "==1.0.3" 47 | }, 48 | "gunicorn": { 49 | "hashes": [ 50 | "sha256:aa8e0b40b4157b36a5df5e599f45c9c76d6af43845ba3b3b0efe2c70473c2471", 51 | "sha256:fa2662097c66f920f53f70621c6c58ca4a3c4d3434205e608e121b5b3b71f4f3" 52 | ], 53 | "index": "pypi", 54 | "version": "==19.9.0" 55 | }, 56 | "itsdangerous": { 57 | "hashes": [ 58 | "sha256:321b033d07f2a4136d3ec762eac9f16a10ccd60f53c0c91af90217ace7ba1f19", 59 | "sha256:b12271b2047cb23eeb98c8b5622e2e5c5e9abd9784a153e9d8ef9cb4dd09d749" 60 | ], 61 | "version": "==1.1.0" 62 | }, 63 | "jinja2": { 64 | "hashes": [ 65 | "sha256:065c4f02ebe7f7cf559e49ee5a95fb800a9e4528727aec6f24402a5374c65013", 66 | "sha256:14dd6caf1527abb21f08f86c784eac40853ba93edb79552aa1e4b8aef1b61c7b" 67 | ], 68 | "index": "pypi", 69 | "version": "==2.10.1" 70 | }, 71 | "kiwisolver": { 72 | "hashes": [ 73 | "sha256:05b5b061e09f60f56244adc885c4a7867da25ca387376b02c1efc29cc16bcd0f", 74 | "sha256:26f4fbd6f5e1dabff70a9ba0d2c4bd30761086454aa30dddc5b52764ee4852b7", 75 | "sha256:3b2378ad387f49cbb328205bda569b9f87288d6bc1bf4cd683c34523a2341efe", 76 | "sha256:400599c0fe58d21522cae0e8b22318e09d9729451b17ee61ba8e1e7c0346565c", 77 | "sha256:47b8cb81a7d18dbaf4fed6a61c3cecdb5adec7b4ac292bddb0d016d57e8507d5", 78 | "sha256:53eaed412477c836e1b9522c19858a8557d6e595077830146182225613b11a75", 79 | "sha256:58e626e1f7dfbb620d08d457325a4cdac65d1809680009f46bf41eaf74ad0187", 80 | "sha256:5a52e1b006bfa5be04fe4debbcdd2688432a9af4b207a3f429c74ad625022641", 81 | "sha256:5c7ca4e449ac9f99b3b9d4693debb1d6d237d1542dd6a56b3305fe8a9620f883", 82 | "sha256:682e54f0ce8f45981878756d7203fd01e188cc6c8b2c5e2cf03675390b4534d5", 83 | "sha256:79bfb2f0bd7cbf9ea256612c9523367e5ec51d7cd616ae20ca2c90f575d839a2", 84 | "sha256:7f4dd50874177d2bb060d74769210f3bce1af87a8c7cf5b37d032ebf94f0aca3", 85 | "sha256:8944a16020c07b682df861207b7e0efcd2f46c7488619cb55f65882279119389", 86 | "sha256:8aa7009437640beb2768bfd06da049bad0df85f47ff18426261acecd1cf00897", 87 | "sha256:939f36f21a8c571686eb491acfffa9c7f1ac345087281b412d63ea39ca14ec4a", 88 | "sha256:9733b7f64bd9f807832d673355f79703f81f0b3e52bfce420fc00d8cb28c6a6c", 89 | "sha256:a02f6c3e229d0b7220bd74600e9351e18bc0c361b05f29adae0d10599ae0e326", 90 | "sha256:a0c0a9f06872330d0dd31b45607197caab3c22777600e88031bfe66799e70bb0", 91 | "sha256:acc4df99308111585121db217681f1ce0eecb48d3a828a2f9bbf9773f4937e9e", 92 | "sha256:b64916959e4ae0ac78af7c3e8cef4becee0c0e9694ad477b4c6b3a536de6a544", 93 | "sha256:d3fcf0819dc3fea58be1fd1ca390851bdb719a549850e708ed858503ff25d995", 94 | "sha256:d52e3b1868a4e8fd18b5cb15055c76820df514e26aa84cc02f593d99fef6707f", 95 | "sha256:db1a5d3cc4ae943d674718d6c47d2d82488ddd94b93b9e12d24aabdbfe48caee", 96 | "sha256:e3a21a720791712ed721c7b95d433e036134de6f18c77dbe96119eaf7aa08004", 97 | "sha256:e8bf074363ce2babeb4764d94f8e65efd22e6a7c74860a4f05a6947afc020ff2", 98 | "sha256:f16814a4a96dc04bf1da7d53ee8d5b1d6decfc1a92a63349bb15d37b6a263dd9", 99 | "sha256:f2b22153870ca5cf2ab9c940d7bc38e8e9089fa0f7e5856ea195e1cf4ff43d5a", 100 | "sha256:f790f8b3dff3d53453de6a7b7ddd173d2e020fb160baff578d578065b108a05f" 101 | ], 102 | "version": "==1.1.0" 103 | }, 104 | "markupsafe": { 105 | "hashes": [ 106 | "sha256:00bc623926325b26bb9605ae9eae8a215691f33cae5df11ca5424f06f2d1f473", 107 | "sha256:09027a7803a62ca78792ad89403b1b7a73a01c8cb65909cd876f7fcebd79b161", 108 | "sha256:09c4b7f37d6c648cb13f9230d847adf22f8171b1ccc4d5682398e77f40309235", 109 | "sha256:1027c282dad077d0bae18be6794e6b6b8c91d58ed8a8d89a89d59693b9131db5", 110 | "sha256:24982cc2533820871eba85ba648cd53d8623687ff11cbb805be4ff7b4c971aff", 111 | "sha256:29872e92839765e546828bb7754a68c418d927cd064fd4708fab9fe9c8bb116b", 112 | "sha256:43a55c2930bbc139570ac2452adf3d70cdbb3cfe5912c71cdce1c2c6bbd9c5d1", 113 | "sha256:46c99d2de99945ec5cb54f23c8cd5689f6d7177305ebff350a58ce5f8de1669e", 114 | "sha256:500d4957e52ddc3351cabf489e79c91c17f6e0899158447047588650b5e69183", 115 | "sha256:535f6fc4d397c1563d08b88e485c3496cf5784e927af890fb3c3aac7f933ec66", 116 | "sha256:62fe6c95e3ec8a7fad637b7f3d372c15ec1caa01ab47926cfdf7a75b40e0eac1", 117 | "sha256:6dd73240d2af64df90aa7c4e7481e23825ea70af4b4922f8ede5b9e35f78a3b1", 118 | "sha256:717ba8fe3ae9cc0006d7c451f0bb265ee07739daf76355d06366154ee68d221e", 119 | "sha256:79855e1c5b8da654cf486b830bd42c06e8780cea587384cf6545b7d9ac013a0b", 120 | "sha256:7c1699dfe0cf8ff607dbdcc1e9b9af1755371f92a68f706051cc8c37d447c905", 121 | "sha256:88e5fcfb52ee7b911e8bb6d6aa2fd21fbecc674eadd44118a9cc3863f938e735", 122 | "sha256:8defac2f2ccd6805ebf65f5eeb132adcf2ab57aa11fdf4c0dd5169a004710e7d", 123 | "sha256:98c7086708b163d425c67c7a91bad6e466bb99d797aa64f965e9d25c12111a5e", 124 | "sha256:9add70b36c5666a2ed02b43b335fe19002ee5235efd4b8a89bfcf9005bebac0d", 125 | "sha256:9bf40443012702a1d2070043cb6291650a0841ece432556f784f004937f0f32c", 126 | "sha256:ade5e387d2ad0d7ebf59146cc00c8044acbd863725f887353a10df825fc8ae21", 127 | "sha256:b00c1de48212e4cc9603895652c5c410df699856a2853135b3967591e4beebc2", 128 | "sha256:b1282f8c00509d99fef04d8ba936b156d419be841854fe901d8ae224c59f0be5", 129 | "sha256:b2051432115498d3562c084a49bba65d97cf251f5a331c64a12ee7e04dacc51b", 130 | "sha256:ba59edeaa2fc6114428f1637ffff42da1e311e29382d81b339c1817d37ec93c6", 131 | "sha256:c8716a48d94b06bb3b2524c2b77e055fb313aeb4ea620c8dd03a105574ba704f", 132 | "sha256:cd5df75523866410809ca100dc9681e301e3c27567cf498077e8551b6d20e42f", 133 | "sha256:e249096428b3ae81b08327a63a485ad0878de3fb939049038579ac0ef61e17e7" 134 | ], 135 | "version": "==1.1.1" 136 | }, 137 | "matplotlib": { 138 | "hashes": [ 139 | "sha256:08d9bc2e2acef42965256acd5015dc2c899cbd53e01bf4214c5510c7ea0efd2d", 140 | "sha256:1e0213f87cc0076f7b0c4c251d7e23601e2419cd98691df79edb95517ba06f0c", 141 | "sha256:1f31053f660df5f0310118d7f5bd1e8025170e9773f0bebe8fec486d0926adf6", 142 | "sha256:399bf6352633aeeb45ca55c6c943fa2738022fb17ae498c32a142ced0b41528d", 143 | "sha256:409a5894efb810d630d2512449c7a4394de9a4d15fc6394e26a409b17d9cc18c", 144 | "sha256:5c5ef5cf1bc8f483123102e2615644937af7d4c01d100acc72bf74a044a78717", 145 | "sha256:d0052be5cdfa27018bb08194b8812c47cb985d60eb682e1809c76e9600839516", 146 | "sha256:e7d6620d145ca9f6c3e88248e5734b6fda430e75e70755b887e48f8e9bc1de2a", 147 | "sha256:f3d8b6bccc577e4e5ecbd58fdd63cacb8e58f0ed1e97616a7f7a7baaf4b8d036" 148 | ], 149 | "index": "pypi", 150 | "version": "==3.1.0" 151 | }, 152 | "numpy": { 153 | "hashes": [ 154 | "sha256:0e2eed77804b2a6a88741f8fcac02c5499bba3953ec9c71e8b217fad4912c56c", 155 | "sha256:1c666f04553ef70fda54adf097dbae7080645435fc273e2397f26bbf1d127bbb", 156 | "sha256:1f46532afa7b2903bfb1b79becca2954c0a04389d19e03dc73f06b039048ac40", 157 | "sha256:315fa1b1dfc16ae0f03f8fd1c55f23fd15368710f641d570236f3d78af55e340", 158 | "sha256:3d5fcea4f5ed40c3280791d54da3ad2ecf896f4c87c877b113576b8280c59441", 159 | "sha256:48241759b99d60aba63b0e590332c600fc4b46ad597c9b0a53f350b871ef0634", 160 | "sha256:4b4f2924b36d857cf302aec369caac61e43500c17eeef0d7baacad1084c0ee84", 161 | "sha256:54fe3b7ed9e7eb928bbc4318f954d133851865f062fa4bbb02ef8940bc67b5d2", 162 | "sha256:5a8f021c70e6206c317974c93eaaf9bc2b56295b6b1cacccf88846e44a1f33fc", 163 | "sha256:754a6be26d938e6ca91942804eb209307b73f806a1721176278a6038869a1686", 164 | "sha256:771147e654e8b95eea1293174a94f34e2e77d5729ad44aefb62fbf8a79747a15", 165 | "sha256:78a6f89da87eeb48014ec652a65c4ffde370c036d780a995edaeb121d3625621", 166 | "sha256:7fde5c2a3a682a9e101e61d97696687ebdba47637611378b4127fe7e47fdf2bf", 167 | "sha256:80d99399c97f646e873dd8ce87c38cfdbb668956bbc39bc1e6cac4b515bba2a0", 168 | "sha256:88a72c1e45a0ae24d1f249a529d9f71fe82e6fa6a3fd61414b829396ec585900", 169 | "sha256:a4f4460877a16ac73302a9c077ca545498d9fe64e6a81398d8e1a67e4695e3df", 170 | "sha256:a61255a765b3ac73ee4b110b28fccfbf758c985677f526c2b4b39c48cc4b509d", 171 | "sha256:ab4896a8c910b9a04c0142871d8800c76c8a2e5ff44763513e1dd9d9631ce897", 172 | "sha256:abbd6b1c2ef6199f4b7ca9f818eb6b31f17b73a6110aadc4e4298c3f00fab24e", 173 | "sha256:b16d88da290334e33ea992c56492326ea3b06233a00a1855414360b77ca72f26", 174 | "sha256:b78a1defedb0e8f6ae1eb55fa6ac74ab42acc4569c3a2eacc2a407ee5d42ebcb", 175 | "sha256:cfef82c43b8b29ca436560d51b2251d5117818a8d1fb74a8384a83c096745dad", 176 | "sha256:d160e57731fcdec2beda807ebcabf39823c47e9409485b5a3a1db3a8c6ce763e" 177 | ], 178 | "index": "pypi", 179 | "version": "==1.16.3" 180 | }, 181 | "pandas": { 182 | "hashes": [ 183 | "sha256:071e42b89b57baa17031af8c6b6bbd2e9a5c68c595bc6bf9adabd7a9ed125d3b", 184 | "sha256:17450e25ae69e2e6b303817bdf26b2cd57f69595d8550a77c308be0cd0fd58fa", 185 | "sha256:17916d818592c9ec891cbef2e90f98cc85e0f1e89ed0924c9b5220dc3209c846", 186 | "sha256:2538f099ab0e9f9c9d09bbcd94b47fd889bad06dc7ae96b1ed583f1dc1a7a822", 187 | "sha256:366f30710172cb45a6b4f43b66c220653b1ea50303fbbd94e50571637ffb9167", 188 | "sha256:42e5ad741a0d09232efbc7fc648226ed93306551772fc8aecc6dce9f0e676794", 189 | "sha256:4e718e7f395ba5bfe8b6f6aaf2ff1c65a09bb77a36af6394621434e7cc813204", 190 | "sha256:4f919f409c433577a501e023943e582c57355d50a724c589e78bc1d551a535a2", 191 | "sha256:4fe0d7e6438212e839fc5010c78b822664f1a824c0d263fd858f44131d9166e2", 192 | "sha256:5149a6db3e74f23dc3f5a216c2c9ae2e12920aa2d4a5b77e44e5b804a5f93248", 193 | "sha256:627594338d6dd995cfc0bacd8e654cd9e1252d2a7c959449228df6740d737eb8", 194 | "sha256:83c702615052f2a0a7fb1dd289726e29ec87a27272d775cb77affe749cca28f8", 195 | "sha256:8c872f7fdf3018b7891e1e3e86c55b190e6c5cee70cab771e8f246c855001296", 196 | "sha256:90f116086063934afd51e61a802a943826d2aac572b2f7d55caaac51c13db5b5", 197 | "sha256:a3352bacac12e1fc646213b998bce586f965c9d431773d9e91db27c7c48a1f7d", 198 | "sha256:bcdd06007cca02d51350f96debe51331dec429ac8f93930a43eb8fb5639e3eb5", 199 | "sha256:c1bd07ebc15285535f61ddd8c0c75d0d6293e80e1ee6d9a8d73f3f36954342d0", 200 | "sha256:c9a4b7c55115eb278c19aa14b34fcf5920c8fe7797a09b7b053ddd6195ea89b3", 201 | "sha256:cc8fc0c7a8d5951dc738f1c1447f71c43734244453616f32b8aa0ef6013a5dfb", 202 | "sha256:d7b460bc316064540ce0c41c1438c416a40746fd8a4fb2999668bf18f3c4acf1" 203 | ], 204 | "index": "pypi", 205 | "version": "==0.24.2" 206 | }, 207 | "pycodestyle": { 208 | "hashes": [ 209 | "sha256:95a2219d12372f05704562a14ec30bc76b05a5b297b21a5dfe3f6fac3491ae56", 210 | "sha256:e40a936c9a450ad81df37f549d676d127b1b66000a6c500caa2b085bc0ca976c" 211 | ], 212 | "version": "==2.5.0" 213 | }, 214 | "pymongo": { 215 | "hashes": [ 216 | "sha256:32421df60d06f479d71b6b539642e410ece3006e8910688e68df962c8eb40a21", 217 | "sha256:324b22a8443e11faca44c96b20e7ec8a9e59a1e664457edeeb4f796080b31cde", 218 | "sha256:4505ff8b7923dd7a8bed1bf25c9c4d0df5ab0b8b2821f2296533f2149a55f401", 219 | "sha256:460b224681ea711e48e3638d15be2249024031b7dcb9622ba19c2e85bd5a26cc", 220 | "sha256:47473b70c5f3cd5ddd2c49ab3b9ceafdafbbed5bc963f147df22a9343d7978f5", 221 | "sha256:49375839af76834e9c5c3cc78c78386873fd0b2ad9a0860a7dc4ec9fe73af9dd", 222 | "sha256:4a65f0f71ece86c860d30a1436b646db8ea32aec518845ef2903ca569faec32e", 223 | "sha256:530621906c5dd6d27305b39c4e017701e5f4299aa68b93cde70eb985f94ca26f", 224 | "sha256:54f4770b5810e8dc3cbeed675874195f02bb2bc4e95a9d665068edfb3baff4f7", 225 | "sha256:5ed9382410e938b0ff76041c34018210504729a83bcf4f6a70c7092c28169f6f", 226 | "sha256:61cad83637ae12c1c825130d7f9325cd6c162e3a64e8747a8144866020be3ff4", 227 | "sha256:61e8e1c58b4fdf47ab79b7c7db8bb022c1e40b3b5fcbbaeea5fc94dc5c75638d", 228 | "sha256:6e04e496af7d156b66cce70460011c621ecbadf5dcdce325c7acbb3cd6ea245d", 229 | "sha256:7ef89ec435e89da902451dde6845066fe2770befaf0301fe2a1ac426b51fced3", 230 | "sha256:854e8425e5eb775ccfffad04ecd094c99923d60a2c2d49babb5c435e836a91fa", 231 | "sha256:9569796d48498e4db4e1d56284b626a8ed15f641ce3a8b2085f06bb03f4c2c88", 232 | "sha256:9d50c99c6388863cbfdc5db9bad62e3a7c2e5fc151554a07c7f3c2530334a34f", 233 | "sha256:9ea016c2c011df21f77c1f806ce45129a344ba2d414bd50f9e065b13a4a134be", 234 | "sha256:a8421f0823174888fb12a5fa675322e756499d71e77ff712b4412d4b8f3c6503", 235 | "sha256:aef7d88384ada699976350a285c7a333f96ebc959e98e7d2c98589f47bbf3b7f", 236 | "sha256:b4d7ff9957ee770cf03bd7156a68a2f2e838e60712d9608eadc8741c15d01e72", 237 | "sha256:c1db85c39e6a60588f855dbc7bd68fb0dab796096148ab5aa4abecaff19e1c6e", 238 | "sha256:cee2fc0b94e66e7230da12fc4b3d34793c49957e16ee04f6468a94e264a1e41d", 239 | "sha256:cf1dea28379a16b23e47db312883f07b3ba8d9d6abc1c59e51d4c8ae1820ab43", 240 | "sha256:d1cd175df7c8b5fc976bade78bf4d9fb5aa7ab465c0f59931e380bbe188ef8fc", 241 | "sha256:d48a94edf3cdd34524936a72ea01b352682b337f33a42db10ba29a96c37147d3", 242 | "sha256:d9cc103a4e97f78bc77a1d72759ab3722f6cdf0374ad4fb4b0c53bd3238bdf98", 243 | "sha256:fcb9ae8aa9158106c5d98a4349ec0d90b68f052d620b2d24622ba03b91e4d81d" 244 | ], 245 | "index": "pypi", 246 | "version": "==3.8.0" 247 | }, 248 | "pyparsing": { 249 | "hashes": [ 250 | "sha256:1873c03321fc118f4e9746baf201ff990ceb915f433f23b395f5580d1840cb2a", 251 | "sha256:9b6323ef4ab914af344ba97510e966d64ba91055d6b9afa6b30799340e89cc03" 252 | ], 253 | "version": "==2.4.0" 254 | }, 255 | "python-dateutil": { 256 | "hashes": [ 257 | "sha256:7e6584c74aeed623791615e26efd690f29817a27c73085b78e4bad02493df2fb", 258 | "sha256:c89805f6f4d64db21ed966fda138f8a5ed7a4fdbc1a8ee329ce1b74e3c74da9e" 259 | ], 260 | "version": "==2.8.0" 261 | }, 262 | "pytz": { 263 | "hashes": [ 264 | "sha256:303879e36b721603cc54604edcac9d20401bdbe31e1e4fdee5b9f98d5d31dfda", 265 | "sha256:d747dd3d23d77ef44c6a3526e274af6efeb0a6f1afd5a69ba4d5be4098c8e141" 266 | ], 267 | "version": "==2019.1" 268 | }, 269 | "six": { 270 | "hashes": [ 271 | "sha256:3350809f0555b11f552448330d0b52d5f24c91a322ea4a15ef22629740f3761c", 272 | "sha256:d16a0141ec1a18405cd4ce8b4613101da75da0e9a7aec5bdd4fa804d0e0eba73" 273 | ], 274 | "version": "==1.12.0" 275 | }, 276 | "werkzeug": { 277 | "hashes": [ 278 | "sha256:865856ebb55c4dcd0630cdd8f3331a1847a819dda7e8c750d3db6f2aa6c0209c", 279 | "sha256:a0b915f0815982fb2a09161cb8f31708052d0951c3ba433ccc5e1aa276507ca6" 280 | ], 281 | "version": "==0.15.4" 282 | } 283 | }, 284 | "develop": { 285 | "entrypoints": { 286 | "hashes": [ 287 | "sha256:589f874b313739ad35be6e0cd7efde2a4e9b6fea91edcc34e58ecbb8dbe56d19", 288 | "sha256:c70dd71abe5a8c85e55e12c19bd91ccfeec11a6e99044204511f9ed547d48451" 289 | ], 290 | "version": "==0.3" 291 | }, 292 | "flake8": { 293 | "hashes": [ 294 | "sha256:859996073f341f2670741b51ec1e67a01da142831aa1fdc6242dbf88dffbe661", 295 | "sha256:a796a115208f5c03b18f332f7c11729812c8c3ded6c46319c59b53efd3819da8" 296 | ], 297 | "index": "pypi", 298 | "version": "==3.7.7" 299 | }, 300 | "mccabe": { 301 | "hashes": [ 302 | "sha256:ab8a6258860da4b6677da4bd2fe5dc2c659cff31b3ee4f7f5d64e79735b80d42", 303 | "sha256:dd8d182285a0fe56bace7f45b5e7d1a6ebcbf524e8f3bd87eb0f125271b8831f" 304 | ], 305 | "version": "==0.6.1" 306 | }, 307 | "mypy": { 308 | "hashes": [ 309 | "sha256:2afe51527b1f6cdc4a5f34fc90473109b22bf7f21086ba3e9451857cf11489e6", 310 | "sha256:56a16df3e0abb145d8accd5dbb70eba6c4bd26e2f89042b491faa78c9635d1e2", 311 | "sha256:5764f10d27b2e93c84f70af5778941b8f4aa1379b2430f85c827e0f5464e8714", 312 | "sha256:5bbc86374f04a3aa817622f98e40375ccb28c4836f36b66706cf3c6ccce86eda", 313 | "sha256:6a9343089f6377e71e20ca734cd8e7ac25d36478a9df580efabfe9059819bf82", 314 | "sha256:6c9851bc4a23dc1d854d3f5dfd5f20a016f8da86bcdbb42687879bb5f86434b0", 315 | "sha256:b8e85956af3fcf043d6f87c91cbe8705073fc67029ba6e22d3468bfee42c4823", 316 | "sha256:b9a0af8fae490306bc112229000aa0c2ccc837b49d29a5c42e088c132a2334dd", 317 | "sha256:bbf643528e2a55df2c1587008d6e3bda5c0445f1240dfa85129af22ae16d7a9a", 318 | "sha256:c46ab3438bd21511db0f2c612d89d8344154c0c9494afc7fbc932de514cf8d15", 319 | "sha256:f7a83d6bd805855ef83ec605eb01ab4fa42bcef254b13631e451cbb44914a9b0" 320 | ], 321 | "index": "pypi", 322 | "version": "==0.701" 323 | }, 324 | "mypy-extensions": { 325 | "hashes": [ 326 | "sha256:37e0e956f41369209a3d5f34580150bcacfabaa57b33a15c0b25f4b5725e0812", 327 | "sha256:b16cabe759f55e3409a7d231ebd2841378fb0c27a5d1994719e340e4f429ac3e" 328 | ], 329 | "version": "==0.4.1" 330 | }, 331 | "pycodestyle": { 332 | "hashes": [ 333 | "sha256:95a2219d12372f05704562a14ec30bc76b05a5b297b21a5dfe3f6fac3491ae56", 334 | "sha256:e40a936c9a450ad81df37f549d676d127b1b66000a6c500caa2b085bc0ca976c" 335 | ], 336 | "version": "==2.5.0" 337 | }, 338 | "pyflakes": { 339 | "hashes": [ 340 | "sha256:17dbeb2e3f4d772725c777fabc446d5634d1038f234e77343108ce445ea69ce0", 341 | "sha256:d976835886f8c5b31d47970ed689944a0262b5f3afa00a5a7b4dc81e5449f8a2" 342 | ], 343 | "version": "==2.1.1" 344 | }, 345 | "typed-ast": { 346 | "hashes": [ 347 | "sha256:132eae51d6ef3ff4a8c47c393a4ef5ebf0d1aecc96880eb5d6c8ceab7017cc9b", 348 | "sha256:18141c1484ab8784006c839be8b985cfc82a2e9725837b0ecfa0203f71c4e39d", 349 | "sha256:2baf617f5bbbfe73fd8846463f5aeafc912b5ee247f410700245d68525ec584a", 350 | "sha256:3d90063f2cbbe39177e9b4d888e45777012652d6110156845b828908c51ae462", 351 | "sha256:4304b2218b842d610aa1a1d87e1dc9559597969acc62ce717ee4dfeaa44d7eee", 352 | "sha256:4983ede548ffc3541bae49a82675996497348e55bafd1554dc4e4a5d6eda541a", 353 | "sha256:5315f4509c1476718a4825f45a203b82d7fdf2a6f5f0c8f166435975b1c9f7d4", 354 | "sha256:6cdfb1b49d5345f7c2b90d638822d16ba62dc82f7616e9b4caa10b72f3f16649", 355 | "sha256:7b325f12635598c604690efd7a0197d0b94b7d7778498e76e0710cd582fd1c7a", 356 | "sha256:8d3b0e3b8626615826f9a626548057c5275a9733512b137984a68ba1598d3d2f", 357 | "sha256:8f8631160c79f53081bd23446525db0bc4c5616f78d04021e6e434b286493fd7", 358 | "sha256:912de10965f3dc89da23936f1cc4ed60764f712e5fa603a09dd904f88c996760", 359 | "sha256:b010c07b975fe853c65d7bbe9d4ac62f1c69086750a574f6292597763781ba18", 360 | "sha256:c908c10505904c48081a5415a1e295d8403e353e0c14c42b6d67f8f97fae6616", 361 | "sha256:c94dd3807c0c0610f7c76f078119f4ea48235a953512752b9175f9f98f5ae2bd", 362 | "sha256:ce65dee7594a84c466e79d7fb7d3303e7295d16a83c22c7c4037071b059e2c21", 363 | "sha256:eaa9cfcb221a8a4c2889be6f93da141ac777eb8819f077e1d09fb12d00a09a93", 364 | "sha256:f3376bc31bad66d46d44b4e6522c5c21976bf9bca4ef5987bb2bf727f4506cbb", 365 | "sha256:f9202fa138544e13a4ec1a6792c35834250a85958fde1251b6a22e07d1260ae7" 366 | ], 367 | "version": "==1.3.5" 368 | } 369 | } 370 | } 371 | --------------------------------------------------------------------------------