<SYSTEM_TASK:>
Solve the following problem using Python, implementing the functions described below, one line at a time
<END_TASK>
<USER_TASK:>
Description:
 def repr_string(outer_string, inner_strings, allow_mixed_seps=True):
 r"""Return a pretty string for ``repr``. The returned string is formatted such that it does not extend beyond the line boundary if avoidable. The line width is taken from NumPy's printing options that can be retrieved with `numpy.get_printoptions`. They can be temporarily overridden using the `npy_printoptions` context manager. See Examples for details. Parameters outer_str : str Name of the class or function that should be printed outside the parentheses. inner_strings : sequence of sequence of str Stringifications of the positional and optional arguments. This is usually the return value of `signature_string_parts`. allow_mixed_seps : bool, optional If ``False`` and the string does not fit on one line, use ``',\n'`` to separate all strings. By default, a mixture of ``', '`` and ``',\n'`` is used to fit as much on one line as possible. In case some of the ``inner_strings`` span multiple lines, it is usually advisable to set ``allow_mixed_seps`` to ``False`` since the result tends to be more readable that way. Returns ------- repr_string : str Full string that can be returned by a class' ``__repr__`` method. Examples -------- Things that fit into one line are printed on one line: MyClass(1, 'hello', None, dtype='float32') Otherwise, if a part of ``inner_strings`` fits on a line of its own, it is printed on one line, but separated from the other part with a line break: MyClass( 2.0, 'this_is_a_very_long_argument_string', long_opt_arg='another_quite_long_string' ) If those parts are themselves too long, they are broken down into several lines: MyClass( 'this_is_a_very_long_argument_string', 'another_very_long_argument_string', long_opt_arg='another_quite_long_string', long_opt2_arg='this_wont_fit_on_one_line_either' ) The usage of mixed separators to optimally use horizontal space can be disabled by setting ``allow_mixed_seps=False``: MyClass( 2.0, 'this_is_a_very_long_argument_string', long_opt_arg='another_quite_long_string' ) With the ``npy_printoptions`` context manager, the available line width can be changed: MyClass( 1, 'hello', None, dtype='float32' ) """

    linewidth = np.get_printoptions()['linewidth']
    pos_strings, opt_strings = inner_strings
    # Length of the positional and optional argument parts of the signature,
    # including separators `', '`
    pos_sig_len = (sum(len(pstr) for pstr in pos_strings) +
                   2 * max((len(pos_strings) - 1), 0))
    opt_sig_len = (sum(len(pstr) for pstr in opt_strings) +
                   2 * max((len(opt_strings) - 1), 0))

    # Length of the one-line string, including 2 for the parentheses and
    # 2 for the joining ', '
    repr_len = len(outer_string) + 2 + pos_sig_len + 2 + opt_sig_len

    if repr_len <= linewidth and not any('\n' in s
                                         for s in pos_strings + opt_strings):
        # Everything fits on one line
        fmt = '{}({})'
        pos_str = ', '.join(pos_strings)
        opt_str = ', '.join(opt_strings)
        parts_sep = ', '
    else:
        # Need to split lines in some way
        fmt = '{}(\n{}\n)'

        if not allow_mixed_seps:
            pos_separators = [',\n'] * (len(pos_strings) - 1)
        else:
            pos_separators = _separators(pos_strings, linewidth)
        if len(pos_strings) == 0:
            pos_str = ''
        else:
            pos_str = pos_strings[0]
            for s, sep in zip(pos_strings[1:], pos_separators):
                pos_str = sep.join([pos_str, s])

        if not allow_mixed_seps:
            opt_separators = [',\n'] * (len(opt_strings) - 1)
        else:
            opt_separators = _separators(opt_strings, linewidth)
        if len(opt_strings) == 0:
            opt_str = ''
        else:
            opt_str = opt_strings[0]
            for s, sep in zip(opt_strings[1:], opt_separators):
                opt_str = sep.join([opt_str, s])

        # Check if we can put both parts on one line. This requires their
        # concatenation including 4 for indentation and 2 for ', ' to
        # be less than the line width. And they should contain no newline.
        if pos_str and opt_str:
            inner_len = 4 + len(pos_str) + 2 + len(opt_str)
        elif (pos_str and not opt_str) or (opt_str and not pos_str):
            inner_len = 4 + len(pos_str) + len(opt_str)
        else:
            inner_len = 0

        if (not allow_mixed_seps or
                any('\n' in s for s in [pos_str, opt_str]) or
                inner_len > linewidth):
            parts_sep = ',\n'
            pos_str = indent(pos_str)
            opt_str = indent(opt_str)
        else:
            parts_sep = ', '
            pos_str = indent(pos_str)
            # Don't indent `opt_str`

    parts = [s for s in [pos_str, opt_str] if s.strip()]  # ignore empty
    inner_string = parts_sep.join(parts)
    return fmt.format(outer_string, inner_string)