# first line: 50
@memory.cache  # persistent memoïzation
def find_orderings(parameter: str, summed_attribute: str, criterion: tuple[str, ...],
                   length: int,
                   authorized_parameter_values: list[str] =None
                   ) -> list[list[str]]:
    """Gather the list of every ordering returned by queries using given values
    of parameter, summed_attribute, and all given values of criterion.
    Args:
        parameter (str): The value of the parameter attribute in the query generator.
        summed_attribute (str): The attribute that you wan to sum in order to sort the values.
        criterion (tuple[str]): The list of attributes that you want to group the query by.
        length (int): The length of orderings, hence the number of different
                      values of parameter that you consider in the query.
    Returns:
        list[list]: The list of all found orderings.
    """
    # instanciate the query generator
    qg = QUERY_PARAM_GB_FACTORY(parameter=parameter,
                                summed_attribute=summed_attribute,
                                criteria=None)

    if authorized_parameter_values is None:
        # reduce the number of compared parameter values
        qg.authorized_parameter_values = qg.authorized_parameter_values#[:length]
    else:
        qg.authorized_parameter_values = authorized_parameter_values#[:length]

    # ensemble de tous les ordres trouvés
    # la clef est la valeur dans la colonne criteria
    orderings = list()

    for criteria in criterion:
        qg.criteria = criteria
        # if VERBOSE: print(repr(QG))
        table = query(str(qg))
        if VERBOSE:
            print(f"request result with criteria '{criteria}' :")
            tprint(table, limit=10)
        table_orders = odrk.get_all_orderings_from_table(table)
        # pprint(table_orders, compact=True, width=1000)
        # update the global list of all found orders
        orderings.extend(table_orders.values())

    # keep only orders that are of the specified length
    # that means removing too short ones, and slicing too long ones
    correct_length_orderings = np.array(
            [ordrng[:length] for ordrng in orderings if len(ordrng) >= length]
            )

    if VERBOSE:
        print(f"found {len(correct_length_orderings)} orderings :")
        print(correct_length_orderings)
        # tprint(correct_length_orderings)

    return correct_length_orderings
