Loading
Pedro Flores
This is a live streamed presentation. You will automatically follow the presenter and see the slide they're currently on.
101 Super Mega Turbo Diesel Intercooler XP 2000 Recargado Endgame Begginer Pack
En realidad python refreshener y si da el tiempo backend flask en python
Para seguir la presentación desde su notebook,
celular,
tablet,
tostadora...
# CONTENIDO
# CONTENIDO
# CONTENIDO
@neowinx
}
# CONTENIDO
# CONTENIDO
# INSTALACIÓN
Para instalar Python, descargar Python 3.10 (o mayor) de http://www.python.org/
Es muy importante: al instalar, hacer check en "Add Python to PATH"
# INSTALACIÓN
Si se tiene varias versiones de Python instaladas, como las que se instalaron anteriormente, pueden listar las mismas con este comando:
py -0p
El resultado seria algo como esto:
C:\Users\youruser>py -0p
Installed Pythons found by py Launcher for Windows
-3.10-64 C:\Users\youruser\AppData\Local\Programs\Python\Python310\python.exe *
-3.9-64 C:\Users\youruser\AppData\Local\Programs\Python\Python39\python.exe
-3.8-64 C:\Users\youruser\AppData\Local\Programs\Python\Python38\python.exe
-3.7-64 C:\Users\youruser\AppData\Local\Programs\Python\Python37\python.exe
-3.7-32 C:\Program Files (x86)\Python37-32\python.exe
-2.7-64 C:\Python27\python.exe
El resultado seria algo como esto:
C:\Users\youruser>py -0p
Installed Pythons found by py Launcher for Windows
-3.10-64 C:\Users\youruser\AppData\Local\Programs\Python\Python310\python.exe *
-3.9-64 C:\Users\youruser\AppData\Local\Programs\Python\Python39\python.exe
-3.8-64 C:\Users\youruser\AppData\Local\Programs\Python\Python38\python.exe
-3.7-64 C:\Users\youruser\AppData\Local\Programs\Python\Python37\python.exe
-3.7-32 C:\Program Files (x86)\Python37-32\python.exe
-2.7-64 C:\Python27\python.exe
Una vez identificada la version que quieren usar:
py -3.9 file_to_run.py
# INSTALACIÓN
# CONTENIDO
# Variables en Python
# -- Numeros y flotantes --
x = 15
price = 9.99
discount = 0.2
result = price * (1 - discount)
print(result)
# -- Cadenas de texto (Strings) --
name = "Rolf"
name = "Rolf"
print(name)
print(name * 2)
# Variables en Python
# -- Cambiando variables --
# Las variables son nombres de valores
a = 25
b = a
# Aqui le dimos el valor '25' a los nombres 'a' y 'b'.
print(a)
print(b)
b = 17
# Aquí le dimos el valor '17' y el nombre 'b'. El nombre 'a' sigue siendo el nombre del valor '25'!
print(a)
print(b)
# Variables en Python
Ejercicio:
# Crear dos variables, var1 y var2, ambos con el mismo valor.
# Crear dos variables, num1 y num2, cuyo multiplo es igual a 16.
# CONTENIDO
# STRINGS
nombre = "Pedro"
saludo = "Hola, Pedro"
print(saludo)
nombre = "Rafa"
print(saludo)
saludo = f"Hola, {nombre}"
print(saludo)
nombre = "Ana"
print(
saludo
) # Esto imprime "Hola, Rafa" porque `saludo` se calculo antes.
print(
f"Hola, {nombre}"
) # Esto es incorrecto debido a que usa `nombre` en el punto actual en el tiempo.
# STRINGS
# -- Usando .format() --
# Podemos definir 'template strings' que reemplacen partes del mismo con otros valores en vez de hacerlo directamente en la cadena.
saludo = "Hola, {}"
con_nombre = saludo.format("Rafa")
print(con_nombre)
frase_mas_larga = "Hola, {}. hoy es {}."
formateado = frase_mas_larga.format("Rafa", "Lunes")
print(formateado)
# CONTENIDO
# ENTRADA DEL USUARIO
nombre = input("Ingrese su nombre: ")
print(nombre)
# -- Matemáticas en la entrada de usuario --
size_input = input("Que tan grande es tu casa (en metros cuadrados): ")
square_feet = int(size_input)
square_metres = square_feet * 10.8 # Verificar este valor
print(f"{square_feet} metros cuadrados es {square_metres} pies cuadrados.")
# CONTENIDO
# PRIMER APP
user_age = input("Enter your age: ")
age_number = int(user_age)
months = age_number * 12
print(f"{age_number} is equal to {months} months.")
# CONTENIDO
# Listas, tuplas y conjuntos
l = ["Bob", "Rolf", "Anne"]
t = ("Bob", "Rolf", "Anne")
s = {"Bob", "Rolf", "Anne"}
# Acceder a items individuales en las listas y tuplas utilizando el índice.
print(l[0])
print(t[0])
# print(s[0]) # Esto da un error porque los conjuntos no mantienen el orden, por lo que acceder al elemento con indice 0 no tiene sentido.
# Modificar items individuales en las listas utilizando el índice.
l[0] = "Smith"
# t[0] = "Smith" # Esto da un error debido a que las tuplas son "inmutables"
print(l)
print(t)
# Anexar elemento a la lista utilizando `.append`
l.append("Jen")
print(l)
# Las tuplas no pueden anexar items debido a que son inmutables.
# Agregar items a un conjunto utilizando `.add`
s.add("Jen")
print(s)
# Los conjuntos no pueden tener el mismo elemento más de una vez
s.add("Bob")
print(s)
# CONTENIDO
# Booleans en Python
# -- Comparaciones --
print(5 == 5) # True
print(5 > 5) # False
print(10 != 10) # False
# Comparaciones: ==, !=, >, <, >=, <=
# -- is --
# Python tambien tiene la palabra reservada `is`. En general no se recomienda usar ya que es un tanto confusa
friends = ["Rolf", "Bob"]
abroad = ["Rolf", "Bob"]
print(friends == abroad) # True
print(friends is abroad) # False
# CONTENIDO
# Sentencia "if"
dia = input("¿Qué día de la semana es hoy?")
if dia == "Lunes":
print("Que tengas un muy buen inicio de semana!")
elif dia == "Viernes":
print("Esta bien terminar un poco antes hoy!")
else:
print("A toda marcha!")
# -- Problema: el usuario no ingrese lo que esperamos --
dia = input("¿Qué día de la semana es hoy? ").lower()
if dia == "lunes":
print("Que tengas un muy buen inicio de semana!")
elif dia == "viernes":
print("Esta bien terminar un poco antes hoy!")
else:
print("A toda marcha!")
# CONTENIDO
# Palabra clave "in"
amigos = ["Rafa", "Blas", "Jazmin"]
print("Jazmin" in friends)
# --
peliculas_miradas = {"The Matrix", "Green Book", "Her"}
peli_de_usuario = input("Ingresa algo que hayas mirado recientemente: ")
print(peli_de_usuario in peliculas_miradas)
# La palabra `in` se encuentra en la mayoria de las secuencias como listas, tuplas y conjuntos.
# CONTENIDO
# Sentencias "if" con "in"
# Ejemplo1
pelis_vistas = {"The Matrix", "Green Book", "Her"}
peli_de_usuario = input("Ingresa algo que hayas visto recientemente: ")
if peli_de_usuario in pelis_vistas:
print(f"Yo he visto {peli_de_usuario} también!")
else:
print("Aún no he visto esa.")
# Sentencias "if" con "in"
# Ejemplo 2
numero = 7
entrada_usuario = input("Ingrese 's' si te gustaria jugar:")
if entrada_usuario in ("s", "S"):
numero_del_usuario = int(input("Adivina el número: "))
if numero_del_usuario == numero:
print("Has adivinado!")
elif numero - numero_del_usuario in (1, -1):
print("Fallaste por 1.")
else:
print("Lo siento, número equivocado")
# Sentencias "if" con "in"
# Ejemplo 2
numero = 7
entrada_usuario = input("Ingrese 's' si te gustaria jugar:")
if entrada_usuario in ("s", "S"):
numero_del_usuario = int(input("Adivina el número: "))
if numero_del_usuario == numero:
print("Has adivinado!")
elif numero - numero_del_usuario in (1, -1):
print("Fallaste por 1.")
else:
print("Lo siento, número equivocado")
# Tambien podemos hacer una transformación en vez de checkear cada opción.
numero = 7
entrada_usuario = input("Ingrese 's' si te gustaria jugar:")
if entrada_usuario.lower() == "s":
numero_del_usuario = int(input("Adivina el número: "))
if numero_del_usuario == numero:
print("Has adivinado!")
elif abs(numero - numero_del_usuario) == 1:
print("Fallaste por 1.")
else:
print("Lo siento, número equivocado")
# CONTENIDO
# Loops en Python
# -- While loop --
number = 7
play = input("Would you like to play? (Y/n) ")
while play != "n":
user_number = int(input("Guess our number: "))
if user_number == number:
print("You guessed correctly!")
elif abs(number - user_number) == 1:
print("You were off by 1.")
else:
print("Sorry, it's wrong!")
play = input("Would you like to play? (Y/n) ")
# Loops en Python
# -- The break keyword --
while True:
play = input("Would you like to play? (Y/n) ")
if play == "n":
break # Exit the loop
user_number = int(input("Guess our number: "))
if user_number == number:
print("You guessed correctly!")
elif abs(number - user_number) == 1:
print("You were off by 1.")
else:
print("Sorry, it's wrong!")
# Loops en Python
# -- For loop --
friends = ["Rolf", "Jen", "Bob", "Anne"]
for friend in friends:
print(f"{friend} is my friend.")
# -- For loop 2 -- Average
grades = [35, 67, 98, 100, 100]
total = 0
amount = len(grades)
for grade in grades:
total += grade
print(total / amount)
# -- Rewritten using sum() --
grades = [35, 67, 98, 100, 100]
total = sum(grades)
amount = len(grades)
print(total / amount)
# You kinda just have to "know" that exists. It takes time and experience, but searching for almost _everything_ really helps. For example, you could've searched for "sum list of numbers python".
# CONTENIDO
# Comprensión de listas en Python
numeros = [1, 3, 5]
cuadrados = [x * 2 for x in numeros]
# -- Manejando cadenas de texto --
amigos = ["Rafa", "Sam", "Samantha", "Sabrina", "Jazmin"]
comienzan_s = []
for amigo in amigos:
if amigo.startswith("S"):
comienzan_s.append(amigo)
print(comienzan_s)
# -- Podemos crear una nueva lista de amigos con nombres que comiencen con S --
amigos = ["Rafa", "Samu", "Samantha", "Sabrina", "Jazmin"]
comienzan_s = [ami for ami in amigos if ami.startswith("S")]
print(comienzan_s)
# -- List comprehension creara una _nueva_ lista --
amigos = ["Samu", "Samantha", "Sabrina"]
comienzan_s = [ami for ami in amigos if ami.startswith("S")] # same as above
print(amigos)
print(comienzan_s)
print(amigos is comienzan_s)
print("friends: ", id(amigos), " starts_s: ", id(comienzan_s))
# CONTENIDO
# Diccionarios
edad_de_amigos = {"Rafa": 24, "Alan": 30, "Ana": 27}
edad_de_amigos["Blas"] = 20
print(edad_de_amigos) # {'Rafa': 24, 'Alan': 30, 'Ana': 27, 'Blas': 20}
print(edad_de_amigos["Bob"])
# -- Lista de diccionarios --
amigos = [
{"name": "Rolf Smith", "age": 24},
{"name": "Adam Wool", "age": 30},
{"name": "Anne Pun", "age": 27},
]
print(amigos)
# Diccionarios
# -- Iteración --
asistencia_estudiantes = {"Rolf": 96, "Bob": 80, "Anne": 100}
for estudiante in asistencia_estudiantes:
print(f"{estudiante}: {asistencia_estudiantes[estudiante]}")
# Mejor
for estudiante, asistencia in asistencia_estudiantes.items():
print(f"{estudiante}: {asistencia}")
# -- Usando la palabra reservada `in` --
if "Bob" in asistencia_estudiantes:
print(f"Bob: {asistencia_estudiantes[estudiante]}")
else:
print("Bob isn't a estudiante in this class!")
# -- Calcular el promedio con `.values()` --
asistencias = asistencia_estudiantes.values()
print(sum(asistencias) / len(asistencias))
# CONTENIDO
# De-estructuración de variables
x, y = 5, 11
# x, y = (5, 11)
# -- Deestructuración en for loops --
asistencia_estudiantes = {"Rafa": 96, "Blas": 80, "Ana": 100}
for estudiante, asistencia in asistencia_estudiantes.items():
print(f"{estudiante}: {asistencia}")
# -- Otro ejemplo --
gente = [("Blas", 42, "Mecanico"), ("Jaime", 24, "Artista"), ("Hugo", 32, "Profesor")]
for nombre, edad, profesion in gente:
print(f"Nombre: {nombre}, Edad: {edad}, Profesion: {profesion}")
# -- Mucho mejor que esto! --
for persona in gente:
print(f"Nombre: {persona[0]}, Edad: {persona[1]}, Profesion: {persona[2]}")
# De-estructuración de variables
# -- Ignorar valores con guion bajo --
persona = ("Blas", 42, "Mecanico")
nombre, _, profesion = persona
print(nombre, profesion) # Blas Mecanico
# -- Recolectando valores --
cabeza, *cola = [1, 2, 3, 4, 5]
print(cabeza) # 1
print(cola) # [2, 3, 4, 5]
*cabeza, cola = [1, 2, 3, 4, 5]
print(cabeza) # [1, 2, 3, 4]
print(cola) # 5
# -- Packing y unpacking --
# Existen también formas de desempaquetar y empaquetar collections usando * y **, pero eso es un poco más avanzado y lo aprenderemos más adelante!
# CONTENIDO
# Funciones en Python
def hola():
print("Hola!")
hola()
# -- Definicion vs. llamada --
# Sige siendo todo secuencial!
def edad_del_usuario_en_segundos():
edad_usuario = int(input("Ingresa tu edad: "))
edad_segundos = edad_usuario * 365 * 24 * 60 * 60
print(f"Tu edad en segundos es {edad_segundos}.")
print("Bienvenido al programa 'edad en segundos'!")
edad_del_usuario_en_segundos()
print("Adios!")
# Funciones en Python
# -- No reusen nombres --
def print():
print("Hola mundo") # Error!
# -- No reusen nombres, es generalmente confuso! --
amigos = ["Rafa", "Blas"]
def agregar_amigo():
nombre_amigo = input("Ingresa el nombre de tu amigo: ")
amigos = amigos + [nombre_amigo] # Otra forma de agregar items a una lista!
agregar_amigo()
print(amigos) # Siempre ['Rafa', 'Blas']
# Funciones en Python
# -- No llames a una funcion antes de haberla definido --
decir_hola()
def decir_hola():
print("Hola!")
# -- Recuerda que el cuerpo de la funcion solo se ejecuta cuando se llama --
def agregar_amigo():
amigos.append("Rafa")
amigos = []
agregar_amigo()
print(amigos) # [Rafa]
# CONTENIDO
# Argumentos y parámetros de funciones
def sumar(x, y):
resultado = x + y
print(resultado)
sumar(2, 3) # 5
# -- Si una funcion no tiene parametros, no puedes pasarle ningun argumento--
def decir_hola():
print("Hola!")
decir_hola("Bob") # Error
# -- Pero si agregas un parametro, entonces debes pasar el argumento --
def decir_hola(nombre):
print(f"Hola, {nombre}!")
decir_hola("Bob")
decir_hola() # Error, needs an argument
# Argumentos y parámetros de funciones
# -- Keyword arguments --
# Para hacer las cosa más claras, en Python uno puede pasar argumentos con nombre (Keyword arguments)
def decir_hola(nombre):
print(f"Hello, {nombre}!")
decir_hola(name="Bob") # Es obvio que debe ser le nombre de alguien
def dividir(dividendo, divisor):
if divisor != 0:
print(dividendo / divisor)
else:
print("Que tonto!")
dividir(dividendo=15, divisor=3)
dividir(15, 0)
dividir(15, divisor=0) # OK
# divide(dividend=15, 0) # No OK, los argumentos con nombre deben ir despues de los argumentos por posicion
# Es recomendable utilizar argumentos con nombre siempre que se pueda, principalmente porque hacen el código cosas más legible a largo plazo.
# CONTENIDO
# Funciones con valores de retorno
def sumar(x, y):
print(x + y)
sumar(5, 8)
resultado = sumar(5, 8)
print(resultado) # None
# Si queremos obtener algo desde la funcion, la misma debe retornar un valor.
# Todas las funciones retornan _algo_. Por defecto, lo que retorna es 'None'.
# -- Retornando valores --
def sumar(x, y):
return x + y
sumar(1, 2) # Ya no imprime nada
resultado = sumar(2, 3)
print(resultado) # 5
# Funciones con valores de retorno
# -- Al retornar, la función termina su ejecución --
def sumar(x, y):
return
print(x + y)
return x + y
resultado = sumar(5, 8) # No se imprime nada
print(resultado) # None, debido a que es el primer 'return'
# -- Retornar con condicionales --
def dividir(dividendo, divisor):
if divisor != 0:
return dividendo / divisor
else:
return "Que tonteria!"
resultado = dividir(15, 3)
print(resultado) # 5
otro_resultado = dividir(15, 0)
print(otro_resultado) # Que tonteria!
# CONTENIDO
# Funciones Lambda
def sumar(x, y):
return x + y
print(sumar(5, 7))
# -- Written as a lambda --
# -- Escrito como funcion lambda --
sumar = lambda x, y: x + y
print(sumar(5, 7))
# Funciones Lambda
# Cuatro partes
# lambda
# parametros
# :
# valor retornado
# Las funciones Lambdas suelen ser cortas, generalmente utilizadas sin darles un nombre.
# Por ejemplo, en conjunción con la función estandar map
# map aplica la función lambda a todos los valores de la secuencia
def doble(x):
return x * 2
secuencia = [1, 3, 5, 9]
dobles = [
doble(x) for x in secuencia
] # Coloca el resultado de doble(x) en una nueva lista, por cada uno de los valores en `secuencia`
dobles = map(doble, secuencia)
print(list(dobles))
# -- Escrito como lambda --
secuencia = [1, 3, 5, 9]
dobles = map(lambda x: x * 2, secuencia)
print(list(dobles))
# Funciones Lambda
def doble(x):
return x * 2
secuencia = [1, 3, 5, 9]
dobles = [
doble(x) for x in secuencia
] # Coloca el resultado de doble(x) en una nueva lista, por cada uno de los valores en `secuencia`
dobles = map(doble, secuencia)
print(list(dobles))
# -- Escrito como lambda --
secuencia = [1, 3, 5, 9]
dobles = map(lambda x: x * 2, secuencia)
print(list(dobles))
# -- Importante recordar --
# Lambdas son simplemente funciones sin nombre.
# Son utilizadas para retornar un valor calculado desde sus párametros.
# Casi siempre son de una linea, para no hacer nada complicado en ellas.
# Muy amenudo es mejor simplemente definir una funcion y darle un nombre propio.
# CONTENIDO
# Dictionary comprehensions
usuarios = [
(0, "Bob", "password"),
(1, "Rolf", "bob123"),
(2, "Jose", "longp4assword"),
(3, "username", "1234"),
]
username_mapping = {user[1]: user for user in usuarios}
userid_mapping = {user[0]: user for user in usuarios}
print(username_mapping)
print(username_mapping["Bob"]) # (0, "Bob", "password")
# -- Puede ser util para el login por ejemplo--
username_input = input("Ingrese su usuario: ")
password_input = input("Ingrese su password: ")
_, username, password = username_mapping[username_input]
if password_input == password:
print("Detalles correctos!")
else:
print("Sus detalles son incorrectos.")
# Si nosotros no usabamos el mapping, el codigo iba a requerir que iterasemos todos los usuarios.
# CONTENIDO
# Unpacking arguments
def multiplicar(*args):
print(args)
total = 1
for arg in args:
total = total * arg
return total
print(multiplicar(3, 5))
print(multiplicar(-1))
# El asterisco toma todos los argumentos y los empaqueta (pack) en una tupla.
# El asterisco tambien puede usarse para desempaquetar (unpack) secuencias en argumentos!
def sumar(x, y):
return x + y
nums = [3, 5]
print(sumar(*nums)) # en vez de sumar(nums[0], nums[1])
# Unpacking arguments
# -- Usos con argumentos con nombre --
# Doble asterisco empaquta y desempaqueta argumentos con nombre
def sumar(x, y):
return x + y
nums = {"x": 15, "y": 25}
print(sumar(**nums))
# Unpacking arguments
# -- Usos con argumentos con nombre --
# Doble asterisco empaquta y desempaqueta argumentos con nombre
def sumar(x, y):
return x + y
nums = {"x": 15, "y": 25}
print(sumar(**nums))
# -- Forzar un parámetro con nombre --
def multiplicar(*args):
total = 1
for arg in args:
total = total * arg
return total
def aplicar(*args, operador):
if operador == "*":
return multiplicar(args)
elif operador == "+":
return sum(args)
else:
return "No se ha proveído un operador válido a aplicar()."
print(aplicar(1, 3, 6, 7, operador="+"))
print(aplicar(1, 3, 5, "+")) # Error
# CONTENIDO
# Unpacking keyword arguments
# -- Unpacking kwargs --
def named(**kwargs):
print(kwargs)
named(name="Bob", age=25)
# named({"name": "Bob", "age": 25}) # Error, el diccionario es realmente un argumento posicional.
# Desempaquetar un dict en argumentos. Esto funciona, pero es un poco más confuso. Aunque cuando se trabaja con variables está bien.
named(**{"name": "Bob", "age": 25})
# -- Unpacking and repacking --
def named(**kwargs):
print(kwargs)
def imprimir_lindo(**kwargs):
named(**kwargs) # Desempaquetar el diccionario en argumentos por nombres.
for arg, value in kwargs.items():
print(f"{arg}: {value}")
imprimir_lindo(name="Bob", age=25)
# Unpacking keyword arguments
# -- Ambos args y kwargs --
def ambos(*args, **kwargs):
print(args)
print(kwargs)
ambos(1, 3, 5, name="Bob", age=25)
# Estos se usa generalmente para aceptar un número ilimitado de argumentos por posicion y por nombres, como para poder pasar alguno de ellos a otras funciones.
# Frequentemente se ven cosas como ésta en código Python:
"""
def post(url, data=None, json=None, **kwargs):
return request('post', url, data=data, json=json, **kwargs)
"""
# La implementación en este punto es irrelevante, lo que permite es que el que llama a la función `post()` pueda pasar argumentos a `request()`.
# -- Error when unpacking --
def myfunction(**kwargs):
print(kwargs)
myfunction(**"Bob") # Error, debe estar mapeado
myfunction(**None) # Error
# CONTENIDO
# Programación orientada a objetos en Python
estudiante = {"name": "Rolf", "grades": (89, 90, 93, 78, 90)}
def promedio(secuencia):
return sum(secuencia) / len(secuencia)
print(promedio(estudiante["grades"]))
# Pero no seria lindo si pudiesemos...
# print(estudiante.promedio()) ?
class Estudiante:
def __init__(self):
self.nombre = "Rolf"
self.puntajes = (89, 90, 93, 78, 90)
def promedio(self):
return sum(self.puntajes) / len(self.puntajes)
estudiante = Estudiante()
print(estudiante.promedio())
# Identico a Estudiante.promedio(estudiante)
# Programación orientada a objetos en Python
# -- Parameters in __init__ --
class Estudiante:
def __init__(self, nombre, puntajes):
self.nombre = nombre
self.puntajes = puntajes
def promedio(self):
return sum(self.puntajes) / len(self.puntajes)
estudiante = Estudiante("Bob", (36, 67, 90, 100, 100))
print(estudiante.average())
# -- Se acuerdan de *args ? --
class Estudiante:
def __init__(self, nombre, *puntajes):
self.nombre = nombre
self.puntajes = puntajes
def promedio(self):
return sum(self.puntajes) / len(self.puntajes)
estudiante = Estudiante("Bob", 36, 67, 90, 100, 100)
print(estudiante.promedio())
# Programación orientada a objetos en Python
# Funciones vs. Métodos
Una función que reside dentro de una clase es llamada método.
Por lo tanto, los métodos son funciones, pero no todas las funciones son métodos.
## Función
def promedio(secuencia):
return sum(secuencia) / len(secuencia)
## Método
class Estudiante:
def __init__(self): # método
self.nombre = "Rolf"
self.puntajes = (79, 90, 95, 99)
def promedio(self): # método
return sum(self.puntajes) / len(self.puntajes)
# CONTENIDO
# @classmethod y @staticmethod
class ClassTest:
def metodo_de_instancia(self):
print(f"Se ha llamado al instance_method de {self}")
@classmethod
def metodo_de_clase(cls):
print(f"Se a llamado al class_method de {cls}")
@staticmethod
def metodo_estatico():
print(f"Se ha llamado al static_method."
"Aquí no obtenemos ni la instancia del objeto, ni la clase.")
instancia = ClassTest()
instancia.metodo_de_instancia()
ClassTest.metodo_de_clase()
ClassTest.metodo_estatico()
# -- ¿Para qué se usan? --
# - Los métodos de instancia son utilizados para todas las operaciones con la instancia que utilicen sus datos.
# - Los métodos de clase son métodos que se usan para operaciones con la clase. Son utilizados generalmente como factories.
# - Los métodos estáticos sno utilizados para colocar métodos dentro de la clase por organización de código más que nada.
# @classmethod y @staticmethod
# -- ¿Para qué se usan? --
# - Los métodos de instancia son utilizados para todas las operaciones con la instancia que utilicen sus datos.
# - Los métodos de clase son métodos que se usan para operaciones con la clase. Son utilizados generalmente como factories.
# - Los métodos estáticos sno utilizados para colocar métodos dentro de la clase por organización de código más que nada.
class Libro:
TIPOS = ("tapa_dura", "tapa_blanda")
def __init__(self, nombre, tipo_libro, peso):
self.nombre = nombre
self.tipo_libro = tipo_libro
self.peso = peso
def __repr__(self):
return f"<Libro {self.nombre}, {self.tipo_libro}, pesando {self.peso}g>"
@classmethod
def tapa_dura(cls, name, page_weight):
return cls(name, cls.TIPOS[0], page_weight + 100)
@classmethod
def tapa_blanda(cls, name, page_weight):
return cls(name, cls.TIPOS[1], page_weight)
pesado = Libro.tapa_dura("Harry Potter", 1500)
liviano = Libro.tapa_blanda("Python 101", 600)
print(pesado)
print(liviano)
# CONTENIDO
# Herencia de clases
class Device:
def __init__(self, name, connected_by):
self.name = name
self.connected_by = connected_by
self.connected = True
def __str__(self):
return f"Device {self.name!r} ({self.connected_by})"
def disconnect(self):
self.connected = False
# printer = Device("Printer", "USB")
# print(printer)
# No queremos agregar cosas específicas de printer, por lo tanto...
class Printer(Device):
def __init__(self, name, connected_by, capacity):
# super(Printer, self).__init__(name, connected_by) - Python2.7
super().__init__(name, connected_by) # Python3+
self.capacity = capacity
self.remaining_pages = capacity
def __str__(self):
return f"{super().__str__()} ({self.remaining_pages} pages remaining)"
def print(self, pages):
if not self.connected:
raise TypeError("Device is disconnected at this time, cannot print.")
print(f"Printing {pages} pages.")
self.remaining_pages -= pages
printer = Printer("Printer", "USB", 500)
printer.print(20)
print(printer)
printer.print(50)
print(printer)
printer.disconnect()
printer.print(30) # Error
# CONTENIDO
# Class composition
# Algo que se ve muy a menudo pero que NO DEBES HACER
class EstanteLibro:
def __init__(self, cantidad):
self.cantidad = cantidad
def __str__(self):
return f"EstanteLibro con {self.cantidad} libros."
estante = EstanteLibro(300)
class Libro(EstanteLibro):
def __init__(self, nombre, cantidad):
super().__init__(cantidad)
self.nombre = nombre
# Esto no tiene sentido, porque ahora hay que pasar `cantidad` a un solo libro:
libro = Libro("Harry Potter", 120)
print(libro) # Que?
# Class composition
# -- Composition over inheritance --
# Herencia: "Un Libro es un estante"
# Composicion: "Un estante tiene muchos libos"
class EstanteLibro:
def __init__(self, *libros):
self.libros = libros
def __str__(self):
return f"EstanteLibro con {len(self.libros)} libros."
class Libro:
def __init__(self, name):
self.name = name
libro = Libro("Harry Potter")
libro2 = Libro("Python 101")
estante = EstanteLibro(libro, libro2)
print(estante)
# CONTENIDO
# Type hinting en Python 3.5+
def lista_promedio(secuencia: list) -> float:
return sum(secuencia) / len(secuencia)
# -- Type hinting clases --
class Libro:
def __init__(self, nombre: str, cantidad_paginas: int):
self.nombre = nombre
self.cantidad_paginas = cantidad_paginas
# -- Listas y colecciones --
from typing import List # , Tuple, Set, etc...
class EstanteLibro:
def __init__(self, libros: List[Libro]):
self.libros = libros
def __str__(self) -> str:
return f"EstanteLibro con {len(self.libros)} libros."
# El beneficio principal es que ahora se te avisara cuando le pases el tipo incorrecto...
libro = Libro(
"Harry Potter", "352"
) # Sugiere que esto es incorrecto si tienes una herramienta que analiza tu código (e.g. PyCharm o Pylint)
estante = EstanteLibro(libro) # También sugiere error aqui
# Type hinting es eso: un hint (una pista, un indicio). No detiene la ejecución del código... pero puede salvarte la vida a veces!
# Type hinting en Python 3.5+
# El beneficio principal es que ahora se te avisara cuando le pases el tipo incorrecto...
libro = Libro(
"Harry Potter", "352"
) # Sugiere que esto es incorrecto si tienes una herramienta que analiza tu código (e.g. PyCharm o Pylint)
estante = EstanteLibro(libro) # También sugiere error aqui
# Type hinting es eso: un hint (una pista, un indicio). No detiene la ejecución del código... pero puede salvarte la vida a veces!
# -- Hinting del objecto actual --
class Libro:
TYPES = ("tapa_dura", "tapa_blanda")
def __init__(self, name: str, tipo_libro: str, peso: int):
self.nombre = name
self.tipo_libro = tipo_libro
self.peso = peso
def __repr__(self) -> str:
return f"<Libro {self.nombre}, {self.tipo_libro}, pesando {self.peso}g>"
@classmethod
def tapa_dura(cls, nombre: str, peso: int) -> "Libro":
return cls(nombre, cls.TYPES[0], peso + 100)
@classmethod
def tapa_blanda(cls, name: str, peso: int) -> "Libro":
return cls(name, cls.TYPES[1], peso)
# INTRODUCCION
<section>
<h2>Tabular Tables</h2>
<table>
<thead>
<tr>
<th>Item</th>
<th>Value</th>
<th>Quantity</th>
</tr>
</thead>
<tbody>
<tr>
<td>Apples</td>
<td>$1</td>
<td>7</td>
</tr>
<tr>
<td>Lemonade</td>
<td>$2</td>
<td>18</td>
</tr>
<tr>
<td>Hand Sanitizer</td>
<td>$999</td>
<td>2</td>
</tr>
</tbody>
</table>
</section>
# PRESENTING CODE