import time
import contextlib
@contextlib.contextmanager
def timer():
    start = time.time()
    yield
    end = time.time()
    print(f'This code block executed in { end - start } seconds.')

with timer():
    for i in range(10):
        time.sleep(0.1)
print('Done!')

"""
Python starts the timer whenever the interprets sees with timer(): and ends it (executes yield and what comes after) as soon as a new unindented statement is written (print('Done!'))
"""

8d58ee72e4dfc19e38af6f760d203418b011ac29
<mask token>

<mask token>


@contextlib.contextmanager
def timer():
    start = time.time()
    yield
    end = time.time()
    print(f'This code block executed in {end - start} seconds.')


<mask token>

<mask token>


@contextlib.contextmanager
def timer():
    start = time.time()
    yield
    end = time.time()
    print(f'This code block executed in {end - start} seconds.')


with timer():
    for i in range(10):
        time.sleep(0.1)
print('Done!')
<mask token>

import time
import contextlib


@contextlib.contextmanager
def timer():
    start = time.time()
    yield
    end = time.time()
    print(f'This code block executed in {end - start} seconds.')


with timer():
    for i in range(10):
        time.sleep(0.1)
print('Done!')
<mask token>

import time
import contextlib
@contextlib.contextmanager
def timer():
    start = time.time()
    yield
    end = time.time()
    print(f'This code block executed in { end - start } seconds.')

with timer():
    for i in range(10):
        time.sleep(0.1)
print('Done!')

"""
Python starts the timer whenever the interprets sees with timer(): and ends it (executes yield and what comes after) as soon as a new unindented statement is written (print('Done!'))
"""
