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