Skip to content

Instantly share code, notes, and snippets.

@dpetukhov
Forked from xfenix/rupluralize.py
Last active September 7, 2023 14:39
Show Gist options
  • Save dpetukhov/cb82a0f4d04f7373293bdf2f491863c8 to your computer and use it in GitHub Desktop.
Save dpetukhov/cb82a0f4d04f7373293bdf2f491863c8 to your computer and use it in GitHub Desktop.
Russian pluralize django template tag
@register.filter(is_safe = False)
@stringfilter
def pluralize(value, forms):
"""
Подбирает окончание существительному после числа
{{someval|pluralize:"товар,товара,товаров"}}
"""
try:
one, two, many = forms.split(u',')
value = str(value)[-2:] # 314 -> 14
if (21 > int(value) > 4):
return many
if value.endswith('1'):
return one
elif value.endswith(('2', '3', '4')):
return two
else:
return many
except (ValueError, TypeError):
return ''
@kstep
Copy link

kstep commented Apr 3, 2020

Не проще ли было взять остаток от деления на 100, а потом на 10 чтобы взять последние 2 и 1 цифры, а не переводить постоянно числа в строки и обратно?

@dpetukhov
Copy link
Author

Думаю да, можно. Много вариантов есть. Мой метод отличается повышенной читаемостью.

А вот тот, о котором вы говорите. Из библиотеки pytils.numeral:

def choose_plural(amount, variants):
    """
    Choose proper case depending on amount

    @param amount: amount of objects
    @type amount: C{integer types}

    @param variants: variants (forms) of object in such form:
        (1 object, 2 objects, 5 objects).
    @type variants: 3-element C{sequence} of C{unicode}
        or C{unicode} (three variants with delimeter ',')

    @return: proper variant
    @rtype: C{unicode}

    @raise ValueError: variants' length lesser than 3
    """
    
    if isinstance(variants, six.text_type):
        variants = split_values(variants)
    check_length(variants, 3)
    amount = abs(amount)
    
    if amount % 10 == 1 and amount % 100 != 11:
        variant = 0
    elif amount % 10 >= 2 and amount % 10 <= 4 and \
         (amount % 100 < 10 or amount % 100 >= 20):
        variant = 1
    else:
        variant = 2
    
    return variants[variant]

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment