# -*- coding: utf-8 -*- from __future__ import unicode_literals import itertools from .base import Num2Word_Base from .utils import get_digits, splitbyx ZERO = ('zero',) ONES = { 1: ('jeden',), 2: ('dwa',), 3: ('trzy',), 4: ('cztery',), 5: ('pięć',), 6: ('sześć',), 7: ('siedem',), 8: ('osiem',), 9: ('dziewięć',), } ONES_ORDINALS = { 1: ('pierwszy', "pierwszo"), 2: ('drugi', "dwu"), 3: ('trzeci', "trzy"), 4: ('czwarty', "cztero"), 5: ('piąty', "pięcio"), 6: ('szósty', "sześcio"), 7: ('siódmy', "siedmio"), 8: ('ósmy', "ośmio"), 9: ('dziewiąty', "dziewięcio"), 10: ('dziesiąty', "dziesięcio"), 11: ('jedenasty', "jedenasto"), 12: ('dwunasty', "dwunasto"), 13: ('trzynasty', "trzynasto"), 14: ('czternasty', "czternasto"), 15: ('piętnasty', "piętnasto"), 16: ('szesnasty', "szesnasto"), 17: ('siedemnasty', "siedemnasto"), 18: ('osiemnasty', "osiemnasto"), 19: ('dziewiętnasty', "dziewiętnasto"), } TENS = { 0: ('dziesięć',), 1: ('jedenaście',), 2: ('dwanaście',), 3: ('trzynaście',), 4: ('czternaście',), 5: ('piętnaście',), 6: ('szesnaście',), 7: ('siedemnaście',), 8: ('osiemnaście',), 9: ('dziewiętnaście',), } TWENTIES = { 2: ('dwadzieścia',), 3: ('trzydzieści',), 4: ('czterdzieści',), 5: ('pięćdziesiąt',), 6: ('sześćdziesiąt',), 7: ('siedemdziesiąt',), 8: ('osiemdziesiąt',), 9: ('dziewięćdzisiąt',), } TWENTIES_ORDINALS = { 2: ('dwudziesty', "dwudziesto"), 3: ('trzydziesty', "trzydiesto"), 4: ('czterdziesty', "czterdziesto"), 5: ('pięćdziesiąty', "pięćdziesięcio"), 6: ('sześćdziesiąty', "sześćdziesięcio"), 7: ('siedemdziesiąty', "siedemdziesięcio"), 8: ('osiemdziesiąty', "osiemdziesięcio"), 9: ('dziewięćdzisiąty', "dziewięćdziesięcio"), } HUNDREDS = { 1: ('sto',), 2: ('dwieście',), 3: ('trzysta',), 4: ('czterysta',), 5: ('pięćset',), 6: ('sześćset',), 7: ('siedemset',), 8: ('osiemset',), 9: ('dziewięćset',), } HUNDREDS_ORDINALS = { 1: ('setny', "stu"), 2: ('dwusetny', "dwustu"), 3: ('trzysetny', "trzystu"), 4: ('czterysetny', "czterystu"), 5: ('pięćsetny', "pięcset"), 6: ('sześćsetny', "sześćset"), 7: ('siedemsetny', "siedemset"), 8: ('osiemsetny', "ośiemset"), 9: ('dziewięćsetny', "dziewięćset"), } THOUSANDS = { 1: ('tysiąc', 'tysiące', 'tysięcy'), # 10^3 } prefixes_ordinal = { 1: "tysięczny", 2: "milionowy", 3: "milairdowy" } prefixes = ( # 10^(6*x) "mi", # 10^6 "bi", # 10^12 "try", # 10^18 "kwadry", # 10^24 "kwinty", # 10^30 "seksty", # 10^36 "septy", # 10^42 "okty", # 10^48 "nony", # 10^54 "decy" # 10^60 ) suffixes = ("lion", "liard") # 10^x or 10^(x+3) for idx, (p, s) in enumerate(itertools.product(prefixes, suffixes)): name = p + s THOUSANDS[idx+2] = (name, name + 'y', name + 'ów') class Num2Word_PL(Num2Word_Base): CURRENCY_FORMS = { 'PLN': ( ('złoty', 'złote', 'złotych'), ('grosz', 'grosze', 'groszy') ), 'EUR': ( ('euro', 'euro', 'euro'), ('cent', 'centy', 'centów') ), } def setup(self): self.negword = "minus" self.pointword = "przecinek" def to_cardinal(self, number): n = str(number).replace(',', '.') if '.' in n: left, right = n.split('.') leading_zero_count = len(right) - len(right.lstrip('0')) decimal_part = ((ZERO[0] + ' ') * leading_zero_count + self._int2word(int(right))) return u'%s %s %s' % ( self._int2word(int(left)), self.pointword, decimal_part ) else: return self._int2word(int(n)) def pluralize(self, n, forms): if n == 1: form = 0 elif 5 > n % 10 > 1 and (n % 100 < 10 or n % 100 > 20): form = 1 else: form = 2 return forms[form] def last_fragment_to_ordinal(self, last, words, level): n1, n2, n3 = get_digits(last) last_two = n2*10+n1 if last_two == 0: words.append(HUNDREDS_ORDINALS[n3][level]) elif level == 1 and last == 1: return elif last_two < 20: if n3 > 0: words.append(HUNDREDS[n3][level]) words.append(ONES_ORDINALS[last_two][level]) elif last_two % 10 == 0: if n3 > 0: words.append(HUNDREDS[n3][level]) words.append(TWENTIES_ORDINALS[n2][level]) else: if n3 > 0: words.append(HUNDREDS[n3][0]) words.append(TWENTIES_ORDINALS[n2][0]) words.append(ONES_ORDINALS[n1][0]) def to_ordinal(self, number): if number % 1 != 0: raise NotImplementedError() words = [] fragments = list(splitbyx(str(number), 3)) level = 0 last = fragments[-1] while last == 0: level = level+1 fragments.pop() last = fragments[-1] if len(fragments) > 1: pre_part = self._int2word(number-(last*1000**level)) words.append(pre_part) self.last_fragment_to_ordinal(last, words, 0 if level == 0 else 1) output = " ".join(words) if last == 1 and level > 0 and output != "": output = output + " " if level > 0: output = output + prefixes_ordinal[level] return output def _int2word(self, n): if n == 0: return ZERO[0] words = [] chunks = list(splitbyx(str(n), 3)) i = len(chunks) for x in chunks: i -= 1 if x == 0: continue n1, n2, n3 = get_digits(x) if n3 > 0: words.append(HUNDREDS[n3][0]) if n2 > 1: words.append(TWENTIES[n2][0]) if n2 == 1: words.append(TENS[n1][0]) elif n1 > 0 and not (i > 0 and x == 1): words.append(ONES[n1][0]) if i > 0: words.append(self.pluralize(x, THOUSANDS[i])) return ' '.join(words)