<SYSTEM_TASK:>
Solve the following problem using Python, implementing the functions described below, one line at a time
<END_TASK>
<USER_TASK:>
Description:
 def connect(host='localhost', port=5672, username='guest', password='guest', virtual_host='/', on_connection_close=None, *, loop=None, sock=None, **kwargs):
 """ Connect to an AMQP server on the given host and port. Log in to the given virtual host using the supplied credentials. This function is a :ref:`coroutine <coroutine>`. :param str host: the host server to connect to. :param int port: the port which the AMQP server is listening on. :param str username: the username to authenticate with. :param str password: the password to authenticate with. :param str virtual_host: the AMQP virtual host to connect to. :param func on_connection_close: function called after connection lost. :keyword BaseEventLoop loop: An instance of :class:`~asyncio.BaseEventLoop` to use. (Defaults to :func:`asyncio.get_event_loop()`) :keyword socket sock: A :func:`~socket.socket` instance to use for the connection. This is passed on to :meth:`loop.create_connection() <asyncio.BaseEventLoop.create_connection>`. If ``sock`` is supplied then ``host`` and ``port`` will be ignored. Further keyword arguments are passed on to :meth:`loop.create_connection() <asyncio.BaseEventLoop.create_connection>`. This function will set TCP_NODELAY on TCP and TCP6 sockets either on supplied ``sock`` or created one. :return: the :class:`Connection` object. """

    from .protocol import AMQP
    from .routing import Dispatcher
    from .connection import open_connection

    loop = asyncio.get_event_loop() if loop is None else loop

    if sock is None:
        kwargs['host'] = host
        kwargs['port'] = port
    else:
        kwargs['sock'] = sock

    dispatcher = Dispatcher()

    def protocol_factory():
        return AMQP(dispatcher, loop, close_callback=on_connection_close)
    transport, protocol = yield from loop.create_connection(protocol_factory, **kwargs)

    # RPC-like applications require TCP_NODELAY in order to acheive
    # minimal response time. Actually, this library send data in one
    # big chunk and so this will not affect TCP-performance.
    sk = transport.get_extra_info('socket')
    # 1. Unfortunatelly we cannot check socket type (sk.type == socket.SOCK_STREAM). https://bugs.python.org/issue21327
    # 2. Proto remains zero, if not specified at creation of socket
    if (sk.family in (socket.AF_INET, socket.AF_INET6)) and (sk.proto in (0, socket.IPPROTO_TCP)):
        sk.setsockopt(socket.IPPROTO_TCP, socket.TCP_NODELAY, 1)

    connection_info = {
        'username': username,
        'password': password,
        'virtual_host': virtual_host
    }
    connection = yield from open_connection(
        loop, transport, protocol, dispatcher, connection_info)
    return connection