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