From eb75bae801ce8a8920657cac4177c6116dce3407 Mon Sep 17 00:00:00 2001 From: Ben Armstrong Date: Mon, 5 Aug 2024 20:50:19 -0300 Subject: [PATCH] Support sort leaves and children by obs. --- dronefly/core/formatters/generic.py | 71 +++++++++++++++-------------- 1 file changed, 37 insertions(+), 34 deletions(-) diff --git a/dronefly/core/formatters/generic.py b/dronefly/core/formatters/generic.py index 0b6d434..5387b4e 100644 --- a/dronefly/core/formatters/generic.py +++ b/dronefly/core/formatters/generic.py @@ -130,47 +130,46 @@ def replacement(match): return _MARKDOWN_ESCAPE_REGEX.sub(r"\\\1", text) -def taxa_per_rank( - taxon_list: list[Union[Taxon, TaxonCount]], - ranks_to_count: Union[list[str], str], - root_taxon_id: int = None, - sort_by: str = None, - order: str = None, -): - """Generate taxa matching ranks to count in treewise order.""" +def _sort_rank_name(order): + """Generate a sort key in `order` by rank and name.""" - def _sort_rank_name(order): - """Generate a sort key in `order` by rank and name.""" + def reverse_taxon_name(taxon): + reverse_key = functools.cmp_to_key(lambda a, b: (a < b) - (a > b)) + return reverse_key(taxon.name) - def reverse_taxon_name(taxon): - reverse_key = functools.cmp_to_key(lambda a, b: (a < b) - (a > b)) - return reverse_key(taxon.name) + def sort_key(taxon): + taxon_name_key = reverse_taxon_name(taxon) if order == "desc" else taxon.name + return (taxon.rank_level or 0) * -1, taxon_name_key - def sort_key(taxon): - taxon_name_key = ( - reverse_taxon_name(taxon) if order == "desc" else taxon.name - ) - return (taxon.rank_level or 0) * -1, taxon_name_key + return sort_key - return sort_key - def _sort_rank_obs_name(order): - """Generate a sort key in `order` by rank, descendant obs count, and name.""" +def _sort_rank_obs_name(order): + """Generate a sort key in `order` by rank, descendant obs count, and name.""" - def sort_key(taxon): - _order = 1 if order == "asc" else -1 - if getattr(taxon, "descendant_obs_count", None): - obs_count = taxon.descendant_obs_count - else: - obs_count = taxon.observations_count - return ( - (taxon.rank_level or 0) * -1, - obs_count * _order, - taxon.name, - ) + def sort_key(taxon): + _order = 1 if order == "asc" else -1 + if getattr(taxon, "descendant_obs_count", None): + obs_count = taxon.descendant_obs_count + else: + obs_count = taxon.observations_count + return ( + (taxon.rank_level or 0) * -1, + obs_count * _order, + taxon.name, + ) + + return sort_key - return sort_key +def taxa_per_rank( + taxon_list: list[Union[Taxon, TaxonCount]], + ranks_to_count: Union[list[str], str], + root_taxon_id: int = None, + sort_by: str = None, + order: str = None, +): + """Generate taxa matching ranks to count in treewise order.""" include_leaves = False include_ranks = None max_depth = 0 @@ -335,7 +334,11 @@ def filter_taxon_list( for rank in tot } if per_rank in ("leaf", "child"): - counted_taxa.sort(key=lambda t: t.name) + # generate a sort key that uses the specified order: + sort_key = ( + _sort_rank_obs_name(order) if sort_by == "obs" else _sort_rank_name(order) + ) + counted_taxa.sort(key=sort_key) return ( counted_taxa, counted_taxon_ids,