Составление предложения / слова во множественном числе на основе значения - PullRequest
0 голосов
/ 03 декабря 2018

Мне интересно, есть ли предпочтительный или, по крайней мере, более читаемый / симпатичный / питонический способ сделать предложение множественным числом на основе вводимых в него данных.

Вот как я это делаюсейчас

ret = f'Done! {deleted} entr{"y was" if deleted == 1 else "ies were"} removed.'

Я знаю, что это работает, но когда я иду и читаю, это не очень хорошо.Я думал либо о создании функции, либо об использовании диктофона (что-то вроде того, что мне нравится), но, может быть, кто-то знает лучший способ.

Решения, которые я пробовал:

с использованием dict

plural = {1:'y was'}
ret = f'Done! {deleted} entr{plural.get(deleted, "ies were")} removed.'

с использованием функции

def plural(num: int):
    return 'y was' if num == 1 else 'ies were'

с использованием логических операторов

ret = f'Done! {deleted} entr{deleted != 1 and "ies were" or "y was"} removed.'

Это действительно единственные другие способы, о которых я могу думать прямо сейчас, которые имеют смысл, и причина, по которой я этого хочу, заключается в том, что у меня есть несколько мест, где мне нужно сделать слова множественными.Проблема в том, что я, возможно, захочу использовать разные формулировки в некоторых местах и ​​хотел бы не повторяться, делая множественное число слов для удобочитаемого формата.

Ответы [ 2 ]

0 голосов
/ 07 декабря 2018

В то время как я нашел @ sophros answer очень знающим и информативным, я решил, что это больше, чем мне нужно.Я решил написать свой собственный класс, так как мне нужно что-то дешевое и простое, которое я могу использовать для разных слов / предложений.Не стесняйтесь использовать себя, если вам это нравится!

class Plural:
    __slots__ = 'word', 'value', 'singular', 'plural', 'zero', 'ignore_negatives'

    def __init__(self, value: int, word: str = "", **kwargs):
        """
        Parameters
        ----------
        value : int
            The determining value
        word : str, optional
            The word to make plural. (defaults to "")
        singular : str, optional
            Appended to `word` if `value` == 1. (defaults to '')
        plural : str, optional
            Appended to `word` if `value` > 1. (defaults to 's')
        zero : str, optional
            Replaces `value` if `value` == 0. (defaults to 0)
        ignore_negatives : bool, optional
            This will raise ValueError if `value` is negative. (defaults to False)
            Set to True if you don't care about negative values.
        """

        self.value, self.word = value, word
        self.singular = kwargs.pop('singular', '')
        self.plural = kwargs.pop('plural', 's')
        self.zero = kwargs.pop('zero', 0)
        self.ignore_negatives = kwargs.pop('ignore_negatives', False)

    def __str__(self):
        v = self.value
        pluralizer = self.plural if abs(v) > 1 else self.singular

        if v < 0 and not self.ignore_negatives:
            raise ValueError

        return f"{v or self.zero} {self.word}{pluralizer}"

Проверьте, что это работает

print(Plural(-2, singular="entry", plural="entries", ignore_negatives = True))
#-2 entries
print(Plural(-1, singular="entry", plural="entries", ignore_negatives = True))
#-1 entry
print(Plural(0, singular="entry", plural="entries"))
#0 entries
print(Plural(1, singular="entry", plural="entries"))
#1 entry
print(Plural(2, singular="entry", plural="entries"))
#2 entries

с отрицательным значением

print(Plural(-1, singular="entry", plural="entries"))
#Traceback (most recent call last):                                                                                            
#File "/home/main.py", line 53, in <module>                                                                                  
#    print(Plural(-1, singular="entry", plural="entries"))                                                                     
#  File "/home/main.py", line 43, in __str__                                                                                   
#    raise ValueError                                                                                                          
#ValueError

Другие варианты использования

print(Plural(1, "entr", singular="y", plural="ies"))
#1 entry
print(Plural(2, "entr", singular="y", plural="ies"))
#2 entries
print(Plural(0, "value", zero="No"))
#No value
print(Plural(1, "value"))
#1 Value
print(Plural(2, "value"))
#2 Values

Если вам просто нужно быстрое и грязное исправление

Либо используйте один из моихПримеры в вопросе или сделать метод, как в моем вопросе, но вот измененная версия как @ Ev.Kounis и @ 9769953 предложено в комментариях (надеюсь, вы не будете против, если я внесу ваши предложения в ответ)

def plural(num: int, word: str = "", single: str = "", mult: str = 's'):
    return f"{num} {(plural, singular)[abs(num) == 1]}"
0 голосов
/ 03 декабря 2018

Может быть, в этом единственном случае (если мы говорим о нескольких отклоняемых строках), тогда таких подходов достаточно.

Но в общем случае локализация (L10N) и интернационализация (I12N) лучше всего обрабатываются с помощьюподходящие библиотеки.

В случае Python у нас есть стандартная библиотека gettext, которую можно использовать для этой цели.По сути, это Python API для GNU gettext , который является отличным вариантом для начала.Существуют дополнительные ресурсы:

  1. Пошаговое руководство Как локализовать скрипт Python.
  2. Более подробное введение в GNUgettext в контексте, если python.
  3. или еще один , если предыдущий вам не подходит.
  4. И, наконец, гораздо более сложный, но всеобъемлющий Руководство по интернационализации python .

Короче говоря, L10N и I12N гораздо больше, чем множественное число ...

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...