<commit_before>from collections import OrderedDict
from itertools import islice
import operator
import curses

from pick import Picker


def back_pick(_options, prompt="Pick: ", indicator='=>'):
    """Instantiates a picker, registers custom handlers for
    going back, and starts the picker.
    """
    def go_back(picker):
        return None, -1

    picker = Picker(_options, title=prompt, indicator=indicator)
    picker.register_custom_handler(ord('h'), go_back)
    picker.register_custom_handler(curses.KEY_LEFT, go_back)
    return picker.start()


def back_pick_multiple(_options, prompt="Pick multiple: ",
                       indicator='=>', ALL="all", DONE="done..."):
    """Calls `pick` in a while loop to allow user to pick multiple
    options. Returns a list of chosen options.
    """
    _options, options = [ALL] + _options + [DONE], []
    while True:
        option, i = back_pick(_options, '{}{}'.format(prompt, options),
                              indicator=indicator)
        if i < 0: # user went back
            return options, i
        if option == ALL:
            return ([ALL], i)
        if option == DONE:
            return (options, i)
        options.append(option)
        _options.remove(option)


class Condition:
    """Container for condition properties.
    """
    _OPERATORS = {
        '==' : operator.eq,
        '!=' : operator.ne,
        '<=' : operator.le,
        '>=' : operator.ge,
        'in' : lambda x, y: x in y,
        'not in' : lambda x, y: x not in y
        }

    def get_operator(op):
        return Condition._OPERATORS[op]

    def __init__(self, condition):
        self._keys = condition['keys']
        self._vals = condition['vals']
        self._operators = condition['operators'] \
                          if 'operators' in condition \
                          else ['==']*len(self._keys)
        vars = [self._keys, self._vals, self._operators]

        assert all(type(var) == list for var in vars), \
            "All properties must be lists"
        assert all(len(var) == len(vars[0]) for var in vars), \
            "All properties must have the same length"
        assert all(o in Condition._OPERATORS for o in self._operators), \
            "Condition has invalid operator(s)"

    def keys(self):<commit_msg>allow client to specify custom conditions, as lambdas or function, that accept two arguments<commit_after>from collections import OrderedDict
from itertools import islice
import operator
import curses
import inspect

from pick import Picker


def back_pick(_options, prompt="Pick: ", indicator='=>'):
    """Instantiates a picker, registers custom handlers for
    going back, and starts the picker.
    """
    def go_back(picker):
        return None, -1

    picker = Picker(_options, title=prompt, indicator=indicator)
    picker.register_custom_handler(ord('h'), go_back)
    picker.register_custom_handler(curses.KEY_LEFT, go_back)
    return picker.start()


def back_pick_multiple(_options, prompt="Pick multiple: ",
                       indicator='=>', ALL="all", DONE="done..."):
    """Calls `pick` in a while loop to allow user to pick multiple
    options. Returns a list of chosen options.
    """
    _options, options = [ALL] + _options + [DONE], []
    while True:
        option, i = back_pick(_options, '{}{}'.format(prompt, options),
                              indicator=indicator)
        if i < 0: # user went back
            return options, i
        if option == ALL:
            return ([ALL], i)
        if option == DONE:
            return (options, i)
        options.append(option)
        _options.remove(option)


class Condition:
    """Container for condition properties.
    """
    _OPERATORS = {
        '==' : operator.eq,
        '!=' : operator.ne,
        '<=' : operator.le,
        '>=' : operator.ge,
        'in' : lambda x, y: x in y,
        'not in' : lambda x, y: x not in y
        }

    def get_operator(op):
        return Condition._OPERATORS[op] if op in Condition._OPERATORS else op

    def check_operator(op):
        if op in Condition._OPERATORS:
            return True
        try:
            n_args = len(inspect.getargspec(op)[0])
            return n_args == 2
        except:
            return False

    def __init__(self, condition):
        self._keys = condition['keys']
        self._vals = condition['vals']
        self._operators = condition['operators'] \
                          if 'operators' in condition \
                          else ['==']*len(self._keys)
        vars = [self._keys, self._vals, self._operators]

        assert all(type(var) == list for var in vars), \
            "All condition properties must be lists"
        assert all(len(var) == len(vars[0]) for var in vars), \
            "All condition properties must have the same length"
        assert all(Condition.check_operator(op) for op in self._operators), \
            "Condition has invalid operator(s)"

    def keys(self):
{'fraction_non_alphanumeric': 0.11602320464092819, 'fraction_numerical': 0.0016003200640128026, 'mean_word_length': 2.2320620555914674, 'pattern_counts': {'":': 0, '<': 7, '<?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': '631380', 'n_tokens_mistral': 1433, 'n_tokens_neox': 1393, 'n_words': 437}