Instruction:
Can you implement a function in Python 3 that
returns help on the available requests.

Response:
def request_help(self, req, msg):
        """Return help on the available requests.

        Return a description of the available requests using a sequence of
        #help informs.

        Parameters
        ----------
        request : str, optional
            The name of the request to return help for (the default is to
            return help for all requests).

        Informs
        -------
        request : str
            The name of a request.
        description : str
            Documentation for the named request.

        Returns
        -------
        success : {'ok', 'fail'}
            Whether sending the help succeeded.
        informs : int
            Number of #help inform messages sent.

        Examples
        --------
        ::

            ?help
            #help halt ...description...
            #help help ...description...
            ...
            !help ok 5

            ?help halt
            #help halt ...description...
            !help ok 1

        """
        if not msg.arguments:
            for name, method in sorted(self._request_handlers.items()):
                doc = method.__doc__
                req.inform(name, doc)
            num_methods = len(self._request_handlers)
            return req.make_reply("ok", str(num_methods))
        else:
            name = msg.arguments[0]
            if name in self._request_handlers:
                method = self._request_handlers[name]
                doc = method.__doc__.strip()
                req.inform(name, doc)
                return req.make_reply("ok", "1")
            return req.make_reply("fail", "Unknown request method.")


Instruction:
Can you generate the documentation for the following Python 3 function
def request_request_timeout_hint(self, req, request):
        timeout_hints = {}
        if request:
            if request not in self._request_handlers:
                raise FailReply('Unknown request method')
            timeout_hint = getattr(
                self._request_handlers[request], 'request_timeout_hint', None)
            timeout_hint = timeout_hint or 0
            timeout_hints[request] = timeout_hint
        else:
            for request_, handler in self._request_handlers.items():
                timeout_hint = getattr(handler, 'request_timeout_hint', None)
                if timeout_hint:
                    timeout_hints[request_] = timeout_hint

        cnt = len(timeout_hints)
        for request_name, timeout_hint in sorted(timeout_hints.items()):
            req.inform(request_name, float(timeout_hint))

        return ('ok', cnt)

Response: Return timeout hints for a specific request.


Instruction:
Given the following Python 3 function, write the documentation
def request_log_level(self, req, msg):
        if msg.arguments:
            try:
                self.log.set_log_level_by_name(msg.arguments[0])
            except ValueError, e:
                raise FailReply(str(e))
        return req.make_reply("ok", self.log.level_name())

Response: Query or set the current logging level.


Instruction:
How would you explain what the following Python 3 function does
def request_restart(self, req, msg):
        if self._restart_queue is None:
            raise FailReply("No restart queue registered -- cannot restart.")

        f = tornado_Future()

        @gen.coroutine
        def _restart():
            # .put should never block because queue should have no size limit
            self._restart_queue.put_nowait(self)
            req.reply('ok')
            raise AsyncReply

        self.ioloop.add_callback(lambda: chain_future(_restart(), f))
        return f

Response: Restart the device server.


Instruction:
How would you code a function in Python 3 to
request the list of connected clients.

Response:
def request_client_list(self, req, msg):
        """Request the list of connected clients.

        The list of clients is sent as a sequence of #client-list informs.

        Informs
        -------
        addr : str
            The address of the client as host:port with host in dotted quad
            notation. If the address of the client could not be determined
            (because, for example, the client disconnected suddenly) then
            a unique string representing the client is sent instead.

        Returns
        -------
        success : {'ok', 'fail'}
            Whether sending the client list succeeded.
        informs : int
            Number of #client-list inform messages sent.

        Examples
        --------
        ::

            ?client-list
            #client-list 127.0.0.1:53600
            !client-list ok 1

        """
        # TODO Get list of ClientConnection* instances and implement a standard
        # 'address-print' method in the ClientConnection class
        clients = self._client_conns
        num_clients = len(clients)
        for conn in clients:
            addr = conn.address
            req.inform(addr)
        return req.make_reply('ok', str(num_clients))


Instruction:
Make a summary of the following Python 3 code
def request_version_list(self, req, msg):
        versions = [
            ("katcp-protocol", (self.PROTOCOL_INFO, None)),
            ("katcp-library", ("katcp-python-%s" % katcp.__version__, katcp.__version__)),
            ("katcp-device", (self.version(), self.build_state())),
        ]
        extra_versions = sorted(self.extra_versions.items())

        for name, (version, build_state) in versions + extra_versions:
            if build_state is None:
                inform_args = (name, version)
            else:
                inform_args = (name, version, build_state)
            req.inform(*inform_args)

        num_versions = len(versions) + len(extra_versions)
        return req.make_reply("ok", str(num_versions))

Response: Request the list of versions of roles and subcomponents.


Instruction:
How would you implement a function in Python 3 that
requests the list of sensors.

Response:
def request_sensor_list(self, req, msg):
        """Request the list of sensors.

        The list of sensors is sent as a sequence of #sensor-list informs.

        Parameters
        ----------
        name : str, optional
            Name of the sensor to list (the default is to list all sensors).
            If name starts and ends with '/' it is treated as a regular
            expression and all sensors whose names contain the regular
            expression are returned.

        Informs
        -------
        name : str
            The name of the sensor being described.
        description : str
            Description of the named sensor.
        units : str
            Units for the value of the named sensor.
        type : str
            Type of the named sensor.
        params : list of str, optional
            Additional sensor parameters (type dependent). For integer and
            float sensors the additional parameters are the minimum and maximum
            sensor value. For discrete sensors the additional parameters are
            the allowed values. For all other types no additional parameters
            are sent.

        Returns
        -------
        success : {'ok', 'fail'}
            Whether sending the sensor list succeeded.
        informs : int
            Number of #sensor-list inform messages sent.

        Examples
        --------
        ::

            ?sensor-list
            #sensor-list psu.voltage PSU\_voltage. V float 0.0 5.0
            #sensor-list cpu.status CPU\_status. \@ discrete on off error
            ...
            !sensor-list ok 5

            ?sensor-list cpu.power.on
            #sensor-list cpu.power.on Whether\_CPU\_hase\_power. \@ boolean
            !sensor-list ok 1

            ?sensor-list /voltage/
            #sensor-list psu.voltage PSU\_voltage. V float 0.0 5.0
            #sensor-list cpu.voltage CPU\_voltage. V float 0.0 3.0
            !sensor-list ok 2

        """
        exact, name_filter = construct_name_filter(msg.arguments[0]
                                                   if msg.arguments else None)
        sensors = [(name, sensor) for name, sensor in
                   sorted(self._sensors.iteritems()) if name_filter(name)]

        if exact and not sensors:
            return req.make_reply("fail", "Unknown sensor name.")

        self._send_sensor_value_informs(req, sensors)
        return req.make_reply("ok", str(len(sensors)))


Instruction:
Can you generate the documentation for the following Python 3 function
def request_sensor_value(self, req, msg):
        exact, name_filter = construct_name_filter(msg.arguments[0]
                                                   if msg.arguments else None)
        sensors = [(name, sensor) for name, sensor in
                   sorted(self._sensors.iteritems()) if name_filter(name)]

        if exact and not sensors:
            return req.make_reply("fail", "Unknown sensor name.")

        katcp_version = self.PROTOCOL_INFO.major
        for name, sensor in sensors:
            timestamp, status, value = sensor.read_formatted(katcp_version)
            req.inform(timestamp, "1", name, status, value)
        return req.make_reply("ok", str(len(sensors)))

Response: Request the value of a sensor or sensors.


Instruction:
Can you generate the documentation for the following Python 3 function
def request_sensor_sampling(self, req, msg):
        f = Future()
        self.ioloop.add_callback(lambda: chain_future(
            self._handle_sensor_sampling(req, msg), f))
        return f

Response: Configure or query the way a sensor is sampled.


Instruction:
Can you tell what is the following Python 3 function doing
def request_sensor_sampling_clear(self, req):
        f = Future()
        @gen.coroutine
        def _clear_strategies():
            self.clear_strategies(req.client_connection)
            raise gen.Return(('ok',))

        self.ioloop.add_callback(lambda: chain_future(_clear_strategies(), f))
        return f

Response: Clear all sampling strategies for this client.


Instruction:
How would you explain what the following Python 3 function does
def level_name(self, level=None):
        if level is None:
            level = self._log_level
        return self.LEVELS[level]

Response: Return the name of the given level value.


Instruction:
Given the following Python 3 function, write the documentation
def level_from_name(self, level_name):
        try:
            return self.LEVELS.index(level_name)
        except ValueError:
            raise ValueError("Unknown logging level name '%s'" % (level_name,))

Response: Return the logging level constant associated with a given name.


Instruction:
Implement a function in Python 3 to
set the logging level.

Response:
def set_log_level(self, level):
        """Set the logging level.

        Parameters
        ----------
        level : logging level constant
            The value to set the logging level to.

        """
        self._log_level = level
        if self._python_logger:
            try:
                level = self.PYTHON_LEVEL.get(level)
            except ValueError as err:
                raise FailReply("Unknown logging level '%s'" % (level))
            self._python_logger.setLevel(level)


Instruction:
Write a Python 3 function for
logging a message at the specified level and inform all clients.

Response:
def log(self, level, msg, *args, **kwargs):
        """Log a message and inform all clients.

        Parameters
        ----------
        level : logging level constant
            The level to log the message at.
        msg : str
            The text format for the log message.
        args : list of objects
            Arguments to pass to log format string. Final message text is
            created using: msg % args.
        kwargs : additional keyword parameters
            Allowed keywords are 'name' and 'timestamp'. The name is the name
            of the logger to log the message to. If not given the name defaults
            to the root logger. The timestamp is a float in seconds. If not
            given the timestamp defaults to the current time.

        """
        timestamp = kwargs.get("timestamp")
        python_msg = msg
        if self._python_logger is not None:
            if timestamp is not None:
                python_msg = ' '.join((
                    'katcp timestamp: %r' % timestamp,
                    python_msg))
            self._python_logger.log(self.PYTHON_LEVEL[level], python_msg, *args)
        if level >= self._log_level:
            name = kwargs.get("name")
            if name is None:
                name = self._root_logger_name
            try:
                inform_msg = msg % args
            except TypeError:
                # Catch the "not enough arguments for format string" exception.
                inform_msg = "{} {}".format(
                    msg,
                    args if args else '').strip()

            self._device_server.mass_inform(
                self._device_server.create_log_inform(
                    self.level_name(level),
                    inform_msg,
                    name,
                    timestamp=timestamp))


Instruction:
Can you create a Python 3 function that
logs an warning message.

Response:
def warn(self, msg, *args, **kwargs):
        """Log an warning message."""
        self.log(self.WARN, msg, *args, **kwargs)


Instruction:
Write a Python 3 script to
log a KATCP logging message to a Python logger.

Response:
def log_to_python(cls, logger, msg):
        """Log a KATCP logging message to a Python logger.

        Parameters
        ----------
        logger : logging.Logger object
            The Python logger to log the given message to.
        msg : Message object
            The #log message to create a log entry from.

        """
        (level, timestamp, name, message) = tuple(msg.arguments)
        log_string = "%s %s: %s" % (timestamp, name, message)
        logger.log({"trace": 0,
                    "debug": logging.DEBUG,
                    "info": logging.INFO,
                    "warn": logging.WARN,
                    "error": logging.ERROR,
                    "fatal": logging.FATAL}[level], log_string)


Instruction:
Explain what the following Python 3 code does
def request_echo(self, sock, msg):
        return katcp.Message.reply(msg.name, "ok", *msg.arguments)

Response: Echo the arguments of the message sent.


Instruction:
Given the following Python 3 function, write the documentation
def log_coroutine_exceptions(coro):
    def log_cb(self, f):
        try:
            f.result()
        except Exception:
            self._logger.exception('Unhandled exception calling coroutine {0!r}'
                                   .format(coro))

    @wraps(coro)
    def wrapped_coro(self, *args, **kwargs):
        try:
            f = coro(self, *args, **kwargs)
        except Exception:
            f = tornado_Future()
            f.set_exc_info(sys.exc_info())
        f.add_done_callback(partial(log_cb, self))
        return f

    return wrapped_coro

Response: A coroutine decorator that logs exceptions and returns a tornado. Future.


Instruction:
Can you generate the documentation for the following Python 3 function
def log_future_exceptions(logger, f, ignore=()):
    def log_cb(f):
        try:
            f.result()
        except ignore:
            pass
        except Exception:
            logger.exception('Unhandled exception returned by future')
    f.add_done_callback(log_cb)

Response: Log any exceptions set to a future.


Instruction:
Make a summary of the following Python 3 code
def steal_docstring_from(obj):
    def deco(fn):
        docs = [obj.__doc__]
        if fn.__doc__:
            docs.append(fn.__doc__)
        fn.__doc__ = '\n\n'.join(docs)
        return fn

    return deco

Response: Decorator that lets you steal a docstring from another object


Instruction:
Implement a Python 3 function for
generating a hashable ID that is stable for methods etc Approach borrowed from blinker Approach borrowed from blinker. Why it matters. Why it matters. Why it matters. Why it matters. Why it matters. Why it matters. Why it matters. Why it matters. Why it matters. Why it matters. Why it matters.

Response:
def hashable_identity(obj):

    """Generate a hashable ID that is stable for methods etc

    Approach borrowed from blinker. Why it matters: see e.g.
    http://stackoverflow.com/questions/13348031/python-bound-and-unbound-method-object
    """
    if hasattr(obj, '__func__'):
        return (id(obj.__func__), id(obj.__self__))
    elif hasattr(obj, 'im_func'):
        return (id(obj.im_func), id(obj.im_self))
    elif isinstance(obj, (basestring, unicode)):
        return obj
    else:
        return id(obj)


Instruction:
Can you create a Python 3 function that
returns a tornado Future that resolves when any of the passed futures resolves.

Response:
def until_any(*futures, **kwargs):
    """Return a future that resolves when any of the passed futures resolves.

    Resolves with the value yielded by the first future to resolve.

    Note, this will only work with tornado futures.

    """
    timeout = kwargs.get('timeout', None)
    ioloop = kwargs.get('ioloop', None) or tornado.ioloop.IOLoop.current()
    any_future = tornado_Future()

    def handle_done(done_future):
        if not any_future.done():
            try:
                any_future.set_result(done_future.result())
            except Exception:
                any_future.set_exc_info(done_future.exc_info())
            # (NM) Nasty hack to remove handle_done from the callback list to prevent a
            # memory leak where one of the futures resolves quickly, particularly when
            # used together with AsyncState.until_state(). Also addresses Jira issue
            # CM-593
            for f in futures:
                if f._callbacks:
                    try:
                        f._callbacks.remove(handle_done)
                    except ValueError:
                        pass

    for f in futures:
        f.add_done_callback(handle_done)
        if any_future.done():
            break

    if timeout:
        return with_timeout(ioloop.time() + timeout, any_future, ioloop)
    else:
        return any_future


Instruction:
Can you tell what is the following Python 3 function doing
def future_timeout_manager(timeout=None, ioloop=None):
    ioloop = ioloop or tornado.ioloop.IOLoop.current()
    t0 = ioloop.time()

    def _remaining():
        return timeout - (ioloop.time() - t0) if timeout else None

    def maybe_timeout(f):
        """Applies timeout if timeout is not None"""
        if not timeout:
            return f
        else:
            remaining = _remaining()
            deadline = ioloop.time() + remaining
            return with_timeout(deadline, f, ioloop)

    maybe_timeout.remaining = _remaining

    return maybe_timeout

Response: Create a coroutine that returns a future that can be used for timeout.


Instruction:
How would you implement a function in Python 3 that
returns a tornado Future that resolves when some of the passed futures resolve.

Response:
def until_some(*args, **kwargs):
    """Return a future that resolves when some of the passed futures resolve.

    The futures can be passed as either a sequence of *args* or a dict of
    *kwargs* (but not both). Some additional keyword arguments are supported,
    as described below. Once a specified number of underlying futures have
    resolved, the returned future resolves as well, or a timeout could be
    raised if specified.

    Parameters
    ----------
    done_at_least : None or int
        Number of futures that need to resolve before this resolves or None
        to wait for all (default None)
    timeout : None or float
        Timeout in seconds, or None for no timeout (the default)

    Returns
    -------
    This command returns a tornado Future that resolves with a list of
    (index, value) tuples containing the results of all futures that resolved,
    with corresponding indices (numbers for *args* futures or keys for *kwargs*
    futures).

    Raises
    ------
    :class:`tornado.gen.TimeoutError`
        If operation times out before the requisite number of futures resolve

    """
    done_at_least = kwargs.pop('done_at_least', None)
    timeout = kwargs.pop('timeout', None)
    # At this point args and kwargs are either empty or contain futures only
    if done_at_least is None:
        done_at_least = len(args) + len(kwargs)
    wait_iterator = tornado.gen.WaitIterator(*args, **kwargs)
    maybe_timeout = future_timeout_manager(timeout)
    results = []
    while not wait_iterator.done():
        result = yield maybe_timeout(wait_iterator.next())
        results.append((wait_iterator.current_index, result))
        if len(results) >= done_at_least:
            break
    raise tornado.gen.Return(results)


Instruction:
Write a Python 3 function that can
format a Message argument to a string

Response:
def format_argument(self, arg):
        """Format a Message argument to a string"""
        if isinstance(arg, float):
            return repr(arg)
        elif isinstance(arg, bool):
            return str(int(arg))
        else:
            try:
                return str(arg)
            except UnicodeEncodeError:
                # unicode characters will break the str cast, so
                # try to encode to ascii and replace the offending characters
                # with a '?' character
                logger.error("Error casting message argument to str! "
                             "Trying to encode argument to ascii.")
                if not isinstance(arg, unicode):
                    arg = arg.decode('utf-8')
                return arg.encode('ascii', 'replace')


Instruction:
Write a Python 3 script to
return True if this is a reply and its first argument is ok.

Response:
def reply_ok(self):
        """Return True if this is a reply and its first argument is 'ok'."""
        return (self.mtype == self.REPLY and self.arguments and
                self.arguments[0] == self.OK)


Instruction:
Explain what the following Python 3 code does
def request(cls, name, *args, **kwargs):
        mid = kwargs.pop('mid', None)
        if len(kwargs) > 0:
            raise TypeError('Invalid keyword argument(s): %r' % kwargs)
        return cls(cls.REQUEST, name, args, mid)

Response: Helper method for creating request messages.


Instruction:
Can you implement a function in Python 3 that
returns a new reply message.

Response:
def reply(cls, name, *args, **kwargs):
        """Helper method for creating reply messages.

        Parameters
        ----------
        name : str
            The name of the message.
        args : list of strings
            The message arguments.

        Keyword Arguments
        -----------------
        mid : str or None
            Message ID to use or None (default) for no Message ID

        """
        mid = kwargs.pop('mid', None)
        if len(kwargs) > 0:
            raise TypeError('Invalid keyword argument(s): %r' % kwargs)
        return cls(cls.REPLY, name, args, mid)


Instruction:
Can you implement a function in Python 3 that
returns a new reply message that is a specific request.

Response:
def reply_to_request(cls, req_msg, *args):
        """Helper method for creating reply messages to a specific request.

        Copies the message name and message identifier from request message.

        Parameters
        ----------
        req_msg : katcp.core.Message instance
            The request message that this inform if in reply to
        args : list of strings
            The message arguments.

        """
        return cls(cls.REPLY, req_msg.name, args, req_msg.mid)


Instruction:
How would you code a function in Python 3 to
create an inform message.

Response:
def inform(cls, name, *args, **kwargs):
        """Helper method for creating inform messages.

        Parameters
        ----------
        name : str
            The name of the message.
        args : list of strings
            The message arguments.

        """
        mid = kwargs.pop('mid', None)
        if len(kwargs) > 0:
            raise TypeError('Invalid keyword argument(s): %r' % kwargs)
        return cls(cls.INFORM, name, args, mid)


Instruction:
Given the following Python 3 function, write the documentation
def reply_inform(cls, req_msg, *args):
        return cls(cls.INFORM, req_msg.name, args, req_msg.mid)

Response: Create an inform message in reply to a request message.


Instruction:
Can you tell what is the following Python 3 function doing
def _unescape_match(self, match):
        char = match.group(1)
        if char in self.ESCAPE_LOOKUP:
            return self.ESCAPE_LOOKUP[char]
        elif not char:
            raise KatcpSyntaxError("Escape slash at end of argument.")
        else:
            raise KatcpSyntaxError("Invalid escape character %r." % (char,))

Response: Given a re. Match unescape the escape code it represents.


Instruction:
Can you generate a brief explanation for the following Python 3 code
def parse(self, line):
        # find command type and check validity
        if not line:
            raise KatcpSyntaxError("Empty message received.")

        type_char = line[0]
        if type_char not in self.TYPE_SYMBOL_LOOKUP:
            raise KatcpSyntaxError("Bad type character %r." % (type_char,))

        mtype = self.TYPE_SYMBOL_LOOKUP[type_char]

        # find command and arguments name
        # (removing possible empty argument resulting from whitespace at end
        #  of command)
        parts = self.WHITESPACE_RE.split(line)
        if not parts[-1]:
            del parts[-1]

        name = parts[0][1:]
        arguments = [self._parse_arg(x) for x in parts[1:]]

        # split out message id
        match = self.NAME_RE.match(name)
        if match:
            name = match.group('name')
            mid = match.group('id')
        else:
            raise KatcpSyntaxError("Bad message name (and possibly id) %r." %
                                   (name,))

        return Message(mtype, name, arguments, mid)

Response: Parse a line of text into a Message object.


Instruction:
Write a Python 3 script to
parse a version string into a ProtocolFlags object.

Response:
def parse_version(cls, version_str):
        """Create a :class:`ProtocolFlags` object from a version string.

        Parameters
        ----------
        version_str : str
            The version string from a #version-connect katcp-protocol
            message.

        """
        match = cls.VERSION_RE.match(version_str)
        if match:
            major = int(match.group('major'))
            minor = int(match.group('minor'))
            flags = set(match.group('flags') or '')
        else:
            major, minor, flags = None, None, set()
        return cls(major, minor, flags)


Instruction:
Can you write a function in Python 3 where it
trues if the current server s protocol version satisfies handler requirements

Response:
def check_protocol(mcs, handler):
        """
        True if the current server's protocol flags satisfy handler requirements

        """
        protocol_info = mcs.PROTOCOL_INFO
        protocol_version = (protocol_info.major, protocol_info.minor)
        protocol_flags = protocol_info.flags

        # Check if minimum protocol version requirement is met
        min_protocol_version = getattr(handler, '_minimum_katcp_version', None)
        protocol_version_ok = (min_protocol_version is None or
                               protocol_version >= min_protocol_version)

        # Check if required optional protocol flags are present
        required_katcp_protocol_flags = getattr(
            handler, '_has_katcp_protocol_flags', None)
        protocol_flags_ok = (
            required_katcp_protocol_flags is None or
            all(flag in protocol_flags
                for flag in required_katcp_protocol_flags))

        return protocol_version_ok and protocol_flags_ok


Instruction:
Explain what the following Python 3 code does
def integer(cls, name, description=None, unit='', params=None,
                default=None, initial_status=None):
        """Instantiate a new integer sensor object.

        Parameters
        ----------
        name : str
            The name of the sensor.
        description : str
            A short description of the sensor.
        units : str
            The units of the sensor value. May be the empty string
            if there are no applicable units.
        params : list
            [min, max] -- miniumum and maximum values of the sensor
        default : int
            An initial value for the sensor. Defaults to 0.
        initial_status : int enum or None
            An initial status for the sensor. If None, defaults to
            Sensor.UNKNOWN. `initial_status` must be one of the keys in
            Sensor.STATUSES

        """
        return cls(cls.INTEGER, name, description, unit, params,
                   default, initial_status)

Response: Instantiate a new integer sensor object.


Instruction:
Explain what the following Python 3 code does
def lru(cls, name, description=None, unit='',
            default=None, initial_status=None):
        """Instantiate a new lru sensor object.

        Parameters
        ----------
        name : str
            The name of the sensor.
        description : str
            A short description of the sensor.
        units : str
            The units of the sensor value. May be the empty string
            if there are no applicable units.
        default : enum, Sensor.LRU_*
            An initial value for the sensor. Defaults to self.LRU_NOMINAL
        initial_status : int enum or None
            An initial status for the sensor. If None, defaults to
            Sensor.UNKNOWN. `initial_status` must be one of the keys in
            Sensor.STATUSES

        """
        return cls(cls.LRU, name, description, unit, None,
                   default, initial_status)

Response: Instantiate a new lru sensor object.


Instruction:
Here you have a function in Python 3, explain what it does
def discrete(cls, name, description=None, unit='', params=None,
                 default=None, initial_status=None):
        """Instantiate a new discrete sensor object.

        Parameters
        ----------
        name : str
            The name of the sensor.
        description : str
            A short description of the sensor.
        units : str
            The units of the sensor value. May be the empty string
            if there are no applicable units.
        params : [str]
            Sequence of all allowable discrete sensor states
        default : str
            An initial value for the sensor. Defaults to the first item
            of params
        initial_status : int enum or None
            An initial status for the sensor. If None, defaults to
            Sensor.UNKNOWN. `initial_status` must be one of the keys in
            Sensor.STATUSES

        """
        return cls(cls.DISCRETE, name, description, unit, params,
                   default, initial_status)

Response: Instantiate a new discrete sensor object.


Instruction:
Here you have a function in Python 3, explain what it does
def address(cls, name, description=None, unit='',
                default=None, initial_status=None):
        """Instantiate a new IP address sensor object.

        Parameters
        ----------
        name : str
            The name of the sensor.
        description : str
            A short description of the sensor.
        units : str
            The units of the sensor value. May be the empty string
            if there are no applicable units.
        default : (string, int)
            An initial value for the sensor. Tuple contaning (host, port).
            default is ("0.0.0.0", None)
        initial_status : int enum or None
            An initial status for the sensor. If None, defaults to
            Sensor.UNKNOWN. `initial_status` must be one of the keys in
            Sensor.STATUSES

        """
        return cls(cls.ADDRESS, name, description, unit, None,
                   default, initial_status)

Response: Instantiate a new IP address sensor object.


Instruction:
Write a Python 3 function for
notifying all observers of changes to this sensor.

Response:
def notify(self, reading):
        """Notify all observers of changes to this sensor."""
        # copy list before iterating in case new observers arrive
        for o in list(self._observers):
            o.update(self, reading)


Instruction:
Implement a Python 3 function for
setting the current value of the sensor.

Response:
def set(self, timestamp, status, value):
        """Set the current value of the sensor.

        Parameters
        ----------
        timestamp : float in seconds
           The time at which the sensor value was determined.
        status : Sensor status constant
            Whether the value represents an error condition or not.
        value : object
            The value of the sensor (the type should be appropriate to the
            sensor's type).

        """
        reading = self._current_reading = Reading(timestamp, status, value)
        self.notify(reading)


Instruction:
How would you code a function in Python 3 to
set the current value of the sensor.

Response:
def set_formatted(self, raw_timestamp, raw_status, raw_value,
                      major=DEFAULT_KATCP_MAJOR):
        """Set the current value of the sensor.

        Parameters
        ----------
        timestamp : str
            KATCP formatted timestamp string
        status : str
            KATCP formatted sensor status string
        value : str
            KATCP formatted sensor value
        major : int, default = 5
            KATCP major version to use for interpreting the raw values

        """
        timestamp = self.TIMESTAMP_TYPE.decode(raw_timestamp, major)
        status = self.STATUS_NAMES[raw_status]
        value = self.parse_value(raw_value, major)
        self.set(timestamp, status, value)


Instruction:
How would you implement a function in Python 3 that
formats a sensor reading as a tuple of strings.

Response:
def format_reading(self, reading, major=DEFAULT_KATCP_MAJOR):
        """Format sensor reading as (timestamp, status, value) tuple of strings.

        All values are strings formatted as specified in the Sensor Type
        Formats in the katcp specification.

        Parameters
        ----------
        reading : :class:`Reading` object
            Sensor reading as returned by :meth:`read`
        major : int
            Major version of KATCP to use when interpreting types.
            Defaults to latest implemented KATCP version.

        Returns
        -------
        timestamp : str
            KATCP formatted timestamp string
        status : str
            KATCP formatted sensor status string
        value : str
            KATCP formatted sensor value

        Note
        ----
        Should only be used for a reading obtained from the same sensor.

        """

        timestamp, status, value = reading
        return (self.TIMESTAMP_TYPE.encode(timestamp, major),
                self.STATUSES[status],
                self._formatter(value, True, major))


Instruction:
Can you generate the documentation for the following Python 3 function
def set_value(self, value, status=NOMINAL, timestamp=None,
                  major=DEFAULT_KATCP_MAJOR):
        """Check and then set the value of the sensor.

        Parameters
        ----------
        value : object
            Value of the appropriate type for the sensor.
        status : Sensor status constant
            Whether the value represents an error condition or not.
        timestamp : float in seconds or None
            The time at which the sensor value was determined.
            Uses current time if None.
        major : int
            Major version of KATCP to use when interpreting types.
            Defaults to latest implemented KATCP version.

        """
        self._kattype.check(value, major)
        if timestamp is None:
            timestamp = time.time()
        self.set(timestamp, status, value)

Response: Set the value of the object in the KATCP system.


Instruction:
Can you generate a brief explanation for the following Python 3 code
def parse_type(cls, type_string):
        if type_string in cls.SENSOR_TYPE_LOOKUP:
            return cls.SENSOR_TYPE_LOOKUP[type_string]
        else:
            raise KatcpSyntaxError("Invalid sensor type string %s" %
                                   type_string)

Response: Parse a KATCP formatted type code into a Sensor type constant.


Instruction:
Here you have a function in Python 3, explain what it does
def parse_params(cls, sensor_type, formatted_params,
                     major=DEFAULT_KATCP_MAJOR):
        """Parse KATCP formatted parameters into Python values.

        Parameters
        ----------
        sensor_type : Sensor type constant
            The type of sensor the parameters are for.
        formatted_params : list of strings
            The formatted parameters that should be parsed.
        major : int
            Major version of KATCP to use when interpreting types.
            Defaults to latest implemented KATCP version.

        Returns
        -------
        params : list of objects
            The parsed parameters.

        """
        typeclass, _value = cls.SENSOR_TYPES[sensor_type]
        if sensor_type == cls.DISCRETE:
            kattype = typeclass([])
        else:
            kattype = typeclass()
        return [kattype.decode(x, major) for x in formatted_params]

Response: Parse KATCP formatted parameters into Python values.


Instruction:
Given the following Python 3 function, write the documentation
def set(self):
        self._flag = True
        old_future = self._waiting_future
        # Replace _waiting_future with a fresh one incase someone woken up by set_result()
        # sets this AsyncEvent to False before waiting on it to be set again.
        self._waiting_future = tornado_Future()
        old_future.set_result(True)

Response: Sets the event flag to true and resolve future(s returned by until_set.


Instruction:
How would you explain what the following Python 3 function does
def wait_with_ioloop(self, ioloop, timeout=None):
        f = Future()

        def cb():
            return gen.chain_future(self.until_set(), f)
        ioloop.add_callback(cb)
        try:
            f.result(timeout)
            return True
        except TimeoutError:
            return self._flag

Response: Do blocking wait until condition is set in ioloop.


Instruction:
How would you explain what the following Python 3 function does
def until_state(self, state, timeout=None):
        if state not in self._valid_states:
            raise ValueError('State must be one of {0}, not {1}'
                             .format(self._valid_states, state))
        if state != self._state:
            if timeout:
                return with_timeout(self._ioloop.time() + timeout,
                                    self._waiting_futures[state],
                                    self._ioloop)
            else:
                return self._waiting_futures[state]
        else:
            f = tornado_Future()
            f.set_result(True)
            return f

Response: Return a tornado Future that will resolve when the requested state is set


Instruction:
Write a Python 3 function that can
return a tornado Future resolves when any of the requested states is set

Response:
def until_state_in(self, *states, **kwargs):
        """Return a tornado Future, resolves when any of the requested states is set"""
        timeout = kwargs.get('timeout', None)
        state_futures = (self.until_state(s, timeout=timeout) for s in states)
        return until_any(*state_futures)


Instruction:
Can you write a function in Python 3 where it
calls with each future that is to be yielded on

Response:
def check_future(self, fut):
        """Call with each future that is to be yielded on"""
        done = self.done = fut.done()
        if done and not self.prev_done:
            self.done_since = self.ioloop.time()
        self.prev_done = done


Instruction:
Write a Python 3 function that can
check if we have time to yield tornado. gen. moment.

Response:
def time_to_yield(self):
        """Call after check_future(). If True, it is time to yield tornado.gen.moment"""
        delta = self.ioloop.time() - self.done_since
        if self.done and delta > self.max_loop_latency:
            return True
        return False


Instruction:
Create a Python 3 function for
making blocking request to client and raise exception if reply is not ok.

Response:
def request_check(client, exception, *msg_parms, **kwargs):
    """Make blocking request to client and raise exception if reply is not ok.

    Parameters
    ----------
    client : DeviceClient instance
    exception: Exception class to raise
    *msg_parms : Message parameters sent to the Message.request() call
    **kwargs : Keyword arguments
        Forwards kwargs['timeout'] to client.blocking_request().
        Forwards kwargs['mid'] to Message.request().

    Returns
    -------
    reply, informs : as returned by client.blocking_request

    Raises
    ------
    *exception* passed as parameter is raised if reply.reply_ok() is False

    Notes
    -----
    A typical use-case for this function is to use functools.partial() to bind
    a particular client and exception. The resulting function can then be used
    instead of direct client.blocking_request() calls to automate error
    handling.

    """
    timeout = kwargs.get('timeout', None)
    req_msg = Message.request(*msg_parms)
    if timeout is not None:
        reply, informs = client.blocking_request(req_msg, timeout=timeout)
    else:
        reply, informs = client.blocking_request(req_msg)

    if not reply.reply_ok():
        raise exception('Unexpected failure reply "{2}"\n'
                        ' with device at {0}, request \n"{1}"'
                        .format(client.bind_address_string, req_msg, reply))
    return reply, informs


Instruction:
Can you generate the documentation for the following Python 3 function
def convert_seconds(self, time_seconds):
        if self.protocol_flags.major >= SEC_TS_KATCP_MAJOR:
            return time_seconds
        else:
            device_time = time_seconds * SEC_TO_MS_FAC
            if self.protocol_flags.major < FLOAT_TS_KATCP_MAJOR:
                device_time = int(device_time)
            return device_time

Response: Convert a time in seconds to the device timestamp units.


Instruction:
Given the following Python 3 function, write the documentation
def _next_id(self):
        assert get_thread_ident() == self.ioloop_thread_id
        self._last_msg_id += 1
        return str(self._last_msg_id)

Response: Return the next available message id.


Instruction:
Can you generate the documentation for the following Python 3 function
def inform_version_connect(self, msg):
        if len(msg.arguments) < 2:
            return
        # Store version information.
        name = msg.arguments[0]
        self.versions[name] = tuple(msg.arguments[1:])
        if msg.arguments[0] == "katcp-protocol":
            protocol_flags = ProtocolFlags.parse_version(msg.arguments[1])
            self._set_protocol_from_inform(protocol_flags, msg)

Response: Process a version - connect message.


Instruction:
Can you create a Python 3 function that
gets message ID for current request and assign to msg. mid if needed.

Response:
def _get_mid_and_update_msg(self, msg, use_mid):
        """Get message ID for current request and assign to msg.mid if needed.

        Parameters
        ----------
        msg : katcp.Message ?request message
        use_mid : bool or None

        If msg.mid is None, a new message ID will be created. msg.mid will be
        filled with this ID if use_mid is True or if use_mid is None and the
        server supports message ids. If msg.mid is already assigned, it will
        not be touched, and will be used as the active message ID.

        Return value
        ------------
        The active message ID

        """
        if use_mid is None:
            use_mid = self._server_supports_ids

        if msg.mid is None:
            mid = self._next_id()
            if use_mid:
                msg.mid = mid
            # An internal mid may be needed for the request/inform/response
            # machinery to work, so we return it
            return mid
        else:
            return msg.mid


Instruction:
How would you explain what the following Python 3 function does
def request(self, msg, use_mid=None):
        mid = self._get_mid_and_update_msg(msg, use_mid)
        self.send_request(msg)
        return mid

Response: Send a request message to the server with automatic message ID assignment.


Instruction:
How would you code a function in Python 3 to
send a request message to the server.

Response:
def send_request(self, msg):
        """Send a request messsage.

        Parameters
        ----------
        msg : Message object
            The request Message to send.

        """
        assert(msg.mtype == Message.REQUEST)
        if msg.mid and not self._server_supports_ids:
            raise KatcpVersionError('Message IDs not supported by server')
        self.send_message(msg)


Instruction:
Can you create a Python 3 function that
sends a message to the ioloop thread.

Response:
def send_message(self, msg):
        """Send any kind of message.

        Parameters
        ----------
        msg : Message object
            The message to send.

        """
        assert get_thread_ident() == self.ioloop_thread_id
        data = str(msg) + "\n"
        # Log all sent messages here so no one else has to.
        if self._logger.isEnabledFor(logging.DEBUG):
            self._logger.debug("Sending to {}: {}"
                               .format(self.bind_address_string, repr(data)))
        if not self._connected.isSet():
            raise KatcpClientDisconnected('Not connected to device {0}'.format(
                self.bind_address_string))
        try:
            return self._stream.write(data)
        except Exception:
            self._logger.warn('Could not send message {0!r} to {1!r}'
                              .format(str(msg), self._bindaddr), exc_info=True)
            self._disconnect(exc_info=True)


Instruction:
Implement a function in Python 3 to
connect to the server.

Response:
def _connect(self):
        """Connect to the server."""
        assert get_thread_ident() == self.ioloop_thread_id
        if self._stream:
            self._logger.warn('Disconnecting existing connection to {0!r} '
                              'to create a new connection')
            self._disconnect()
            yield self._disconnected.until_set()

        stream = None
        try:
            host, port = self._bindaddr
            stream = self._stream = yield self._tcp_client.connect(
                host, port, max_buffer_size=self.MAX_MSG_SIZE)
            stream.set_close_callback(partial(self._stream_closed_callback,
                                              stream))
            # our message packets are small, don't delay sending them.
            stream.set_nodelay(True)
            stream.max_write_buffer_size = self.MAX_WRITE_BUFFER_SIZE
            self._logger.debug('Connected to {0} with client addr {1}'
                               .format(self.bind_address_string,
                                       address_to_string(stream.socket.getsockname())))
            if self._connect_failures >= 5:
                self._logger.warn("Reconnected to {0}"
                                  .format(self.bind_address_string))
            self._connect_failures = 0
        except Exception, e:
            if self._connect_failures % 5 == 0:
                # warn on every fifth failure

                # TODO (NM 2015-03-04) This can get a bit verbose, and typically we have
                # other mechanisms for tracking failed connections. Consider doing some
                # kind of exponential backoff starting at 5 times the reconnect time up to
                # once per 5 minutes
                self._logger.debug("Failed to connect to {0!r}: {1}"
                                  .format(self._bindaddr, e))
            self._connect_failures += 1
            stream = None
            yield gen.moment
            # TODO some kind of error rate limiting?

            if self._stream:
                # Can't use _disconnect() and wait on self._disconnected, since
                # exception may have been raised before _stream_closed_callback
                # was attached to the iostream.
                self._logger.debug('stream was set even though connecting failed')
                self._stream.close()
                self._disconnected.set()

        if stream:
            self._disconnected.clear()
            self._connected.set()
            self.last_connect_time = self.ioloop.time()
            try:
                self.notify_connected(True)
            except Exception:
                self._logger.exception("Notify connect failed. Disconnecting.")
                self._disconnect()


Instruction:
Explain what the following Python 3 code does
def handle_message(self, msg):
        # log messages received so that no one else has to
        if self._logger.isEnabledFor(logging.DEBUG):
            self._logger.debug(
                "received from {}: {}"
                .format(self.bind_address_string, repr(str(msg))))

        if msg.mtype == Message.INFORM:
            return self.handle_inform(msg)
        elif msg.mtype == Message.REPLY:
            return self.handle_reply(msg)
        elif msg.mtype == Message.REQUEST:
            return self.handle_request(msg)
        else:
            self._logger.error("Unexpected message type from server ['%s']."
                               % (msg,))

Response: Handle a message from the server.


Instruction:
Given the following Python 3 function, write the documentation
def handle_inform(self, msg):
        method = self._inform_handlers.get(
            msg.name, self.__class__.unhandled_inform)

        try:
            return method(self, msg)
        except Exception:
            e_type, e_value, trace = sys.exc_info()
            reason = "\n".join(traceback.format_exception(
                e_type, e_value, trace, self._tb_limit))
            self._logger.error("Inform %s FAIL: %s" % (msg.name, reason))

Response: Dispatch an inform message to the appropriate method.


Instruction:
Here you have a function in Python 3, explain what it does
def handle_reply(self, msg):
        method = self.__class__.unhandled_reply
        if msg.name in self._reply_handlers:
            method = self._reply_handlers[msg.name]

        try:
            return method(self, msg)
        except Exception:
            e_type, e_value, trace = sys.exc_info()
            reason = "\n".join(traceback.format_exception(
                e_type, e_value, trace, self._tb_limit))
            self._logger.error("Reply %s FAIL: %s" % (msg.name, reason))

Response: Dispatch a reply message to the appropriate method.


Instruction:
Implement a function in Python 3 to
dispatch a request to the appropriate method.

Response:
def handle_request(self, msg):
        """Dispatch a request message to the appropriate method.

        Parameters
        ----------
        msg : Message object
            The request message to dispatch.

        """
        method = self.__class__.unhandled_request
        if msg.name in self._request_handlers:
            method = self._request_handlers[msg.name]

        try:
            reply = method(self, msg)
            if isinstance(reply, Message):
                # If it is a message object, assume it is a reply.
                reply.mid = msg.mid
                assert (reply.mtype == Message.REPLY)
                assert (reply.name == msg.name)
                self._logger.info("%s OK" % (msg.name,))
                self.send_message(reply)
            else:
                # Just pass on what is, potentially, a future. The implementor
                # of the request handler method must arrange for a reply to be
                # sent. Since clients have no business dealing with requests in
                # any case we don't do much to help them.
                return reply
        # We do want to catch everything that inherits from Exception
        # pylint: disable-msg = W0703
        except Exception:
            e_type, e_value, trace = sys.exc_info()
            reason = "\n".join(traceback.format_exception(
                e_type, e_value, trace, self._tb_limit))
            self._logger.error("Request %s FAIL: %s" % (msg.name, reason))


Instruction:
Implement a Python 3 function for
setting the tornado. ioloop. IOLoop instance to use.

Response:
def set_ioloop(self, ioloop=None):
        """Set the tornado.ioloop.IOLoop instance to use.

        This defaults to IOLoop.current(). If set_ioloop() is never called the
        IOLoop is managed: started in a new thread, and will be stopped if
        self.stop() is called.

        Notes
        -----
        Must be called before start() is called

        """
        self._ioloop_manager.set_ioloop(ioloop, managed=False)
        self.ioloop = ioloop


Instruction:
Explain what the following Python 3 code does
def enable_thread_safety(self):
        if self.threadsafe:
            return                        # Already done!
        if self._running.isSet():
            raise RuntimeError('Cannot enable thread safety after start')

        def _getattr(obj, name):
            # use 'is True' so mock objects don't return true for everything
            return getattr(obj, name, False) is True

        for name in dir(self):
            try:
                meth = getattr(self, name)
            except AttributeError:
                # Subclasses may have computed attributes that don't work
                # before they are started, so let's ignore those
                pass
            if not callable(meth):
                continue
            make_threadsafe = _getattr(meth, 'make_threadsafe')
            make_threadsafe_blocking = _getattr(meth, 'make_threadsafe_blocking')

            if make_threadsafe:
                assert not make_threadsafe_blocking
                meth = self._make_threadsafe(meth)
                setattr(self, name, meth)
            elif make_threadsafe_blocking:
                meth = self._make_threadsafe_blocking(meth)
                setattr(self, name, meth)

        self._threadsafe = True

Response: Enable thread - safety features.


Instruction:
Given the following Python 3 function, write the documentation
def start(self, timeout=None):
        if self._running.isSet():
            raise RuntimeError("Device client already started.")
        # Make sure we have an ioloop
        self.ioloop = self._ioloop_manager.get_ioloop()
        if timeout:
            t0 = self.ioloop.time()
        self._ioloop_manager.start(timeout)
        self.ioloop.add_callback(self._install)
        if timeout:
            remaining_timeout = timeout - (self.ioloop.time() - t0)
            self.wait_running(remaining_timeout)

Response: Start the device client in a new thread.


Instruction:
Write a Python 3 script for
stopping a running client from another thread.

Response:
def stop(self, timeout=None):
        """Stop a running client (from another thread).

        Parameters
        ----------
        timeout : float in seconds
           Seconds to wait for client thread to have *started*.

        """
        ioloop = getattr(self, 'ioloop', None)
        if not ioloop:
            raise RuntimeError('Call start() before stop()')
        if timeout:
            if get_thread_ident() == self.ioloop_thread_id:
                raise RuntimeError('Cannot block inside ioloop')
            self._running.wait_with_ioloop(self.ioloop, timeout)

        def _cleanup():
            self._running.clear()
            self._disconnect()
        self._ioloop_manager.stop(timeout=timeout, callback=_cleanup)


Instruction:
Can you create a Python 3 function that
waits until the client is running.

Response:
def wait_running(self, timeout=None):
        """Wait until the client is running.

        Parameters
        ----------
        timeout : float in seconds
            Seconds to wait for the client to start running.

        Returns
        -------
        running : bool
            Whether the client is running

        Notes
        -----
        Do not call this from the ioloop, use until_running().

        """
        ioloop = getattr(self, 'ioloop', None)
        if not ioloop:
            raise RuntimeError('Call start() before wait_running()')
        return self._running.wait_with_ioloop(ioloop, timeout)


Instruction:
Make a summary of the following Python 3 code
def until_connected(self, timeout=None):
        t0 = self.ioloop.time()
        yield self.until_running(timeout=timeout)
        t1 = self.ioloop.time()
        if timeout:
            timedelta = timeout - (t1 - t0)
        else:
            timedelta = None
        assert get_thread_ident() == self.ioloop_thread_id
        yield self._connected.until_set(timeout=timedelta)

Response: Return future that resolves when the client is connected.


Instruction:
Can you create a Python 3 function that
returns a future that resolves after receipt of katcp protocol info.

Response:
def until_protocol(self, timeout=None):
        """Return future that resolves after receipt of katcp protocol info.

        If the returned future resolves, the server's protocol information is
        available in the ProtocolFlags instance self.protocol_flags.

        """
        t0 = self.ioloop.time()
        yield self.until_running(timeout=timeout)
        t1 = self.ioloop.time()
        if timeout:
            timedelta = timeout - (t1 - t0)
        else:
            timedelta = None
        assert get_thread_ident() == self.ioloop_thread_id
        yield self._received_protocol_info.until_set(timeout=timedelta)


Instruction:
Make a summary of the following Python 3 code
def _push_async_request(self, msg_id, request, reply_cb, inform_cb,
                            user_data, timeout_handle):
        """Store reply / inform callbacks for request we've sent."""
        assert get_thread_ident() == self.ioloop_thread_id
        self._async_queue[msg_id] = (
            request, reply_cb, inform_cb, user_data, timeout_handle)
        if request.name in self._async_id_stack:
            self._async_id_stack[request.name].append(msg_id)
        else:
            self._async_id_stack[request.name] = [msg_id]

Response: Push a request onto the async queue.


Instruction:
Can you implement a function in Python 3 that
pops the set of callbacks for a request.

Response:
def _pop_async_request(self, msg_id, msg_name):
        """Pop the set of callbacks for a request.

        Return tuple of Nones if callbacks already popped (or don't exist).

        """
        assert get_thread_ident() == self.ioloop_thread_id
        if msg_id is None:
            msg_id = self._msg_id_for_name(msg_name)
        if msg_id in self._async_queue:
            callback_tuple = self._async_queue[msg_id]
            del self._async_queue[msg_id]
            self._async_id_stack[callback_tuple[0].name].remove(msg_id)
            return callback_tuple
        else:
            return None, None, None, None, None


Instruction:
Can you tell what is the following Python 3 function doing
def _peek_async_request(self, msg_id, msg_name):
        assert get_thread_ident() == self.ioloop_thread_id
        if msg_id is None:
            msg_id = self._msg_id_for_name(msg_name)
        if msg_id in self._async_queue:
            return self._async_queue[msg_id]
        else:
            return None, None, None, None, None

Response: Return the set of callbacks for a request.


Instruction:
Can you generate a brief explanation for the following Python 3 code
def _msg_id_for_name(self, msg_name):
        if msg_name in self._async_id_stack and self._async_id_stack[msg_name]:
            return self._async_id_stack[msg_name][0]

Response: Find the message id for a given request name.


Instruction:
How would you explain what the following Python 3 function does
def callback_request(self, msg, reply_cb=None, inform_cb=None,
                         user_data=None, timeout=None, use_mid=None):
        """Send a request messsage.

        Parameters
        ----------
        msg : Message object
            The request message to send.
        reply_cb : function
            The reply callback with signature reply_cb(msg)
            or reply_cb(msg, \*user_data)
        inform_cb : function
            The inform callback with signature inform_cb(msg)
            or inform_cb(msg, \*user_data)
        user_data : tuple
            Optional user data to send to the reply and inform
            callbacks.
        timeout : float in seconds
            How long to wait for a reply. The default is the
            the timeout set when creating the AsyncClient.
        use_mid : boolean, optional
            Whether to use message IDs. Default is to use message IDs
            if the server supports them.

        """
        if timeout is None:
            timeout = self._request_timeout

        mid = self._get_mid_and_update_msg(msg, use_mid)

        if timeout is None:  # deal with 'no timeout', i.e. None
            timeout_handle = None
        else:
            timeout_handle = self.ioloop.call_later(
                timeout, partial(self._handle_timeout, mid, self.ioloop.time()))

        self._push_async_request(
            mid, msg, reply_cb, inform_cb, user_data, timeout_handle)

        try:
            self.send_request(msg)
        except KatcpClientError, e:
            error_reply = Message.request(msg.name, "fail", str(e))
            error_reply.mid = mid
            self.handle_reply(error_reply)

Response: Send a request to the server.


Instruction:
Can you tell what is the following Python 3 function doing
def future_request(self, msg, timeout=None, use_mid=None):
        if timeout is None:
            timeout = self._request_timeout

        f = tornado_Future()
        informs = []

        def reply_cb(msg):
            f.set_result((msg, informs))

        def inform_cb(msg):
            informs.append(msg)

        try:
            self.callback_request(msg, reply_cb=reply_cb, inform_cb=inform_cb,
                                  timeout=timeout, use_mid=use_mid)
        except Exception:
            f.set_exc_info(sys.exc_info())
        return f

Response: Send a request to the server with future replies.


Instruction:
How would you explain what the following Python 3 function does
def blocking_request(self, msg, timeout=None, use_mid=None):
        assert (get_thread_ident() != self.ioloop_thread_id), (
            'Cannot call blocking_request() in ioloop')
        if timeout is None:
            timeout = self._request_timeout

        f = Future()  # for thread safety
        tf = [None]   # Placeholder for tornado Future for exception tracebacks
        def blocking_request_callback():
            try:
                tf[0] = frf = self.future_request(msg, timeout=timeout,
                                                  use_mid=use_mid)
            except Exception:
                tf[0] = frf = tornado_Future()
                frf.set_exc_info(sys.exc_info())
            gen.chain_future(frf, f)

        self.ioloop.add_callback(blocking_request_callback)

        # We wait on the future result that should be set by the reply
        # handler callback. If this does not occur within the
        # timeout it means something unexpected went wrong. We give it
        # an extra second to deal with (unlikely?) slowness in the
        # rest of the code.
        extra_wait = 1
        wait_timeout = timeout
        if wait_timeout is not None:
            wait_timeout = wait_timeout + extra_wait
        try:
            return f.result(timeout=wait_timeout)
        except TimeoutError:
            raise RuntimeError('Unexpected error: Async request handler did '
                               'not call reply handler within timeout period')
        except Exception:
            # Use the tornado future to give us a usable traceback
            tf[0].result()
            assert False

Response: Send a request and wait for its reply.


Instruction:
Create a Python 3 function for
handling the inform message related to any current requests.

Response:
def handle_inform(self, msg):
        """Handle inform messages related to any current requests.

        Inform messages not related to the current request go up
        to the base class method.

        Parameters
        ----------
        msg : Message object
            The inform message to dispatch.

        """
        # this may also result in inform_cb being None if no
        # inform_cb was passed to the request method.
        if msg.mid is not None:
            _request, _reply_cb, inform_cb, user_data, _timeout_handle = \
                self._peek_async_request(msg.mid, None)
        else:
            request, _reply_cb, inform_cb, user_data, _timeout_handle = \
                self._peek_async_request(None, msg.name)
            if request is not None and request.mid is not None:
                # we sent a mid but this inform doesn't have one
                inform_cb, user_data = None, None

        if inform_cb is None:
            inform_cb = super(AsyncClient, self).handle_inform
            # override user_data since handle_inform takes no user_data
            user_data = None

        try:
            if user_data is None:
                inform_cb(msg)
            else:
                inform_cb(msg, *user_data)
        except Exception:
            e_type, e_value, trace = sys.exc_info()
            reason = "\n".join(traceback.format_exception(
                e_type, e_value, trace, self._tb_limit))
            self._logger.error("Callback inform %s FAIL: %s" %
                               (msg.name, reason))


Instruction:
Given the following Python 3 function, write the documentation
def _do_fail_callback(
            self, reason, msg, reply_cb, inform_cb, user_data, timeout_handle):
        """Do callback for a failed request."""
        # this may also result in reply_cb being None if no
        # reply_cb was passed to the request method

        if reply_cb is None:
            # this happens if no reply_cb was passed in to the request
            return

        reason_msg = Message.reply(msg.name, "fail", reason, mid=msg.mid)

        try:
            if user_data is None:
                reply_cb(reason_msg)
            else:
                reply_cb(reason_msg, *user_data)
        except Exception:
            e_type, e_value, trace = sys.exc_info()
            exc_reason = "\n".join(traceback.format_exception(
                e_type, e_value, trace, self._tb_limit))
            self._logger.error("Callback reply during failure %s, %s FAIL: %s" %
                               (reason, msg.name, exc_reason))

Response: Do callback for a failed request.


Instruction:
Can you implement a function in Python 3 that
handles a timed - out callback request.

Response:
def _handle_timeout(self, msg_id, start_time):
        """Handle a timed-out callback request.

        Parameters
        ----------
        msg_id : uuid.UUID for message
            The name of the reply which was expected.

        """
        msg, reply_cb, inform_cb, user_data, timeout_handle = \
            self._pop_async_request(msg_id, None)
        # We may have been racing with the actual reply handler if the reply
        # arrived close to the timeout expiry,
        # which means the self._pop_async_request() call gave us None's.
        # In this case, just bail.
        #
        # NM 2014-09-17 Not sure if this is true after porting to tornado,
        # but I'm too afraid to remove this code :-/
        if timeout_handle is None:
            return

        reason = "Request {0.name} timed out after {1:f} seconds.".format(
            msg, self.ioloop.time() - start_time)
        self._do_fail_callback(
            reason, msg, reply_cb, inform_cb, user_data, timeout_handle)


Instruction:
How would you code a function in Python 3 to
handle a reply message related to the current request.

Response:
def handle_reply(self, msg):
        """Handle a reply message related to the current request.

        Reply messages not related to the current request go up
        to the base class method.

        Parameters
        ----------
        msg : Message object
            The reply message to dispatch.

        """
        # this may also result in reply_cb being None if no
        # reply_cb was passed to the request method
        if msg.mid is not None:
            _request, reply_cb, _inform_cb, user_data, timeout_handle = \
                self._pop_async_request(msg.mid, None)
        else:
            request, _reply_cb, _inform_cb, _user_data, timeout_handle = \
                self._peek_async_request(None, msg.name)
            if request is not None and request.mid is None:
                # we didn't send a mid so this is the request we want
                _request, reply_cb, _inform_cb, user_data, timeout_handle = \
                    self._pop_async_request(None, msg.name)
            else:
                reply_cb, user_data = None, None

        if timeout_handle is not None:
            self.ioloop.remove_timeout(timeout_handle)

        if reply_cb is None:
            reply_cb = super(AsyncClient, self).handle_reply
            # override user_data since handle_reply takes no user_data
            user_data = None

        try:
            if user_data is None:
                reply_cb(msg)
            else:
                reply_cb(msg, *user_data)
        except Exception:
            e_type, e_value, trace = sys.exc_info()
            reason = "\n".join(traceback.format_exception(
                e_type, e_value, trace, self._tb_limit))
            self._logger.error("Callback reply %s FAIL: %s" %
                               (msg.name, reason))


Instruction:
How would you explain what the following Python 3 function does
def validate_answer(self, value):
        # Check that the answer is JSON-serializable
        try:
            serialized = json.dumps(value)
        except (ValueError, TypeError):
            raise serializers.ValidationError("Answer value must be JSON-serializable")

        # Check the length of the serialized representation
        if len(serialized) > Submission.MAXSIZE:
            raise serializers.ValidationError("Maximum answer size exceeded.")

        return value

Response: Validate the answer value.


Instruction:
Given the following Python 3 function, write the documentation
def get_annotations(self, obj):
        annotations = ScoreAnnotation.objects.filter(score_id=obj.id)
        return [
            ScoreAnnotationSerializer(instance=annotation).data
            for annotation in annotations
        ]

Response: Inspect ScoreAnnotations to attach all relevant annotations.


Instruction:
Write a Python 3 script for
creating a reset score.

Response:
def create_reset_score(cls, student_item):
        """
        Create a "reset" score (a score with a null submission).

        Only scores created after the most recent "reset" score
        should be used to determine a student's effective score.

        Args:
            student_item (StudentItem): The student item model.

        Returns:
            Score: The newly created "reset" score.

        Raises:
            DatabaseError: An error occurred while creating the score

        """
        # By setting the "reset" flag, we ensure that the "highest"
        # score in the score summary will point to this score.
        # By setting points earned and points possible to 0,
        # we ensure that this score will be hidden from the user.
        return cls.objects.create(
            student_item=student_item,
            submission=None,
            points_earned=0,
            points_possible=0,
            reset=True,
        )


Instruction:
Write a Python 3 script to
listen for new Scores and update the relevant ScoreSummary.

Response:
def update_score_summary(sender, **kwargs):
        """
        Listen for new Scores and update the relevant ScoreSummary.

        Args:
            sender: not used

        Kwargs:
            instance (Score): The score model whose save triggered this receiver.

        """
        score = kwargs['instance']
        try:
            score_summary = ScoreSummary.objects.get(
                student_item=score.student_item
            )
            score_summary.latest = score

            # A score with the "reset" flag set will always replace the current highest score
            if score.reset:
                score_summary.highest = score
            # The conversion to a float may return None if points possible is zero
            # In Python, None is always less than an integer, so any score
            # with non-null points possible will take precedence.
            elif score.to_float() > score_summary.highest.to_float():
                score_summary.highest = score
            score_summary.save()
        except ScoreSummary.DoesNotExist:
            ScoreSummary.objects.create(
                student_item=score.student_item,
                highest=score,
                latest=score,
            )
        except DatabaseError as err:
            logger.exception(
                u"Error while updating score summary for student item {}"
                .format(score.student_item)
            )


Instruction:
Can you write a function in Python 3 where it
adds the arguments to the command parser.

Response:
def add_arguments(self, parser):
        """
        Add arguments to the command parser.

        Uses argparse syntax.  See documentation at
        https://docs.python.org/3/library/argparse.html.
        """
        parser.add_argument(
            '--start', '-s',
            default=0,
            type=int,
            help=u"The Submission.id at which to begin updating rows. 0 by default."
        )
        parser.add_argument(
            '--chunk', '-c',
            default=1000,
            type=int,
            help=u"Batch size, how many rows to update in a given transaction. Default 1000.",
        )
        parser.add_argument(
            '--wait', '-w',
            default=2,
            type=int,
            help=u"Wait time between transactions, in seconds. Default 2.",
        )


Instruction:
Explain what the following Python 3 code does
def handle(self, *args, **options):
        # Note that by taking last_id here, we're going to miss any submissions created *during* the command execution
        # But that's okay! All new entries have already been created using the new style, no acion needed there
        last_id = Submission._objects.all().aggregate(Max('id'))['id__max']
        log.info("Beginning uuid update")

        current = options['start']
        while current < last_id:
            end_chunk = current + options['chunk'] if last_id - options['chunk'] >= current else last_id
            log.info("Updating entries in range [{}, {}]".format(current, end_chunk))
            with transaction.atomic():
                for submission in Submission._objects.filter(id__gte=current, id__lte=end_chunk).iterator():
                    submission.save(update_fields=['uuid'])
            time.sleep(options['wait'])
            current = end_chunk + 1

Response: This is the main entry point for the command execution.


Instruction:
Can you write a function in Python 3 where it
retrieves all submissions associated with the given student item. Developer utility for accessing all the submissions associated with a student item. The student item is specified by the unique combination of course, student, and item. Args: request (dict): The request. course_id (str): The course id for this student item. student_id (str): The student id for this student item. item_id (str): The item id for this student item. Returns: HttpResponse: The response object for this request. Renders a simple development page with all the submissions related to the specified student item.

Response:
def get_submissions_for_student_item(request, course_id, student_id, item_id):
    """Retrieve all submissions associated with the given student item.

    Developer utility for accessing all the submissions associated with a
    student item. The student item is specified by the unique combination of
    course, student, and item.

    Args:
        request (dict): The request.
        course_id (str): The course id for this student item.
        student_id (str): The student id for this student item.
        item_id (str): The item id for this student item.

    Returns:
        HttpResponse: The response object for this request. Renders a simple
            development page with all the submissions related to the specified
            student item.

    """
    student_item_dict = dict(
        course_id=course_id,
        student_id=student_id,
        item_id=item_id,
    )
    context = dict(**student_item_dict)
    try:
        submissions = get_submissions(student_item_dict)
        context["submissions"] = submissions
    except SubmissionRequestError:
        context["error"] = "The specified student item was not found."

    return render_to_response('submissions.html', context)


Instruction:
Write a Python 3 script for
creating a submission for assessment.

Response:
def create_submission(student_item_dict, answer, submitted_at=None, attempt_number=None):
    """Creates a submission for assessment.

    Generic means by which to submit an answer for assessment.

    Args:
        student_item_dict (dict): The student_item this
            submission is associated with. This is used to determine which
            course, student, and location this submission belongs to.

        answer (JSON-serializable): The answer given by the student to be assessed.

        submitted_at (datetime): The date in which this submission was submitted.
            If not specified, defaults to the current date.

        attempt_number (int): A student may be able to submit multiple attempts
            per question. This allows the designated attempt to be overridden.
            If the attempt is not specified, it will take the most recent
            submission, as specified by the submitted_at time, and use its
            attempt_number plus one.

    Returns:
        dict: A representation of the created Submission. The submission
        contains five attributes: student_item, attempt_number, submitted_at,
        created_at, and answer. 'student_item' is the ID of the related student
        item for the submission. 'attempt_number' is the attempt this submission
        represents for this question. 'submitted_at' represents the time this
        submission was submitted, which can be configured, versus the
        'created_at' date, which is when the submission is first created.

    Raises:
        SubmissionRequestError: Raised when there are validation errors for the
            student item or submission. This can be caused by the student item
            missing required values, the submission being too long, the
            attempt_number is negative, or the given submitted_at time is invalid.
        SubmissionInternalError: Raised when submission access causes an
            internal error.

    Examples:
        >>> student_item_dict = dict(
        >>>    student_id="Tim",
        >>>    item_id="item_1",
        >>>    course_id="course_1",
        >>>    item_type="type_one"
        >>> )
        >>> create_submission(student_item_dict, "The answer is 42.", datetime.utcnow, 1)
        {
            'student_item': 2,
            'attempt_number': 1,
            'submitted_at': datetime.datetime(2014, 1, 29, 17, 14, 52, 649284 tzinfo=<UTC>),
            'created_at': datetime.datetime(2014, 1, 29, 17, 14, 52, 668850, tzinfo=<UTC>),
            'answer': u'The answer is 42.'
        }

    """
    student_item_model = _get_or_create_student_item(student_item_dict)
    if attempt_number is None:
        try:
            submissions = Submission.objects.filter(
                student_item=student_item_model)[:1]
        except DatabaseError:
            error_message = u"An error occurred while filtering submissions for student item: {}".format(
                student_item_dict)
            logger.exception(error_message)
            raise SubmissionInternalError(error_message)
        attempt_number = submissions[0].attempt_number + 1 if submissions else 1

    model_kwargs = {
        "student_item": student_item_model.pk,
        "answer": answer,
        "attempt_number": attempt_number,
    }
    if submitted_at:
        model_kwargs["submitted_at"] = submitted_at

    try:
        submission_serializer = SubmissionSerializer(data=model_kwargs)
        if not submission_serializer.is_valid():
            raise SubmissionRequestError(field_errors=submission_serializer.errors)
        submission_serializer.save()

        sub_data = submission_serializer.data
        _log_submission(sub_data, student_item_dict)

        return sub_data

    except DatabaseError:
        error_message = u"An error occurred while creating submission {} for student item: {}".format(
            model_kwargs,
            student_item_dict
        )
        logger.exception(error_message)
        raise SubmissionInternalError(error_message)


Instruction:
Can you generate a brief explanation for the following Python 3 code
def get_submission(submission_uuid, read_replica=False):
    if not isinstance(submission_uuid, six.string_types):
        if isinstance(submission_uuid, UUID):
            submission_uuid = six.text_type(submission_uuid)
        else:
            raise SubmissionRequestError(
                msg="submission_uuid ({!r}) must be serializable".format(submission_uuid)
            )

    cache_key = Submission.get_cache_key(submission_uuid)
    try:
        cached_submission_data = cache.get(cache_key)
    except Exception:
        # The cache backend could raise an exception
        # (for example, memcache keys that contain spaces)
        logger.exception("Error occurred while retrieving submission from the cache")
        cached_submission_data = None

    if cached_submission_data:
        logger.info("Get submission {} (cached)".format(submission_uuid))
        return cached_submission_data

    try:
        submission = _get_submission_model(submission_uuid, read_replica)
        submission_data = SubmissionSerializer(submission).data
        cache.set(cache_key, submission_data)
    except Submission.DoesNotExist:
        logger.error("Submission {} not found.".format(submission_uuid))
        raise SubmissionNotFoundError(
            u"No submission matching uuid {}".format(submission_uuid)
        )
    except Exception as exc:
        # Something very unexpected has just happened (like DB misconfig)
        err_msg = "Could not get submission due to error: {}".format(exc)
        logger.exception(err_msg)
        raise SubmissionInternalError(err_msg)

    logger.info("Get submission {}".format(submission_uuid))
    return submission_data

Response: Retrieves a single submission by uuid.


Instruction:
Create a Python 3 function to
retrieve a submission by its unique identifier including the associated student item.

Response:
def get_submission_and_student(uuid, read_replica=False):
    """
    Retrieve a submission by its unique identifier, including the associated student item.

    Args:
        uuid (str): the unique identifier of the submission.

    Kwargs:
        read_replica (bool): If true, attempt to use the read replica database.
            If no read replica is available, use the default database.

    Returns:
        Serialized Submission model (dict) containing a serialized StudentItem model

    Raises:
        SubmissionNotFoundError: Raised if the submission does not exist.
        SubmissionRequestError: Raised if the search parameter is not a string.
        SubmissionInternalError: Raised for unknown errors.

    """
    # This may raise API exceptions
    submission = get_submission(uuid, read_replica=read_replica)

    # Retrieve the student item from the cache
    cache_key = "submissions.student_item.{}".format(submission['student_item'])
    try:
        cached_student_item = cache.get(cache_key)
    except Exception:
        # The cache backend could raise an exception
        # (for example, memcache keys that contain spaces)
        logger.exception("Error occurred while retrieving student item from the cache")
        cached_student_item = None

    if cached_student_item is not None:
        submission['student_item'] = cached_student_item
    else:
        # There is probably a more idiomatic way to do this using the Django REST framework
        try:
            student_item_qs = StudentItem.objects
            if read_replica:
                student_item_qs = _use_read_replica(student_item_qs)

            student_item = student_item_qs.get(id=submission['student_item'])
            submission['student_item'] = StudentItemSerializer(student_item).data
            cache.set(cache_key, submission['student_item'])
        except Exception as ex:
            err_msg = "Could not get submission due to error: {}".format(ex)
            logger.exception(err_msg)
            raise SubmissionInternalError(err_msg)

    return submission


Instruction:
Here you have a function in Python 3, explain what it does
def get_submissions(student_item_dict, limit=None):
    student_item_model = _get_or_create_student_item(student_item_dict)
    try:
        submission_models = Submission.objects.filter(
            student_item=student_item_model)
    except DatabaseError:
        error_message = (
            u"Error getting submission request for student item {}"
            .format(student_item_dict)
        )
        logger.exception(error_message)
        raise SubmissionNotFoundError(error_message)

    if limit:
        submission_models = submission_models[:limit]

    return SubmissionSerializer(submission_models, many=True).data

Response: Returns the submissions for the specified student item.


Instruction:
Given the following Python 3 function, write the documentation
def get_all_submissions(course_id, item_id, item_type, read_replica=True):
    submission_qs = Submission.objects
    if read_replica:
        submission_qs = _use_read_replica(submission_qs)
    # We cannot use SELECT DISTINCT ON because it's PostgreSQL only, so unfortunately
    # our results will contain every entry of each student, not just the most recent.
    # We sort by student_id and primary key, so the reults will be grouped be grouped by
    # student, with the most recent submission being the first one in each group.
    query = submission_qs.select_related('student_item').filter(
        student_item__course_id=course_id,
        student_item__item_id=item_id,
        student_item__item_type=item_type,
    ).order_by('student_item__student_id', '-submitted_at', '-id').iterator()

    for unused_student_id, row_iter in itertools.groupby(query, operator.attrgetter('student_item.student_id')):
        submission = next(row_iter)
        data = SubmissionSerializer(submission).data
        data['student_id'] = submission.student_item.student_id
        yield data

Response: For the given item get the most recent submission for every student who has submitted.


Instruction:
Can you write a function in Python 3 where it
gets all the information for the given course and item type.

Response:
def get_all_course_submission_information(course_id, item_type, read_replica=True):
    """ For the given course, get all student items of the given item type, all the submissions for those itemes,
    and the latest scores for each item. If a submission was given a score that is not the latest score for the
    relevant student item, it will still be included but without score.

    Args:
        course_id (str): The course that we are getting submissions from.
        item_type (str): The type of items that we are getting submissions for.
        read_replica (bool): Try to use the database's read replica if it's available.

    Yields:
        A tuple of three dictionaries representing:
        (1) a student item with the following fields:
            student_id
            course_id
            student_item
            item_type
        (2) a submission with the following fields:
            student_item
            attempt_number
            submitted_at
            created_at
            answer
        (3) a score with the following fields, if one exists and it is the latest score:
            (if both conditions are not met, an empty dict is returned here)
            student_item
            submission
            points_earned
            points_possible
            created_at
            submission_uuid
    """

    submission_qs = Submission.objects
    if read_replica:
        submission_qs = _use_read_replica(submission_qs)

    query = submission_qs.select_related('student_item__scoresummary__latest__submission').filter(
        student_item__course_id=course_id,
        student_item__item_type=item_type,
    ).iterator()

    for submission in query:
        student_item = submission.student_item
        serialized_score = {}
        if hasattr(student_item, 'scoresummary'):
            latest_score = student_item.scoresummary.latest

            # Only include the score if it is not a reset score (is_hidden), and if the current submission is the same
            # as the student_item's latest score's submission. This matches the behavior of the API's get_score method.
            if (not latest_score.is_hidden()) and latest_score.submission.uuid == submission.uuid:
                serialized_score = ScoreSerializer(latest_score).data
        yield (
            StudentItemSerializer(student_item).data,
            SubmissionSerializer(submission).data,
            serialized_score
        )


Instruction:
Explain what the following Python 3 code does
def get_top_submissions(course_id, item_id, item_type, number_of_top_scores, use_cache=True, read_replica=True):
    if number_of_top_scores < 1 or number_of_top_scores > MAX_TOP_SUBMISSIONS:
        error_msg = (
            u"Number of top scores must be a number between 1 and {}.".format(MAX_TOP_SUBMISSIONS)
        )
        logger.exception(error_msg)
        raise SubmissionRequestError(msg=error_msg)

    # First check the cache (unless caching is disabled)
    cache_key = "submissions.top_submissions.{course}.{item}.{type}.{number}".format(
        course=course_id,
        item=item_id,
        type=item_type,
        number=number_of_top_scores
    )
    top_submissions = cache.get(cache_key) if use_cache else None

    # If we can't find it in the cache (or caching is disabled), check the database
    # By default, prefer the read-replica.
    if top_submissions is None:
        try:
            query = ScoreSummary.objects.filter(
                student_item__course_id=course_id,
                student_item__item_id=item_id,
                student_item__item_type=item_type,
                latest__points_earned__gt=0
            ).select_related('latest', 'latest__submission').order_by("-latest__points_earned")

            if read_replica:
                query = _use_read_replica(query)
            score_summaries = query[:number_of_top_scores]
        except DatabaseError:
            msg = u"Could not fetch top score summaries for course {}, item {} of type {}".format(
                course_id, item_id, item_type
            )
            logger.exception(msg)
            raise SubmissionInternalError(msg)

        # Retrieve the submission content for each top score
        top_submissions = [
            {
                "score": score_summary.latest.points_earned,
                "content": SubmissionSerializer(score_summary.latest.submission).data['answer']
            }
            for score_summary in score_summaries
        ]

        # Always store the retrieved list in the cache
        cache.set(cache_key, top_submissions, TOP_SUBMISSIONS_CACHE_TIMEOUT)

    return top_submissions

Response: This function returns a number of top submissions for a particular student item within a particular assessment module.


Instruction:
Implement a Python 3 function for
getting the score for a particular student item Each student item should have a unique score. This function will return the score if it is available. A score is only calculated for a student item if it has completed the workflow for a particular assessment module. Args: student_item (dict): The dictionary representation of a student item. Function returns the score related to this student item. Returns: score (dict): The score associated with this student item. None if there is no score found. Raises: SubmissionInternalError: Raised if a score cannot be retrieved because of an internal server error. Examples: >>> student_item = { >>> "student_id":"Tim", >>> "course_id":"TestCourse", >>> "item_id":"u_67", >>> "item_type":"openassessment" >>> } >>> >>> get_score(student_item) [{ 'student_item': 2, 'submission': 2, 'points_earned': 8, 'points_possible': 20, 'created_at': datetime.datetime(2014, 2, 7, 18, 30, 1, 807911, tzinfo=<UTC>) }]

Response:
def get_score(student_item):
    """Get the score for a particular student item

    Each student item should have a unique score. This function will return the
    score if it is available. A score is only calculated for a student item if
    it has completed the workflow for a particular assessment module.

    Args:
        student_item (dict): The dictionary representation of a student item.
            Function returns the score related to this student item.

    Returns:
        score (dict): The score associated with this student item. None if there
            is no score found.

    Raises:
        SubmissionInternalError: Raised if a score cannot be retrieved because
            of an internal server error.

    Examples:
        >>> student_item = {
        >>>     "student_id":"Tim",
        >>>     "course_id":"TestCourse",
        >>>     "item_id":"u_67",
        >>>     "item_type":"openassessment"
        >>> }
        >>>
        >>> get_score(student_item)
        [{
            'student_item': 2,
            'submission': 2,
            'points_earned': 8,
            'points_possible': 20,
            'created_at': datetime.datetime(2014, 2, 7, 18, 30, 1, 807911, tzinfo=<UTC>)
        }]

    """
    try:
        student_item_model = StudentItem.objects.get(**student_item)
        score = ScoreSummary.objects.get(student_item=student_item_model).latest
    except (ScoreSummary.DoesNotExist, StudentItem.DoesNotExist):
        return None

    # By convention, scores are hidden if "points possible" is set to 0.
    # This can occur when an instructor has reset scores for a student.
    if score.is_hidden():
        return None
    else:
        return ScoreSerializer(score).data


Instruction:
Write a Python 3 script to
return a dictionary mapping item_ids to scores.

Response:
def get_scores(course_id, student_id):
    """Return a dict mapping item_ids to scores.

    Scores are represented by serialized Score objects in JSON-like dict
    format.

    This method would be used by an LMS to find all the scores for a given
    student in a given course.

    Scores that are "hidden" (because they have points earned set to zero)
    are excluded from the results.

    Args:
        course_id (str): Course ID, used to do a lookup on the `StudentItem`.
        student_id (str): Student ID, used to do a lookup on the `StudentItem`.

    Returns:
        dict: The keys are `item_id`s (`str`) and the values are tuples of
        `(points_earned, points_possible)`. All points are integer values and
        represent the raw, unweighted scores. Submissions does not have any
        concept of weights. If there are no entries matching the `course_id` or
        `student_id`, we simply return an empty dictionary. This is not
        considered an error because there might be many queries for the progress
        page of a person who has never submitted anything.

    Raises:
        SubmissionInternalError: An unexpected error occurred while resetting scores.
    """
    try:
        score_summaries = ScoreSummary.objects.filter(
            student_item__course_id=course_id,
            student_item__student_id=student_id,
        ).select_related('latest', 'latest__submission', 'student_item')
    except DatabaseError:
        msg = u"Could not fetch scores for course {}, student {}".format(
            course_id, student_id
        )
        logger.exception(msg)
        raise SubmissionInternalError(msg)
    scores = {
        summary.student_item.item_id: UnannotatedScoreSerializer(summary.latest).data
        for summary in score_summaries if not summary.latest.is_hidden()
    }
    return scores