def deep_extend(*args):
        """
        Deep copy of each item ("extend" makes swallow copy!)
        """
        def clone_obj(item):
            if isinstance(item, dict):
                return dict(**item)
            if isinstance(item, (list, tuple)):
                return list(item)
            return None

        def iterator(item, i, iterable):
            obj = clone_obj(item)
            if obj is None:
                iterable[i] = item
            else:
                if isinstance(obj, dict):
                    iterable[i] = deep_extend({}, obj)
                elif isinstance(obj, (list, tuple)):
                    FuncFlow.each(obj, iterator)
                    iterable[i] = obj
                else:
                    raise TypeError("deep_copy cannot handle this type: {}".format(type(obj)))

        args = list(args)
        dest = args.pop(0)

        for source in args:
            if source:
                for k, v in source.items():
                    obj = clone_obj(v)
                    if obj is None:
                        dest[k] = v
                    else:
                        FuncFlow.each(obj, iterator)
                        dest[k] = obj
        return dest

deep_extend(args=(2,))

<function FuncFlow.deep_extend.<locals>.clone_obj at 0x7f4e6dc12d30>

<function FuncFlow.deep_extend.<locals>.iterator at 0x7f4e6dc12c10>


def get_nested(d, path, delimiter="/"):
    """
    Address nested dicts via combined path
    """
    def item_by_tag(d, tags):
        # print(">>>>>>>>>>>>>> running nested", d, tags)
        t = tags[-1]
        if len(tags) == 1:
            return d[t]
        return item_by_tag(d[t], tags[:-1])

    tags = path.split(delimiter)
    tags.reverse()
    # print(">>>>>>>>>>>>>> splitted", tags)
    return item_by_tag(d, tags)

get_nested(d={'nested': {'data': 'should be unchanged', 'event': None}}, path='nested/event', delimiter='/')

<function get_nested.<locals>.item_by_tag at 0x7f4e6dc12d30>


def extend(*args):
        args = list(args)
        dest = args.pop(0)
        for source in args:
            if source:
                dest.update(source)
        return dest

extend(args=({}, {}))


def digit_version(version_str: str, length: int = 4):
    """Convert a version string into a tuple of integers.

    This method is usually used for comparing two versions. For pre-release
    versions: alpha < beta < rc.

    Args:
        version_str (str): The version string.
        length (int): The maximum number of version levels. Default: 4.

    Returns:
        tuple[int]: The version info in digits (integers).
    """
    assert 'parrots' not in version_str
    version = parse(version_str)
    assert version.release, f'failed to parse version {version_str}'
    release = list(version.release)
    release = release[:length]
    if len(release) < length:
        release = release + [0] * (length - len(release))
    if version.is_prerelease:
        mapping = {'a': -3, 'b': -2, 'rc': -1}
        val = -4
        # version.pre can be None
        if version.pre:
            if version.pre[0] not in mapping:
                warnings.warn(f'unknown prerelease version {version.pre[0]}, '
                              'version checking may go wrong')
            else:
                val = mapping[version.pre[0]]
            release.extend([val, version.pre[-1]])
        else:
            release.extend([val, 0])

    elif version.is_postrelease:
        release.extend([1, version.post])
    else:
        release.extend([0, 0])
    return tuple(release)

digit_version(version_str='2.2.2+cu121', length=4)


def from_file(filepath, delimiter="", blanklines=False):
    """Imports userdata from a file.

    :type filepath: string

    :param filepath  The absolute path to the file.

    :type delimiter: string

    :param: delimiter  Delimiter to use with the troposphere.Join().

    :type blanklines: boolean

    :param blanklines  If blank lines should be ignored

    rtype: troposphere.Base64
    :return The base64 representation of the file.
    """
    data = []

    try:
        with open(filepath, "r") as f:
            for line in f:
                if blanklines and line.strip("\n\r ") == "":
                    continue

                data.append(line)
    except IOError:
        raise IOError("Error opening or reading file: {}".format(filepath))

    return Base64(Join(delimiter, data))

from_file(filepath='/local/rcs/XXX/code/pytrace-collector/logs/self_collected/tried/cloudtools+troposphere/cloudtools+troposphere/tests/userdata_test_scripts/char_escaping.sh', delimiter='', blanklines=False)


def SeparateFlagArgs(args: list):
  """Splits a list of args into those for Flags and those for Fire.

  If an isolated '--' arg is not present in the arg list, then all of the args
  are for Fire. If there is an isolated '--', then the args after the final '--'
  are flag args, and the rest of the args are fire args.

  Args:
    args: The list of arguments received by the Fire command.
  Returns:
    A tuple with the Fire args (a list), followed by the Flag args (a list).
  """
  if len(args) > 0 and (args[-1] == '-h' or args[-1] == '--help') and '--' not in args:
    args.pop()
    args.append('--')
    args.append('-h')

  if '--' in args:
    separator_index = len(args) - 1 - args[::-1].index('--')  # index of last --
    flag_args = args[separator_index + 1:]
    args = args[:separator_index]
    return args, flag_args

  return args, []

SeparateFlagArgs(args=['a', 'b', '--'])


def prepare_docstring_help(N):
    """Replace docstrings to include the parameters (schema)"""
    # at this point, the params have not yet been populated

    args = []
    if hasattr(N, '__annotations__'):
        for attr_name, cls in N.__annotations__.items():

            filtered = filter_params(N)
            parsed = parse_source_for_params(filtered)
            attr = attr_map(parsed).get(attr_name)
            if attr is None:
                continue

            args.append(argument_help(attr_name, attr))

    return '\n'.join(args)

prepare_docstring_help(N={})

{'type': 'int', 'default': '0', 'description': ''}


def filter_params(N):
    """Filter source lines of the class
    Returns:
        fields as source lines
    """
    filtered_source = []
    for line in inspect.getsourcelines(N.__class__)[0][1:]:
        # When parsing, post_init would bleed into the attributes without this hack
        if line.strip().startswith('def '):
            break
        filtered_source.append(line)
    return filtered_source

filter_params(N={})


def _ParseFn(args):
    """Parses the list of `args` into (varargs, kwargs), remaining_args."""
    kwargs, remaining_kwargs, remaining_args = _ParseKeywordArgs(
        args, all_args, fn_spec.varkw)

    # Note: _ParseArgs modifies kwargs.
    parsed_args, kwargs, remaining_args, capacity = _ParseArgs(
        fn_spec.args, fn_spec.defaults, num_required_args, kwargs,
        remaining_args, metadata)

    if fn_spec.varargs or fn_spec.varkw:
      # If we're allowed *varargs or **kwargs, there's always capacity.
      capacity = True

    extra_kw = set(kwargs) - set(fn_spec.kwonlyargs)
    if fn_spec.varkw is None and extra_kw:
      raise FireError('Unexpected kwargs present:', extra_kw)

    missing_kwonly = set(required_kwonly) - set(kwargs)
    if missing_kwonly:
      raise FireError('Missing required flags:', missing_kwonly)

    # If we accept *varargs, then use all remaining arguments for *varargs.
    if fn_spec.varargs is not None:
      varargs, remaining_args = remaining_args, []
    else:
      varargs = []

    for index, value in enumerate(varargs):
      varargs[index] = _ParseValue(value, None, None, metadata)

    varargs = parsed_args + varargs
    remaining_args += remaining_kwargs

    consumed_args = args[:len(args) - len(remaining_args)]
    return (varargs, kwargs), consumed_args, remaining_args, capacity

_ParseFn(args=['x'], all_args=[], fn_spec={args=[], varargs=None, varkw='cli_args', defaults=(), kwonlyargs=[], kwonlydefaults={}, annotations={}}, metadata={'ACCEPTS_POSITIONAL_ARGS': False}, num_required_args=0, required_kwonly=set())


def config_dict(configuration_tuple):
    config_dict = {}

    config_file = configuration_tuple._asdict().get('CFG')
    if config_file is None:
        config_file = configfile.get_config_path(configuration_tuple)

    if config_file is not None:
        config_dict = utils.filter_fields(configfile.read_config(config_file), configuration_tuple)
        config_dict = utils.type_correct_with(config_dict, configuration_tuple)

    return config_dict

config_dict(configuration_tuple={})


def type_correct_with(cdict, cfg_tuple):
    """Use type hints of the cfg tuple to cast parameters i.e. attributes into their intended types"""
    # TODO: This would be cleaner, if the config would use Schema or derivative in the
    # first place and use its validation process
    res = {}
    for k, v in cdict.items():
        typename = getattr(cfg_tuple, k)
        res.update({k: type(typename)(v)})
    return res

type_correct_with(cdict={'bar': '42'}, cfg_tuple={})


def is_eq(value, rep=None):
    if rep is None:
        rep = repr(value)

    def is_valid(data, explain=False):
        if not explain:
            return data == value
        return (
            True, 'data is equal to {}'.format(rep)
        ) if data == value else (
            False, 'data is not equal to {}'.format(rep)
        )
    return is_valid

is_eq(value=0, rep=None)

<function is_eq.<locals>.is_valid at 0x7fde77983310>


def is_geq(value, rep=None):
    if rep is None:
        rep = repr(value)

    def is_valid(data, explain=False):
        if not explain:
            return data >= value
        return (
            True, 'data is greater than or equal to {}'.format(rep)
        ) if data >= value else (
            False, 'data is not greater than or equal to {}'.format(rep)
        )
    return is_valid

is_geq(value=0, rep=None)

<function is_geq.<locals>.is_valid at 0x7fde765b6b80>


def is_lt(value, rep=None):
    if rep is None:
        rep = repr(value)

    def is_valid(data, explain=False):
        if not explain:
            return data < value
        return (
            True, 'data is lower than {}'.format(rep)
        ) if data < value else (
            False, 'data is not lower than {}'.format(rep)
        )
    return is_valid

is_lt(value=0, rep=None)

<function is_lt.<locals>.is_valid at 0x7fde765b6040>


def make_repo(path=None):
    if not path:
        path = "."
    repo = git.Repo.init(path)
    repo.config_writer().set_value("user", "name", "Test User").release()
    repo.config_writer().set_value("user", "email", "testuser@example.com").release()

    return repo

make_repo(path='/tmp/tmpbbwa2p3f')


def safe_abs_path(res):
    "Gives an abs path, which safely returns a full (not 8.3) windows path"
    res = Path(res).resolve()
    return str(res)

safe_abs_path(res='/tmp/tmpbbwa2p3f')


def is_image_file(file_name):
    """
    Check if the given file name has an image file extension.

    :param file_name: The name of the file to check.
    :return: True if the file is an image, False otherwise.
    """
    file_name = str(file_name)  # Convert file_name to string
    return any(file_name.endswith(ext) for ext in IMAGE_EXTENSIONS)

is_image_file(file_name=PosixPath('/tmp/tmpcr1f5en7/.gitignore'))


def find_original_update_blocks(content, fence=DEFAULT_FENCE):
    # make sure we end with a newline, otherwise the regex will miss <<UPD on the last line
    if not content.endswith("\n"):
        content = content + "\n"

    pieces = re.split(split_re, content)

    pieces.reverse()
    processed = []

    # Keep using the same filename in cases where GPT produces an edit block
    # without a filename.
    current_filename = None
    try:
        while pieces:
            cur = pieces.pop()

            if cur in (DIVIDER, UPDATED):
                processed.append(cur)
                raise ValueError(f"Unexpected {cur}")

            if cur.strip() != HEAD:
                processed.append(cur)
                continue

            processed.append(cur)  # original_marker

            filename = strip_filename(processed[-2].splitlines()[-1], fence)
            try:
                if not filename:
                    filename = strip_filename(processed[-2].splitlines()[-2], fence)
                if not filename:
                    if current_filename:
                        filename = current_filename
                    else:
                        raise ValueError(missing_filename_err)
            except IndexError:
                if current_filename:
                    filename = current_filename
                else:
                    raise ValueError(missing_filename_err)

            current_filename = filename

            original_text = pieces.pop()
            processed.append(original_text)

            divider_marker = pieces.pop()
            processed.append(divider_marker)
            if divider_marker.strip() != DIVIDER:
                raise ValueError(f"Expected `{DIVIDER}` not {divider_marker.strip()}")

            updated_text = pieces.pop()
            processed.append(updated_text)

            updated_marker = pieces.pop()
            processed.append(updated_marker)
            if updated_marker.strip() != UPDATED:
                raise ValueError(f"Expected `{UPDATED}` not `{updated_marker.strip()}")

            yield filename, original_text, updated_text
    except ValueError as e:
        processed = "".join(processed)
        err = e.args[0]
        raise ValueError(f"{processed}\n^^^ {err}")
    except IndexError:
        processed = "".join(processed)
        raise ValueError(f"{processed}\n^^^ Incomplete SEARCH/REPLACE block.")
    except Exception:
        processed = "".join(processed)
        raise ValueError(f"{processed}\n^^^ Error parsing SEARCH/REPLACE block.")

find_original_update_blocks(content='ok', fence=('<source>', '</source>'))

'ok'

'ok'

'ok\n'


def do_replace(fname, content, before_text, after_text, fence=None):
    before_text = strip_quoted_wrapping(before_text, fname, fence)
    after_text = strip_quoted_wrapping(after_text, fname, fence)
    fname = Path(fname)

    # does it want to make a new file?
    if not fname.exists() and not before_text.strip():
        fname.touch()
        content = ""

    if content is None:
        return

    if not before_text.strip():
        # append to existing file, or start a new file
        new_content = content + after_text
    else:
        new_content = replace_most_similar_chunk(content, before_text, after_text)

    return new_content

do_replace(fname='/tmp/tmp7g7a2csg/file.txt', content='two\n', before_text='two\n', after_text='three\n', fence=('```', '```'))

'two\n'

'two\n'

'two\n'


def strip_quoted_wrapping(res, fname=None, fence=DEFAULT_FENCE):
    """
    Given an input string which may have extra "wrapping" around it, remove the wrapping.
    For example:

    filename.ext
    ```
    We just want this content
    Not the filename and triple quotes
    ```
    """
    if not res:
        return res

    res = res.splitlines()

    if fname and res[0].strip().endswith(Path(fname).name):
        res = res[1:]

    if res[0].startswith(fence[0]) and res[-1].startswith(fence[1]):
        res = res[1:-1]

    res = "\n".join(res)
    if res and res[-1] != "\n":
        res += "\n"

    return res

strip_quoted_wrapping(res='two\n', fname='/tmp/tmp7g7a2csg/file.txt', fence=('```', '```'))


def replace_most_similar_chunk(whole, part, replace):
    """Best efforts to find the `part` lines in `whole` and replace them with `replace`"""

    whole, whole_lines = prep(whole)
    part, part_lines = prep(part)
    replace, replace_lines = prep(replace)

    res = perfect_or_whitespace(whole_lines, part_lines, replace_lines)
    if res:
        return res

    # drop leading empty line, GPT sometimes adds them spuriously (issue #25)
    if len(part_lines) > 2 and not part_lines[0].strip():
        skip_blank_line_part_lines = part_lines[1:]
        res = perfect_or_whitespace(whole_lines, skip_blank_line_part_lines, replace_lines)
        if res:
            return res

    # Try to handle when it elides code with ...
    try:
        res = try_dotdotdots(whole, part, replace)
        if res:
            return res
    except ValueError:
        pass

    return
    # Try fuzzy matching
    res = replace_closest_edit_distance(whole_lines, part, part_lines, replace_lines)
    if res:
        return res

replace_most_similar_chunk(whole='two\n', part='two\n', replace='three\n')


def perfect_or_whitespace(whole_lines, part_lines, replace_lines):
    # Try for a perfect match
    res = perfect_replace(whole_lines, part_lines, replace_lines)
    if res:
        return res

    # Try being flexible about leading whitespace
    res = replace_part_with_missing_leading_whitespace(whole_lines, part_lines, replace_lines)
    if res:
        return res

perfect_or_whitespace(whole_lines=['two\n'], part_lines=['two\n'], replace_lines=['three\n'])


def perfect_replace(whole_lines, part_lines, replace_lines):
    part_tup = tuple(part_lines)
    part_len = len(part_lines)

    for i in range(len(whole_lines) - part_len + 1):
        whole_tup = tuple(whole_lines[i : i + part_len])
        if part_tup == whole_tup:
            res = whole_lines[:i] + replace_lines + whole_lines[i + part_len :]
            return "".join(res)

perfect_replace(whole_lines=['two\n'], part_lines=['two\n'], replace_lines=['three\n'])


def parse_quoted_filenames(args):
    filenames = re.findall(r"\"(.+?)\"|(\S+)", args)
    filenames = [name for sublist in filenames for name in sublist if name]
    return filenames

parse_quoted_filenames(args='foo.txt bar.txt')


def match_but_for_leading_whitespace(whole_lines, part_lines):
    num = len(whole_lines)

    # does the non-whitespace all agree?
    if not all(whole_lines[i].lstrip() == part_lines[i].lstrip() for i in range(num)):
        return

    # are they all offset the same?
    add = set(
        whole_lines[i][: len(whole_lines[i]) - len(part_lines[i])]
        for i in range(num)
        if whole_lines[i].strip()
    )

    if len(add) != 1:
        return

    return add.pop()

match_but_for_leading_whitespace(whole_lines=['    line1\n', '    line2\n'], part_lines=['line1\n', 'line2\n'])


def check_gitignore(git_root, io, ask=True):
    if not git_root:
        return

    try:
        repo = git.Repo(git_root)
        if repo.ignored(".aider"):
            return
    except git.exc.InvalidGitRepositoryError:
        pass

    pat = ".aider*"

    gitignore_file = Path(git_root) / ".gitignore"
    if gitignore_file.exists():
        content = io.read_text(gitignore_file)
        if content is None:
            return
        if pat in content.splitlines():
            return
    else:
        content = ""

    if ask and not io.confirm_ask(f"Add {pat} to .gitignore (recommended)?"):
        return

    if content and not content.endswith("\n"):
        content += "\n"
    content += pat + "\n"
    io.write_text(gitignore_file, content)

    io.tool_output(f"Added {pat} to .gitignore")

check_gitignore(git_root=PosixPath('/tmp/tmpcr1f5en7'), io={user_input_color=None, tool_output_color=None, tool_error_color=None, input=None, output=None, pretty=False, yes=True, input_history_file=None, chat_history_file=None, encoding='utf-8', dry_run=False, console=<console width=105 None>}, ask=True)

{user_input_color=None, tool_output_color=None, tool_error_color=None, input=None, output=None, pretty=False, yes=True, input_history_file=None, chat_history_file=None, encoding='utf-8', dry_run=False, console=<console width=105 None>, num_user_asks=1}

'.aider*\n'


def find_diffs(content):
    # We can always fence with triple-quotes, because all the udiff content
    # is prefixed with +/-/space.

    if not content.endswith("\n"):
        content = content + "\n"

    lines = content.splitlines(keepends=True)
    line_num = 0
    edits = []
    while line_num < len(lines):
        while line_num < len(lines):
            line = lines[line_num]
            if line.startswith("```diff"):
                line_num, these_edits = process_fenced_block(lines, line_num + 1)
                edits += these_edits
                break
            line_num += 1

    # For now, just take 1!
    # edits = edits[:1]

    return edits

find_diffs(content='\nSome text...\n\n```diff\n--- /dev/null\n+++ file.txt\n@@ ... @@\n-Original\n+Modified\n```\n')


def test_decorated_processors(partial_val):
    class ExampleSchema(Schema):
        """Includes different ways to invoke decorators and set up methods"""

        TAG = "TAG"

        value = fields.Integer(as_string=True)

        # Implicit default raw, pre dump, static method.
        @pre_dump
        def increment_value(self, item, **kwargs):
            assert "many" in kwargs
            item["value"] += 1
            return item

        # Implicit default raw, post dump, class method.
        @post_dump
        def add_tag(self, item, **kwargs):
            assert "many" in kwargs
            item["value"] = self.TAG + item["value"]
            return item

        # Explicitly raw, post dump, instance method.
        @post_dump(pass_many=True)
        def add_envelope(self, data, many, **kwargs):
            key = self.get_envelope_key(many)
            return {key: data}

        # Explicitly raw, pre load, instance method.
        @pre_load(pass_many=True)
        def remove_envelope(self, data, many, partial, **kwargs):
            assert partial is partial_val
            key = self.get_envelope_key(many)
            return data[key]

        @staticmethod
        def get_envelope_key(many):
            return "data" if many else "datum"

        # Explicitly not raw, pre load, instance method.
        @pre_load(pass_many=False)
        def remove_tag(self, item, partial, **kwargs):
            assert partial is partial_val
            assert "many" in kwargs
            item["value"] = item["value"][len(self.TAG) :]
            return item

        # Explicit default raw, post load, instance method.
        @post_load()
        def decrement_value(self, item, partial, **kwargs):
            assert partial is partial_val
            assert "many" in kwargs
            item["value"] -= 1
            return item

    schema = ExampleSchema(partial=partial_val)

    # Need to re-create these because the processors will modify in place.
    make_item = lambda: {"value": 3}
    make_items = lambda: [make_item(), {"value": 5}]

    item_dumped = schema.dump(make_item())
    assert item_dumped == {"datum": {"value": "TAG4"}}
    item_loaded = schema.load(item_dumped)
    assert item_loaded == make_item()

    items_dumped = schema.dump(make_items(), many=True)
    assert items_dumped == {"data": [{"value": "TAG4"}, {"value": "TAG6"}]}
    items_loaded = schema.load(items_dumped, many=True)
    assert items_loaded == make_items()

test_decorated_processors(partial_val=True)

<function test_decorated_processors.<locals>.<lambda> at 0x7f27f9f7d310>

<function test_decorated_processors.<locals>.<lambda> at 0x7f27f9158550>


def _addpoint(sol, i, distances, prec):
    """
    Try to add point i to a given solution-approach.

    gives all possibilties and a status about the solution:
        state = 0: possibilities found
        state = 1: no possibilities but no contradiction
        state = 2: solution-approach has a contradiction with point i
    """
    res = []

    # if i is already part of the solution return it
    if np.ndim(sol[i]) != 0:
        return [sol], 0

    # collect the points already present in the solution
    solpnts = []
    for n, m in enumerate(sol):
        if np.ndim(m) != 0:
            solpnts.append(n)

    # number of present points
    pntscount = len(solpnts)

    # try to add the point in all possible constellations
    for n in range(pntscount - 1):
        for m in range(n + 1, pntscount):
            tmppnt, state = _pntcoord(
                sol, i, solpnts[n], solpnts[m], distances, prec
            )

            # if possiblities are found, add them (at most 2! (think about))
            if state == 0:
                for pnt in tmppnt:
                    res.append(dcopy(sol))
                    res[-1][i] = pnt

            # if one possiblity or a contradiction is found, return the result
            if state != 1:
                return res, state

    # if the state remaind 1, return empty result and no contradiction
    return res, state

_addpoint(sol=[array([0., 0.]), array([3., 0.]), 0, 0], i=2, distances=array([[ 0.,  3.,  4.,  1.],       [ 3.,  0.,  2.,  3.],       [ 4.,  2.,  0., -1.],       [ 1.,  3., -1.,  0.]]), prec=0.1)


def _pntcoord(sol, i, n, m, distances, prec):
    """
    Generate coordinates for point i in constellation to points m and n.

    Check if these coordinates are valid with all other points in the solution.
    """
    tmppnt = []

    state = 1

    pntscount = len(sol)

    # if no distances known, return empty result and the unknown-state
    if distances[i, n] < -0.5 or distances[i, m] < -0.5:
        return tmppnt, state

    # if the Triangle inequality is not fullfilled give a contradiction
    if distances[i, n] + distances[i, m] < _dist(sol[n], sol[m]):
        state = 2
        return tmppnt, state

    # generate the affine rotation to bring the points in the right place
    g = _affinef(*_invtranmat(*_tranmat(sol[n], sol[m])))

    # generate the coordinates
    x = _xvalue(distances[i, n], distances[i, m], _dist(sol[n], sol[m]))
    y1, y2 = _yvalue(distances[i, n], distances[i, m], _dist(sol[n], sol[m]))

    # generate the possible positons
    pos1 = g(np.array([x, y1]))
    pos2 = g(np.array([x, y2]))

    valid1 = True
    valid2 = True

    # check if the possible positions are valid
    for k in range(pntscount):
        if np.ndim(sol[k]) != 0 and distances[i, k] > -0.5:
            valid1 &= abs(_dist(sol[k], pos1) - distances[i, k]) < prec
            valid2 &= abs(_dist(sol[k], pos2) - distances[i, k]) < prec

    # if any position is valid, add it to the result
    if valid1 or valid2:
        state = 0
        same = abs(y1 - y2) < prec / 4.0
        if valid1:
            tmppnt.append(dcopy(pos1))
        if valid2 and not same:
            tmppnt.append(dcopy(pos2))
    # if the positions are not valid, give a contradiction
    else:
        state = 2

    return tmppnt, state

_pntcoord(sol=[array([0., 0.]), array([3., 0.]), 0, 0], i=2, n=0, m=1, distances=array([[ 0.,  3.,  4.,  1.],       [ 3.,  0.,  2.,  3.],       [ 4.,  2.,  0., -1.],       [ 1.,  3., -1.,  0.]]), prec=0.1)

<function _affinef.<locals>.func at 0x7f9d2f5dc9d0>


def _tranmat(a, b):
    """
    Get the coefficents for the affine-linear function f(x)=Ax+s.

    Which fullfills that A is a rotation-matrix,
    f(a) = [0,0] and f(b) = [|b-a|,0].
    """
    A = np.zeros((2, 2))
    A[0, 0] = b[0] - a[0]
    A[1, 1] = b[0] - a[0]
    A[1, 0] = -(b[1] - a[1])
    A[0, 1] = +(b[1] - a[1])
    A /= _dist(a, b)
    s = -np.dot(A, a)
    return A, s

_tranmat(a=array([0., 0.]), b=array([3., 0.]))


def _yvalue(b, a, c):
    """
    Get the two possible y-values for the upper point of a triangle.

    where c is the length of the down side starting in the origin and
    lying on the x-axes, a is the distance of the unknown point to the origen
    and b is the distance of the unknown point to the righter given point
    """
    # ckeck flatness to eliminate numerical errors when the triangle is flat
    if a + b <= c or a + c <= b or b + c <= a:
        return 0.0, -0.0

    res = 2 * ((a * b) ** 2 + (a * c) ** 2 + (b * c) ** 2)
    res -= a ** 4 + b ** 4 + c ** 4
    # in case of numerical errors set res to 0 (hope you check validty before)
    res = max(res, 0.0)
    res = np.sqrt(res)
    res /= 2 * c
    return res, -res

_yvalue(b=4.0, a=2.0, c=3.0)


def _solequal(sol1, sol2, prec):
    """
    Compare two different solutions with a given precicion.

    Return True if they equal.
    """
    res = True

    for sol_1, sol_2 in zip(sol1, sol2):
        if np.ndim(sol_1) != 0 and np.ndim(sol_2) != 0:
            res &= _dist(sol_1, sol_2) < prec
        elif np.ndim(sol_1) != 0 and np.ndim(sol_2) == 0:
            return False
        elif np.ndim(sol_1) == 0 and np.ndim(sol_2) != 0:
            return False

    return res

_solequal(sol1=[array([0., 0.]), array([3., 0.]), array([3.5       , 1.93649167]), array([ 0.16666667, -0.9860133 ])], sol2=[array([0., 0.]), array([3., 0.]), array([3.5       , 1.93649167]), array([0.16666667, 0.9860133 ])], prec=0.1)


def _process_namespace(name, namespaces, ns_sep=':', attr_prefix='@'):
    if not namespaces:
        return name
    try:
        ns, name = name.rsplit(ns_sep, 1)
    except ValueError:
        pass
    else:
        ns_res = namespaces.get(ns.strip(attr_prefix))
        name = '{}{}{}{}'.format(
            attr_prefix if ns.startswith(attr_prefix) else '',
            ns_res, ns_sep, name) if ns_res else name
    return name

_process_namespace(name='http://defaultns.com/:root', namespaces={'http://defaultns.com/': '', 'http://a.com/': 'a', 'http://b.com/': 'b'}, ns_sep=':', attr_prefix='@')


def response_error(code_status, message=None):
    payload = {'error': HTTP_STATUS_CODES.get(code_status, "something went wrong")}
    if message:
        payload['message'] = message
    response = jsonify(payload)
    response.status_code = code_status
    return response

response_error(code_status=400, message='Invalid input')

'Invalid input'

{'error': 'Bad Request', 'message': 'Invalid input'}

'Invalid input'

Response: <Response 50 bytes [200 OK]>

Response: <Response 50 bytes [400 BAD REQUEST]>


def check_data(a, b):
    if not isinstance(a, np.ndarray):
        a = np.array(a)

    if not isinstance(b, np.ndarray):
        b = np.array(b)

    if type(a) != type(b):
        raise ValueError("Type mismatch: %s and %s" % (type(a), type(b)))

    if a.size != b.size:
        raise ValueError("Arrays must be equal in length.")
    return a, b

check_data(a=[], b=1)


def clasifier(optimizer):
    X, y = make_classification(
        n_samples=1000, n_features=100, n_informative=75, random_state=1111, n_classes=2, class_sep=2.5
    )
    y = one_hot(y)

    X -= np.mean(X, axis=0)
    X /= np.std(X, axis=0)
    X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.15, random_state=1111)

    model = NeuralNet(
        layers=[
            Dense(128, Parameters(init="uniform")),
            Activation("relu"),
            Dropout(0.5),
            Dense(64, Parameters(init="normal")),
            Activation("relu"),
            Dense(2),
            Activation("softmax"),
        ],
        loss="categorical_crossentropy",
        optimizer=optimizer,
        metric="accuracy",
        batch_size=64,
        max_epochs=10,
    )
    model.fit(X_train, y_train)
    predictions = model.predict(X_test)
    return roc_auc_score(y_test[:, 0], predictions[:, 0])

clasifier(optimizer={rho=0.95, eps=1e-08, lr=1.0})

{verbose=True, shuffle=False, optimizer=<mla.neuralnet.optimizers.Adadelta object at 0x7f43904a38e0>, layers=[<mla.neuralnet.layers.basic.Dense object at 0x7f43904a3610>, <mla.neuralnet.layers.basic.Activation object at 0x7f43904a33d0>, <mla.neuralnet.layers.basic.Dropout object at 0x7f43904a32b0>, <mla.neuralnet.layers.basic.Dense object at 0x7f43904a3c70>, <mla.neuralnet.layers.basic.Activation object at 0x7f43904a3550>, <mla.neuralnet.layers.basic.Dense object at 0x7f43904a3820>, <mla.neuralnet.layers.basic.Activation object at 0x7f43904a3730>], batch_size=64, max_epochs=10, _n_layers=0, log_metric=True, metric_name='accuracy', bprop_entry=-1, training=False, _initialized=False}


def str2datetime(string):
    """
    Convert a normalized Benthos timestamp to a datetime object

    Parameters
    ----------
    string : str
        String to convert
    """

    if string == "0000-00-00T24:60:60Z":
        return None

    ms = string[20:-1]
    ms += "000000"[:6 - len(ms)]
    return datetime.datetime(
        int(string[:4]),
        int(string[5:7]),
        int(string[8:10]),
        int(string[11:13]),
        int(string[14:16]),
        int(string[17:19]),
        int(ms))

str2datetime(string='1970-01-01T00:00:00.0Z')


def getLogger(name, stdout=None):
    """ Return logger suitable for Cumulus """
    logger = logging.getLogger(name)
    # clear existing handlers
    logger.handlers = []
    if (stdout is None):
        logger.addHandler(logging.NullHandler())
    if stdout is not None:
        handler = logging.StreamHandler()
        handler.setLevel(stdout['level'])
        handler.setFormatter(CumulusFormatter())
        logger.addHandler(handler)
    # logging level
    logger.setLevel(1)
    return logger

getLogger(name='cumulus.aws', stdout=None)


def load_json_dict(filename, *args):
    """Checks if file exists. Returns {} if something fails."""
    data = {}
    if os.path.exists(filename):
        lock.acquire()
        with open(filename, "r") as f:
            try:
                data = _json.load(f)
                if not isinstance(data, dict):
                    data = {}
            except:
                data = {}  # TODO: issue a warning and bubble it up
        lock.release()
        if args:
            return {key: data[key] for key in args if key in data}
    return data

load_json_dict(filename='/home/XXX/.plotly/.config', args=())

{'plotly_domain': 'https://plot.ly', 'plotly_streaming_domain': 'stream.plot.ly', 'plotly_api_domain': 'https://api.plot.ly', 'plotly_ssl_verification': True, 'plotly_proxy_authorization': False, 'world_readable': True, 'sharing': 'public', 'auto_open': True}

<_io.TextIOWrapper name='/home/XXX/.plotly/.config' mode='r' encoding='UTF-8'>


def _get_logger(name):
    """Gets a logger by name, or creates and configures it for the first time."""
    logger = logging.getLogger(name)
    logger.setLevel(logging.INFO)
    # If the logger is configured, skip the configure
    if not logger.handlers and not logging.getLogger().handlers:
        handler = logging.StreamHandler(sys.stderr)
        logger.addHandler(handler)
    return logger

_get_logger(name='hyperopt.utils')


def delete(self, *, ip_parameter, cascade):

        as_address = clean_address(ip_parameter)
        as_network = clean_network(ip_parameter)

        if as_address in self.__description:
            return self.__remove_ip_object(as_address)
        elif as_network in self.__description:
            return self.__remove_ip_object(as_network)

        raise IPObjectNotInSpaceError("cannot delete undescribed IP object")

delete(self=AddressSpace(_AddressSpace__strict=False, _AddressSpace__description={IPv4Address('203.0.113.128'): 'an IPv4 test net address'}, _AddressSpace__networks={}, _AddressSpace__addresses={4: {IPv4Address('203.0.113.128')}}, _AddressSpace__parent_supernet={IPv4Address('203.0.113.128'): None}, _AddressSpace__children_ip_object={None: {IPv4Address('203.0.113.128')}}), ip_parameter='203.0.113.128', cascade=True, self._AddressSpace__addresses={4: {IPv4Address('203.0.113.128')}}, self._AddressSpace__children_ip_object={None: {IPv4Address('203.0.113.128')}}, self._AddressSpace__description={IPv4Address('203.0.113.128'): 'an IPv4 test net address'}, self._AddressSpace__networks={}, self._AddressSpace__parent_supernet={IPv4Address('203.0.113.128'): None}, self._AddressSpace__strict=False)

AddressSpace(_AddressSpace__strict=False, _AddressSpace__description={}, _AddressSpace__networks={}, _AddressSpace__addresses={4: {IPv4Address('203.0.113.128')}}, _AddressSpace__parent_supernet={}, _AddressSpace__children_ip_object={None: set()})


def __remove_ip_object(self, ip_object):

        if ip_object not in self.__description:
            raise IPObjectNotInSpaceError(
                "cannot remove undescribed IP object"
            )

        if isinstance(ip_object, IPAddressTuple):

            supernet = self.__parent_supernet[ip_object]
            self.__children_ip_object[supernet].remove(ip_object)
            del self.__parent_supernet[ip_object]
            del self.__description[ip_object]

        elif isinstance(ip_object, IPNetworkTuple):

            supernet = self.__parent_supernet[ip_object]
            children_of_supernet = (
                self.__children_ip_object.setdefault(supernet, set())
            )

            for child in self.__children_ip_object[ip_object]:
                self.__parent_supernet[child] = supernet
                children_of_supernet.add(child)

            del self.__children_ip_object[ip_object]
            del self.__parent_supernet[ip_object]
            del self.__description[ip_object]

        else:

            raise TypeError("ip_parameter must be a valid IP object")

        return True

__remove_ip_object(self=AddressSpace(_AddressSpace__strict=False, _AddressSpace__description={IPv4Address('203.0.113.128'): 'an IPv4 test net address'}, _AddressSpace__networks={}, _AddressSpace__addresses={4: {IPv4Address('203.0.113.128')}}, _AddressSpace__parent_supernet={IPv4Address('203.0.113.128'): None}, _AddressSpace__children_ip_object={None: {IPv4Address('203.0.113.128')}}), ip_object=IPv4Address('203.0.113.128'), self._AddressSpace__addresses={4: {IPv4Address('203.0.113.128')}}, self._AddressSpace__children_ip_object={None: {IPv4Address('203.0.113.128')}}, self._AddressSpace__description={IPv4Address('203.0.113.128'): 'an IPv4 test net address'}, self._AddressSpace__networks={}, self._AddressSpace__parent_supernet={IPv4Address('203.0.113.128'): None}, self._AddressSpace__strict=False)

AddressSpace(_AddressSpace__strict=False, _AddressSpace__description={IPv4Address('203.0.113.128'): 'an IPv4 test net address'}, _AddressSpace__networks={}, _AddressSpace__addresses={4: {IPv4Address('203.0.113.128')}}, _AddressSpace__parent_supernet={IPv4Address('203.0.113.128'): None}, _AddressSpace__children_ip_object={None: set()})

AddressSpace(_AddressSpace__strict=False, _AddressSpace__description={IPv4Address('203.0.113.128'): 'an IPv4 test net address'}, _AddressSpace__networks={}, _AddressSpace__addresses={4: {IPv4Address('203.0.113.128')}}, _AddressSpace__parent_supernet={}, _AddressSpace__children_ip_object={None: set()})


def _test_grad_nd(n, ndim):
    coords = [np.arange(n)] * ndim
    xc = np.meshgrid(*coords, indexing="ij")

    # u = sum_i(xc[i]**2)
    u = reduce(lambda x,y: x+y**2, xc, 0.0)
    ucopy = np.copy(u)

    # check the gradient values
    slices = tuple([slice(1,-1,None)] * ndim)
    for i in range(ndim):
        assert grad(u, axis=i) == pytest.approx(2*xc[i][slices])

    # check if u is unchanged
    assert np.all(u == ucopy)

_test_grad_nd(n=92, ndim=1)


def _test_grad2_nd(n, ndim):
    coords = [np.arange(n)] * ndim
    xc = np.meshgrid(*coords, indexing="ij")

    # u = sum_i(xc[i]**2)
    u = reduce(lambda x,y: x+y**2, xc, 0.0)
    ucopy = np.copy(u)

    # check the gradient values
    gu = np.zeros(tuple([n-2]*ndim))
    gu2 = gu + 2.0
    for i in range(ndim):
        for j in range(ndim):
            if i == j:
                assert grad2(u, axes=(i,j)) == pytest.approx(gu2)
            else:
                assert grad2(u, axes=(i,j)) == pytest.approx(gu)

    # check if u is unchanged
    assert np.all(u == ucopy)

_test_grad2_nd(n=32, ndim=1)


def det_hess(u):
    """
    Get the determinant of the Hessian matrix of `u`.

    Parameters
    ----------
    * `u` : numpy.ndarray
        The ndarray input with shape (n0+2, n1+2, ..., nd1+2).

    Returns
    -------
    * numpy.ndarray
        The ndarray of the second grad of `u` with shape (n0, n1, ..., nd1).
    """
    ndim = np.ndim(u)
    inshape = np.asarray(u.shape)
    outshape = list(inshape - 2)

    # obtain the second gradient per each pairs of axes
    hess_unarranged = np.zeros([ndim, ndim] + outshape)
    for i in range(ndim):
        for j in range(i,ndim):
            grad2_val = grad2(u, (i,j))
            hess_unarranged[i,j] = grad2_val
            hess_unarranged[j,i] = grad2_val

    # rearrange hessian to have shape: outshape + [ndim, ndim]
    perm_idx = list(range(2,ndim+2)) + list(range(2))
    hess = np.transpose(hess_unarranged, perm_idx)

    # calculate and return the determinant
    return np.linalg.det(hess)

det_hess(u=array([  0.,   1.,   4.,   9.,  16.,  25.,  36.,  49.,  64.,  81., 100.,       121., 144., 169., 196., 225., 256., 289., 324., 361., 400., 441.,       484., 529., 576., 625., 676., 729., 784., 841., 900., 961.]))


def forward(source, phi):
    """
    Obtain the target density distribution given the source distribution and
    the mapping potential, phi.
    The mapping from source coordinate, $x$, to the target coordinate, $y$, is
    given by:

    $$
    y = x + \nabla phi(x).
    $$

    The coordinate in i-th dimension is given by `np.arange(source.shape[i])`.

    Parameters
    ----------
    * `source` : numpy.ndarray
        The source density distribution in n-dimensional array.
    * `phi` : numpy.ndarray
        The mapping potential given above. It must have the same shape as
        `source`.

    Returns
    -------
    * numpy.ndarray
        The target density distribution in n-dimensional array.
    """
    # convert to np.ndarray
    source = np.asarray(source)
    phi = np.asarray(phi)
    # check the shapes of inputs
    if source.shape != phi.shape:
        raise ValueError("The source and phi must have the same shape.")

    # calculate the total potential so that $y = \nabla u(x)$
    u0, u, phi_pad = _get_full_potential(phi)
    ndim = np.ndim(phi)

    # calculate the determinant of the hessian
    det_hess_s = det_hess(u)

    # get the displacement in (n x D) format
    x = np.array([grad(u0, axis=i) for i in range(ndim)]).reshape((ndim,-1)).T
    y = np.array([grad(u , axis=i) for i in range(ndim)]).reshape((ndim,-1)).T

    # interpolate the values
    interp = lambda s: griddata(y, s.flatten(), x, "linear").reshape(s.shape)
    target_s = source / det_hess_s
    target = interp(target_s)

    # fill nan values with zeros
    target[np.isnan(target)] = 0.0
    return target

forward(source=array([3.72665317e-06, 6.14389891e-06, 1.00262383e-05, 1.61957424e-05,       2.58959932e-05, 4.09857759e-05, 6.42099934e-05, 9.95728564e-05,       1.52843925e-04, 2.32233182e-04, 3.49276399e-04, 5.19975743e-04,       7.66241736e-04, 1.11767979e-03, 1.61375600e-03, 2.30636063e-03,       3.26276232e-03, 4.56890930e-03, 6.33298575e-03, 8.68907130e-03,       1.18006814e-02, 1.58638899e-02, 2.11096565e-02, 2.78049116e-02,       3.62518979e-02, 4.67852390e-02, 5.97662260e-02, 7.55738747e-02,       9.45924385e-02, 1.17195255e-01, 1.43725065e-01, 1.74471250e-01,       2.09644807e-01, 2.49352209e-01, 2.93569685e-01, 3.42119690e-01,       3.94651546e-01, 4.50628259e-01, 5.09321387e-01, 5.69815527e-01,       6.31023482e-01, 6.91712523e-01, 7.50541364e-01, 8.06106646e-01,       8.56996891e-01, 9.01851159e-01, 9.39419053e-01, 9.68618450e-01,       9.88587205e-01, 9.98725433e-01, 9.98725433e-01, 9.88587205e-01,       9.68618450e-01, 9.39419053e-01, 9.01851159e-01, 8.56996891e-01,       8.06106646e-01, 7.50541364e-01, 6.91712523e-01, 6.31023482e-01,       5.69815527e-01, 5.09321387e-01, 4.50628259e-01, 3.94651546e-01,       3.42119690e-01, 2.93569685e-01, 2.49352209e-01, 2.09644807e-01,       1.74471250e-01, 1.43725065e-01, 1.17195255e-01, 9.45924385e-02,       7.55738747e-02, 5.97662260e-02, 4.67852390e-02, 3.62518979e-02,       2.78049116e-02, 2.11096565e-02, 1.58638899e-02, 1.18006814e-02,       8.68907130e-03, 6.33298575e-03, 4.56890930e-03, 3.26276232e-03,       2.30636063e-03, 1.61375600e-03, 1.11767979e-03, 7.66241736e-04,       5.19975743e-04, 3.49276399e-04, 2.32233182e-04, 1.52843925e-04,       9.95728564e-05, 6.42099934e-05, 4.09857759e-05, 2.58959932e-05,       1.61957424e-05, 1.00262383e-05, 6.14389891e-06, 3.72665317e-06]), phi=array([0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.,       0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.,       0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.,       0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.,       0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.,       0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.]))

<function forward.<locals>.<lambda> at 0x7fab7f2e3700>


def _get_default_expanded_coordinate(shape, ndim):
    x_coords = []
    for i in range(ndim):
        idx = [None] * ndim
        idx[i] = slice(None, None, None)
        x_coords.append(np.arange(shape[i])[tuple(idx)])
    return x_coords

_get_default_expanded_coordinate(shape=array([102]), ndim=1)


idx_pad0_r = _get_idx(ndim, dim, slice(pw[0]+1, pw[0]+2, None))


def _test_forward_nd_slanted_pot(n, ndim, abs=None):
    x = np.arange(n) - n / 2.0
    xs = np.meshgrid(*([x]*ndim), indexing="ij")
    xs_sq = reduce(lambda x,y:x+y*y, xs, 0.0)

    # phi is slanted on the first dimension, so the target will be shifted
    # source on the first dimension by A
    A = n / 6.0
    sigma = (n/30.)
    source = np.exp(-xs_sq / (2*sigma**2))
    source_copy = np.copy(source)
    phi = xs[0] * A
    target = sb.forward(source, phi)

    xs2 = np.copy(xs)
    xs2[0] -= A
    xs2_sq = reduce(lambda x,y:x+y*y, xs2, 0.0)
    target_calc = np.exp(-xs2_sq / (2*sigma**2))

    # accurate within 2.5*(1/n)*100%
    abs = 2.5/n if abs is None else abs
    assert target == pytest.approx(target_calc, abs=abs)

    # check the dimension of target
    assert np.ndim(target) == ndim

    # make sure the source is not changed
    assert np.all(source == source_copy)

_test_forward_nd_slanted_pot(n=100, ndim=1, abs=None)


def _test_forward_nd_quad_pot(n, ndim, abs=None):
    x = np.arange(n) - n / 2.0
    xs = np.meshgrid(*([x]*ndim), indexing="ij")
    xs_sq = reduce(lambda x,y:x+y*y, xs, 0.0)

    # phi is quadratic on all dimension, so the target will be scaled
    # source on all dimension by (1+B)
    B = 1.0
    scale = 1 + B
    sigma = (n/30.)
    source = np.exp(-xs_sq / (2*sigma**2))
    source_copy = np.copy(source)
    phi = 0.5*B*xs_sq
    target = sb.forward(source, phi)

    target_calc = (scale**-ndim)*np.exp(-xs_sq / (2*(sigma*scale)**2))

    # accurate within 2.5*(1/n)*100%
    abs = 2.5/n if abs is None else abs
    assert target == pytest.approx(target_calc, abs=abs)

    # check the dimension of target
    assert np.ndim(target) == ndim

    # make sure the source is not changed
    assert np.all(source == source_copy)

_test_forward_nd_quad_pot(n=100, ndim=1, abs=None)


def test_audioclip_stereo_max_volume(nchannels, channel_muted):
    def make_frame(t):
        frame = []
        # build channels (one of each pair muted)
        for i in range(int(nchannels / 2)):
            if channel_muted == "left":
                # if muted channel is left, [0, sound, 0, sound...]
                frame.append(np.sin(t * 0))
                frame.append(np.sin(440 * 2 * np.pi * t))
            else:
                # if muted channel is right, [sound, 0, sound, 0...]
                frame.append(np.sin(440 * 2 * np.pi * t))
                frame.append(np.sin(t * 0))
        return np.array(frame).T

    clip = AudioClip(make_frame, fps=44100, duration=1)
    max_volume = clip.max_volume(stereo=True)
    # if `stereo == True`, `AudioClip.max_volume` returns a Numpy array`
    assert isinstance(max_volume, np.ndarray)
    assert len(max_volume) == nchannels

    # check channels muted and with sound
    for i, channel_max_volume in enumerate(max_volume):
        if i % 2 == 0:
            if channel_muted == "left":
                assert channel_max_volume == 0
            else:
                assert channel_max_volume > 0
        else:
            if channel_muted == "right":
                assert channel_max_volume == 0
            else:
                assert channel_max_volume > 0

test_audioclip_stereo_max_volume(nchannels=2, channel_muted='left')

<function test_audioclip_stereo_max_volume.<locals>.make_frame at 0x7f8c02a8e670>

{start=0, end=1, duration=1, memoize=False, memoized_t=None, memoized_frame=None, fps=44100, nchannels=2}


def test_clip_with_end(duration, start, end, expected_start, expected_duration):
    clip = ColorClip(color=(255, 0, 0), size=(2, 2), duration=duration).with_fps(1)
    if start is not None:
        clip = clip.with_start(start)
    else:
        clip.start = None
    clip = clip.with_end(end)

    assert clip.start == expected_start
    assert clip.duration == expected_duration

test_clip_with_end(duration=3, start=1, end=2, expected_start=1, expected_duration=1)

{start=0, end=3, duration=3, memoize=False, memoized_t=None, memoized_frame=None, mask=None, audio=None, relative_pos=False, layer=0, is_mask=False, has_constant_size=True, size=(2, 2), img=array([[[255,   0,   0],        [255,   0,   0]],       [[255,   0,   0],        [255,   0,   0]]]), fps=1}

{start=1, end=4, duration=3, memoize=False, memoized_t=None, memoized_frame=None, mask=None, audio=None, relative_pos=False, layer=0, is_mask=False, has_constant_size=True, size=(2, 2), img=array([[[255,   0,   0],        [255,   0,   0]],       [[255,   0,   0],        [255,   0,   0]]]), fps=1}

{start=1, end=2, duration=1, memoize=False, memoized_t=None, memoized_frame=None, mask=None, audio=None, relative_pos=False, layer=0, is_mask=False, has_constant_size=True, size=(2, 2), img=array([[[255,   0,   0],        [255,   0,   0]],       [[255,   0,   0],        [255,   0,   0]]]), fps=1}


def subprocess_call(cmd, logger="bar"):
    """Executes the given subprocess command.

    Set logger to None or a custom Proglog logger to avoid printings.
    """
    logger = proglog.default_bar_logger(logger)
    logger(message="MoviePy - Running:\n>>> " + " ".join(cmd))

    popen_params = cross_platform_popen_params(
        {"stdout": sp.DEVNULL, "stderr": sp.PIPE, "stdin": sp.DEVNULL}
    )

    proc = sp.Popen(cmd, **popen_params)

    out, err = proc.communicate()  # proc.wait()
    proc.stderr.close()

    if proc.returncode:
        logger(message="MoviePy - Command returned an error")
        raise IOError(err.decode("utf8"))
    else:
        logger(message="MoviePy - Command successful")

    del proc

subprocess_call(cmd=['unset', '-background', 'transparent', '-fill', 'white', '-font', 'Liberation-Mono', '-pointsize', '25', '-size', '640x480', '-gravity', 'center', 'caption:@/tmp/tmp6pdbi5v3.txt', '-type', 'truecolormatte', 'PNG32:/tmp/tmpkd0efulh.png'], logger=None)

{state={'bars': OrderedDict()}, stored={}, logs=[], log_indent=0, ignored_bars=None, logged_bars='all', min_time_interval=0, ignore_bars_under=0}

{state={'bars': OrderedDict(), 'message': 'MoviePy - Running:\n>>> unset -background transparent -fill white -font Liberation-Mono -pointsize 25 -size 640x480 -gravity center caption:@/tmp/tmp6pdbi5v3.txt -type truecolormatte PNG32:/tmp/tmpkd0efulh.png'}, stored={}, logs=[], log_indent=0, ignored_bars=None, logged_bars='all', min_time_interval=0, ignore_bars_under=0}


def ffmpeg_write_image(filename, image, logfile=False, pixel_format=None):
    """Writes an image (HxWx3 or HxWx4 numpy array) to a file, using ffmpeg.

    Parameters
    ----------

    filename : str
        Path to the output file.

    image : np.ndarray
        Numpy array with the image data.

    logfile : bool, optional
        Writes the ffmpeg output inside a logging file (``True``) or not
        (``False``).

    pixel_format : str, optional
        Pixel format for ffmpeg. If not defined, it will be discovered checking
        if the image data contains an alpha channel (``"rgba"``) or not
        (``"rgb24"``).
    """
    if image.dtype != "uint8":
        image = image.astype("uint8")
    if not pixel_format:
        pixel_format = "rgba" if (image.shape[2] == 4) else "rgb24"

    cmd = [
        FFMPEG_BINARY,
        "-y",
        "-s",
        "%dx%d" % (image.shape[:2][::-1]),
        "-f",
        "rawvideo",
        "-pix_fmt",
        pixel_format,
        "-i",
        "-",
        filename,
    ]

    if logfile:
        log_file = open(filename + ".log", "w+")
    else:
        log_file = sp.PIPE

    popen_params = cross_platform_popen_params(
        {"stdout": sp.DEVNULL, "stderr": log_file, "stdin": sp.PIPE}
    )

    proc = sp.Popen(cmd, **popen_params)
    out, err = proc.communicate(image.tobytes())

    if proc.returncode:
        error = (
            f"{err}\n\nMoviePy error: FFMPEG encountered the following error while "
            f"writing file {filename} with command {cmd}:\n\n {err.decode()}"
        )

        raise IOError(error)

    del proc

ffmpeg_write_image(filename='/tmp/moviepy_ffmpeg_write_image.png', image=array([[[  0., 255.,   0.],        [ 51., 204.,   0.],        [102., 153.,   0.],        [153., 102.,   0.],        [204.,  51.,   0.]]]), logfile=False, pixel_format=None)

['/local/rcs/XXX/miniforge3/envs/Zulko+moviepy/lib/python3.9/site-packages/imageio_ffmpeg/binaries/ffmpeg-linux64-v4.2.2', '-y', '-s', '5x1', '-f', 'rawvideo', '-pix_fmt', 'rgb24', '-i', '-', '/tmp/moviepy_ffmpeg_write_image.png']

<Popen: returncode: None args: ['/local/rcs/XXX/miniforge3/envs/Zulko+mov...>

<Popen: returncode: 0 args: ['/local/rcs/XXX/miniforge3/envs/Zulko+moviep...>

b"ffmpeg version 4.2.2-static https://johnvansickle.com/ffmpeg/  Copyright (c) 2000-2019 the FFmpeg developers\n  built with gcc 8 (Debian 8.3.0-6)\n  configuration: --enable-gpl --enable-version3 --enable-static --disable-debug --disable-ffplay --disable-indev=sndio --disable-outdev=sndio --cc=gcc --enable-fontconfig --enable-frei0r --enable-gnutls --enable-gmp --enable-libgme --enable-gray --enable-libaom --enable-libfribidi --enable-libass --enable-libvmaf --enable-libfreetype --enable-libmp3lame --enable-libopencore-amrnb --enable-libopencore-amrwb --enable-libopenjpeg --enable-librubberband --enable-libsoxr --enable-libspeex --enable-libsrt --enable-libvorbis --enable-libopus --enable-libtheora --enable-libvidstab --enable-libvo-amrwbenc --enable-libvpx --enable-libwebp --enable-libx264 --enable-libx265 --enable-libxml2 --enable-libdav1d --enable-libxvid --enable-libzvbi --enable-libzimg\n  libavutil      56. 31.100 / 56. 31.100\n  libavcodec     58. 54.100 / 58. 54.100\n  libavformat    58. 29.100 / 58. 29.100\n  libavdevice    58.  8.100 / 58.  8.100\n  libavfilter     7. 57.100 /  7. 57.100\n  libswscale      5.  5.100 /  5.  5.100\n  libswresample   3.  5.100 /  3.  5.100\n  libpostproc    55.  5.100 / 55.  5.100\nInput #0, rawvideo, from 'pipe:':\n  Duration: N/A, start: 0.000000, bitrate: 3 kb/s\n    Stream #0:0: Video: rawvideo (RGB[24] / 0x18424752), rgb24, 5x1, 3 kb/s, 25 tbr, 25 tbn, 25 tbc\nStream mapping:\n  Stream #0:0 -> #0:0 (rawvideo (native) -> png (native))\nOutput #0, image2, to '/tmp/moviepy_ffmpeg_write_image.png':\n  Metadata:\n    encoder         : Lavf58.29.100\n    Stream #0:0: Video: png, rgb24, 5x1, q=2-31, 200 kb/s, 25 fps, 25 tbn, 25 tbc\n    Metadata:\n      encoder         : Lavc58.54.100 png\nframe=    1 fps=0.0 q=-0.0 Lsize=N/A time=00:00:00.04 bitrate=N/A speed=1.64x    \nvideo:0kB audio:0kB subtitle:0kB other streams:0kB global headers:0kB muxing overhead: unknown\n"


def test_freeze(t, freeze_duration, total_duration, padding_end, output_frames):
    input_frames = ["R", "G", "B"]
    clip_duration = len(input_frames)

    # create BitmapClip with predefined set of colors, during 1 second each one
    clip = BitmapClip([list(color) for color in input_frames], fps=1).with_duration(
        clip_duration
    )

    # build kwargs passed to `freeze`
    possible_kwargs = {
        "t": t,
        "freeze_duration": freeze_duration,
        "total_duration": total_duration,
        "padding_end": padding_end,
    }
    kwargs = {
        kw_name: kw_value
        for kw_name, kw_value in possible_kwargs.items()
        if kw_value is not None
    }

    # freeze clip
    if hasattr(output_frames, "__traceback__"):
        with pytest.raises(output_frames):
            freeze(clip, **kwargs)
        return
    else:
        freezed_clip = freeze(clip, **kwargs)

    # assert new duration
    expected_freeze_duration = (
        freeze_duration
        if freeze_duration is not None
        else total_duration - clip_duration
    )
    assert freezed_clip.duration == clip_duration + expected_freeze_duration

    # assert colors are the expected
    for i, color in enumerate(freezed_clip.iter_frames()):
        expected_color = list(BitmapClip.DEFAULT_COLOR_DICT[output_frames[i]])
        assert list(color[0][0]) == expected_color

test_freeze(t=None, freeze_duration=1, total_duration=None, padding_end=None, output_frames=['R', 'R', 'G', 'B'])

{'t': None, 'freeze_duration': 1, 'total_duration': None, 'padding_end': None}

{start=0, end=4, duration=4, memoize=False, memoized_t=None, memoized_frame=None, mask=None, audio=None, relative_pos=False, layer=0, size=(1, 1), is_mask=False, has_constant_size=True, timings=array([0, 1, 4]), start_times=array([0, 1]), fps=1}


def test_mask_and(image_from, duration, color, mask_color, expected_color):
    """Checks ``mask_and`` FX behaviour."""
    clip_size = tuple(random.randint(3, 10) for i in range(2))

    if duration == "random":
        duration = round(random.uniform(0, 0.5), 2)

    # test ImageClip and np.ndarray types as mask argument
    clip = ColorClip(color=color, size=clip_size).with_duration(duration)
    mask_clip = ColorClip(color=mask_color, size=clip.size)
    masked_clip = mask_and(
        clip, mask_clip if image_from == "ImageClip" else mask_clip.get_frame(0)
    )

    assert masked_clip.duration == clip.duration
    assert np.array_equal(masked_clip.get_frame(0)[0][0], np.array(expected_color))

    # test VideoClip as mask argument
    color_frame, mask_color_frame = (np.array([[color]]), np.array([[mask_color]]))
    clip = VideoClip(lambda t: color_frame).with_duration(duration)
    mask_clip = VideoClip(lambda t: mask_color_frame).with_duration(duration)
    masked_clip = mask_and(clip, mask_clip)

    assert np.array_equal(masked_clip.get_frame(0)[0][0], np.array(expected_color))

test_mask_and(image_from='np.ndarray', duration=None, color=(0, 0, 0), mask_color=(255, 255, 255), expected_color=(0, 0, 0))

{start=0, end=None, duration=None, memoize=False, memoized_t=None, memoized_frame=None, mask=None, audio=None, relative_pos=False, layer=0, size=(1, 1), is_mask=False, has_constant_size=True}


def _validate_htype_overwrites(htype: str, htype_overwrite: dict):
    """Raises errors if ``htype_overwrite`` has invalid keys or was missing required values."""

    defaults = HTYPE_CONFIGURATIONS[htype]

    for key, value in htype_overwrite.items():
        if key not in defaults:
            raise TensorMetaInvalidHtypeOverwriteKey(htype, key, list(defaults.keys()))

        if isinstance(value, str) and value == UNSPECIFIED:
            if defaults[key] == REQUIRE_USER_SPECIFICATION:
                raise TensorMetaMissingRequiredValue(htype, key)

    sc = htype_overwrite["sample_compression"]
    cc = htype_overwrite["chunk_compression"]
    compr = sc if cc in (None, UNSPECIFIED) else cc
    actual_htype = f"link[{htype}]" if htype_overwrite["is_link"] else htype
    if htype.startswith("image") and sc == UNSPECIFIED and cc == UNSPECIFIED:
        raise TensorMetaMissingRequiredValue(
            actual_htype, ["chunk_compression", "sample_compression"]  # type: ignore
        )
    if htype in ("audio", "video", "point_cloud", "mesh", "nifti"):
        if cc not in (UNSPECIFIED, None):
            raise UnsupportedCompressionError("Chunk compression", htype=htype)
        elif sc == UNSPECIFIED:
            raise TensorMetaMissingRequiredValue(
                actual_htype, "sample_compression"  # type: ignore
            )
    supported_compressions = HTYPE_SUPPORTED_COMPRESSIONS.get(htype)
    if (
        compr
        and compr != UNSPECIFIED
        and supported_compressions
        and compr not in supported_compressions
    ):
        raise UnsupportedCompressionError(compr, htype=htype)

_validate_htype_overwrites(htype='generic', htype_overwrite={'sample_compression': 'unspecified', 'chunk_compression': 'unspecified', 'dtype': 'unspecified', 'hidden': False, 'tiling_threshold': None, 'max_chunk_size': 2000000, 'is_sequence': False, 'is_link': False, 'verify': True})

{'dtype': None, 'sample_compression': None, 'chunk_compression': None, 'typestr': None, 'max_chunk_size': None, 'tiling_threshold': None, 'is_sequence': False, 'is_link': False, 'hidden': False, 'links': None, 'verify': False}


def serialize_chunkids(version: str, arr: np.ndarray) -> memoryview:
    """Serializes chunk ID encoders into a single byte stream. This is how the encoders will be written to the storage provider.

    Args:
        version: (str) Version of deeplake library.
        arr: (np.ndarray) Encoded chunk ids from a `ChunkIdEncoder` instance.

    Returns:
        Serialized chunk ids as memoryview.
    """
    len_version = len(version)
    write_dtype = version_compare(version, "2.7.6") >= 0
    flatbuff = bytearray(1 + int(write_dtype) + len_version + arr.nbytes)

    # Write version
    len_version = len(version)
    flatbuff[0] = len_version
    flatbuff[1 : 1 + len_version] = version.encode("ascii")
    offset = 1 + len_version

    # write encoder dtype
    if write_dtype:
        dtype = arr.dtype
        num_bytes = int(dtype.itemsize)
        flatbuff[offset] = num_bytes
        offset += 1

    # Write ids
    flatbuff[offset : offset + arr.nbytes] = arr.tobytes()
    offset += arr.nbytes
    return memoryview(flatbuff)

serialize_chunkids(version='3.8.18', arr=array([], shape=(0, 2), dtype=uint64))


def _draw_random_tile(self):
        random_index = random.randrange(0, len(self.tile_bag))
        selected_tile = self.tile_bag.pop(random_index)

        return selected_tile

_draw_random_tile(self=REPR FAILED, self.tile_bag=[*, *, A, A, A, A, A, A, A, A, A, B, B, C, C, D, D, D, D, E, E, E, E, E, E, E, E, E, E, E, E, F, F, G, G, G, H, H, I, I, I, I, I, I, I, I, I, J, K, L, L, L, L, M, M, N, N, N, N, N, N, O, O, O, O, O, O, O, O, P, P, Q, R, R, R, R, R, R, S, S, S, S, T, T, T, T, T, T, U, U, U, U, V, V, W, W, X, Y, Y, Z])


def move_is_sublist(letter_list_1, letter_list_2):
    letter_counter_1 = collections.Counter(letter_list_1)
    letter_counter_2 = collections.Counter(letter_list_2)
    for letter, cardinality in letter_counter_1.items():
        if cardinality > letter_counter_2[letter]:
            # print('Not enough {} tiles in rack.'.format(letter))
            return False

    return True

move_is_sublist(letter_list_1=[1, 2, 3], letter_list_2=[1, 2, 3, 4])


def get_word_letter_location_set(word, start_location, is_vertical_move):
    letter_location_set = set()
    next_location_func = get_next_location_function(
        use_positive_seek=True,
        use_vertical_words=is_vertical_move
    )

    current_location = start_location
    word_iterator = iter(word)
    for character in word_iterator:
        if character == '(':  # characters in parenthesis are existing tiles
            character = next(word_iterator, None)
            while character != ')':
                current_location = next_location_func(current_location)
                character = next(word_iterator, None)

            character = next(word_iterator, None)

        if character:
            letter_location_set.add((character, current_location))
            current_location = next_location_func(current_location)

    return letter_location_set

get_word_letter_location_set(word='BAKER', start_location=('h', 8), is_vertical_move=False)

<function get_next_location_function.<locals>.<lambda> at 0x7feb6dd68f70>


def next_player_move(self, letter_location_set):
        player_to_move_id, player_rack = get_current_player_data(
            self.move_number,
            self.player_rack_list
        )

        is_legal_move = move_is_legal(self.board,
                                      self.move_number,
                                      letter_location_set,
                                      player_rack)

        if is_legal_move:
            if move_successfully_challenged():
                letter_location_set = set()

            for move_letter, board_location in letter_location_set:
                tile_index = get_rack_tile_index(player_rack, move_letter)
                tile_obj = player_rack.pop(tile_index)
                self.board[board_location] = tile_obj

            move_score = score_move(letter_location_set, self.board)
            self.player_score_list_list[player_to_move_id].append(move_score)
            self._refill_player_rack(player_rack)
            self._cancel_bonus_squares(letter_location_set)

            if len(player_rack) == 0 and len(self.tile_bag) == 0:  # Final move
                last_move_score_list = score_end_of_game(self.player_rack_list,
                                                         player_to_move_id)

                for i, last_move_score in enumerate(last_move_score_list):
                    self.player_score_list_list[i].append(last_move_score)

                conclude_game(self.player_score_list_list)

            self.move_number += 1
            return True
        else:
            return False

next_player_move(self=  abcdefghijklmno1 _______________2 _______________3 _______________4 _______________5 _______________6 _______________7 _______________8 _______★_______9 _______________10_______________11_______________12_______________13_______________14_______________15_______________[[Q, E, O, S, G, H, E, B, A, K, E, R], [R, Z, L, A, U, L, A], [W, C, E, T, N, E, E], [T, R, O, B, T, N, N]]Moves played: 0Player 1's move72 tiles remain in bagPlayer 1: 0Player 2: 0Player 3: 0Player 4: 0, letter_location_set={('K', ('j', 8)), ('B', ('h', 8)), ('A', ('i', 8)), ('E', ('k', 8)), ('R', ('l', 8))}, self.board=  abcdefghijklmno1 _______________2 _______________3 _______________4 _______________5 _______________6 _______________7 _______________8 _______★_______9 _______________10_______________11_______________12_______________13_______________14_______________15_______________, self.move_number=0, self.player_rack_list=[[Q, E, O, S, G, H, E, B, A, K, E, R], [R, Z, L, A, U, L, A], [W, C, E, T, N, E, E], [T, R, O, B, T, N, N]], self.player_score_list_list=[[], [], [], []], self.tile_bag=[*, *, A, A, A, A, A, A, A, B, C, D, D, D, D, E, E, E, E, E, E, E, F, F, G, G, H, I, I, I, I, I, I, I, I, I, J, K, L, L, M, M, N, N, N, O, O, O, O, O, O, P, P, R, R, R, R, S, S, S, T, T, T, U, U, U, V, V, W, X, Y, Y])


def all_move_tiles_connected(board, location_set):
    column_list = [column for column, _ in location_set]
    row_list = [row for _, row in location_set]
    move_is_vertical = (len(set(column_list)) == 1)

    if move_is_vertical:
        this_column = column_list[0]
        for this_row in range(min(row_list), max(row_list) + 1):
            this_tile = board[(this_column, this_row)]
            if not (this_tile or (this_column, this_row) in location_set):
                # print('Not all tiles in vertical move are connected: '
                #       'location {} is empty'.format((this_column, this_row)))

                return False
    else:
        column_range = range(
            config.LETTER_CODE_DICT[min(column_list)],
            config.LETTER_CODE_DICT[max(column_list)] + 1
        )

        this_row = row_list[0]
        for this_column_num in column_range:
            this_column = chr(this_column_num)
            this_tile = board[(this_column, this_row)]
            if not (this_tile or (this_column, this_row) in location_set):
                # print('Not all tiles in horizontal move are connected: '
                #       'location {} is empty'.format((this_column, this_row)))

                return False

    return True

all_move_tiles_connected(board=  abcdefghijklmno1 _______________2 _______________3 _______________4 _______________5 _______________6 _______________7 _______________8 _______★_______9 _______________10_______________11_______________12_______________13_______________14_______________15_______________, location_set={('j', 8), ('l', 8), ('h', 8), ('i', 8), ('k', 8)})


def rolling_mean_by_h(x, h, w, name):
    """Compute a rolling mean of x, after first aggregating by h.

    Right-aligned. Computes a single mean for each unique value of h. Each
    mean is over at least w samples.

    Parameters
    ----------
    x: Array.
    h: Array of horizon for each value in x.
    w: Integer window size (number of elements).
    name: Name for metric in result dataframe

    Returns
    -------
    Dataframe with columns horizon and name, the rolling mean of x.
    """
    # Aggregate over h
    df = pd.DataFrame({'x': x, 'h': h})
    df2 = (
        df.groupby('h').agg(['sum', 'count']).reset_index().sort_values('h')
    )
    xs = df2['x']['sum'].values
    ns = df2['x']['count'].values
    hs = df2.h.values

    trailing_i = len(df2) - 1
    x_sum = 0
    n_sum = 0
    # We don't know output size but it is bounded by len(df2)
    res_x = np.empty(len(df2))

    # Start from the right and work backwards
    for i in range(len(df2) - 1, -1, -1):
        x_sum += xs[i]
        n_sum += ns[i]
        while n_sum >= w:
            # Include points from the previous horizon. All of them if still
            # less than w, otherwise weight the mean by the difference
            excess_n = n_sum - w
            excess_x = excess_n * xs[i] / ns[i]
            res_x[trailing_i] = (x_sum - excess_x)/ w
            x_sum -= xs[trailing_i]
            n_sum -= ns[trailing_i]
            trailing_i -= 1

    res_h = hs[(trailing_i + 1):]
    res_x = res_x[(trailing_i + 1):]

    return pd.DataFrame({'horizon': res_h, name: res_x})

rolling_mean_by_h(x=array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9]), h=array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9]), w=1, name='x')


def rolling_median_by_h(x, h, w, name):
    """Compute a rolling median of x, after first aggregating by h.

    Right-aligned. Computes a single median for each unique value of h. Each
    median is over at least w samples.

    For each h where there are fewer than w samples, we take samples from the previous h,
    moving backwards. (In other words, we ~ assume that the x's are shuffled within each h.)

    Parameters
    ----------
    x: Array.
    h: Array of horizon for each value in x.
    w: Integer window size (number of elements).
    name: Name for metric in result dataframe

    Returns
    -------
    Dataframe with columns horizon and name, the rolling median of x.
    """
    # Aggregate over h
    df = pd.DataFrame({'x': x, 'h': h})
    grouped = df.groupby('h')
    df2 = grouped.size().reset_index().sort_values('h')
    hs = df2['h']

    res_h = []
    res_x = []
    # Start from the right and work backwards
    i = len(hs) - 1
    while i >= 0:
        h_i = hs[i]
        xs = grouped.get_group(h_i).x.tolist()

        # wrap in array so this works if h is pandas Series with custom index or numpy array
        next_idx_to_add = np.array(h == h_i).argmax() - 1
        while (len(xs) < w) and (next_idx_to_add >= 0):
            # Include points from the previous horizon. All of them if still
            # less than w, otherwise just enough to get to w.
            xs.append(x[next_idx_to_add])
            next_idx_to_add -= 1
        if len(xs) < w:
            # Ran out of points before getting enough.
            break
        res_h.append(hs[i])
        res_x.append(np.median(xs))
        i -= 1
    res_h.reverse()
    res_x.reverse()
    return pd.DataFrame({'horizon': res_h, name: res_x})

rolling_median_by_h(x=array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9]), h=array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9]), w=1, name='x')

<pandas.core.groupby.generic.DataFrameGroupBy object at 0x7ff75ca12880>


def create_request_parameters(parent, request_model, params=None, index=None):
    """
    Handle request parameters that can be filled in from identifiers,
    resource data members or constants.

    By passing ``params``, you can invoke this method multiple times and
    build up a parameter dict over time, which is particularly useful
    for reverse JMESPath expressions that append to lists.

    :type parent: ServiceResource
    :param parent: The resource instance to which this action is attached.
    :type request_model: :py:class:`~boto3.resources.model.Request`
    :param request_model: The action request model.
    :type params: dict
    :param params: If set, then add to this existing dict. It is both
                   edited in-place and returned.
    :type index: int
    :param index: The position of an item within a list
    :rtype: dict
    :return: Pre-filled parameters to be sent to the request operation.
    """
    if params is None:
        params = {}

    for param in request_model.params:
        source = param.source
        target = param.target

        if source == 'identifier':
            # Resource identifier, e.g. queue.url
            value = getattr(parent, xform_name(param.name))
        elif source == 'data':
            # If this is a data member then it may incur a load
            # action before returning the value.
            value = get_data_member(parent, param.path)
        elif source in ['string', 'integer', 'boolean']:
            # These are hard-coded values in the definition
            value = param.value
        elif source == 'input':
            # This is provided by the user, so ignore it here
            continue
        else:
            raise NotImplementedError(f'Unsupported source type: {source}')

        build_param_structure(params, target, value, index)

    return params

create_request_parameters(parent=dynamodb.Table(name='MyTable'), request_model={_definition=OrderedDict([('operation', 'Scan'), ('params', [OrderedDict([('target', 'TableName'), ('source', 'identifier'), ('name', 'Name')])])]), operation='Scan'}, params=None, index=None)

{target='TableName', source='identifier', name='Name', path=None, value=None}


def test_lexer_single_token(expression, result):
    lexer = MOALexer()
    tokens = tuple(token.type for token in lexer.tokenize(expression))
    assert tokens == result

test_lexer_single_token(expression='1234', result=('INTEGER',))


def suggest_type(full_text, text_before_cursor):
    """Takes the full_text that is typed so far and also the text before the
    cursor to suggest completion type and scope.

    Returns a tuple with a type of entity ('table', 'column' etc) and a scope.
    A scope for a column category will be a list of tables.
    """

    word_before_cursor = last_word(text_before_cursor,
            include='many_punctuations')

    identifier = None

    # here should be removed once sqlparse has been fixed
    try:
        # If we've partially typed a word then word_before_cursor won't be an empty
        # string. In that case we want to remove the partially typed string before
        # sending it to the sqlparser. Otherwise the last token will always be the
        # partially typed string which renders the smart completion useless because
        # it will always return the list of keywords as completion.
        if word_before_cursor:
            if word_before_cursor.endswith(
                    '(') or word_before_cursor.startswith('\\'):
                parsed = sqlparse.parse(text_before_cursor)
            else:
                parsed = sqlparse.parse(
                    text_before_cursor[:-len(word_before_cursor)])

                # word_before_cursor may include a schema qualification, like
                # "schema_name.partial_name" or "schema_name.", so parse it
                # separately
                p = sqlparse.parse(word_before_cursor)[0]

                if p.tokens and isinstance(p.tokens[0], Identifier):
                    identifier = p.tokens[0]
        else:
            parsed = sqlparse.parse(text_before_cursor)
    except (TypeError, AttributeError):
        return [{'type': 'keyword'}]

    if len(parsed) > 1:
        # Multiple statements being edited -- isolate the current one by
        # cumulatively summing statement lengths to find the one that bounds the
        # current position
        current_pos = len(text_before_cursor)
        stmt_start, stmt_end = 0, 0

        for statement in parsed:
            stmt_len = len(str(statement))
            stmt_start, stmt_end = stmt_end, stmt_end + stmt_len

            if stmt_end >= current_pos:
                text_before_cursor = full_text[stmt_start:current_pos]
                full_text = full_text[stmt_start:]
                break

    elif parsed:
        # A single statement
        statement = parsed[0]
    else:
        # The empty string
        statement = None

    # Check for special commands and handle those separately
    if statement:
        # Be careful here because trivial whitespace is parsed as a statement,
        # but the statement won't have a first token
        tok1 = statement.token_first()
        if tok1 and (tok1.value == 'source' or tok1.value.startswith('\\')):
            return suggest_special(text_before_cursor)

    last_token = statement and statement.token_prev(len(statement.tokens))[1] or ''

    return suggest_based_on_last_token(last_token, text_before_cursor,
                                       full_text, identifier)

suggest_type(full_text='SELECT  FROM tabl', text_before_cursor='SELECT ')

'SELECT  FROM tabl'

'SELECT  FROM tabl'

(<Statement 'SELECT ' at 0x7F95D0DD9D60>,)


def get_mylogin_cnf_path():
    """Return the path to the login path file or None if it doesn't exist."""
    mylogin_cnf_path = os.getenv('MYSQL_TEST_LOGIN_FILE')

    if mylogin_cnf_path is None:
        app_data = os.getenv('APPDATA')
        default_dir = os.path.join(app_data, 'MySQL') if app_data else '~'
        mylogin_cnf_path = os.path.join(default_dir, '.mylogin.cnf')

    mylogin_cnf_path = os.path.expanduser(mylogin_cnf_path)

    if exists(mylogin_cnf_path):
        logger.debug("Found login path file at '{0}'".format(mylogin_cnf_path))
        return mylogin_cnf_path
    return None

get_mylogin_cnf_path()


def read_config_file(f, list_values=True):
    """Read a config file.

    *list_values* set to `True` is the default behavior of ConfigObj.
    Disabling it causes values to not be parsed for lists,
    (e.g. 'a,b,c' -> ['a', 'b', 'c']. Additionally, the config values are
    not unquoted. We are disabling list_values when reading MySQL config files
    so we can correctly interpret commas in passwords.

    """

    if isinstance(f, basestring):
        f = os.path.expanduser(f)

    try:
        config = ConfigObj(f, interpolation=False, encoding='utf8',
                           list_values=list_values)
    except ConfigObjError as e:
        log(logger, logging.WARNING, "Unable to parse line {0} of config file "
            "'{1}'.".format(e.line_number, f))
        log(logger, logging.WARNING, "Using successfully parsed config values.")
        return e.config
    except (IOError, OSError) as e:
        log(logger, logging.WARNING, "You don't have permission to read "
            "config file '{0}'.".format(e.filename))
        return None

    return config

read_config_file(f={}, list_values=True)

ConfigObj({'main': {'weather': 'cloudy with a chance of meatballs'}})


def format_uptime(uptime_in_seconds):
    """Format number of seconds into human-readable string.

    :param uptime_in_seconds: The server uptime in seconds.
    :returns: A human-readable string representing the uptime.

    >>> uptime = format_uptime('56892')
    >>> print(uptime)
    15 hours 48 min 12 sec
    """

    m, s = divmod(int(uptime_in_seconds), 60)
    h, m = divmod(m, 60)
    d, h = divmod(h, 24)

    uptime_values = []

    for value, unit in ((d, 'days'), (h, 'hours'), (m, 'min'), (s, 'sec')):
        if value == 0 and not uptime_values:
            # Don't include a value/unit if the unit isn't applicable to
            # the uptime. E.g. don't do 0 days 0 hours 1 min 30 sec.
            continue
        elif value == 1 and unit.endswith('s'):
            # Remove the "s" if the unit is singular.
            unit = unit[:-1]
        uptime_values.append('{0} {1}'.format(value, unit))

    uptime = ' '.join(uptime_values)
    return uptime

format_uptime(uptime_in_seconds=59)


def read_config_files(files, list_values=True):
    """Read and merge a list of config files."""

    config = create_default_config(list_values=list_values)
    _files = copy(files)
    while _files:
        _file = _files.pop(0)
        _config = read_config_file(_file, list_values=list_values)

        # expand includes only if we were able to parse config
        # (otherwise we'll just encounter the same errors again)
        if config is not None:
            _files = get_included_configs(_file) + _files
        if bool(_config) is True:
            config.merge(_config)
            config.filename = _config.filename

    return config

read_config_files(files=['/etc/myclirc', '/home/XXX/.config/mycli/myclirc', '~/.myclirc', '/local/rcs/XXX/code/pytrace-collector/logs/self_collected/tried/dbcli+mycli/dbcli+mycli/.myclirc'], list_values=True)

ConfigObj({'main': {'smart_completion': 'True', 'multi_line': 'False', 'destructive_warning': 'True', 'log_file': '~/.mycli.log', 'log_level': 'INFO', 'timing': 'True', 'beep_after_seconds': '0', 'table_format': 'ascii', 'syntax_style': 'default', 'key_bindings': 'emacs', 'wider_completion_menu': 'False', 'prompt': '\\t \\u@\\h:\\d> ', 'prompt_continuation': '->', 'less_chatty': 'False', 'login_path_as_host': 'False', 'auto_vertical_output': 'False', 'keyword_casing': 'auto', 'enable_pager': 'True', 'pager': 'less'}, 'colors': {'completion-menu.completion.current': 'bg:#ffffff #000000', 'completion-menu.completion': 'bg:#008888 #ffffff', 'completion-menu.meta.completion.current': 'bg:#44aaaa #000000', 'completion-menu.meta.completion': 'bg:#448888 #ffffff', 'completion-menu.multi-column-meta': 'bg:#aaffff #000000', 'scrollbar.arrow': 'bg:#003333', 'scrollbar': 'bg:#00aaaa', 'selected': '#ffffff bg:#6666aa', 'search': '#ffffff bg:#4444aa', 'search.current': '#ffffff bg:#44aa44', 'bottom-toolbar': 'bg:#222222 #aaaaaa', 'bottom-toolbar.off': 'bg:#222222 #888888', 'bottom-toolbar.on': 'bg:#222222 #ffffff', 'search-toolbar': 'noinherit bold', 'search-toolbar.text': 'nobold', 'system-toolbar': 'noinherit bold', 'arg-toolbar': 'noinherit bold', 'arg-toolbar.text': 'nobold', 'bottom-toolbar.transaction.valid': 'bg:#222222 #00ff5f bold', 'bottom-toolbar.transaction.failed': 'bg:#222222 #ff005f bold', 'output.header': '#00ff5f bold', 'output.odd-row': '', 'output.even-row': '', 'output.null': '#808080'}, 'favorite_queries': {}, 'alias_dsn': {}})