Repasamos lambda¶
Veamos el desafío de la clase anterior¶
Una posible solución:
In [2]:
Copied!
cadena = "casa"
cadena_encriptada = list(map(lambda x: chr(ord(x) + 1), cadena))
cadena_encriptada
cadena = "casa"
cadena_encriptada = list(map(lambda x: chr(ord(x) + 1), cadena))
cadena_encriptada
Out[2]:
['d', 'b', 't', 'b']
¿cadena_encriptada es una cadena? ¿De qué tipo es?
In [4]:
Copied!
cadena_encriptada = "".join(cadena_encriptada)
cadena_encriptada
cadena_encriptada = "".join(cadena_encriptada)
cadena_encriptada
Out[4]:
'd****b****t****b'
Otra forma: función reduce¶
In [5]:
Copied!
from functools import reduce
cadena = ["a", "e", "i"]
vocales = reduce((lambda x, y: x + y), cadena)
vocales
from functools import reduce
cadena = ["a", "e", "i"]
vocales = reduce((lambda x, y: x + y), cadena)
vocales
Out[5]:
'aei'
In [6]:
Copied!
producto = reduce((lambda x, y: x * y), [1, 2, 3, 4])
producto
producto = reduce((lambda x, y: x * y), [1, 2, 3, 4])
producto
Out[6]:
24
Otro ejemplo¶
In [7]:
Copied!
def my_add(a, b):
result = a + b
print(f"{a} + {b} = {result}")
return result
def my_add(a, b):
result = a + b
print(f"{a} + {b} = {result}")
return result
In [8]:
Copied!
my_add(5, 5)
my_add(5, 5)
5 + 5 = 10
Out[8]:
10
In [11]:
Copied!
numbers = [0, 1, 2, 3, 4]
reduce(my_add, numbers)
numbers = [0, 1, 2, 3, 4]
reduce(my_add, numbers)
0 + 1 = 1 1 + 2 = 3 3 + 3 = 6 6 + 4 = 10
Out[11]:
10
Les dejé algo para investigar en el video del fin de semana....¶
¿Cuándo un módulo se denomina __main__?¶
Recordemos con este ejemplo cuál es la situación:¶
#módulo funciones
def uno():
print("uno")
print(f"El nombre de este módulo es {__name__}")
#uno()
#uso_funciones
import funciones
funciones.uno()
El módulo __main__¶
- Las instrucciones ejecutadas en el nivel de llamadas superior del intérprete, ya sea desde un script o interactivamente, se consideran parte del módulo llamado __main__, por lo tanto tienen su propio espacio de nombres global.
#módulo funciones
def uno():
print("uno")
print(f"El nombre de este módulo es {__name__}")
if __name__ == "__main__":
uno()
Veamos este otro ejemplo:¶
# modulo utiles
def vocales(cadena):
print(list(filter(lambda l: l.lower() in "aeiou", cadena)))
# modulo uso_utiles
import utiles
utiles.vocales("Holaaaa!!!!!!")
- Primero: ¿qué hace?
¿Y si queremos invocar el módulo utiles (e invocar a la función vocales) desde la línea de comandos?¿Cómo les pasamos la cadena a analizar?¶
In [12]:
Copied!
import sys
type(sys.argv)
import sys
type(sys.argv)
Out[12]:
list
- ¿De qué tipo es argv?
- ¿Qué valores contiene?
# modulo utiles
def vocales(cadena):
print(list(filter(lambda l: l.lower() in "aeiou", cadena)))
if __name__ == "__main__":
import sys
vocales(sys.argv[1])
Paquetes¶
- Veamos el ejemplo de la documentación oficial de paquetes
import sound.effects.echo
from sound.effects import echo
¿Qué contiene el archivo __init__.py?¶
¿Qué pasa si tenemos la siguiente sentencia?¶
from sound import *
- __all__: es una variable que contiene una lista con los nombres de los módulos que deberían poder importarse cuando se encuentra la sentencia from package import *.
#Por ejemplo, en sound/effects/__init__.py
__all__ = ["echo", "surround", "reverse"]
- Si __all__ no está definida, from sound.effects import * no importa los submódulos dentro del paquete sound.effects al espacio de nombres.
- Ejemplo: analicemos esta librería: console-menu
Pensemos en las siguientes situaciones¶
¿Qué estructura usamos si queremos:
- guardar los puntajes cada vez que jugamos a un juego determinado?,
- tener un banco de preguntas para que cada vez que juguemos al juego de repaso las pueda acotar por temas?,
- manipular los Python Plus de los estudiantes por turnos?.
¿Qué tienen todas estas situaciones en común?
Necesitamos una estructura que permita que los datos puedan persistir cuando la ejecución del programa finalice.¶
Algunas consideraciones antes de empezar¶
- Lo básico: ¿qué es un archivo?
- ¿Cómo podemos manipular los archivos desde un programa Python?
Manejo de archivos¶
- Existen funciones predefinidas.
- Si las operaciones fallan, se levanta una excepción.
- Los archivos se manejan como objetos que se crean usando la función open.
- Tarea para el hogar. Investigar: ¿qué diferencias hay entre un archivo de texto y uno binario?
Veamos este ejemplo¶
In [13]:
Copied!
archi1 = open('archivo.txt', 'w')
archi1 = open('archivo.txt', 'w')
- ¿De qué modo se abre este archivo? ¿Qué significa?
- Luego de la instrucción, ¿dónde se encuentra archivo.txt?
- ¿Cuándo puede dar un error esta sentencia?
¿Y este otro ejemplo?¶
In [15]:
Copied!
archi2 = open('archivoxse.txt', 'x')
archi2 = open('archivoxse.txt', 'x')
- Y en este caso, ¿de qué modo se abre este archivo?
- ¿Cuándo puede dar un error esta sentencia?
¿Y en este caso?¶
In [16]:
Copied!
archi3 = open('archivo.txt')
archi3 = open('archivo.txt')
- En realidad la función open tiene más argumentos:
open(file, mode='r', buffering=-1, encoding=None, errors=None, newline=None, closefd=True, opener=None)
- encoding: sólo para modo texto. Por defecto, la codificación establecida en las configuraciones del sistema
- errors: sólo en modo texto. Es una cadena que dice qué hacer ante un error en la codificación/decodificación. ("strict", "ignore", ..)
- newline: sólo modo texto. Puede ser: None, '', '\n', '\r', y '\r\n'.
archi = open("pp.xxx", "r+", encoding="UTF-8")
In [ ]:
Copied!
import locale
locale.getpreferredencoding()
import locale
locale.getpreferredencoding()
¿Qué pasa si el archivo no está en la misma carpeta y tenmos que utilizar la ruta completa ?¶
In [17]:
Copied!
import os
ruta = os.path.dirname(os.path.realpath("."))
ruta
import os
ruta = os.path.dirname(os.path.realpath("."))
ruta
Out[17]:
'/home/claudia/ownCloud/Materias/Python/2022/entorno3.10'
In [18]:
Copied!
ruta_completa = os.path.join(ruta, "ejemplo","clase4", "archivo.txt")
ruta_completa
ruta_completa = os.path.join(ruta, "ejemplo","clase4", "archivo.txt")
ruta_completa
Out[18]:
'/home/claudia/ownCloud/Materias/Python/2022/entorno3.10/ejemplo/clase4/archivo.txt'
¿Cómo almacenamos datos en un archivo?¶
- El caso más sencillo: guardanto texto en un archivo.
In [21]:
Copied!
f = open('archivo.txt', 'w')
print(f.write('Hola, xxxxxx'))
print(f.write('Mundo!'))
f.close()
f = open('archivo.txt', 'w')
print(f.write('Hola, xxxxxx'))
print(f.write('Mundo!'))
f.close()
12 6
- write(cadena): escribe cadena en el archivo y retorna cantidad de caracteres escritos.
- close(): cierra el archivo.
¿Cómo leemos los datos guardados?¶
In [24]:
Copied!
f = open('archivo.txt', 'r')
x = f.read(4)
print(f.read())
x
f = open('archivo.txt', 'r')
x = f.read(4)
print(f.read())
x
, xxxxxxMundo!
Out[24]:
'Hola'
- read(cantidad_bytes): lee cantidad_bytes del archivo.
- Si cantidad_bytes es <0 o no está, lee hasta fin de archivo.
- Retorna "" si EOF.
- Tarea: probar el siguiente ejemplo que muestran otras formas de leer caracteres desde un archivo de texto.
In [ ]:
Copied!
def leo_caracteres():
f = open("imagine.txt","r")
for x in f.read():
print(x)
f.close()
def leo_lineas():
f = open("imagine.txt","r")
print(f.readlines())
f.close()
def otra_forma():
f = open("imagine.txt","r")
for linea in f:
print(linea)
f.close()
def main():
print('Leo caracteres')
leo_caracteres()
print('-' * 20)
print('Leo lineas')
leo_lineas()
print('-' * 20)
print('Otra forma')
otra_forma()
if __name__ == "__main__":
otra_forma()
def leo_caracteres():
f = open("imagine.txt","r")
for x in f.read():
print(x)
f.close()
def leo_lineas():
f = open("imagine.txt","r")
print(f.readlines())
f.close()
def otra_forma():
f = open("imagine.txt","r")
for linea in f:
print(linea)
f.close()
def main():
print('Leo caracteres')
leo_caracteres()
print('-' * 20)
print('Leo lineas')
leo_lineas()
print('-' * 20)
print('Otra forma')
otra_forma()
if __name__ == "__main__":
otra_forma()
¿Qué pasa si necesito guardar información que tiene una estructura?¶
Pensemos en estos ejemplos:
- Los puntajes cada vez que juego a un juego. Información tipo: nombre jugador, puntaje, fecha.
- El banco de preguntas: tema, enunciado, respuesta correcta.
- Los Python Plus de los estudiantes por turnos: turno, nombre, apellido, num_alumno, cantidad_puntos, etc.
En estos casos también podría usar un archivo de texto: ¿cómo se les ocurre?
Algunas posibilidades¶
'equipo: Astralis - e-sport: CSGO - pais: Dinamarca'
---
equipo:Astralis
e-sport:CSGO
pais:Dinamarca
---
'Astralis-CSGO-Dinamarca'
'Astralis*CSGO*Dinamarca*'
- ¿Pros y contras?
Hay otras formas mejores...¶
- Veamos este ejemplo: https://developers.mercadolibre.com.ar/es_ar/categorias-y-publicaciones#close
Módulo json¶
- Python tiene un módulo que permite trabajar con este formato.
- Para usarlo, debemos importarlo.
In [25]:
Copied!
import json
import json
- Permite serializar objetos.
- serializamos con: dumps() y dump().
- desserializamos con: loads() y load().
- Más info en: https://docs.python.org/3/library/json.html
Veamos este ejemplo¶
- Generamos un archivo con bandas de distintas ciudades:
- Tenemos: nombre de la banda, ciudad en la que se generó y una referencia a su trabajo.
- Empecemos por La Plata...
In [26]:
Copied!
import json
archivo = open("bandas.txt", "w")
datos = [
{"nombre": "William Campbell", "ciudad": "La Plata", "ref": "www.instagram.com/williamcampbellok"},
{"nombre": "Buendia", "ciudad": "La Plata", "ref":"https://buendia.bandcamp.com/"},
{"nombre": "Lúmine", "ciudad": "La Plata", "ref": "https://www.instagram.com/luminelp/"}]
json.dump(datos, archivo)
archivo.close()
import json
archivo = open("bandas.txt", "w")
datos = [
{"nombre": "William Campbell", "ciudad": "La Plata", "ref": "www.instagram.com/williamcampbellok"},
{"nombre": "Buendia", "ciudad": "La Plata", "ref":"https://buendia.bandcamp.com/"},
{"nombre": "Lúmine", "ciudad": "La Plata", "ref": "https://www.instagram.com/luminelp/"}]
json.dump(datos, archivo)
archivo.close()
- ¿De qué tipo es la variable datos?
In [29]:
Copied!
# Ahora accedemos a los datos guardados
import json
archivo = open("bandas.txt", "r")
datos = json.load(archivo)
print(datos)
datos_a_mostrar = json.dumps(datos, indent=4)
print(datos_a_mostrar)
archivo.close()
# Ahora accedemos a los datos guardados
import json
archivo = open("bandas.txt", "r")
datos = json.load(archivo)
print(datos)
datos_a_mostrar = json.dumps(datos, indent=4)
print(datos_a_mostrar)
archivo.close()
[{'nombre': 'William Campbell', 'ciudad': 'La Plata', 'ref': 'www.instagram.com/williamcampbellok'}, {'nombre': 'Buendia', 'ciudad': 'La Plata', 'ref': 'https://buendia.bandcamp.com/'}, {'nombre': 'Lúmine', 'ciudad': 'La Plata', 'ref': 'https://www.instagram.com/luminelp/'}] [ { "nombre": "William Campbell", "ciudad": "La Plata", "ref": "www.instagram.com/williamcampbellok" }, { "nombre": "Buendia", "ciudad": "La Plata", "ref": "https://buendia.bandcamp.com/" }, { "nombre": "L\u00famine", "ciudad": "La Plata", "ref": "https://www.instagram.com/luminelp/" } ]
- ¿De qué tipo de datos? ¿Y datos_a_mostrar?
CSV: ¿más formatos?¶
- CSV (Comma Separated Values).
- Es un formato muy común para importar/exportar desde/hacia hojas de cálculo y bases de datos.
- Ejemplo:
nombre,ciudad,ref
William Campbell,La Plata,www.instagram.com/williamcampbellok
Buendia,La Plata,https://buendia.bandcamp.com/
Lúmine,La Plata,https://www.instagram.com/luminelp/
Datasets¶
- Hay muchos datasets disponibles de muchas temáticas:
- En nuestro país:
- Otros:
¿Qué vemos en netflix?¶
Vamos a trabajar con el archivo: netflix_titles.csv
In [31]:
Copied!
import csv
ruta = os.path.dirname(os.path.realpath("."))
ruta_archivo = os.path.join(ruta, "teorias", "ejemplos","clase4", "netflix_titles.csv")
ruta_archivo
archivo = open(ruta_archivo, "r")
csvreader = csv.reader(archivo, delimiter=',')
#encabezado = csvreader.__next__()
encabezado = next(csvreader)
print(encabezado)
archivo.close()
import csv
ruta = os.path.dirname(os.path.realpath("."))
ruta_archivo = os.path.join(ruta, "teorias", "ejemplos","clase4", "netflix_titles.csv")
ruta_archivo
archivo = open(ruta_archivo, "r")
csvreader = csv.reader(archivo, delimiter=',')
#encabezado = csvreader.__next__()
encabezado = next(csvreader)
print(encabezado)
archivo.close()
['show_id', 'type', 'title', 'director', 'cast', 'country', 'date_added', 'release_year', 'rating', 'duration', 'listed_in', 'description']
Leemos el contenido completo¶
In [32]:
Copied!
archivo = open(ruta_archivo, "r")
csvreader = csv.reader(archivo, delimiter=',')
#encabezado = csvreader.__next__()
encabezado = next(csvreader)
print(encabezado)
for linea in csvreader:
if linea[1] == "TV Show" and linea[5] == "Argentina":
print(f"{linea[2]:<40} {linea[3]}")
archivo.close()
archivo = open(ruta_archivo, "r")
csvreader = csv.reader(archivo, delimiter=',')
#encabezado = csvreader.__next__()
encabezado = next(csvreader)
print(encabezado)
for linea in csvreader:
if linea[1] == "TV Show" and linea[5] == "Argentina":
print(f"{linea[2]:<40} {linea[3]}")
archivo.close()
['show_id', 'type', 'title', 'director', 'cast', 'country', 'date_added', 'release_year', 'rating', 'duration', 'listed_in', 'description'] The Kingdom Okupas No Time for Shame Millennials Carmel: Who Killed Maria Marta? Alejandro Hartmann Secreto bien guardado Almost Happy Hernán Guerschuny Puerta 7 Monzón: A Knockout Blow El Marginal Apache: The Life of Carlos Tevez Go! Live Your Way Heidi, bienvenida a casa The Kirlian Frequency Creators Edha Historia de un clan Psiconautas
¿De qué tipo es línea?
Otra solución ...¶
In [33]:
Copied!
archivo = open(ruta_archivo, "r")
csvreader = csv.reader(archivo, delimiter=',')
shows_ar = filter(lambda x: x[5] == "Argentina" and x[1] == "TV Show", csvreader)
for elem in shows_ar:
print(f"{elem[2]:<40} {elem[3]}")
print(shows_ar)
archivo.close()
archivo = open(ruta_archivo, "r")
csvreader = csv.reader(archivo, delimiter=',')
shows_ar = filter(lambda x: x[5] == "Argentina" and x[1] == "TV Show", csvreader)
for elem in shows_ar:
print(f"{elem[2]:<40} {elem[3]}")
print(shows_ar)
archivo.close()
The Kingdom Okupas No Time for Shame Millennials Carmel: Who Killed Maria Marta? Alejandro Hartmann Secreto bien guardado Almost Happy Hernán Guerschuny Puerta 7 Monzón: A Knockout Blow El Marginal Apache: The Life of Carlos Tevez Go! Live Your Way Heidi, bienvenida a casa The Kirlian Frequency Creators Edha Historia de un clan Psiconautas <filter object at 0x7fa9ac227700>
Creamos nuestro archivo csv de bandas de música¶
- csv.writer: retorna un objeto que convierte los datos con los que trabajamos en el programa en cadenas con el formato delimitadas con el separador correspondiente.
In [ ]:
Copied!
import csv
import json
archivo = open("bandas.txt")
archivo_csv = open("bandas.csv", "w")
bandas = json.load(archivo)
writer = csv.writer(archivo_csv)
writer.writerow(["Nombre", "Ciudad de procedencia", "Refencias"])
for banda in bandas:
writer.writerow([banda["nombre"], banda["ciudad"], banda["ref"]])
archivo.close()
archivo_csv.close()
#type(writer)
import csv
import json
archivo = open("bandas.txt")
archivo_csv = open("bandas.csv", "w")
bandas = json.load(archivo)
writer = csv.writer(archivo_csv)
writer.writerow(["Nombre", "Ciudad de procedencia", "Refencias"])
for banda in bandas:
writer.writerow([banda["nombre"], banda["ciudad"], banda["ref"]])
archivo.close()
archivo_csv.close()
#type(writer)
Lo leemos¶
In [ ]:
Copied!
archivo_cvs = open("bandas.csv", "r")
csvreader = csv.reader(archivo_cvs, delimiter=',')
for linea in csvreader:
print(linea)
archivo_csv.close()
archivo_cvs = open("bandas.csv", "r")
csvreader = csv.reader(archivo_cvs, delimiter=',')
for linea in csvreader:
print(linea)
archivo_csv.close()
Otra forma de acceder: csv.DictReader¶
In [ ]:
Copied!
archivo_cvs = open("bandas.csv", "r")
csvreader = csv.DictReader(archivo_cvs, delimiter=',')
for linea in csvreader:
print(linea["Nombre"])
archivo_csv.close()
archivo_cvs = open("bandas.csv", "r")
csvreader = csv.DictReader(archivo_cvs, delimiter=',')
for linea in csvreader:
print(linea["Nombre"])
archivo_csv.close()
Desafío 1¶
Dado el conjunto de datos con series y películas de Netflix, queremos:
1- guardar en otro archivo las peliculas agregadas en el año 2021.
2- los cinco (5) países con más producciones en Netflix.
Desafío 2¶
- Implementar un programa que muestre un menú a través del cual se puedan visualizar los resultados del desafío 1.
- Pueden usar la librería console-menu analizada en clase.
- Pueden agregar más opciones con los ejemplos mostrados en la clase
Los que quieran, compartir con @clauBanchoff¶
- Recuerden mandarme mensaje para revisar.