import inspect
from typing import OrderedDict


def get_args_kwargs(fct, n_optional):
    """
    Extracts arguments and optional parameters of a function.

    :param fct: function
    :param n_optional: number of arguments to consider as
        optional arguments and not parameters, this parameter skips
        the first *n_optional* paramerters
    :return: arguments, OrderedDict

    Any optional argument ending with '_' is ignored.
    """
    params = inspect.signature(fct).parameters
    if n_optional == 0:
        items = list(params.items())
        args = [name for name, p in params.items()
                if p.default == inspect.Parameter.empty]
    else:
        items = []
        args = []
        for name, p in params.items():
            if p.default == inspect.Parameter.empty:
                args.append(name)
            else:
                if n_optional > 0:
                    args.append(name)
                    n_optional -= 1
                else:
                    items.append((name, p))

    kwargs = OrderedDict((name, p.default) for name, p in items
                         if (p.default != inspect.Parameter.empty and
                             name != 'op_version'))
    if args[0] == 'self':
        args = args[1:]
        kwargs['op_'] = None
    return args, kwargs