<SYSTEM_TASK:>
Given the following text description, write Python code to implement the functionality described below step by step
<END_TASK>
<USER_TASK:>
Description:
 Tasks are one of the primary ways to interact with the event loop. Tasks wrap coroutines and track when they are complete. Tasks are subclasses of Future, so other coroutines can wait for them and each has a result that can be retrieved after the task completes.
Starting a Task
To start a task, use create_task() to create a Task instance. The resulting task will run as part of the concurrent operations managed by the event loop as long as the loop is running and the coroutine does not return.
Step1:  Canceling a Task
Step2:  This example creates and then cancels a task before starting the event loop. The result is a CancelledError exception from run_until_complete().
If a task is canceled while it is waiting for another concurrent operation, the task is notified of its cancellation by having a CancelledError exception raised at the point where it is waiting.
Step3:  Creating Tasks from Coroutines
The ensure_future() function returns a Task tied to the execution of a coroutine. That Task instance can then be passed to other code, which can wait for it without knowing how the original coroutine was constructed or called
<ASSISTANT_TASK:>
Python Code:
# %load asyncio_create_task.py
import asyncio
async def task_func():
    print('in task_func')
    return 'the result'
async def main(loop):
    print('creating task')
    task = loop.create_task(task_func())
    print('waiting for {!r}'.format(task))
    return_value = await task
    print('task completed {!r}'.format(task))
    print('return value: {!r}'.format(return_value))
event_loop = asyncio.get_event_loop()
try:
    event_loop.run_until_complete(main(event_loop))
finally:
    event_loop.close()
!python asyncio_create_task.py
Explanation: Tasks are one of the primary ways to interact with the event loop. Tasks wrap coroutines and track when they are complete. Tasks are subclasses of Future, so other coroutines can wait for them and each has a result that can be retrieved after the task completes.
Starting a Task
To start a task, use create_task() to create a Task instance. The resulting task will run as part of the concurrent operations managed by the event loop as long as the loop is running and the coroutine does not return.
End of explanation
# %load asyncio_cancel_task.py
import asyncio
async def task_func():
    print('in task_func')
    return 'the result'
async def main(loop):
    print('creating task')
    task = loop.create_task(task_func())
    print('canceling task')
    task.cancel()
    print('canceled task {!r}'.format(task))
    try:
        await task
    except asyncio.CancelledError:
        print('caught error from canceled task')
    else:
        print('task result: {!r}'.format(task.result()))
event_loop = asyncio.get_event_loop()
try:
    event_loop.run_until_complete(main(event_loop))
finally:
    event_loop.close()
!python asyncio_cancel_task.py
Explanation: Canceling a Task
End of explanation
# %load asyncio_cancel_task2.py
import asyncio
async def task_func():
    print('in task_func, sleeping')
    try:
        await asyncio.sleep(1)
    except asyncio.CancelledError:
        print('task_func was canceled')
        raise
    return 'the result'
def task_canceller(t):
    print('in task_canceller')
    t.cancel()
    print('canceled the task')
async def main(loop):
    print('creating task')
    task = loop.create_task(task_func())
    loop.call_soon(task_canceller, task)
    try:
        await task
    except asyncio.CancelledError:
        print('main() also sees task as canceled')
event_loop = asyncio.get_event_loop()
try:
    event_loop.run_until_complete(main(event_loop))
finally:
    event_loop.close()
!python asyncio_cancel_task2.py
Explanation: This example creates and then cancels a task before starting the event loop. The result is a CancelledError exception from run_until_complete().
If a task is canceled while it is waiting for another concurrent operation, the task is notified of its cancellation by having a CancelledError exception raised at the point where it is waiting.
End of explanation
# %load asyncio_ensure_future.py
import asyncio
async def wrapped():
    print('wrapped')
    return 'result'
async def inner(task):
    print('inner: starting')
    print('inner: waiting for {!r}'.format(task))
    result = await task
    print('inner: task returned {!r}'.format(result))
async def starter():
    print('starter: creating task')
    task = asyncio.ensure_future(wrapped())
    print('starter: waiting for inner')
    await inner(task)
    print('starter: inner returned')
event_loop = asyncio.get_event_loop()
try:
    print('entering event loop')
    result = event_loop.run_until_complete(starter())
finally:
    event_loop.close()
!python asyncio_ensure_future.py
Explanation: Creating Tasks from Coroutines
The ensure_future() function returns a Task tied to the execution of a coroutine. That Task instance can then be passed to other code, which can wait for it without knowing how the original coroutine was constructed or called
End of explanation
<END_TASK>