<SYSTEM_TASK:>
Given the following text description, write Python code to implement the functionality described below step by step
<END_TASK>
<USER_TASK:>
Description:
 Write a function and a class version of each decorator.
Timer decorator.
Step1:  HTML tag adder.
Step2:  Arbitrary tag adder.
Step3:  Check if all parameters (keyword too) are of a given type.
Step4:  Write a decorator that makes sure that a function only raises one type of error. If it would raise another exception, raise this type instead.
via https
<ASSISTANT_TASK:>
Python Code:
import functools
from datetime import datetime
def timer(func):
    @functools.wraps(func)
    def timed_func(*args, **kwargs):
        start = datetime.now()
        ret = func(*args, **kwargs)
        tm = datetime.now() - start
        print("Running time: {}".format(tm.total_seconds()))
        return ret
    return timed_func
@timer
def fast_func():
    for _ in range(1000):
        pass
    
@timer
def slow_func():
    for _ in range(10000000):
        pass
    
fast_func()
slow_func()
Explanation: Write a function and a class version of each decorator.
Timer decorator.
End of explanation
def html_wrapper(func):
    @functools.wraps(func)
    def wrapped(*args, **kwargs):
        return "<html>{}</html>".format(func(*args, **kwargs))
    return wrapped
@html_wrapper
def greeter(name):
    return "Hello {}".format(name)
greeter("Judit")
Explanation: HTML tag adder.
End of explanation
def tag_wrapper(tag_name):
    def concrete_decorator(func):
        @functools.wraps(func)
        def wrapped(*args, **kwargs):
            return "<{0}>{1}</{0}>".format(tag_name, func(*args, **kwargs))
        return wrapped
    return concrete_decorator
@tag_wrapper("h1")
def greeter(name):
    return "Hello {}".format(name)
greeter("John")
Explanation: Arbitrary tag adder.
End of explanation
def check_type(param_type):
    def concrete_decorator(func):
        @functools.wraps(func)
        def wrapped(*args, **kwargs):
            for idx, arg in enumerate(args):
                if not isinstance(arg, param_type):
                    raise TypeError("Positional arg {0} is of wrong type ({1})".format(idx, type(arg)))
            for kw, arg in kwargs.items():
                if not isinstance(arg, param_type):
                    raise TypeError("{0} is of wrong type ({1})".format(kw, type(arg)))
            return func(*args, **kwargs)
        return wrapped
    return concrete_decorator
@check_type(int)
def age_printer(age):
    print("I am {} old".format(age))
    
age_printer(1)
Explanation: Check if all parameters (keyword too) are of a given type.
End of explanation
# def only_one_exception(exc_type):
Explanation: Write a decorator that makes sure that a function only raises one type of error. If it would raise another exception, raise this type instead.
via https://github.com/manahl/PythonTrainingExercises
End of explanation
<END_TASK>