Challenge: Time My Functions
Time my functions with meta-programming.
We'll cover the following...
Problem statement
In this exercise, we want to time our functions. What we want is that whenever a class method executes, it should print the time taken by itself.
Let’s get into detail. Consider the scenario below while attempting the challenge.
We have an Animal class. It has a function talk as follows:
class Animal():
def talk(self):
time.sleep(1)
print("Animal talk")
And, we have a decorator time_taken that calculates the required time taken by any function.
Now, if we want to calculate the time for talk, we can simply add @time_taken before its header, and the problem is solved!
But what if we create child classes of Animal in the future and want to decorate all the functions of child classes? Adding @time_taken at the beginning of every definition would be time-taking and hectic.
To avoid such a repetitive fuss, if we know beforehand that every subclass must have this timing property, then we should look up to metaclass based solution.
So, the challenge is that when the classes are created, they should be immediately wrapped up by a timing method decorator. The solution requires three steps:
-
Create a metaclass
TimeMetafeeding class object to the class decorator method -
Create a class decorator method
timeitthat makes use oftime_takendecorator to debug class methods. -
Create
time_takendecorator that times the passed method by keeping track of start time and end time.
Try to solve the problem below. Do not forget to use the concepts taught in the previous lessons. Feel free to view the solution in the next lesson, after giving it a few shots. Good luck!
import time# Decorator for timing the passed functionsdef time_taken(func):# Implement your function herepass# Class decorator making use of time_taken decorator to debug class methodsdef timeit(cls):# Implement your function herepass''' Metaclass feeding created class object to timeit method to get timingfunctionality enabled objects '''class TimeMeta(type):# Implement your class herepass''' Base class with metaclass TimeMeta, now all the subclass of thiswill have timing applied '''class Animal(metaclass=TimeMeta):def talk(self):time.sleep(1)print("Animal talk")class Cow(Animal):def talk(self):time.sleep(1)print("Moo")class Dog(Animal):def talk(self):time.sleep(1)print("Bark")# Testing the codeanimal = Animal()cow = Cow()dog = Dog()print(animal.talk())print(cow.talk())print(dog.talk())
We hope that you were able to solve the challenge.