Skip to content

Instantly share code, notes, and snippets.

@dkgndianko
Last active October 28, 2019 12:01
Show Gist options
  • Select an option

  • Save dkgndianko/7bd2e4a7047cf826da3728ea63e2631b to your computer and use it in GitHub Desktop.

Select an option

Save dkgndianko/7bd2e4a7047cf826da3728ea63e2631b to your computer and use it in GitHub Desktop.

Revisions

  1. dkgndianko revised this gist Oct 28, 2019. 1 changed file with 2 additions and 1 deletion.
    3 changes: 2 additions & 1 deletion repository_method_generator.py
    Original file line number Diff line number Diff line change
    @@ -5,7 +5,8 @@
    OPERATORS_MAPPING = {"=": "=", "lt": "<", "gt": ">", "lte": "<=", "gte": ">=", "not": "!=", "none": "is None",
    "is": "is"}


    # TODO: Add docstrings
    # After first generation, add method to the repository class for further calling.
    def _generate_method(method_name: str) -> Callable:
    zip_iterator = _process_getter(method_name.split("_"))

  2. dkgndianko created this gist Oct 28, 2019.
    69 changes: 69 additions & 0 deletions repository_method_generator.py
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,69 @@
    from typing import List, Callable, Iterator, Tuple

    LOGICAL_SEPARATORS = ["and", "or"]
    OPERATORS = ["lt", "gt", "not", "in", "none"]
    OPERATORS_MAPPING = {"=": "=", "lt": "<", "gt": ">", "lte": "<=", "gte": ">=", "not": "!=", "none": "is None",
    "is": "is"}


    def _generate_method(method_name: str) -> Callable:
    zip_iterator = _process_getter(method_name.split("_"))

    def the_method(*args):
    res = []
    l = len(args)
    it = iter(args)
    for param, operation, logical in zip_iterator:
    try:
    value = next(it)
    if isinstance(value, bool): # we must base on type of param
    operation = "is"
    res.append(f"{param} {OPERATORS_MAPPING[operation]} {value}")
    except StopIteration:
    raise TypeError(f"{method_name} is missing 1 required positional argument: '{param}'")
    return ", ".join(res)

    return the_method


    def _process_getter(parts: List[str]) -> Iterator[Tuple[str, str, str]]:
    current_name = None
    operators = []
    logicals = []
    names = []
    last_logical = None
    operation = None
    for name in parts:
    if not current_name:
    current_name = name
    continue
    if name in OPERATORS:
    operation = name
    elif name in LOGICAL_SEPARATORS:
    operators.append(operation or "=")
    logicals.append(last_logical or "and")
    names.append(current_name)
    last_logical = name
    current_name = None
    else:
    current_name = f"{current_name}_{name}"
    operators.append(operation or "=")
    logicals.append(last_logical or "and")
    names.append(current_name)
    return zip(names, operators, logicals)


    def test():
    methods = {"username_and_password": ("mouhamad", "CTSM@@Ngui"), "value_gt_and_name_not_and_age_lt": (2, "Beep", 63), "last_change_or_password_expired": ("2019-05-21", False), "age_gt_and_is_enabled_and_locked": (18, False, False)}
    # for m in methods:
    # r = _process_getter(m.split("_"))
    # r = [str(e) for e in r]
    # print(f"{m} -> {r}")
    for m, values in methods.items():
    f = _generate_method(m)
    res = f(*values)
    print(f"{m} -> {res}")


    if __name__ == "__main__":
    test()