Seguramente también han visto decoradores que reciben parámetros, para esto solo tiene que anidar una función más para que esta reciban los parámetros del decorador y la siguiente es la que recibe la función a la que decora.
Introducción
¿Qué necesitas saber para tomar el curso?
¿Cómo funciona Python?
Cómo organizar las carpetas de tus proyectos
Static Typing
¿Qué son los tipados?
Tipado estático en Python
Practicando el tipado estático
Conceptos avanzados de funciones
Scope: alcance de las variables
Closures
Programando closures
Decoradores
Programando decoradores
Estructuras de datos avanzadas
Iteradores
La sucesión de Fibonacci
Generadores
Mejorando nuestra sucesión de Fibonacci
Sets
Operaciones con sets
Eliminando los repetidos de una lista
Bonus
Manejo de fechas
Time zones
Conclusión
Completaste la trilogía. ¿Cómo seguir?
Aún no tienes acceso a esta clase
Crea una cuenta y continúa viendo este curso
Aportes 239
Preguntas 15
Seguramente también han visto decoradores que reciben parámetros, para esto solo tiene que anidar una función más para que esta reciban los parámetros del decorador y la siguiente es la que recibe la función a la que decora.
Este es el código, solo funciona con texto, no hice lo de *args.
Y este sería el resultado XD
Acá el mío jejeje
Hola compañeros esta es mi aplicación de decoradores, pues sucede que soy Data Scientist y estoy entrenando un modelo de IA que es capaz de generar texto, y actualmente funciona como un chatbot, pero aun no esta perfecto y comete ciertos erres y a veces dice palabras que no quiero xdxd … entonces debo hacer una limpieza y formatear el texto una vez terminada la predicción:
entonces la lógica para hacer la limpieza la cree dentro de un decorador:
y luego lo importo el decorador para utilizarlo al momento de generar texto:
y ahora le cuento a Kate que estoy aprendiendo decoradores con Facundo(Kate se llama mi modelo) 😃
Yo realice el juego de piedra, papel o Tijera, donde la maquina selecciona su jugada de manera random y nosotros utilizamos la función mi_turno para pasarle la jugada desde una variable global. Y la función wrapper se encarga de analizar quien gana.
Al ejecutar:
Hice un decorador para poner en memoria cache consultas de SQL para evitar conexiones hacia la base de datos
Hola, aquí mi reto que decidí hacer. Básicamente lo que hace es obtener la distancia euclidiana entre dos puntos, que es la que todos conocen. Pero aparte la decore con una función para obtener la distancia de manhattan.
Agregué un decorador a mi juego del ahorcado donde ahora muestra lo que demoro en ganar el juego, lo mas sorprendente es que me funcionó jaja 😀
Hice que el mío tomara una función que lee un archivo csv, y me devuelva una pequeña descripción de los datos leídos.
def describe_df(func):
def wrapper():
func()
print(f'El tamano del data set es: {func().shape}')
print(f'Los tipos de datos del dataset son:\n{func().dtypes}')
return wrapper
@describe_df
def data_csv():
df = pd.read_csv('Direccion archivo csv')
return df
El siguiente programa consiste en encriptar un texto por medio del cifrado César, que consiste en correr la posición de los caracteres que componen el texto a través del alfabeto o un listado alfanumérico.
La función encrypt cifra el texto mediante el número de posiciones a correr, estos son datos ingresados por el usuario (text, shift_number).
El decorador entrega una función que permite descifrar el texto.
def decrypt(func):
def wrapper(text: str, shift_number: int) -> str:
shift_number = shift_number * (-1)
return func(text, shift_number)
return wrapper
def encrypt(string: str, shift_number: int) -> str:
alphabet_lower = "abcdefghijklmnñopqrstuvwxyz"
alphabet_upper = "ABCDEFGHIJKLMNÑOPQRSTUVWXYZ"
numbers = "0123456789"
encrypted = "" # Encrypted string
for charact in string:
if charact.islower() and (charact in alphabet_lower):
index = alphabet_lower.find(charact)
index = (index + shift_number) % 27
encrypted += alphabet_lower[index]
elif charact.isupper() and (charact in alphabet_upper):
index = alphabet_upper.find(charact)
index = (index + shift_number) % 27
encrypted += alphabet_upper[index]
elif charact in numbers:
index = numbers.find(charact)
index = (index + shift_number) % 10
encrypted += numbers[index]
else:
encrypted += charact # for special characters
return encrypted
if __name__ == "__main__":
text = input("Enter the text to encrypt: ")
shifts_number = int(input("Enter the number of shifts: "))
encrypted_text = encrypt(text, shifts_number)
print("\n Encrypted text: " + encrypted_text)
# Decrypt process
decrypt_function = decrypt(encrypt)
decrypt_text = decrypt_function(encrypted_text, shifts_number)
print("\n Decrypted text: " + decrypt_text)
Muy interesante y divertido!
Realicé un pequeño programa al que podemos ingresarle el hábito que queremos desarrollar y la cantidad de minutos al día que le vamos a dedicar, aplicando lo que aprendimos de decoradores y closures. cuentenmé qué tal les parece y qué puedo mejorarle. 😁
def year_of_daily_effort(func):
def wrapper(*args, **kwargs):
func(*args, **kwargs)
habit_and_time = args
total_yearly = int(habit_and_time[1])*365
print('At the end of the year you will practice ' + str(habit_and_time[0])+' a total of '+str(total_yearly)+' minutes!')
return wrapper
@year_of_daily_effort
def daily_habit(habit: str, minutes: int) -> str:
print(f"your habit is {habit} for {minutes} minutes daily")
daily_habit("yoga",25)
#OUTPUT
#your habit is yoga for 25 minutes daily
#At the end of the year you will practice yoga a total of 9125 minutes!
Como pueden notar, descubrí que podemos hacer operaciones conlor args dentro del wrapper accediendo a ellos como componentes de una lista según fueron ingresados.
😆 Yo hice un decorador que contara las palabras más comunes de una canción. 🎶🎶🎶
👉 Repositorio Completo
import urllib.request
from collections import Counter
def word_counter(func):
def counter(*args, **kwargs):
data = func(*args, **kwargs)
total_words = data.split()
stopwords = ['y','Y','la','de','una','los','me','No','con','que','el','un','es','en','Que','muy','al','a','él','le','quiere','A','da','faltan','Mas','bien']
words = [word for word in total_words if word not in stopwords]
wordcount = Counter(words)
print('\n>>> TOP FIVE WORDS IN THIS SONG <<<\n')
for w in wordcount.most_common(5):
print(f"{w[0]}: {w[1]}")
return counter
@word_counter
def text_reader(url):
data = urllib.request.urlopen(url).read().decode('utf_8')
return data
chilanga_banda = 'https://raw.githubusercontent.com/isabelyb/word_counter/main/chilanga_banda_lyrics.txt'
p_to = 'https://raw.githubusercontent.com/isabelyb/word_counter/main/pto.txt'
ciclon = 'https://raw.githubusercontent.com/isabelyb/word_counter/main/ciclon.txt'
# Output
text_reader(chilanga_banda)
# >>> TOP FIVE WORDS IN THIS SONG <<<
# bailan: 8
# tibiritábara: 8
# Pachucos: 4
# cholos: 4
# chundos: 4
text_reader(p_to)
# >>> TOP FIVE WORDS IN THIS SONG <<<
# Puto,: 26
# machino: 8
# Marica: 4
# nena: 4
# putino: 4
text_reader(ciclon)
# >>> TOP FIVE WORDS IN THIS SONG <<<
# rueda: 8
# vueltas: 7
# flecha: 6
# Gira: 6
# Dios: 3
Hice la vaquita que vimos en el curso de terminal, permite poner el texto que deseemos, siempre que sea de una línea para que lo diga la vaquita cow, espero les guste (y sirva de guía para lo que podemos hacer con decoradores):
# Decorador para usar Cowsay con cualquier texto (a 1 línea)
from datetime import date, datetime
def cowsay(func):
def wrapper(text):
lenght = len(text)
print(" _" + lenght*"_" + "_ ")
print("< " + text + " > ")
print(" -" + lenght*"-" + "- ")
print(" \ ^__^ ")
print(" \ (oo)\_______ ")
print(" (__)\ )\/\ ")
print(" ||----w | ")
print(" || || ")
return wrapper
@cowsay
def mytext(text):
print(text)
mytext("No pares de aprender!")
Buenas comparto mi código, hice un decorador que te devuelve el nombre de la función que ingresas en formato ASCII artístico para ello debes instalar pyfiglet con pip install pyfiglet.
Codigo:
import pyfiglet
def print_name(func):
def wrapper():
name = func.__name__
ascii_banner = pyfiglet.figlet_format(name)
print(ascii_banner)
func()
return wrapper
@print_name
def Platzi():
print("Running function...")
Platzi()
Resultado:
este es el mío, sencillo pero funciona
import os
def decorator(func):
def wrapper():
os.system('cls')
print('❤❤❤ ⭐⭐⭐')
func()
return wrapper
@decorator
def gereetings():
greeting = input('intruduce tu nombre: ')
print('hola un gusto conocerte', greeting.capitalize(), 'nos alegra mucho conocerte')
def run():
gereetings()
if __name__=='__main__':
run()
Haciendo un web scraper a https://news.ycombinator.com/ , tome el título y el link de cada artículo y al final usando un decorador coloque un emoji que se escoge aleatoriamente.
import requests
import lxml.html as html
import datetime
import emoji
import random
HOME_URL = 'https://news.ycombinator.com/'
XPATH_LINK_TO_ARTICLE = '//td[@class="title"]/a/@href'
XPATH_TITLE = '//td[@class="title"]/a/text()'
def random_emoji():
list_emojis = ["💚","🐍","🚀","🐱👤","🏛","🗺","🤣","👌","🐱🐉", "🐲", "🐘", "🦘", "🐳", "🧠", "🦾", "💅", "🎈", "📗", "🟨"]
rand = random.choice(list_emojis)
return rand
def put_emoji(parse_home):
def wrapper(*args, **kwargs):
parse_home()
today = datetime.date.today().strftime('%d-%m-%Y')
with open(f'{today}.txt', 'a', encoding='utf-8') as f:
f.write(f'\n\t\tThe emoji of today is: {args[0]}\n')
return wrapper
@put_emoji
def parse_home():
try:
response = requests.get(HOME_URL)
if response.status_code ==200:
home = response.content.decode("utf-8")
parsed = html.fromstring(home)
links_to_articles = parsed.xpath(XPATH_LINK_TO_ARTICLE)
title_of_articles = parsed.xpath(XPATH_TITLE)
today = datetime.date.today().strftime('%d-%m-%Y')
with open(f'{today}.txt', 'w', encoding='utf-8') as f:
for i in range(0,len(title_of_articles)-1):
f.write(f'Title description: {title_of_articles[i]}')
f.write(f'\n\t Link: {links_to_articles[i]}')
f.write('\n\n')
else:
raise ValueError(f"Error: {response.status_code}")
except ValueError as ve:
print(ve)
def run():
rand=random_emoji()
parse_home(rand)
if __name__ == '__main__':
run()
Hola Amigos, el programa que hice está basado en un tipo Sign Up sencillo, para saber si una persona o tripulante puede hacer un Viaje Interestellar! 😄
Los parámetros para evaluar al viajero fueron tomados de los requisitos que pide la NASA para ser un astronauta.
El código puede ser partido y repartido en muchos módulos (packages), por cuestiones de practicidad
from platform import system
from os import system as console_command
from time import sleep
from datetime import date
from typing import Any, Callable, Generator, List
from numpy import arange as np_range
# Validations
def validate_strings(x: int, y: int, header: str, error_message: str) -> str:
"""Validate strings."""
while True:
gotoxy(x, y); print(header, end='')
gotoxy(x+len(header), y); string_not_formatted: str = input('').rstrip().title()
if string_not_formatted.replace(' ', '').isalpha() and string_not_formatted != '':
if string_not_formatted[0] != ' ':
blank_space: List = [pos for pos, char in enumerate(string_not_formatted) if char == ' ']
into_bucle: bool = False
for idx in blank_space:
try:
iterator: int = idx + 1
if string_not_formatted[idx] == string_not_formatted[iterator]: # ' ' == ' ' -> ERROR!
into_bucle = True
break
except IndexError: pass
if not into_bucle:
string: str = ''
for letter in string_not_formatted.split(): string += letter + ' '
return string.strip()
else: pass
else: pass
gotoxy(x+len(header)+len(string_not_formatted), y); print(error_message)
sleep_screen(x+len(header)+len(string_not_formatted), y, error_message, string_not_formatted)
def validate_floats(x: int, y: int, header: str, error_message: str, type: str) -> float:
"""Validate floats."""
while True:
gotoxy(x, y); print(header, end='')
try:
gotoxy(x+len(header), y); numbers: str = input('').rstrip()
if numbers[0] != ' ':
if type == 'w':
number_weight = [round(x, 2) for x in np_range(20, 635.01, 0.01)]
if binary_search(number_weight, float(numbers)):
return float(numbers)
else:
number_height = [round(i, 2) for i in np_range(0.72, 2.73, 0.01)]
if binary_search(number_height, float(numbers)):
return float(numbers)
else: pass
except ValueError: pass
gotoxy(x+len(header)+len(numbers), y); print(error_message)
sleep_screen(x+len(header)+len(numbers), y, error_message, numbers)
def validate_dates(x: int, y: int, header: str, error_message: str) -> date:
"""Validate dates."""
while True:
gotoxy(x, y); print(header, end='')
try:
gotoxy(x+len(header), y)
string: str = input('').rstrip().replace(' ', '!').replace('\t', '!!!!!!!!')
list_string: List = string.split('/')
if list_string[0][0] != '0' and list_string[1][0] != '0' and list_string[2][0] != '0':
if len(list_string) == 3:
return date(int(list_string[0]), int(list_string[1]), int(list_string[2]))
else: pass
else: pass
except (SyntaxError, ValueError, NameError, TypeError, IndexError): pass
gotoxy(x+len(header)+len(string), y); print(error_message)
sleep_screen(x+len(header)+len(string), y, error_message, string)
def calculate_age(birth_date: date) -> int:
"""Calculate age."""
today: date = date.today()
age: int = today.year - birth_date.year - ((today.month, today.day) < (birth_date.month, birth_date.day))
return age
def validate_blood(x: int, y: int, header: str, error_message: str) -> str:
"""Validate type of blood."""
while True:
gotoxy(x, y); print(header, end='')
gotoxy(x+len(header), y); string: str = input('').rstrip().upper()
if string[0] != ' ':
if len(string) in range(2, 4):
if len(string) == 2:
if string in ('O+', 'O-', 'A+', 'A-', 'B+', 'B-'): return string
else: pass
else:
if string in ('AB+', 'AB-'): return string
else: pass
else: pass
gotoxy(x+len(header)+len(string), y); print(error_message)
sleep_screen(x+len(header)+len(string), y, error_message, string)
def validate_gender(x: int, y: int, header: str, error_message: str) -> str:
"""Validate a person's gender."""
while True:
string: str = validate_strings(x, y, header, error_message)
if string[0] != ' ':
if len(string) == 1:
if string in ('M', 'F'): return string
else: pass
else: pass
gotoxy(x+len(header)+len(string), y); print(error_message)
sleep_screen(x+len(header)+len(string), y, error_message, string)
# Fuctions for the program.
def welcome_traveler() -> None:
"""Welcome the traveler and explain the program."""
clean_screen()
gotoxy(4, 4); print("INTERSTELLAR TRAVEL ⊂(◉‿◉)つ")
gotoxy(6, 6); print("* Hello traveler, welcome to the adventure of your life!")
gotoxy(7, 8); print("+ Then, sign out to see if you can do interestellar")
gotoxy(9, 9); print("travel without any problems.")
gotoxy(6, 11); print("→ Press a key to continue..."); input('')
def greeting_traveler(func) -> Callable[[Any], Any]:
"""Greet the traveler."""
def wrapper(*args: Any) -> Any:
clean_screen()
gotoxy(4, 4); print("INTERSTELLAR TRAVEL ⊂(◉‿◉)つ")
gotoxy(6, 6); print("→ Hello traveler, we are preparing")
gotoxy(9, 7); print("you for the trip!")
return func(*args)
return wrapper
def processing(x: int, y: int, sms: str) -> None:
"""It's responsible for simulating a system processing."""
for _ in range(1, 16): # 5 seconds for processing.
try:
gotoxy(x, y); print(sms+next(generator))
sleep(0.333333334)
gotoxy(x, y); print(' '*len(sms))
except (NameError, StopIteration):
generator: Generator = (i for i in ('. )', '.. )', '...)'))
@greeting_traveler
def choice_of_traveler(*args: Any) -> bool:
"""Initialize the traveler's choice."""
args = args[0]
age: int; height: float; bmi: float
age, height, bmi = \
args[0], args[1], args[2]
traveler: List = []
gotoxy(8, 9); print("» Validating data to know if you are")
gotoxy(11, 10); print("an ideal candidate to travel.")
# Test 1.
sms_proc = "(Processing"
gotoxy(8, 12); print("~ Age (23-37)")
processing(30, 12, sms_proc)
if age in range(23, 38):
gotoxy(30, 12); print('[ ✓ ]')
traveler.append(True)
else:
gotoxy(30, 12); print('[ X ]')
traveler.append(False)
# Test 2.
gotoxy(8, 13); print("~ Height (1.50-1.90)")
processing(30, 13, sms_proc)
number_height = [round(i, 2) for i in np_range(1.50, 1.91, 0.01)]
if binary_search(number_height, height):
gotoxy(30, 13); print('[ ✓ ]')
traveler.append(True)
else:
gotoxy(30, 13); print('[ X ]')
traveler.append(False)
# Test 3.
gotoxy(8, 14); print("~ BMI ( )")
processing(30, 14, sms_proc)
if bmi < 18.5:
gotoxy(15, 14); print(' Underweight ')
gotoxy(30, 14); print('[ X ]')
traveler.append(False)
elif bmi >= 18.5 and bmi < 25:
gotoxy(15, 14); print('Normal weight')
gotoxy(30, 14); print('[ ✓ ]')
traveler.append(True)
elif bmi >= 25 and bmi < 30:
gotoxy(15, 14); print(' Overweight ')
gotoxy(30, 14); print('[ X ]')
traveler.append(False)
elif bmi >= 30:
gotoxy(15, 14); print(' Obesity ')
gotoxy(30, 14); print('[ X ]')
traveler.append(False)
if False in traveler: return False
else: return True
def goodbyes(name: str, choice: bool) -> None:
"""Farewell to the traveler and tells him
if he passed the test to make the trip or not."""
if choice:
gotoxy(6, 16); print("→ Congratulations {}! You are an ideal candidate.".format(name))
else:
gotoxy(6, 16); print("→ Sorry {}, you are not an ideal candidate.".format(name))
gotoxy(0, 17); print('')
gotoxy(8, 18); print("→ Press a key to exit..."); input('')
# Utilities
def calculate_bmi(weight: float, height: float) -> float:
"""Calculate the Body Mass Index."""
return round(weight / (height**2), 1)
def binary_search(list_num: List, item: float) -> Any:
"""Binary search algorithm."""
if len(list_num) == 0: return False
else:
midpoint = len(list_num) // 2
if list_num[midpoint] == item: return True
else:
if item < list_num[midpoint]: return binary_search(list_num[:midpoint], item)
else: return binary_search(list_num[midpoint+1:], item)
def gotoxy(x: int, y: int) -> None:
"""This function is in charge of positioning
the cursor on any axis of the console."""
print ("%c[%d;%df" % (0x1B, y, x), end='')
def clean_screen() -> None:
"""This function is responsible for cleaning the screen."""
if system() == 'Windows': console_command('cls')
else: console_command('clear')
def sleep_screen(x: int=4, y: int=20, error: str='',
date_input: Any='', time: int=3) -> None:
"""This function is responsible for cleaning the
screen while waiting a few seconds."""
for second in reversed(range(1, time+1)):
gotoxy(x+len(error), y); print(' '*150)
if second != 1:
gotoxy(x+len(error), y); print(" // Wait", second, "seconds!")
sleep(1)
else:
gotoxy(x+len(error), y); print(" // Wait", second, "second !")
sleep(1)
gotoxy(x-len(date_input), y); print(' '*200)
# Main program.
def main():
ERROR_MESSAGE = " Please enter a valid information..."
welcome_traveler()
clean_screen()
gotoxy(4, 4); print("INTERSTELLAR TRAVEL ⊂(◉‿◉)つ")
gotoxy(10, 6); print("TRAVELER DATA")
names_tvl: str = validate_strings(10, 8, "→ Names : ", ERROR_MESSAGE)
birthday_tvl: date = validate_dates(10, 9, "→ Birthday (year/month/day) : ", ERROR_MESSAGE)
age_tvl: int = calculate_age(birthday_tvl)
gotoxy(10, 10); print("→ Age :", str(age_tvl), 'years old')
gender_tvl: str = validate_gender(10, 11, '→ Gender (Male"M"|Female"F") : ', ERROR_MESSAGE)
blood_type_tvl: str = validate_blood(10, 12, "→ Blood Type (O+, A-...N±) : ", ERROR_MESSAGE)
height_tvl: float = validate_floats(10, 13, "→ Height (Meters) : ", ERROR_MESSAGE, 'h')
weight_tvl: float = validate_floats(10, 14, "→ Weight (Kilograms) : ", ERROR_MESSAGE, 'w')
gotoxy(6, 16); print("→ Press a key to continue..."); input('')
bmi_tvl: float = calculate_bmi(weight_tvl, height_tvl)
choice_tvl: bool = choice_of_traveler((age_tvl, height_tvl, bmi_tvl))
goodbyes(names_tvl, choice_tvl)
clean_screen()
if __name__ == '__main__':
main()
*ARGS y **KWARGS
Para mayor desarrollo de ambos conceptos, les dejo las siguientes lecturas:
concepto: https://www.geeksforgeeks.org/args-kwargs-python/
10 Examples to Master *args and **kwargs in Python: https://towardsdatascience.com/10-examples-to-master-args-and-kwargs-in-python-6f1e8cc30749
Creo que se entiende además de ser divertido 😄
Hice mi propio decorador que indica cual es la dificultad de una función a traves de la cantidad de argumentos pasados (Espero que se entienda xd)
def function_level(func):
def wrapper(*args, **kwargs):
print(func(*args, **kwargs))
n_lenghts = len(args)
if n_lenghts == 1:
print('It\'s an easy function')
elif n_lenghts == 2 or n_lenghts == 3:
print('It\'s a middle level function')
else:
print('It\'s a hard function')
return wrapper
@function_level
def division(a: int, b: int) -> int:
return a/b
division(2, 2)
Reto
Bart say
def bart_say(func):
def wrapper(text):
func(text)
print(' |/')
print("|\/\/\/|")
print("| |")
print("| |")
print("| (o)(o)")
print("C _)")
print("| ,___|")
print("| /")
print("/____|")
print("/ |")
return wrapper
@bart_say
def print_text(input_text):
text_len = len(input_text)
print("⌈" + text_len * "¯" + "⌉")
print("⁞" + input_text + "⁞")
print("⌊" + text_len * "_" + "⌋")
def run():
input_text = str(input("Input a text: "))
print_text(input_text)
if __name__ == '__main__':
run()
Vamos a hacer un programa que nos diga si Thanos de mata o no cuando chasquea los dedos.
import random
def infinityGauntlet(func):
def wrapper(*args, **kwargs):
func(*args, **kwargs)
fingerSnap=random.randint(0, 1)
if fingerSnap == 1:
print('Mueres')
else:
print('Vives')
return wrapper
@infinityGauntlet
def genocide(name = 'Joel'):
print('Hola '+ name + (', Thanos decide que: '))
genocide()
#Resultado:
#Hola Joel, Thanos decide que
#Vives
Codigo del reto:
Si tengo una funcion que reciba texto y quiero asegurarme que solo tencha letras
el decorador retorna el texto pero quitando caracteres que sean digitos
def num_extractor(func: callable) -> callable:
def wrapper(text: str) -> str:
nums_extracted = [char for char in text if not char.isdigit()]
return "".join(nums_extracted)
return wrapper
@num_extractor
def text_receiver(text: str) -> str:
return text
text = "hola2 aksm22"
result = text_receiver(text)
print(result) # hola aksm
Hice esto intentando aplicar los conocimientos de la trilogía de Python. Sacando la idea del curso de programación básica , calculando el peso en cada planeta.
Alguna mejora o mejor implementación me gustaría saberla:
PLANETS_GRAVITY = [
{
'value': 0,
'name': 'Tierra',
'grivity': 9.807
},
{
'value': 1,
'name': 'Marte',
'grivity': 3.711
},
{
'value': 2,
'name': 'Jupiter',
'grivity': 24.8
},
{
'value': 3,
'name': 'Mercurio',
'grivity': 3.7,
},
{
'value': 4,
'name': 'Urano',
'grivity': 8.89,
},
{
'value': 5,
'name': 'Venus',
'grivity': 8.89,
},
{
'value': 6,
'name': 'Saturno',
'grivity': 10.44,
},
{
'value': 7,
'name': 'Neptuno',
'grivity': 11.15
},
]
from datetime import datetime
def execution_time(calculate): #Calcula el tiempo que se demora una funcion en ejecutarse
def wrapper(*args, **kwargs): #*arg, **kwargs SIRVE PARA PONER LOS ARGUMENTOS IMPISITAMENTE
initial_time = datetime.now() #imarca tiempo de inicializacion
calculate(*args, **kwargs) #Ejecuta la funcio
final_time = datetime.now() #Marca tiempo de finalizacion
time_elapsed = final_time - initial_time #Tiempo total = tiempo final - timpoInicial
print('\nEl programa funciono por ' + str(round(time_elapsed.total_seconds(),2)) + ' segundos')
return wrapper
def calculate(weight, planet):
planet_name = [num_planet['name'] for num_planet in PLANETS_GRAVITY if num_planet['value'] == planet]
planet_gravity = [num_planet['grivity'] for num_planet in PLANETS_GRAVITY if num_planet['value'] == planet]
gravity_eart = [num_planet['grivity'] for num_planet in PLANETS_GRAVITY if num_planet['value'] == 0]
my_weight_in_planet = weight * planet_gravity[0] / gravity_eart[0]
print('\nTu peso en ', planet_name[0], 'es de ', str(round(my_weight_in_planet,2)),'kg')
@execution_time
def run():
print('Tu peso en otros planetas')
weight = int(input('¿Cuanto pesas?: kg '))
planet = int(input('''¿De que planeta quiere saber tu peso?:
1: Marte.
2: Jupiter.
3: Mercurio.
4: Urano.
5: Venus.
6: Saturno.
7: Neptuno.
Ingresa el numero correspondiente: '''))
while planet < 0 or planet > 7:
planet = int(input('''Seleccion invalida
¿De que planeta quiere saber tu peso'''))
calculate(weight, planet)
if __name__ == '__main__':
run()
Pequeño codigo que crea un archivo .txt con un mensaje dado:
Este es mi reto. En una lista creo un conjunto de materias y los créditos necesarios para aprobar esa materia. Luego desde la terminal pide el ingreso de la materia y los créditos obtenidos.
def verify_status_materia(func):
def wrapper(materia, creditos):
func(materia, creditos)
assert type(materia) == str, "El nombre de la materia debe ser un string"
assert type(creditos) == int, "El valor de los créditos debe ser un número"
list_materias = [
{
"materia": "Geometria",
"creditos": 18
},
{
"materia": "Yoga",
"creditos": 17
},
{
"materia": "Desarrollo Web",
"creditos": 17
},
{
"materia": "Estructura de datos",
"creditos": 15
},
{
"materia": "Artes",
"creditos": 16
},
]
res = list(filter( lambda datos: datos['materia'].lower() == materia.lower(), list_materias ))
if (len(res) > 0):
if creditos >= res[0]['creditos']:
print("Felicidades, aprobaste!! :) ")
else:
print("Lo sentimos, acabas de reprobar la materia! :( ")
else:
print("Materia no encontrada, digite correctamente la materia")
return wrapper
@verify_status_materia
def verificar_aprobacion(materia: str, nota: float):
print("Bucando en la bd, por favor espere")
for _ in range(1,50000000):
pass
def run():
materia = input("Ingresa el nombre de una materia: ")
creditos = int(input("Ingresa los créditos obtenidios: "))
verificar_aprobacion(materia, creditos)
if __name__ == '__main__':
run()
, te dice cuanto se demora en ejecutar el proceso(incluido el tiempo que te toma escribir las variables).
También te lo grafica(En este punto no se si lo hice bien, ya que use la media de X y la media de Y para graficar , ojala alguien me pueda explicar.).
Independientemente de la funcionalidad me sirvió para recordar algunas cosas de otros cursos.
import random
from typing import List
from bokeh.plotting import figure, show
from estadistica import media
from datetime import datetime
def time_func(func) -> int:
def lapse(*args, **kwargs):
init_time = datetime.now()
func(*args, **kwargs)
end_time = datetime.now()
total_time = end_time - init_time
print("Se demora: " + str(total_time.total_seconds()))
return lapse
def average(func) -> int:
def average_print(*args):
result_med = media(func(*args))
return result_med
return average_print
@average
def x_y_generator(list_size) -> List:
list = []
for _ in range(list_size):
list.append(random.randrange(1, 100))
return list
def show_figure(x_list, y_list):
print(x_list, " Media de X")
print( y_list, " Media de Y")
graph = figure(title = "Bokeh Vertical Bar Graph")
width = 0.1
graph.vbar(x_list, top = y_list, width = width)
show(graph)
def generator_list(number_of_points, list_size):
x_list: List [int] = []
y_list: List [int] = []
for _ in range(number_of_points):
x_list.append(x_y_generator(list_size))
y_list.append(x_y_generator(list_size))
show_figure(x_list, y_list)
@time_func
def main():
number_of_points = int(input("Cuantos puntos en tu grafico quieres?: "))
list_size = int(input("Cuantos valores quieres por cada lista?: "))
generator_list(number_of_points, list_size)
if __name__ =='__main__':
main()
No es mucho, pero es trabajo honesto
En mi opinion si seria necesario los quiz cuando se termine un modulo…y a los mismos aumentar por lo menos a 6 preguntas…
Aquí dejo mi aporte, es un “jueguito” donde pierdes si te sale el fantasma.
import random
from os import system
door = """
------> 🚪 <------
Encontraste una puerta"""
decision = """
¿Quieres entrar?(y/n): """
decision_2 = """
Tienes un arma de los caza fantasma.
¿Quieres usarla?(y/n): """
pasos = """
-----------------------------------
👟 👟 👟 👟 👟.....caminando"""
nothing = """
En esta habitación no hay nada."""
boo = """
._ _ _ _ _ _ _ _
| |
| BOOOO! |
|_ _ _ _ _ _ _|
\/
👻"""
def walk_to(func):
def steps():
stuff = ['nada', 'nada', 'ghost']
while True:
behind_to = random.choice(stuff)
print(pasos)
print(door)
deci = input(decision)
if deci == 'y':
if behind_to == 'nada':
system('clear')
print(nothing)
elif behind_to == 'ghost':
func()
break
return steps
def run():
@walk_to
def scare():
system('clear')
print(boo)
print('Salado ñaño, PERDISTE')
scare()
if __name__=='__main__':
run()
Espero que me puedan ayudar con consejos para poder seguir mejorando.
Nunca paren de aprender!
Un decorador para sacar la raíz cuadrada.
def square_root(function):
def wrapper(*args, **kwargs):
print(round(math.sqrt(function(*args, **kwargs)), 9))
return wrapper
@square_root
def suma(a, b):
return a + b
suma(10, 10) # terminl -> 4.472135955
"""
create a function that receives two numbers for example 425 and 46
and outputs 446, thus by removing the length of the second number from de firs
and changing it by de second number.
Then add a decorator that add the message "Your updated number is:
Good Luck!!
"""
def execution_time(func):
def wrapper(*args, **karg):
initial_time = datetime.now()
func(*args, **karg)
final_time = datetime.now()
time_enlapsed = final_time - initial_time
print(f'Time enlapsed {time_enlapsed} seconds')
return wrapper
def message(func):
def wrapper(*args, **karg):
print("Your updated number is: ")
func(*args, **karg)
return wrapper
@execution_time
@message
def change(primitive_number, new_number) ->int:
leng_new_number = len(str(new_number))
primitive_number_cut = int(primitive_number/(10 ** leng_new_number))
updated_number = (primitive_number_cut * 10 ** leng_new_number) + new_number
print(" " * 24 + str(updated_number))
def run():
primitive_number = 425
new_number = 46
change(primitive_number, new_number) #should output 446
if __name__=="__main__":
run()
import math
def motivation(func):
def wrapper(*args, **kwargs):
print("Hola amigo, este es el resultado de tu operación:")
print(func(*args, **kwargs))
print("Sigue adelante, recuerda que la práctica hace al maestro!")
print("¡No te rindas nunca y nunca pares de aprender!")
return wrapper
@motivation
def multiply(a: int,b: int) -> int:
return a*b
def sum(a: int,b: int) -> int:
return a+b
@motivation
def sqrt(a: int) -> float:
return math.sqrt(a)
if __name__ == '__main__':
print(str(multiply(8,125))+"\n")
print(str(sum(8,12))+"\n")
print(str(sqrt(20))+"\n")
Yo decidí decorar mis operaciones matemáticas con frases que me inspiran. Espero usarlas en mi vida diaria de manera más práctica.
Hice una función que genera listas de tamaño n con números aleatorios entre min y max. El decorador se encarga de ordenar estas listas. Realmente es muy básico y se puede hacer directamente pero no se me ocurría algo más. 😅
Quería hacer una función para tener la temperatura, humedad, altura… de una ciudad dada y con decoradores agregar nuevas funcionalidades, como saber si ir o no a la playa o si llevar sombrilla … pero creo que es una mala implementación de los decoradores, aiuda
import requests, json
# ingresamos la API KEY
api_key = 'ddacb260cd156611fd36dd307458bc44'
# direccion web desde donde solicitaremos la informacion
base_url = "ap.openweathermap.org?"
# ciudad (se lo mas especifico posible en el nombre)
city_name = 'Mexico'
# esta es la URL completa con la informacion concatenada para realizar la petición correcta
complete_url = base_url + "appid=" + api_key + "&q=" + city_name
# Ejecutamos la consulta
response = requests.get(complete_url)
# Obtenemos la respuesta en formato JSON
x = response.json()
if x["cod"] == 200:
# En “main” se encuentra la informacion principal del estado del tiempo
y = x["main"]
# Almacenamos la temperatura
temperatura = x['main']['temp']- 273
# presion atmosferica
current_pressure = y["pressure"]
# humedad
current_humidity = y["humidity"]
print('La temperatura de la ciudad de ' + x['name'] + ' es de : ' + str(temperatura))
Este código calcula el tiempo que tarda en realizar una transferencia. Debes ingresar el nombre, número de cuenta y la cantidad a tranferir.
Solo simula el proceso básico de una transferencia.
from datetime import datetime
def execution_time(func):
def wrapper(*args, **kwargs):
initial_time = datetime.now()
func(*args, **kwargs)
final_time = datetime.now()
result = final_time - initial_time
print(f'The process took {result.total_seconds()} seconds.')
return wrapper
@execution_time
def transfer(account: str, balance: int):
beneficiary = input("Beneficiary's name: ")
bank_account = int(input("Recipient's bank account: "))
amount = int(input("Amount you want to transfer: "))
actual_balance = balance - amount
if actual_balance < 0:
print('You do not have enough credit')
else:
print(f'You have just transferred ${amount} to {beneficiary}.')
print(f'Your current balance is ${actual_balance}')
transfer('Alexander', 4000)
Función para calcular el tiempo en llegar a un número de uno en uno.
from datetime import datetime
def execution_time(func):
def wrapper(*args, **kwargs):
initial_time = datetime.now()
func(*args, **kwargs)
final_time = datetime.now()
time_elapsed = final_time - initial_time
print(f'Pasaron {time_elapsed.total_seconds()} segundos en ejecutar el número.')
return wrapper
@execution_time
def run():
number = int(input('Dame un número y vemos en cuanto llegamos: '))
for i in range(0, number):
i = i + 1
print(i)
if __name__ == '__main__':
run()
from datetime import datetime
def execution_time(func):
def wrapper(*args, **kwargs):
initial_time = datetime.now()
func(*args, **kwargs)
final_time = datetime.now()
time_elapsed = final_time - initial_time
print(f’Pasaron {time_elapsed.total_seconds()} segundos’)
return wrapper
@execution_time
def random_func():
for _ in range(1, 10000000):
pass
random_func()
def number_random(func):
def wrapper(*args, **kwargs):
os.system('clear')
print('adivina el numero del 1 al 10')
number = random.randint(1, 10)
func(*args, **kwargs)
if args == number:
print(f'yes the number is {number}')
else:
print(f'Game over the number is {number}')
return wrapper
@number_random
def num(n):
print(f'your number is {n}')
def run():
num(2)
if __name__ == '__main__':
run()
Este es mi aporte
<
clients_list = []
file = "../base/.data.csv"
def save_disc(func):
def wraper(*args,**kwargs):
func(*args,**kwargs)
mode = "a"
if os.stat(file).st_size == 0:
mode = "w"
with open(file,mode=mode,encoding="utf-8") as csvfile:
writer = csv.DictWriter(csvfile,fieldnames["name","age"])
if mode == "w":
writer.writeheader()
writer.writerows(clients_list)
return wraper
@save_disc
def create_client(name,age):
new_client = Client(name,age)
clients_list.append(new_client.to_dict())
>
Les presento a continuación el reto libre. Consiste en generar un log por cada ejecución de una función en un archivo de texto .log. El archivo va a contener el nombre de la función, el resultado y la fecha en la que se ejecutó.
Previo al ejercicio se debe tener el archivo file.log en la misma ruta del proyecto, se lo puede mejorar, pero la idea es aplicar los decoradores en algo práctico:
import os
from datetime import datetime
def log_function(func):
def wrapper(*args, **kwargs):
THIS_FOLDER = os.path.dirname(os.path.abspath(__file__))
my_file = os.path.join(THIS_FOLDER, 'file.log')
date = datetime.now()
xfile = open(my_file, "a")
output = func(*args, **kwargs)
print(output)
xfile.write(f"Log-{func} - Resultado: {output} Fecha: {date}\n")
xfile.close()
return wrapper
@log_function
def suma(a: int, b:int) -> int:
return (a+b)
@log_function
def resta(a: int, b:int) -> int:
return (a+b)
@log_function
def multiplica(a: int, b:int)-> int:
return (a*b)
@log_function
def divide(a: int, b:int)-> float:
assert b!=0, "No se puede dividir para 0"
return (a/b)
suma(2,50)
resta(5,2)
multiplica(6,2)
divide(50,2)
Lo que hice fue una función que reciba un texto y que obtenga todos los nombres que “matcheen” con este texto. El decorador que hice fue para hacer que los espacios del texto se transformen en comodines y que esos espacios matcheen con cualquier letra.
from typing import List
import re
NAMES = [
'Joaquín Cruz',
'Jessica Cruz',
'Pablo Martínez',
'Cuarta Person',
'Roberto Martínez',
'Bárbara Jerez'
]
def with_query(func):
def wrapper(query : str) -> List[str]:
query = f'.*{query.replace(" ", ".*")}.*'
return func(query)
return wrapper
@with_query
def match_names(query):
ret : List[str] = []
pattern = re.compile(query, flags=re.IGNORECASE)
for name in NAMES:
if pattern.match(name):
ret.append(name)
return ret
def run():
print(match_names('j cruz'))
if __name__ == '__main__':
run()
Resultado:
['Joaquín Cruz', 'Jessica Cruz']
# Reto: decorador que recibe parámetros
def set_custom_messages(init_msg, final_msg):
def set_messages(func):
def wrapper(*args, **kwargs):
print(init_msg)
func(*args, **kwargs)
print(final_msg)
return wrapper
return set_messages
@set_custom_messages("Este es el mensaje inicial", "Este es el mensaje final")
def walk(message):
print(message)
if __name__ == "__main__":
walk("Estoy caminando")
Buenos días, yo hice un ejemplo sencillo para trabajar con decoradores. Hice un decorador que calculaba el volumen de un prisma en base al área de la figura. Por cierto si alguien sabe como pasarle a un decorador un argumento de entrada además de la función se los agradecería. Aquí dejo mi código.
def volume(func):
def wrapper(*args, **kwargs):
height = int(input('Ingrese la altura del prisma: '))
area = func(*args, **kwargs)
return area * height
return wrapper
@volume
def triangule(a: int, b: int)->float:
return a * b / 2
@volume
def rectangle(a: int, b: int)->int:
return a * b
def run():
print('Encontrar el area de un prisma triangular y uno cuadrangular')
a = int(input('Ingrese el valor de A: '))
b = int(input('Ingrese el valor de b: '))
prism_r = rectangle(a,b)
prism_t = triangule(a,b)
print('El volumen del prisma cuadrangular es', prism_r)
print('El volumen del prisma triangular es', prism_t)
if __name__=='__main__':
run()
Si alguien tiene algún tipo de comentarios de como mejorar mi codigo, sera bien recibido.
Mi primer decorador, calcula el precio de un articulo con descuento.
def percentage_calculator_2(func):
def wrapper(item_price, item_percentage):
discount_price = item_price * item_percentage // 100
print("Tu artículo tiene un descuento de " + str(discount_price) )
func(item_price, item_percentage)
final_price = item_price - discount_price
print("Tu artículo cuesta " + str(final_price) + " después del descuento")
return wrapper
@percentage_calculator_2
def percentage_calculator (item_price: int, item_percentage: int) -> float:
print("Estamos trabajando para ti")
def run():
item_price = int(input("¿Que valor tiene tu artículo ? "))
item_percentage = int(input("¿Cuanto descuento tiene tu artículo ? "))
percentage_calculator(item_price, item_percentage)
if __name__ == '__main__':
run()
Código para elegir la cena y un decorador para añadir opciones extra y darle algo mas de variedad:
Yo hice un auto-scatter muy sencillo, básicamente le pasas una función que te regrese una lista de coordenadas, una lista de x
y una lista de y
y te hace el scatter automáticamente… Simple, pero le veo futuro
def auto_scatter(func):
def wrapper(*args, **kwargs):
X = func(*args, **kwargs)
plt.scatter(X[0], X[1])
plt.show()
return wrapper
En este caso lo probé con un generador de puntos aleatorio
@auto_scatter
def generate_random_points():
x = [floor(random()*101) for _ in range(100)]
y = [floor(random()*101) for _ in range(100)]
return x, y
Y listop C: generate_random_points()
Mi código sobre sabor de helado mas contorno como sugar sintatic 😉
def decorador(func):
"""Function decorador"""
def wrapper(message):
"""Function wrapper"""
add = input("Peanut contour or chococlate chip? ")
print(f'Your ice cream is of {message} with {add}')
return wrapper
@decorador
def ice_cream(message):
"""Function message"""
print(f'The ice cream is of: {message}')
def run():
"""Function start"""
message = input("Chocolate or Vanilla ice cream? ")
ice_cream(message)
if __name__ == '__main__':
run()
En mi opinion creo que los decoradores deberian ser creados para ser usados multiples veces en diferentes programas.
Por lo cual no se me ocurren muchas formas de usarlos a menos que sea en el uso de Frameworks cuyo codigo podria repetirse demaciado en donde serian bastante utiles pero fuera de eso heeee…
no se me ocurren muchas ideas.
Por cierto hice este programa hace relativamente poco en el curso CRUD con el profe David Aroesti
en fin lo hice con un FrameWork de C llamado Qt y que funciona con Python y otros lenguajes, el unico caso en donde se me ocurrio poner un @decorador fue en una funcion ejecutadora que siempre se repite de ahi en fuera no se me ocurren mas ideas XD
Si quieren ver el código completo y jugar con el, esta en mi github
from QtAgregar import QAgregar
from QtBusqueda import QBusqueda
from QtEditar import QEditar
from QtEliminar import QEliminar
from QtMostrar import QMostrar
from QtMultiplesIndices import QMultiplesIndices
from QtOpciones import QOpciones
from cliente import CLIENTES, AbrirBase_Declientes,GuardarBase_DeClientes
from PyQt5 import QtGui, QtCore
from PyQt5.QtWidgets import QApplication,\
QWidget,\
QLabel,\
QHBoxLayout,\
QVBoxLayout
class Ventana_principal(QWidget):
def __init__(self,lista = None):
super(QWidget,self).__init__()
self.propiedades_de_ventana()
self.iniciador(lista)
self.interfaz()
self.conexiones()
def propiedades_de_ventana(self):
self.setMinimumWidth(750)
def iniciador(self,lista):
self.LISTA_CLIENTES = lista
self.lista_de_widgets = []
self.boton_pulsado = None
self.menu_principal = QOpciones()
self.tabla_de_clientes = QMostrar()
self.menu_de_busqueda = QBusqueda()
self.editar = QEditar()
self.agregar = QAgregar()
self.eliminar = QEliminar()
self.elegir_cliente = QMultiplesIndices()
imagen = QtGui.QPixmap('./iconos/Python Qt5.png')
imagen.scaled(50,100)
self.Imagen = QLabel()
self.Imagen.setPixmap(imagen)
self.lista_de_widgets.append(self.menu_de_busqueda)
self.lista_de_widgets.append(self.editar)
self.lista_de_widgets.append(self.agregar)
self.lista_de_widgets.append(self.eliminar)
self.lista_de_widgets.append(self.Imagen)
self.lista_de_widgets.append(self.elegir_cliente)
self.__bloquear(4)
def __bloquear(self,exepcion = None):
if exepcion != None:
self.lista_de_widgets[exepcion].setHidden(False)
for ind, widget in enumerate(self.lista_de_widgets):
if ind != exepcion:
widget.setHidden(True)
def interfaz(self):
encabezado = QHBoxLayout()
encabezado.addWidget(self.menu_principal)
lateral_izq = QVBoxLayout()
lateral_izq.addWidget(self.menu_de_busqueda)
lateral_izq.addWidget(self.elegir_cliente)
lateral_izq.addWidget(self.editar)
lateral_izq.addWidget(self.agregar)
lateral_izq.addWidget(self.eliminar)
lateral_izq.addWidget(self.Imagen)
lateral_izq.setAlignment(QtCore.Qt.AlignTop)
lateral_der = QHBoxLayout()
lateral_der.addWidget(self.tabla_de_clientes)
centro = QHBoxLayout()
centro.addLayout(lateral_izq)
centro.addLayout(lateral_der)
self.CUERPO = QVBoxLayout(self)
self.CUERPO.addLayout(encabezado)
self.CUERPO.addLayout(centro)
def conexiones(self):
self.menu_principal.click[int].connect(self.__activar_funciones)
self.menu_principal.cancelar.connect(self.__restablecer_funciones)
self.menu_de_busqueda.click_busqueda[list].connect(self.__encontrado)
self.menu_de_busqueda.click_cancelar.connect(lambda: self.menu_principal.cancelar.emit(self.boton_pulsado))
self.elegir_cliente.indice_elegido[int].connect(self.__modificar_eliminar)
self.elegir_cliente.cancelar.connect(lambda: self.menu_principal.cancelar.emit(self.boton_pulsado))
self.eliminar.eliminar.connect(self.__mostrar)
self.eliminar.cancelar.connect(lambda: self.menu_principal.cancelar.emit(self.boton_pulsado))
self.editar.cambioHecho.connect(self.__mostrar)
self.editar.cancelar.connect(lambda: self.menu_principal.cancelar.emit(self.boton_pulsado))
self.agregar.Agregado[dict].connect(self.__agregar)
self.agregar.Cancelar.connect(lambda: self.menu_principal.cancelar.emit(self.boton_pulsado))
def __activar_funciones(self, ind = 4):
self.boton_pulsado = ind
if ind == 0 or ind == 1 or ind == 3:
self.__bloquear(0)
self.menu_de_busqueda.cargar(self.LISTA_CLIENTES)
elif ind == 2:
self.__bloquear(ind)
if ind == 4:
self.__mostrar()
def __mostrar(self):
self.__bloquear(4)
self.menu_principal._desbloquear(self.boton_pulsado)
self.tabla_de_clientes.ReCargar(self.LISTA_CLIENTES)
if self.boton_pulsado != 4:
GuardarBase_DeClientes()
def __encontrado(self, lista_de_informacion):
lista_de_diccionarios = lista_de_informacion[1]
self.tabla_de_clientes.ReCargar(lista_de_diccionarios)
if self.boton_pulsado == 0: # buscar
self.menu_principal.cancelar.emit(0)
else:
if len(lista_de_informacion[0]) > 1:
self.__bloquear(5)
self.elegir_cliente.cargar(lista_de_informacion[0])
else:
self.__modificar_eliminar(lista_de_informacion[0][0])
def __modificar_eliminar(self,ind):
print(ind)
self.__bloquear(self.boton_pulsado)
if self.boton_pulsado == 1: # editar
self.editar.cargar(self.LISTA_CLIENTES[ind])
if self.boton_pulsado == 3: # eliminar
self.eliminar.cargar(self.LISTA_CLIENTES,ind)
def __agregar(self, diccionario_nuevo):
self.LISTA_CLIENTES.append(diccionario_nuevo)
self.__mostrar()
def __restablecer_funciones(self):
self.__bloquear()
def DECO_QT_exec(__funcion__):
import sys
def window(*argc, **argv):
app = QApplication(sys.argv)
__funcion__(*argc,**argv)
sys.exit(app.exec_())
return window
@DECO_QT_exec
def ventana(lista:list):
v = Ventana_principal(lista)
v.show()
if __name__ == '__main__':
AbrirBase_Declientes()
ventana(CLIENTES) ```
Hey que tal, bueno no sé si a alguien le sirva mi código, pero lo único que hace es hacer que es que ejecute una función y espere 5 segundos. Esto lo hice pensando en tipo que le digas algo al usuario (como instrucciones para un juego) y deje el tiempo para que lo lea. Sin más aquí el código
from time import sleep
def amimir(func):
def mimiendo(*args,**kwargs):
func(*args,**kwargs)
sleep(5)
return mimiendo
@amimir
def texto(text:str)->None:
print(text)
texto('Heyyy muy buenas a todos, guapisimos, aquí vegetta777 en un nuevo gameplay en directo')
Dejo este snippet para validar permisos de usuarios a cierto recurso. En este snippet se añaden 2 decoradores, el primero para saber si el usuario está logeado y según para saber si el usuario tiene alguno de los permisos necesarios para acceder al recurso. Dejo un par de comentarios donde pueden extender la lógica según su caso de uso
This is my share.
<from datetime import datetime
def check_time(func):
def set(*args, **kwargs):
time_start = datetime.now()
func(*args, **kwargs)
time_end = datetime.now()
total_delay = time_end - time_start
print(f'Pasaron en total: {str(total_delay.total_seconds())} segundos')
return set
@check_time
def run(n: int) -> str:
if n < 2:
print('Not a prime number.')
else:
table = [x for x in range(2, n) if n % x == 0]
if len(table) > 0:
print('Not a prime number.')
else:
print('Its a prime number.')
if __name__ == '__main__':
run(104729)
>
Salto de linea con decoradores:
# this function prints a blank line
def new_line_decorator(func):
# This wrapper function supports parametrized functions
def wrapper(*args, **kwargs):
print("\n", end="")
func(*args, **kwargs)
return wrapper
# This decorator stores passes say_hello() function to new_line_decorator and calls its wrapper
@new_line_decorator
def say_hello():
print("Hello World!")
def main():
print("Hola")
say_hello()
if __name__ == '__main__':
main()
El mismo ejercicio de closures ahora con decoradores e incluyendo una variable al decorador lo que hace que se necesite una función anidada extra para capturarla
Yo estoy casi seguro que esto cuenta como decoración. Un programa que se conecta con la API de CMC y trae nombre, s+imbolo y precio del top 10 de tokens
#Este programa hace un request a la api de Coin Market Cap y trae datos del top 10 de tokens
import requests
headers = {
'X-CMC_PRO_API_KEY': 'e3238e46-ef8e-4dcd-a053-492ea0450877',
'Accepts': 'application/json'
}
params = {
'start': '1',
'limit': '10',
'convert': 'USD'
}
url = 'https://pro-api.coinmarketcap.com/v1/cryptocurrency/listings/latest'
#Esta decoración recibe a la función get_data la cual se encarga de hacer el request a la API de CoinMarketCap
#Se recibe la data desordenada y en la nested function se ordena y se filtra por los datos que queremos, nombre, token y precio actual
def get_coin_prices_dec(func):
def wrapper():
for dict in func():
print(dict['name'], '-', dict['symbol'], '-', 'Price:',round(dict['quote']['USD']['price'], 2), 'USD')
return wrapper
def run():
@get_coin_prices_dec
def get_data():
json = requests.get(url, params=params, headers=headers).json()
data = json['data']
#print(data)
return data
get_data()
if __name__ == '__main__':
run()
Opinions?
La función emergency_items compara dos listas para verificar si tienen los mismos elementos.
El decorador recibe como parámetro a emergency_items (la cual devolvió una lista) y, con la nested function “wrapper”, la transforma en una cadena de texto he imprime un mensaje en consola.
def list_to_string(func):
def wrapper(*args, **kuargs):
strings = '\n \t \03 '.join(func(*args, **kuargs))
print(f' You have allredy: \n \t \03 {strings.upper()}')
return wrapper
@list_to_string
def emergency_itemms() -> list:
required_items = ["life jakcet", "warm clothes", "medication"]
items: list = ["life jakcet", "warm clothes", "medication"]
if items == required_items:
print("elements ok")
else:
print("WARRING! YOU NEED ALL ITEMS")
return items
if __name__ == "__main__":
emergency_itemms()
Hola, esto fue lo que se me ocurrió, un decorador que le de formato de dólares a una suma:
def decorador(funcion):
def contenedor(x,y):
funcion(x,y)
suma = x + y
print("$" + str(suma) + ' USD')
return contenedor
@decorador
def suma_numeros(x,y):
pass
suma_numeros(20,50)
MI decorador es una firma para colocar al final del código, yo lo probe en el reto de identificar un numero primo.
def firma (func):
def agregar_firma(*args, **kwargs):
func(*args, **kwargs)
print ('\nEste código ha sido creado por David Castelblanco')
return agregar_firma
@firma
def is_prime(number: int) -> bool:
contador: int =0
for i in range(1, number+1):
if i == 1 or i==number:
continue
if number % i ==0:
contador +=1
if contador >0 or number==1:
print('El numero elegido NO es primo')
else:
print('El numero elegido SI es primo')
def run():
number = int(input('Elige un numero para saber si es primo: '))
is_prime(number)
if __name__=='__main__':
run()
Hice un programa para asegurar que la longitud de un contraseña sea mayor a 6 caracteres, y si si que confirme la contraseña
#decorador que valida la longitud de la contraseña
def validacion(func):
def validacion_contraseña(letras):
if len(letras) > 6:
print("Contraseña validada cumple la longitud")
func(letras)
else:
print("Contresaña validada no cumple longitud")
quit()
return func
return validacion_contraseña
#ingrese la contraseña y valida que sean iguales
@validacion
def contraseña(letras):
confirmacion = input("Ingrese la contraseña nuevamente: ")
if letras == confirmacion:
print("contraseña asegurada")
else:
print("contraseña no coincide")
contraseña_nueva = input("Ingrese su contraseña: ")
contraseña(contraseña_nueva)
Aqui mi aporte al ejercicio libre con decoradores
A partir de su peso en Kg y su estatura en metros le devuelve su calificacion segun su indice de masa corporal IMC
def imc_grade(func):
def wrapper(*args, **kwargs):
n= func(*args, **kwargs)
match n:
case x if n > 15 and n < 16.1:
print("IMC= " + str(x) + " Delgadez Severa. Debe alimentarse mejor")
case n if n > 16 and n < 18.6 :
print("IMC= " + str(x) + " Delgado. Revise su Alimentación y haga ejercicios")
case n if n > 18.5 and n < 25.1 :
print("IMC= " + str(x) + " Ud. está saludable. Siga asi, cuide su alimentacion y haga ejercicios")
case n if n > 25 and n < 30:
print("IMC= " + str(x) + " Ud. tiene sobrepeso. Comience a hacer ejercicios")
case n if n > 29.9 and n < 35:
print("IMC= " + str(x) + " Ud. tiene obesidad moderada. Debe hacer ejercicios y revisar sus hábitos alimenticios")
case n if n > 34.9 and n < 40:
print("IMC= " + str(x) + " Ud. tiene obesidad severa. Debe hacer ejercicios, cambiar sus hábitos alimenticios y buscar ayuda")
case n if n > 39.9:
print("IMC= " + str(x) + " La obesidad no es buena. Busque ayuda de inmediato. Está a tiempo de mejorar")
return wrapper
@imc_grade
def calc_imc() -> float:
peso: float = float(input("Inserte su peso en Kg: "))
assert type(peso) == float, "Sólo puedes usar números"
estatura: float = float(input("Inserte su estatura en metros: "))
assert type(estatura) == float, "Sólo puedes usar números"
return round(peso/estatura**2,1)
calc_imc()
Hice una función que imprime cuántos puntos le faltan a los equipos para clasificar (cogí datos de google al 21 de marzo de 2022 en la liga de Colombia), después de actualizar una tabla. Se me ocurrió porque a veces como aficionado uno quiere ver qué podría faltar o qué resultados se necesitan para que el equipo de uno clasifique. La función de actualizar tabla podría usarse siempre en otro script que guarde los resultados reales, por ejemplo, pero en este caso la reutilice. Lo hice sencillo pero sería chévere complementarlo con web scrapping para hacerlo en tiempo real, poder poner más de un resultado, etc 😄
def is_capicua(func):
def verify(n: int) -> bool:
s = str(n)
return s == s[::-1]
def wrapper(a: int,b:int) -> int:
if verify(a) and verify(b):
return func(a,b)
else:
raise ValueError("Ambos números deben ser capícuas")
return wrapper
@is_capicua
def sum(a: int,b: int) -> int:
return a + b
if __name__ == "__main__":
print(sum(121,212))
print(sum(121,213))
Hola dejo mi aporte, en donde utilizo un clousure para indicar que ya acabo el programa, el programa que cree fue una calculadora
def mensaje_ini(func):
def wrapper(*args,**kwargs):
func(*args,**kwargs)
print("Este programa esta termino, mil gracias")
return wrapper
while True:
try:
a = int(input("Por favor ingrese un número: "))
b = int(input("Por favor ingrese un número: "))
signo = input("Por favor indique que tipo de operación desea realizar (suma (+),resta(-),multiplicación(*),división(/)): ")
if signo not in ('+','-','*','/'):
print("Ingrese una operación valida")
signo = input("Ingrese una opción de signo valida nuevamente (suma (+),resta(-),multiplicación(*),división(/)): ")
break
except ValueError:
print("Introduzca números validos y vuelvalo a intentar ")
@mensaje_ini
def calculadora(a,b,signo):
if signo == '+':
print(f'la suma de {a} + {b} es igual a: {a+b}')
elif signo == '-':
print(f'la suma de {a} - {b} es igual a {a-b}')
elif signo == '*':
print(f'la suma de {a} * {b} es igual a {a*b}')
elif signo == '/':
print(f'la suma de {a} / {b} es igual a {a/b}')
if __name__ == '__main__':
calculadora(a,b,signo)
Hola a todos! hay retos muy interesantes por ahí. Yo hice un decorador que transforma un número complejo en forma cartesiana a forma polar
from numpy import pi, abs, angle
def show_polar(number):
print("abs: "+ str(number[0]) + " < " + str(number[1]) + "°")
def polar_notation(func):
def wrapper(*args, **kwargs):
number = func(*args, **kwargs)
r = abs(number)
theta = angle(number) * 180 / pi
return [r, theta]
return wrapper
@polar_notation
def multiply_complex(a, b):
return a * b
@polar_notation
def sum(a,b):
return a + b
Hice un decorador que imprime el resultado de una funcion (siempre que esta retorne algun valor), para poder hacer un seguimiento a los resultados devueltos por las funciones sin llenarme de print() por todos lados.
def show_result(identificator):
def function_identificator(function):
print(f'{identificator}')
def wrapper(*args, **kwargs):
print('Result: ', function(*args, **kwargs))
return wrapper
return function_identificator
@show_result('Potencia: ')
def elevate(number, power):
return number ** power
def run():
elevate(5,2)
if __name__ == '__main__':
run()
#output
#Potencia:
#Result: 25
Hice para sumar n números… sin importar cuantos haya.
# function to calculate the sum of x values
def sum_of(func):
def wrapper(*args, **kwargs):
suma = 0
for i in func(*args, **kwargs):
assert type(i) == int, 'Necesitamos un número entero para sumar'
suma += i
return suma
return wrapper
@sum_of
def suma(*args):
return args
# Llamamos a nuestra función
def run():
print(suma(1,2,3,4,5,6))
# print(suma(1,2,3,4,5,'6'))
# Creamos nuestro entrypoint
if __name__ == '__main__':
run()
Aqui les dejo mi codigo Realice Multiplicacion, Suma y Resta de Fracciones con decoradores.
from datetime import datetime
Menu = """"
******RETO DECORADORES*****
Calculando el tiempo de ejecución en:
1. Multiplicacion de Fracciones
2. Division de Fracciones
3. Suma de Fracciones
"""
print(Menu)
def execution_time(func):
def wrapper(*args, **kwargs):
initial_time = datetime.now()
func(*args, **kwargs)
final_time = datetime.now()
time_elapsed = final_time - initial_time
print("Tiempo : "+ str(time_elapsed.total_seconds())+ " Segundos")
return wrapper
@execution_time
def multiplicacion(a: int, b: int, c: int, d: int)-> int:
numerador = a*c
denominador = b*d
print("Multiplicacion de Fracciones")
print(f"El resultado es: {numerador}/{denominador} ")
@execution_time
def division(a: float, b: float, c: float, d: float)-> float:
numerador = a*d
denominador = b*c
print("División De Fracciones")
print (f"El resultado es: {numerador}/{denominador} ")
@execution_time
def suma(n1: int, n2: int, n3: int, n4: int)->int:
numerador = n1+n3
denominador = n4
print("Suma de Fracciones")
print(f"El resultado es: {numerador}/{denominador} ")
multiplicacion(1, 2, 3, 4)
division(4.2, 5.3, 3.2, 9.2)
suma(3, 4, 2, 4)
Que buena clase jaja
El decorador se asegura que la funcion es llamada cuando el usario se ha autenticado
Solución al reto.
Utilizo los decoradores para permitir o denegar la ejecución de la función decorada, dependiendo de si el usuario está listado en el grupo con permisos.
PRIVILEGED_USERS = ['Jose', 'Anna', 'Facundo']
NORMAL_USERS = ['David', 'Nicolás', 'Carlos']
def exec_privileged_rights(func):
""" This decorator only executes decorated function if user is listed in PRIVILEGED_USERS """
def wrapper(*args, **kwargs):
actual_user = input('Introduce tu usuario: ')
assert actual_user in PRIVILEGED_USERS, 'El usuario no tiene permisos de acceso'
func(*args, **kwargs)
return wrapper
def exec_normal_rights(func):
""" This decorator only executes decorated function if user is listed in PRIVILEGED_USERS or in NORMAL_USERS"""
def wrapper(*args, **kwargs):
actual_user = input('Introduce tu usuario: ')
assert actual_user in PRIVILEGED_USERS or actual_user in NORMAL_USERS, 'El usuario no tiene permisos de acceso'
func(*args, **kwargs)
return wrapper
@exec_privileged_rights
def return_secret_info():
print('Esto es una información confidencial')
@exec_normal_rights
def return_private_info():
print('Esta información no es confidencial')
def run():
return_secret_info()
return_private_info()
if __name__ == '__main__':
run()
Solo se me ocurrio usar un decorador para validar los cuartos creados en un generador de mapas tipo Rogue-like
from typing import List
ui_habitacion={
"width":int,
"height":int,
"reward":str,
"type":str,
"init_enemies":bool
}
generated_rooms:List = []
def validate_room(func):
def wrapper(*args,**kwargs):
room:ui_habitacion = func(*args,**kwargs)
if room["type"]=="treasure":
assert generated_rooms.count(room)<1, "Hay mas un cuarto del tesoro"
generated_rooms.append(room)
return room
return wrapper
@validate_room
def generate_treasure_room() -> ui_habitacion:
treasure_room:ui_habitacion = {
"width":1,
"height":1,
"reward":"Daddy Long Legs",
"type":"treasure",
"init_enemies":False
}
return treasure_room
def run():
generate_treasure_room()
print(generated_rooms)
generate_treasure_room()
if __name__=="__main__":
run()
Hice este decorador para obtetener descuentos en la compra de un producto de acuerdo a la membresía
def get_porcent_value(membership : str) :
if membership.lower() == 'bronce':
return 10
if membership.lower() == 'plata':
return 15
if membership.lower() == 'oro':
return 20
def price_with_discount(func):
def wrapper(membership: str, price: float):
func(membership, price)
porcent: int = get_porcent_value(membership)
new_price: float = price - (price * (porcent / 100))
print('¡Felicidades! Por tu membresía, has ganado ' + str(porcent) + '% de descuento. Tu nuevo precio es:', str(new_price))
return wrapper
@price_with_discount
def buy_product(membership: str, price: float):
print('Bienvenido. ¡Estamos de promoción! veamos que has ganado: ')
print('Membresía: '+ membership)
print('Precio: '+ str(price))
buy_product('Oro',154.99)
buy_product('Plata',154.99)
buy_product('bronce',154.99)
Yo hice un temporizador que ejecuta una función después de determinado tiempo 😁
.
Aquí un poco más de contenido (decoradores con clases)
https://realpython.com/primer-on-python-decorators/
Mi pequeño aporte, realmente no se me ocurría algún ejercicio xd
def decorador(func):
def wrapper(*args, **kwargs):
print("Hola, Bienvenido")
func(*args, **kwargs)
return wrapper
def estudio(universidad):
print(f"Estudias en {universidad}")
estudio=decorador(estudio)
estudio("UANL")
Comparto mi programa, espero retro!, gracias!
Hice un ejemplo de ordenar pizza para utilizar el decorador de tiempo de ejecución como tiempo para preparar tu pedido 😄 Quedo así:
from datetime import datetime
from os import system
import time
chef = """
████████ ████████
████▒▒▒▒▒▒▒▒████ ██▒▒░░░░▒▒██
██░░▒▒▒▒▒▒▒▒▒▒▒▒▒▒██ ██▒▒░░ ░░▒▒██
██░░░░▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒██ ██████████ ██▒▒ ░░██
██░░░░▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒██ ████████ ██▒▒░░ ░░▒▒██ ██░░ ██
██░░░░░░▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒██ ██▒▒░░░░▒▒████░░ ░░██ ██░░ ██
██░░ ░░▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒████▒▒░░ ░░▒▒▒▒░░ ░░▒▒██ ██▒▒░░ ██
██░░░░░░▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒██░░ ░░▒▒░░░░ ░░▒▒▒▒██ ██▒▒░░ ██
██░░░░░░░░░░▒▒▒▒▒▒▒▒▒▒▒▒▒▒██░░ ░░░░ ░░▒▒██ ██▒▒██
██░░ ░░░░░░▒▒▒▒▒▒▒▒░░██▒▒░░ ░░ ░░██ ██░░██
██░░ ░░░░ ░░░░▒▒██▒▒▒▒░░░░▒▒ ░░ ░░██ ██▒▒██
████░░░░░░░░▒▒▒▒▒▒████▒▒░░░░▒▒░░░░ ▒▒░░▒▒██ ██░░██
████░░░░▒▒▒▒██▒▒ ██░░▒▒▒▒░░░░▒▒▒▒▒▒▒▒ ▒▒██ ██▒▒██
████████████▒▒ ██▒▒▒▒▒▒▒▒░░░░ ██ ██░░██
████▒▒ ████████░░░░░░ ██ ██████▒▒██
████▒▒ ▒▒▒▒▒▒▓▓░░░░▒▒▒▒████▒▒▒▒████▒▒▒▒▓▓▒▒██
████████░░░░░░████░░▓▓░░░░▓▓░░░░▒▒░░░░██████
██▒▒░░░░░░░░░░░░░░ ██░░ ██░░░░▒▒░░░░░░██
██▒▒░░░░░░░░░░░░░░▒▒▓▓░░░░▓▓░░░░░░░░░░▒▒██
██▒▒░░░░░░░░░░░░░░░░██░░░░██░░░░░░▒▒░░▒▒██
██▓▓▒▒░░░░░░░░▒▒▒▒░░░░░░░░░░░░░░▒▒░░██
██▒▒░░░░░░░░░░░░░░░░▒▒░░░░░░░░░░██
██▒▒░░░░░░░░░░░░░░░░▒▒░░░░░░░░░░██
██▒▒░░░░░░░░░░░░░░░░░░░░░░░░░░▒▒██
██▒▒░░░░░░░░░░░░░░░░░░░░░░░░░░▒▒██
██▓▓▒▒░░░░░░░░░░░░░░░░░░░░░░░░██
██▓▓▒▒░░░░░░░░░░░░░░░░░░░░░░██
██▒▒▒▒▒▒░░░░░░░░░░░░░░░░▒▒▓▓▓▓██
██▒▒ ▒▒▒▒░░░░▒▒░░░░░░░░▒▒▓▓▒▒▒▒▒▒██
██▓▓▒▒▒▒▒▒▒▒▒▒▒▒▓▓▒▒▒▒▒▒▒▒▓▓▒▒▒▒▒▒▒▒▓▓██
██▓▓▒▒▒▒▒▒▒▒▒▒▒▒▓▓████▓▓▓▓▓▓▒▒▒▒▒▒▒▒▓▓██
████████████████ ████████████████
"""
pizza = """
⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣠⣤⣶⣶⣦⣄⣀⠀⠀⠀⠀⠀⠀⠀⠀⠀
⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢰⣿⣿⣿⣿⣿⣿⣿⣷⣦⡀⠀⠀⠀⠀⠀⠀
⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢠⣷⣤⠀⠈⠙⢿⣿⣿⣿⣿⣿⣦⡀⠀⠀⠀⠀
⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣠⣿⣿⣿⠆⠰⠶⠀⠘⢿⣿⣿⣿⣿⣿⣆⠀⠀⠀
⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⣼⣿⣿⣿⠏⠀⢀⣠⣤⣤⣀⠙⣿⣿⣿⣿⣿⣷⡀⠀
⠀⠀⠀⠀⠀⠀⠀⠀⢠⠋⢈⣉⠉⣡⣤⢰⣿⣿⣿⣿⣿⣷⡈⢿⣿⣿⣿⣿⣷⡀
⠀⠀⠀⠀⠀⠀⠀⡴⢡⣾⣿⣿⣷⠋⠁⣿⣿⣿⣿⣿⣿⣿⠃⠀⡻⣿⣿⣿⣿⡇
⠀⠀⠀⠀⠀⢀⠜⠁⠸⣿⣿⣿⠟⠀⠀⠘⠿⣿⣿⣿⡿⠋⠰⠖⠱⣽⠟⠋⠉⡇
⠀⠀⠀⠀⡰⠉⠖⣀⠀⠀⢁⣀⠀⣴⣶⣦⠀⢴⡆⠀⠀⢀⣀⣀⣉⡽⠷⠶⠋⠀
⠀⠀⠀⡰⢡⣾⣿⣿⣿⡄⠛⠋⠘⣿⣿⡿⠀⠀⣐⣲⣤⣯⠞⠉⠁⠀⠀⠀⠀⠀
⠀⢀⠔⠁⣿⣿⣿⣿⣿⡟⠀⠀⠀⢀⣄⣀⡞⠉⠉⠉⠉⠁⠀⠀⠀⠀⠀⠀⠀⠀
⠀⡜⠀⠀⠻⣿⣿⠿⣻⣥⣀⡀⢠⡟⠉⠉⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
⢰⠁⠀⡤⠖⠺⢶⡾⠃⠀⠈⠙⠋⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
⠈⠓⠾⠇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
"""
soda = """
"""
import cowsay
pizza_flavors = {
'Pepperoni': 1000000,
'Pastor' : 60000000,
'Hawaian' : 30000000
}
soda_flavors = {
'Cola':1000000,
'Sprite': 60000000,
'Mundet': 70000000
}
def clear():
return system('cls')
def order_time(func):
def wrapper(*args, **kwargs):
initial_time = datetime.now()
func(*args, **kwargs)
final_time = datetime.now()
seconds = final_time - initial_time
print(f'Product: {args[0]}\n\tProcessing time = {str(seconds.total_seconds())} seconds')
return wrapper
@order_time
def order_pizza(sabor = 'Pepperoni', product = 'Pizza'):
for k,v in pizza_flavors.items():
if k == sabor:
for _ in range(1,v):
pass
@order_time
def order_soda(sabor = 'Cola', product = 'Soda'):
for k,v in soda_flavors.items():
if k == sabor:
for _ in range(1,v):
pass
def run():
flag = True
while flag:
print('Write the number of one flavor for your pizza:\n 1. Pepperoni\n2. Pastor\n 3. Special')
try:
p_flavor = int(input('Enter a number: '))
if p_flavor > 3:
raise ValueError()
flag = False
except:
clear()
print('\nSorry! Value not valid\nPlease try again\n')
pass
clear()
flag = True
while flag:
print('Write the number of one flavor for your soda:\n1. Cola\n 2. Coffe\n 3. Green Tea')
try:
s_flavor = int(input('Enter a number: '))
if s_flavor > 3:
raise ValueError()
flag = False
except:
clear()
print('\nSorry! Value not valid\nPlease try again\n')
pass
clear()
p_list = list(pizza_flavors)
s_list = list(soda_flavors)
p_flavor = p_list[p_flavor-1]
s_flavor = s_list[s_flavor-1]
print('We are preparing your order. Please wait . . . ')
print(chef)
time.sleep(5)
clear()
print(f'\nThank you for your order, here is your {p_flavor} Pizza and a {s_flavor}\n')
print(pizza)
time.sleep(5)
clear()
order_pizza(p_flavor)
order_soda(s_flavor)
if __name__=='__main__':
clear()
cowsay.cow('Hello Bro!')
print('This is Kirby\'s Pizza Place\n ¿What would you order today?\n')
run()
time.sleep(5)
clear()
cowsay.cow('Have a nice day Bro!')
Mi aporte para encontrar una letra o palabra en una variable con texto, utilizando decoradores.
def countstring(func):
def wrapper(*args, **kwargs):
print("Cuenta la cantidad de letras en el texto")
func(*args,**kwargs)
return wrapper
return wrapper
a = """
Esto es una prueba para contar letras o palabras
en una variable con texto
"""
@countstring
def contar(texto,p):
print(f'Hay {texto.count(p)} "{p}" en la variable')
contar(a, "a")
Hola amigos, comparto esta página con 10 Decoradores de Python muy útiles e interesantes:
https://towardsdatascience.com/10-fabulous-python-decorators-ab674a732871
Algunos sirven para acelerar el código usando la caché de Python, otros para que nuestro programa haga algo al terminar. Esto se podría usar por ejemplo al cerrar un Programa y que automáticamente se guarde nuestro Archivo sin perder datos. Y el código es muy fácil. Utilizando el módulo atexit:
from atexit import register
@register
def termin():
print(" Goodbye!")
Realmente la eficiencia, potencia y elegancia de Python es sorprendente. Espero les sea útil.
Hola a todos aplique las funciones con varios decoradores,
def saludo(func):
def envoltura(*args, **kwargs):
return f'hola \n{func(*args, **kwargs)}'
return envoltura
def mayusculas(func):
def envoltura(*args, **kwargs):
return func(*args, **kwargs).upper()
return envoltura
def aggemogi(func):
def envoltura(*args, **kwargs):
return (f'{func(*args, **kwargs)} 🤑🤑')
return envoltura
@aggemogi
@mayusculas
@saludo
def mensaje(nombre):
return f'{nombre}, recibiste un mensaje'
@mayusculas
@aggemogi
def dollars(dinero: int, cambio:int):
return f'tienes {round(dinero * cambio,2)} dolares'
def run():
print(mensaje("Danny"))
print(dollars(100,7.78))
if __name__ == "__main__":
run()
HOLA
DANNY, RECIBISTE UN MENSAJE 🤑🤑
TIENES 778.0 DOLARES 🤑🤑
Pues, tal vez no sea muy avanzado y seguro se puede optimizar mucho pero hice un sombrero seleccionador. Ironicamente, la tres veces que ingrese Harry Potter, salió Slytherin. Les dejo el codigo.
import random
def hogwarts(func):
def wrapper(name):
func(name)
houses = (“Gryffindor”, “Slytherin”, “Hufflepuff”, “Ravenclaw”)
selected_house = random.choice(houses)
print("Hola "+ name + “, soy el sombrero seleccionador.”)
print("Tu hogar en Hogwarts será " + selected_house)
return wrapper
@hogwarts
def the_hat(magician):
print("Bienvenido " + magician)
print(“Ponte el sombrero seleccionador”)
input(“Presiona enter cuando estes listo/a…”)
def run():
name = input("Ingresa tu nombre: ")
the_hat(name)
if name == ‘main’:
run()
¡Hola! Mi decorador guarda el resultado de alguna función en un archivo de texto. Por si quiero saber el código de error o para copiar/pegar resultados que me parezcan útiles 😁
import time
from typing import List
def log_to_file(mode: str = "w"):
def write_to_file(func):
def wrapper(*args, **kwargs):
filename = time.strftime("%Y-%M-%d %H:%M")
with open(filename, mode, encoding="utf-8") as file:
result = func(*args, **kwargs)
file.write(str(result))
return wrapper
return write_to_file
@log_to_file()
def print_multiples(number: int, limit: int = 100) -> List[int]:
multiples = [i for i in range(limit + 1) if (i % number == 0)]
return multiples
@log_to_file()
def beautify_text(message):
better_message = f"💖{message}💖"
return better_message
# ---------------------------
# Main function & entry point
# ---------------------------
def run():
print_multiples(7,150)
beautify_text("Holi")
if __name__ == '__main__':
run()
Mi solución al reto.
Por algún motivo que se me escapa, cuando uso el *args y el **kargs no me sale.
def decorator_func(func):
def wrapper(texto):
func(texto)
texto = texto.title()
texto = texto.strip()
return texto
return wrapper
@decorator_func
def input_name(string):
return f'Bienvenido {string}'
if __name__ == '__main__':
name = input('Ingresa tu nombre: ')
print(input_name(name))
~
Les dejo mi aporte, convertir una cadena en mayusculas y minusculas.
def convert_upper_lower(func):
def wrapped(*args, **Kwargs):
string=func(*args, **Kwargs).replace(" ","")
convert = []
for i in range(len(string)):
if i%2==0:
convert.append(string[i].upper())
else:
convert.append(string[i].lower())
print(convert[i])
return wrapped
@convert_upper_lower
def character_string(string):
return string
def run():
character_string('free challenge')
if __name__=='__main__':
run()
No es mucho, pero es trabajo honesto.
:
def decorador_log(func):
def decorador_funcion(*args, **kwargs):
with open(fichero_log, 'a') as opened_file:
output = func(*args, **kwargs)
opened_file.write(f"{output}\n")
return decorador_funcion
return decorador_log
@log('ficherosalida.log')
def suma(a, b):
return a + b
@log('ficherosalida.log')
def resta(a, b):
return a - b
@log('ficherosalida.log')
def multiplicadivide(a, b, c):
return a*b/c
suma(10, 30)
resta(7, 23)
multiplicadivide(5, 10, 2)
La función decoradora se puede plantear como la función A que recibe a la función parámetro que seria B y a su vez crea la función nested o interior que seria C, así A lleva consigo a B como parámetro y retorna a C como la función donde se crea la lógica para decorar a B
Hice una pequeña calculadora donde el decorador es el que da los encabezados antes de cada operación e individualmente calcula cuanto tiempo tardó haciendo la operación, además en multiplicación utilicé *args para poder enviar el número de parámetros que quisiera para multiplicarlos
from datetime import datetime
def headings(function):
def write_heading(*args, **kwargs):
initial_time = datetime.now()
print('el resultado de su calculo fue: ')
print(function(*args, **kwargs))
print('Fin del calculo')
final_time = datetime.now()
time_expended = final_time - initial_time
print ("pasaron "+ str(time_expended.total_seconds()) + "segundos ")
return write_heading
@headings
def addition(a: int, b: int):
return a+b
@headings
def subtraction(a: int, b: int, c:int, d:int):
return a-b-c-d
@headings
def multiplication(*args):
length = len(args)
accumulator = 1
for i in range (length):
accumulator = args[i] * accumulator
return accumulator
if __name__ == "__main__":
addition(1,2)
subtraction(100,2,3,23)
multiplication(2,2,2,2,2,2,2,2,2,2)
Este es el resultado en la terminal:
el resultado de su calculo fue:
3
Fin del calculo
pasaron 0.0segundos
el resultado de su calculo fue:
72
Fin del calculo
pasaron 0.0segundos
el resultado de su calculo fue:
1024
Fin del calculo
pasaron 0.001002segundos
Mi aporte
Este ejemplo muestra como mostrar los parámetros deseados:
def decorator_divisor(func):
def wrapper(*args, **kwargs):
func(*args,**kwargs)
return f'It has been calculated the divsors of {args[0]} as a list and the sum of {args}'
return wrapper
@decorator_divisor
def divisor (number1,number2):
divisor_blank = []
for i in range(1,number1+1):
if number1 % i == 0:
divisor_blank.append(i)
suma = number1 + number2
print(divisor_blank)
print(number1 + number2)
print(divisor(20,21))
from datetime import datetime
def MostrasCuadroArriba(func):
def wrapper(*args, **kwargs):
func(*args, **kwargs)
print("--------------------------")
print("| |")
print("--------------------------")
return wrapper
@MostrasCuadroArriba
def MostarFecha():
print("La Hora Actual es la: " + str(datetime.now()))
MostarFecha()
Hice un decorador que me diga el tipo de variable que imprime una función
def variables_type(func):
def wripper(*args,**kwargs):
func(*args,**kwargs)
print(type(func(*args,**kwargs)))
return(wripper)
@variables_type
def make_list(a: int ,b :int )->list:
c=[]
for i in range(a,b+1):
c.append(i)
return c
make_list(1,9)
Yo hice un programita sencillo para calcular el índice de masa corporal y que te dice si estás bajo de peso, normal, con sobrepeso, obeso o extremadamente obeso.
# This program calculates our Body Mass Index given height and weight.
# Using a decorator it tells us if our weight status (underweight, normal, overweight, obese)
def define_status(func):
def wrapper(*args, **kwargs):
# To catch the returned bmi valie from the ffunction
bmi = func(*args, **kwargs)
# Conditions to determine the status for a male
if bmi <= 18.5:
status = 'Underweight'
elif bmi > 18.5 and bmi <= 24.9:
status = 'Normal'
elif bmi > 24.9 and bmi <= 29.9:
status = 'Overweight'
elif bmi > 29.9 and bmi <= 34.9:
status = 'Obese'
elif bmi > 29.9 and bmi <= 34.9:
status = 'Extremly obese'
#Printing the status
print(f'Weight status: {status}')
return wrapper
#With this function we calculate the bmi
@define_status
def bmi_calculator(height: float, weight:float) -> float:
bmi = weight / (height**2)
print (f'Your Body Mass Index is :{bmi}')
return bmi
def run():
height = float(input('Your height in meters: '))
weight= float(input('Your weight in kilograms: '))
bmi_calculator(height,weight)
if __name__ == '__main__':
run()
Todavía pueden ponerse más detalles como opciones de si eres mujer, niña, niño, try and catch para errores, etc.
El programa calcula el p_value de la distribución de datos aplicando Z-test, adicional se decora para aplicar T-test
mi solución #1:
# EJEMPLO DECORADOR QUE TRANSFORMA A MAYUSCULA EL MENSAJE Y EL NOMBRE
def minusculas(func):
def wrapper(texto):
print("Se cambió lo siguiente a minúscula: ")
return func(texto).lower()
return wrapper
@minusculas
def mensaje(nombre):
return "{} HAS RECIBIDO UN MENSAJE".format(nombre)
print(mensaje('CARLOS'))
mi solución #2: (verifica la dimensión de un dataset y si tiene valores nulos…
Se puede mejorar!)
import json
import pandas as pd
from urllib.request import urlopen
# carga del dataframe con la data de la plataforma localbitcoins
url = ("https://jsonplaceholder.typicode.com/comments")
data = json.load(urlopen(url))
df = pd.DataFrame(data=data)
# Decorator function that return the null values of a dataset
def null_values(func):
def wrapper(df):
return print(func(df.isnull().sum()))
return wrapper
@null_values
def shape_of_df(df):
return df.shape
print(shape_of_df(df))
¿Quieres ver más aportes, preguntas y respuestas de la comunidad? Crea una cuenta o inicia sesión.