diff --git a/augur/filter/_run.py b/augur/filter/_run.py index cca387f13..928937ca5 100644 --- a/augur/filter/_run.py +++ b/augur/filter/_run.py @@ -17,7 +17,7 @@ from augur.io.file import PANDAS_READ_CSV_OPTIONS, open_file from augur.io.metadata import InvalidDelimiter, Metadata, read_metadata from augur.io.sequences import read_sequences, write_sequences -from augur.io.print import print_err +from augur.io.print import print_err, _n from augur.io.vcf import is_vcf as filename_is_vcf, write_vcf from augur.types import EmptyOutputReportingMethod from . import include_exclude_rules @@ -427,7 +427,7 @@ def run(args): total_strains_passed = len(valid_strains) total_strains_filtered = len(metadata_strains) + num_excluded_by_lack_of_metadata - total_strains_passed - print_err(f"{total_strains_filtered} {'strain was' if total_strains_filtered == 1 else 'strains were'} dropped during filtering") + print_err(f"{total_strains_filtered} {_n('strain was', 'strains were', total_strains_filtered)} dropped during filtering") if num_excluded_by_lack_of_metadata: print_err(f"\t{num_excluded_by_lack_of_metadata} had no metadata") @@ -457,13 +457,13 @@ def run(args): parameters = {} parameters["count"] = count - parameters["were"] = "was" if count == 1 else "were" - parameters["they"] = "it" if count == 1 else "they" + parameters["were"] = _n("was", "were", count) + parameters["they"] = _n("it", "they", count) print_err("\t" + report_template_by_filter_name[filter_name].format(**parameters)) if (group_by and args.sequences_per_group) or args.subsample_max_sequences: seed_txt = ", using seed {}".format(args.subsample_seed) if args.subsample_seed else "" - print_err(f"\t{num_excluded_subsamp} {'was' if num_excluded_subsamp == 1 else 'were'} dropped because of subsampling criteria{seed_txt}") + print_err(f"\t{num_excluded_subsamp} {_n('was', 'were', num_excluded_subsamp)} dropped because of subsampling criteria{seed_txt}") if total_strains_passed == 0: empty_results_message = "All samples have been dropped! Check filter rules and metadata file format." @@ -476,4 +476,4 @@ def run(args): else: raise ValueError(f"Encountered unhandled --empty-output-reporting method {args.empty_output_reporting!r}") - print_err(f"{total_strains_passed} {'strain' if total_strains_passed == 1 else 'strains'} passed all filters") + print_err(f"{total_strains_passed} {_n('strain', 'strains', total_strains_passed)} passed all filters") diff --git a/augur/filter/subsample.py b/augur/filter/subsample.py index 11f2eef86..d73e0102d 100644 --- a/augur/filter/subsample.py +++ b/augur/filter/subsample.py @@ -10,7 +10,7 @@ from augur.dates import get_year_month, get_year_week from augur.errors import AugurError from augur.io.metadata import METADATA_DATE_COLUMN -from augur.io.print import print_err +from augur.io.print import print_err, _n from . import constants from .weights_file import WEIGHTS_COLUMN, COLUMN_VALUE_FOR_DEFAULT_WEIGHT, get_default_weight, get_weighted_columns, read_weights_file @@ -352,8 +352,8 @@ def get_weighted_group_sizes( # Warn on any under-sampled groups for _, row in weights.iterrows(): if row[INPUT_SIZE_COLUMN] < row[TARGET_SIZE_COLUMN]: - sequences = 'sequence' if row[TARGET_SIZE_COLUMN] == 1 else 'sequences' - are = 'is' if row[INPUT_SIZE_COLUMN] == 1 else 'are' + sequences = _n('sequence', 'sequences', row[TARGET_SIZE_COLUMN]) + are = _n('is', 'are', row[INPUT_SIZE_COLUMN]) group = list(f'{col}={value!r}' for col, value in row[group_by].items()) print_err(f"WARNING: Targeted {row[TARGET_SIZE_COLUMN]} {sequences} for group {group} but only {row[INPUT_SIZE_COLUMN]} {are} available.") @@ -411,7 +411,7 @@ def _drop_unused_groups( extra_groups = set(weights.index) - valid_index if extra_groups: count = len(extra_groups) - unit = "group" if count == 1 else "groups" + unit = _n("group", "groups", count) print_err(f"NOTE: Skipping {count} {unit} due to lack of entries in metadata.") weights = weights[weights.index.isin(valid_index)] @@ -427,8 +427,8 @@ def _adjust_weights_for_unweighted_columns( ) -> pd.DataFrame: """Adjust weights for unweighted columns to reflect equal weighting within each weighted group. """ - columns = 'column' if len(unweighted_columns) == 1 else 'columns' - those = 'that' if len(unweighted_columns) == 1 else 'those' + columns = _n('column', 'columns', len(unweighted_columns)) + those = _n('that', 'those', len(unweighted_columns)) print_err(f"NOTE: Weights were not provided for the {columns} {', '.join(repr(col) for col in unweighted_columns)}. Using equal weights across values in {those} {columns}.") weights_grouped = weights.groupby(weighted_columns) diff --git a/augur/io/print.py b/augur/io/print.py index d79f76eca..607379019 100644 --- a/augur/io/print.py +++ b/augur/io/print.py @@ -1,3 +1,4 @@ +import gettext import sys from augur.debug import DEBUGGING @@ -13,3 +14,9 @@ def print_debug(*args): """Print to stderr if in debugging mode.""" if DEBUGGING: print_err(*args) + + +# Use ngettext() without a message catalog for its singular/plural handling so +# we can make proper error messages. gettext() (no "n") is conventionally +# aliased as "_", so alias ngettext() as "_n". +_n = gettext.NullTranslations().ngettext diff --git a/augur/merge.py b/augur/merge.py index a1401a25a..3d735baea 100644 --- a/augur/merge.py +++ b/augur/merge.py @@ -32,7 +32,6 @@ you want to use a version different from what's on PATH), set the SQLITE3 environment variable to path of the desired sqlite3 executable. """ -import gettext import os import re import subprocess @@ -48,19 +47,13 @@ from augur.argparse_ import ExtendOverwriteDefault, SKIP_AUTO_DEFAULT_IN_HELP from augur.errors import AugurError from augur.io.metadata import DEFAULT_DELIMITERS, DEFAULT_ID_COLUMNS, Metadata -from augur.io.print import print_err, print_debug +from augur.io.print import print_err, print_debug, _n from augur.utils import first_line T = TypeVar('T') -# Use ngettext() without a message catalog for its singular/plural handling so -# we can make proper error messages. gettext() (no "n") is conventionally -# aliased as "_", so alias ngettext() as "_n". -_n = gettext.NullTranslations().ngettext - - class NamedMetadata(Metadata): name: str """User-provided descriptive name for this metadata file."""