Solutions decorator exercises

Warm up exercise

 1# returntype.py
 2
 3# All functions has a return type and value. If no one is specified, the function will return a value of 'None' which has the type of 'NoneType'.
 4# So a function like this:
 5
 6def add():
 7    print('Hello')
 8
 9# will in reality look like this:
10
11def add():
12    print('Hello')
13    return None
14
15# so it is important not to think that this function:
16
17def add():
18    print('Hello')
19
20# has the return value of 'Hello'.
21# It has a side effect of printing out 'Hello', but a return value of 'None'.

Small Exercises

 1# add.py
 2
 3import datetime
 4
 5def log(func):
 6    def wrapper(*args):
 7        f = open('log.txt', 'a+')
 8        f.write(f'{datetime.datetime.now()}, {args}, {func(*args)}\n')
 9        return func(*args)
10    return wrapper
11
12@log
13def add(*args):
14    sum = 0
15    for i in args:
16        sum += i 
17    return sum
18
19@log
20def printer(text):
21    print('From printer')

Ex1: Time it!

 1# timer.py
 2import time
 3
 4def timer(func):                                                                                                                                   
 5    def wrapper(*args, **kwargs):                                                                                                                  
 6        start = time.time()                                                                                                                        
 7        func(*args, **kwargs)                                                                                                                      
 8        end = (time.time()) - start                                                                                                              
 9        print(f'Time elapsed: {end}')                                                                                                              
10
11    return wrapper                                                                                                                                 
12
13
14@timer                                                                                                                                             
15def genrate_list(num):                                                                                                                             
16    [x for x in range(1, num)]

Ex3: Slow down code

 1"""
 2    Exercise: Slow down code
 3
 4    The code below counts down from n -> 0.
 5    calling countdown(5) prints: 5 4 3 2 1 0
 6
 7    Create a decorator that slows down you code by 1 second for each step. 
 8    Call it slowdown().
 9    For this you can use the 'time' module.
10
11    The countdown function is a recursive function.
12    
13    When you got the 'slowdown code' working on this recursive function, try to create a more (for you) normal function that does the countdown, and see what happens if you decorate that function with you slowdown() function
14
15"""
16
17import time 
18
19def slowdown(func):
20    def wrapper(n):
21        time.sleep(1)
22        return func(n) 
23    return wrapper
24
25
26
27@slowdown
28def countdown(n):
29    if not n:   # 0 is false, not false is true
30        print('liftoff')
31    else:
32        print(n)
33        return countdown(n-1) # call the same function with n as one less 

Ex4: Game

 1def sharpshooter(func):
 2    def wrapper(*args):
 3        return f'{func(*args)} the sharpshooter'
 4    return wrapper
 5
 6def stealthy(func):
 7    def wrapper(*args):
 8        return f'{func(*args)} and the stealthy character'
 9    return wrapper
10
11@stealthy
12@sharpshooter
13def player():
14    return "I'm the player character"
15
16print(player())

Ex5: Register

 1REGISTER = []
 2
 3def register(func):
 4    REGISTER.append(func)
 5    return func
 6
 7# this functions simulate html pages
 8@register
 9def home():
10    return 'Im the home page'
11
12@register
13def about():
14    return 'Im the about page'
15
16def excluded_for_now():
17    return 'excluded'
18
19
20# simple menu demo 
21def menu():
22    for i in enumerate(REGISTER):
23        print( f'{i[1].__name__}' , end=' ')
24    print()
25
26choise = False
27
28while True: 
29    menu()
30    if choise:
31        choise = REGISTER[choise - 1]()
32        print(choise)
33    choise = int(input('choose a number: '))
34
35
36
37