aboutsummaryrefslogtreecommitdiffstats
path: root/scripts/numspell.py
blob: 9b5979e28ba0950d2dcb9e49ce4b4fbf8dcb0e3c (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
# -*- coding: utf-8 -*-
"""Turns the numbers in a transcription into words, so it can be compared
with the script (which spells everything out)."""
import re

U = ["cero", "uno", "dos", "tres", "cuatro", "cinco", "seis", "siete", "ocho", "nueve",
     "diez", "once", "doce", "trece", "catorce", "quince", "dieciseis", "diecisiete",
     "dieciocho", "diecinueve", "veinte", "veintiuno", "veintidos", "veintitres",
     "veinticuatro", "veinticinco", "veintiseis", "veintisiete", "veintiocho", "veintinueve"]
D = {3: "treinta", 4: "cuarenta", 5: "cincuenta", 6: "sesenta",
     7: "setenta", 8: "ochenta", 9: "noventa"}
C = {1: "ciento", 2: "doscientos", 3: "trescientos", 4: "cuatrocientos", 5: "quinientos",
     6: "seiscientos", 7: "setecientos", 8: "ochocientos", 9: "novecientos"}


def _lt1000(n):
    if n < 30:
        return U[n]
    if n < 100:
        d, u = divmod(n, 10)
        return D[d] + (" y " + U[u] if u else "")
    if n == 100:
        return "cien"
    c, r = divmod(n, 100)
    return C[c] + (" " + _lt1000(r) if r else "")


def spell_int(n):
    if n < 1000:
        return _lt1000(n)
    if n < 1000000:
        m, r = divmod(n, 1000)
        pre_frames = "mil" if m == 1 else _lt1000(m) + " mil"
        return pre_frames + (" " + _lt1000(r) if r else "")
    m, r = divmod(n, 1000000)
    pre_frames = "un millon" if m == 1 else _lt1000(m) + " millones"
    return pre_frames + (" " + spell_int(r) if r else "")


def _tok(m):
    s = m.group(0)
    s = re.sub(r"\.(?=\d{3}\b)", "", s)          # 384.000 -> 384000
    if "," in s:
        a, b = s.split(",", 1)
        whole = spell_int(int(a or 0))
        dec = " ".join(U[int(c)] for c in b if c.isdigit())
        return f"{whole} coma {dec}"
    if "." in s:                                  # 0.5 English style
        a, b = s.split(".", 1)
        return f"{spell_int(int(a or 0))} coma " + " ".join(U[int(c)] for c in b if c.isdigit())
    return spell_int(int(s))


def expand(text):
    t = text.replace("%", " por ciento ").replace("º", "")
    t = re.sub(r"\d+(?:[.,]\d+)*", _tok, t)
    return re.sub(r"\s+", " ", t).strip()