<SYSTEM_TASK:>
Solve the following problem using Python, implementing the functions described below, one line at a time
<END_TASK>
<USER_TASK:>
Description:
 def request(*types, **options):
 """Decorator for request handler methods. The method being decorated should take a req argument followed by arguments matching the list of types. The decorator will unpack the request message into the arguments. Parameters types : list of kattypes The types of the request message parameters (in order). A type with multiple=True has to be the last type. Keyword Arguments include_msg : bool, optional Pass the request message as the third parameter to the decorated request handler function (default is False). major : int, optional Major version of KATCP to use when interpreting types. Defaults to latest implemented KATCP version. Examples -------- '''?is-odd <my_int>, reply '1' if <my_int> is odd, else 0''' """

    include_msg = options.pop('include_msg', False)
    has_req = options.pop('has_req', True)
    major = options.pop('major', DEFAULT_KATCP_MAJOR)
    check_req = options.pop('_check_req', True)
    if len(options) > 0:
        raise TypeError('does not take keyword argument(s) %r.'
                        % options.keys())
    # Check that only the last type has multiple=True
    if len(types) > 1:
        for type_ in types[:-1]:
            if type_._multiple:
                raise TypeError('Only the last parameter type '
                                'can accept multiple arguments.')

    def decorator(handler):
        argnames = []

        # If this decorator is on the outside, get the parameter names which
        # have been preserved by the other decorator
        all_argnames = getattr(handler, "_orig_argnames", None)

        if all_argnames is None:
            # We must be on the inside. Introspect the parameter names.
            all_argnames = inspect.getargspec(handler)[0]

        params_start = 1        # Skip 'self' parameter
        if has_req:         # Skip 'req' parameter
            params_start += 1
        if include_msg:
            params_start += 1
        # Get other parameter names
        argnames = all_argnames[params_start:]

        if has_req and include_msg:
            def raw_handler(self, req, msg):
                new_args = unpack_types(types, msg.arguments, argnames, major)
                return handler(self, req, msg, *new_args)

        elif has_req and not include_msg:
            def raw_handler(self, req, msg):
                new_args = unpack_types(types, msg.arguments, argnames, major)
                return handler(self, req, *new_args)

        elif not has_req and include_msg:
            def raw_handler(self, msg):
                new_args = unpack_types(types, msg.arguments, argnames, major)
                return handler(self, msg, *new_args)

        elif not has_req and not include_msg:
            def raw_handler(self, msg):
                new_args = unpack_types(types, msg.arguments, argnames, major)
                return handler(self, *new_args)

        update_wrapper(raw_handler, handler)
        # explicitly note that this decorator has been run, so that
        # return_reply can know if it's on the outside.
        raw_handler._request_decorated = True
        return raw_handler

    return decorator