<commit_before># :coding: utf-8
# :copyright: Copyright (c) 2013 <NAME>
# :license: See LICENSE.txt.

import re
from collections import defaultdict

from ._version import __version__
from .collection import Collection
from .error import CollectionError


#: Pattern for matching an index with optional padding.
DIGITS_PATTERN = '(?P<index>(?P<padding>0*)\d+)'

#: Common patterns that can be passed to :py:func:`~clique.assemble`.
PATTERNS = {
    'frames': '\.{0}\.\D+\d?$'.format(DIGITS_PATTERN),
    'versions': 'v{0}'.format(DIGITS_PATTERN)
}


def assemble(
    iterable, patterns=None, minimum_items=2, case_sensitive=True,
    assume_padded_when_ambiguous=False
):
    '''Assemble items in *iterable* into discreet collections.

    *patterns* may be specified as a list of regular expressions to limit
    the returned collection possibilities. Use this when interested in
    collections that only match specific patterns. Each pattern must contain
    the expression from :py:data:`DIGITS_PATTERN` exactly once.

    A selection of common expressions are available in :py:data:`PATTERNS`.

    .. note::

        If a pattern is supplied as a string it will be automatically compiled
        to a :py:class:`re.RegexObject` instance for convenience.

    When *patterns* is not specified, collections are formed by examining all
    possible groupings of the items in *iterable* based around common numerical
    components.

    *minimum_items* dictates the minimum number of items a collection must have
    in order to be included in the result. The default is 2, filtering out
    single item collections.

    If *case_sensitive* is False, then items will be treated as part of the same
    collection when they only differ in casing. To avoid ambiguity, the
    resulting collection will always be lowercase. For example, "item.0001.dpx"
    and "Item.0002.dpx" would be part of the same collection, "item.%04d.dpx".

    .. note::

        Any compiled *patterns* will also respect the set case sensitivity.

    For certain collections it may be ambiguous whether they are padded or not.
    For example, 1000-1010 can be considered either an unpadded collection or a
    four padded collection. By default, Clique is conservative and assumes that
    the collection is unpadded. To change this behaviour, set
    assume_padded_when_ambiguous* to True and any ambiguous collection will have
    a relevant padding set.

    .. note::

        *assume_padded_when_ambiguous* has no effect on collections that are
        unambiguous. For example, 1-100 will always be considered unpadded
        regardless of the *assume_padded_when_ambiguous* setting.

    Return tuple of two lists (collections, remainder) where 'collections' is a
    list of assembled :py:class:`~clique.collection.Collection` instances and
    'remainder' is a list of items that did not belong to any collection.

    '''
    collection_map = defaultdict(set)
    collections = []
    remainder = []

    # Compile patterns.
    flags = 0
    if not case_sensitive:
        flags |= re.IGNORECASE
<commit_msg>Fix parameter rendering.<commit_after># :coding: utf-8
# :copyright: Copyright (c) 2013 <NAME>
# :license: See LICENSE.txt.

import re
from collections import defaultdict

from ._version import __version__
from .collection import Collection
from .error import CollectionError


#: Pattern for matching an index with optional padding.
DIGITS_PATTERN = '(?P<index>(?P<padding>0*)\d+)'

#: Common patterns that can be passed to :py:func:`~clique.assemble`.
PATTERNS = {
    'frames': '\.{0}\.\D+\d?$'.format(DIGITS_PATTERN),
    'versions': 'v{0}'.format(DIGITS_PATTERN)
}


def assemble(
    iterable, patterns=None, minimum_items=2, case_sensitive=True,
    assume_padded_when_ambiguous=False
):
    '''Assemble items in *iterable* into discreet collections.

    *patterns* may be specified as a list of regular expressions to limit
    the returned collection possibilities. Use this when interested in
    collections that only match specific patterns. Each pattern must contain
    the expression from :py:data:`DIGITS_PATTERN` exactly once.

    A selection of common expressions are available in :py:data:`PATTERNS`.

    .. note::

        If a pattern is supplied as a string it will be automatically compiled
        to a :py:class:`re.RegexObject` instance for convenience.

    When *patterns* is not specified, collections are formed by examining all
    possible groupings of the items in *iterable* based around common numerical
    components.

    *minimum_items* dictates the minimum number of items a collection must have
    in order to be included in the result. The default is 2, filtering out
    single item collections.

    If *case_sensitive* is False, then items will be treated as part of the same
    collection when they only differ in casing. To avoid ambiguity, the
    resulting collection will always be lowercase. For example, "item.0001.dpx"
    and "Item.0002.dpx" would be part of the same collection, "item.%04d.dpx".

    .. note::

        Any compiled *patterns* will also respect the set case sensitivity.

    For certain collections it may be ambiguous whether they are padded or not.
    For example, 1000-1010 can be considered either an unpadded collection or a
    four padded collection. By default, Clique is conservative and assumes that
    the collection is unpadded. To change this behaviour, set
    *assume_padded_when_ambiguous* to True and any ambiguous collection will have
    a relevant padding set.

    .. note::

        *assume_padded_when_ambiguous* has no effect on collections that are
        unambiguous. For example, 1-100 will always be considered unpadded
        regardless of the *assume_padded_when_ambiguous* setting.

    Return tuple of two lists (collections, remainder) where 'collections' is a
    list of assembled :py:class:`~clique.collection.Collection` instances and
    'remainder' is a list of items that did not belong to any collection.

    '''
    collection_map = defaultdict(set)
    collections = []
    remainder = []

    # Compile patterns.
    flags = 0
    if not case_sensitive:
        flags |= re.IGNORECASE

{'fraction_non_alphanumeric': 0.0724404378622022, 'fraction_numerical': 0.010624597553122988, 'mean_word_length': 3.595414201183432, 'pattern_counts': {'":': 0, '<': 9, '<?xml version=': 0, '>': 9, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1429749', 'n_tokens_mistral': 1769, 'n_tokens_neox': 1649, 'n_words': 726}