Merge pull request #1413 from forslund/feature/it-time-and-numbers
Add Italian nice_time() and pronounce_number()pull/1407/merge
commit
9e8461b087
|
@ -78,6 +78,9 @@ def nice_time(dt, lang="en-us", speech=True, use_24hour=False,
|
|||
lang_lower = str(lang).lower()
|
||||
if lang_lower.startswith("en"):
|
||||
return nice_time_en(dt, speech, use_24hour, use_ampm)
|
||||
elif lang_lower.startswith("it"):
|
||||
return nice_time_it(dt, speech, use_24hour, use_ampm)
|
||||
|
||||
# TODO: Other languages
|
||||
return str(dt)
|
||||
|
||||
|
@ -96,6 +99,8 @@ def pronounce_number(number, lang="en-us", places=2):
|
|||
lang_lower = str(lang).lower()
|
||||
if lang_lower.startswith("en"):
|
||||
return pronounce_number_en(number, places=places)
|
||||
elif lang_lower.startswith("it"):
|
||||
return pronounce_number_it(number, places=places)
|
||||
|
||||
# Default to just returning the numeric value
|
||||
return str(number)
|
||||
|
|
|
@ -16,6 +16,37 @@
|
|||
#
|
||||
|
||||
|
||||
NUM_STRING_IT = {
|
||||
0: 'zero',
|
||||
1: 'uno',
|
||||
2: 'due',
|
||||
3: 'tre',
|
||||
4: 'quattro',
|
||||
5: 'cinque',
|
||||
6: 'sei',
|
||||
7: 'sette',
|
||||
8: 'otto',
|
||||
9: 'nove',
|
||||
10: 'dieci',
|
||||
11: 'undici',
|
||||
12: 'dodici',
|
||||
13: 'tredici',
|
||||
14: 'quattordici',
|
||||
15: 'quindici',
|
||||
16: 'sedici',
|
||||
17: 'diciassette',
|
||||
18: 'diciotto',
|
||||
19: 'diciannove',
|
||||
20: 'venti',
|
||||
30: 'trenta',
|
||||
40: 'quaranta',
|
||||
50: 'cinquanta',
|
||||
60: 'sessanta',
|
||||
70: 'settanta',
|
||||
80: 'ottanta',
|
||||
90: 'novanta'
|
||||
}
|
||||
|
||||
FRACTION_STRING_IT = {
|
||||
2: 'mezz',
|
||||
3: 'terz',
|
||||
|
@ -39,9 +70,20 @@ FRACTION_STRING_IT = {
|
|||
}
|
||||
|
||||
|
||||
def nice_number_it(result):
|
||||
""" Italian conversion for nice_number """
|
||||
whole, num, den = result
|
||||
def nice_number_it(mixed):
|
||||
"""
|
||||
Helper for for nice_number adapted to italian
|
||||
adapted to italian fron en version
|
||||
|
||||
Convert (1 1 3) to spoken value like "1 e un terzo"
|
||||
|
||||
Args:
|
||||
mixed (int,int,int): the mixed number; whole, numerator, denominator
|
||||
Return:
|
||||
(str): spoken version of the number
|
||||
"""
|
||||
|
||||
whole, num, den = mixed
|
||||
if num == 0:
|
||||
return str(whole)
|
||||
# denominatore
|
||||
|
@ -63,10 +105,156 @@ def nice_number_it(result):
|
|||
# venti e 3 decimi
|
||||
return_string = '{} e {} {}'.format(whole, num, den_str)
|
||||
|
||||
# plurali
|
||||
# gestisce il plurale del denominatore
|
||||
if num > 1:
|
||||
return_string += 'i'
|
||||
else:
|
||||
return_string += 'o'
|
||||
|
||||
return return_string
|
||||
|
||||
|
||||
def pronounce_number_it(num, places=2):
|
||||
"""
|
||||
Convert a number to it's spoken equivalent
|
||||
adapted to italian fron en version
|
||||
|
||||
For example, '5.2' would return 'cinque virgola due'
|
||||
|
||||
Args:
|
||||
num(float or int): the number to pronounce (under 100)
|
||||
places(int): maximum decimal places to speak
|
||||
Returns:
|
||||
(str): The pronounced number
|
||||
"""
|
||||
if abs(num) >= 100:
|
||||
# TODO: Support for numbers over 100
|
||||
return str(num)
|
||||
|
||||
result = ""
|
||||
if num < 0:
|
||||
result = "meno "
|
||||
num = abs(num)
|
||||
|
||||
if num > 20:
|
||||
tens = int(num-int(num) % 10)
|
||||
ones = int(num - tens)
|
||||
result += NUM_STRING_IT[tens]
|
||||
if ones > 0:
|
||||
if ones == 1 or ones == 8:
|
||||
result = result[:-1] # ventuno ventotto
|
||||
result += NUM_STRING_IT[ones]
|
||||
|
||||
else:
|
||||
result += NUM_STRING_IT[int(num)]
|
||||
|
||||
# Deal with fractional part
|
||||
if not num == int(num) and places > 0:
|
||||
result += " virgola"
|
||||
place = 10
|
||||
while int(num*place) % 10 > 0 and places > 0:
|
||||
result += " " + NUM_STRING_IT[int(num*place) % 10]
|
||||
place *= 10
|
||||
places -= 1
|
||||
return result
|
||||
|
||||
|
||||
def nice_time_it(dt, speech=True, use_24hour=False, use_ampm=False):
|
||||
"""
|
||||
Format a time to a comfortable human format
|
||||
adapted to italian fron en version
|
||||
|
||||
For example, generate 'cinque e trenta' for speech or '5:30' for
|
||||
text display.
|
||||
|
||||
Args:
|
||||
dt (datetime): date to format (assumes already in local timezone)
|
||||
speech (bool): format for speech (default/True) or display (False)=Fal
|
||||
use_24hour (bool): output in 24-hour/military or 12-hour format
|
||||
use_ampm (bool): include the am/pm for 12-hour format
|
||||
Returns:
|
||||
(str): The formatted time string
|
||||
"""
|
||||
if use_24hour:
|
||||
# e.g. "03:01" or "14:22"
|
||||
string = dt.strftime("%H:%M")
|
||||
else:
|
||||
if use_ampm:
|
||||
# e.g. "3:01 AM" or "2:22 PM"
|
||||
string = dt.strftime("%I:%M %p")
|
||||
else:
|
||||
# e.g. "3:01" or "2:22"
|
||||
string = dt.strftime("%I:%M")
|
||||
if string[0] == '0':
|
||||
string = string[1:] # strip leading zeros
|
||||
|
||||
if not speech:
|
||||
return string
|
||||
|
||||
# Generate a speakable version of the time
|
||||
if use_24hour:
|
||||
speak = ""
|
||||
# Either "zero 8 zerozero" o "13 zerozero"
|
||||
if string[0:2] == '00':
|
||||
speak += "zerozero"
|
||||
elif string[0] == '0':
|
||||
speak += pronounce_number_it(int(string[0])) + " "
|
||||
if int(string[1]) == 1:
|
||||
speak += "una" # TODO: valutare forma "l'una"
|
||||
else:
|
||||
speak += pronounce_number_it(int(string[1]))
|
||||
else:
|
||||
speak = pronounce_number_it(int(string[0:2]))
|
||||
|
||||
# in italian "13 e 25"
|
||||
speak += " e "
|
||||
|
||||
if string[3:5] == '00':
|
||||
speak += "zerozero"
|
||||
else:
|
||||
if string[3] == '0':
|
||||
speak += pronounce_number_it(0) + " "
|
||||
speak += pronounce_number_it(int(string[4]))
|
||||
else:
|
||||
speak += pronounce_number_it(int(string[3:5]))
|
||||
return speak
|
||||
else:
|
||||
if dt.hour == 0 and dt.minute == 0:
|
||||
return "mezzanotte"
|
||||
if dt.hour == 12 and dt.minute == 0:
|
||||
return "mezzogiorno"
|
||||
# TODO: "10 e un quarto", "4 e tre quarti" and ot her idiomatic times
|
||||
|
||||
if dt.hour == 0:
|
||||
speak = "mezzanotte"
|
||||
elif dt.hour == 1 or dt.hour == 13:
|
||||
speak = "una"
|
||||
elif dt.hour > 13: # era minore
|
||||
speak = pronounce_number_it(dt.hour-12)
|
||||
else:
|
||||
speak = pronounce_number_it(dt.hour-12)
|
||||
|
||||
speak += " e"
|
||||
if dt.minute == 0:
|
||||
speak = speak[:-2]
|
||||
if not use_ampm:
|
||||
speak += " in punto"
|
||||
else:
|
||||
if dt.minute < 10:
|
||||
speak += " zero"
|
||||
speak += " " + pronounce_number_it(dt.minute)
|
||||
|
||||
if use_ampm:
|
||||
|
||||
if dt.hour < 4:
|
||||
speak.strip()
|
||||
elif dt.hour > 12:
|
||||
speak += " del pomeriggio"
|
||||
elif dt.hour > 17:
|
||||
speak += " della sera"
|
||||
elif dt.hour > 20:
|
||||
speak += " della notte"
|
||||
else:
|
||||
speak += " della mattina"
|
||||
|
||||
return speak
|
||||
|
|
|
@ -16,8 +16,11 @@
|
|||
#
|
||||
|
||||
import unittest
|
||||
import datetime
|
||||
|
||||
from mycroft.util.format import nice_number
|
||||
from mycroft.util.format import nice_time
|
||||
from mycroft.util.format import pronounce_number
|
||||
|
||||
NUMBERS_FIXTURE_IT = {
|
||||
1.435634: '1.436',
|
||||
|
@ -60,5 +63,141 @@ class TestNiceNumberFormat(unittest.TestCase):
|
|||
number, lang="it-it")))
|
||||
|
||||
|
||||
# def pronounce_number(number, lang="it-it", places=2):
|
||||
class TestPronounceNumber(unittest.TestCase):
|
||||
def test_convert_int(self):
|
||||
self.assertEqual(pronounce_number(0, lang="it"), "zero")
|
||||
self.assertEqual(pronounce_number(1, lang="it"), "uno")
|
||||
self.assertEqual(pronounce_number(10, lang="it"), "dieci")
|
||||
self.assertEqual(pronounce_number(15, lang="it"), "quindici")
|
||||
self.assertEqual(pronounce_number(21, lang="it"), "ventuno")
|
||||
self.assertEqual(pronounce_number(27, lang="it"), "ventisette")
|
||||
self.assertEqual(pronounce_number(30, lang="it"), "trenta")
|
||||
self.assertEqual(pronounce_number(83, lang="it"), "ottantatre")
|
||||
|
||||
def test_convert_negative_int(self):
|
||||
self.assertEqual(pronounce_number(-1, lang="it"), "meno uno")
|
||||
self.assertEqual(pronounce_number(-10, lang="it"), "meno dieci")
|
||||
self.assertEqual(pronounce_number(-15, lang="it"), "meno quindici")
|
||||
self.assertEqual(pronounce_number(-21, lang="it"), "meno ventuno")
|
||||
self.assertEqual(pronounce_number(-27, lang="it"), "meno ventisette")
|
||||
self.assertEqual(pronounce_number(-30, lang="it"), "meno trenta")
|
||||
self.assertEqual(pronounce_number(-83, lang="it"), "meno ottantatre")
|
||||
|
||||
def test_convert_decimals(self):
|
||||
self.assertEqual(pronounce_number(1.234, lang="it"),
|
||||
"uno virgola due tre")
|
||||
self.assertEqual(pronounce_number(21.234, lang="it"),
|
||||
"ventuno virgola due tre")
|
||||
self.assertEqual(pronounce_number(21.234, lang="it", places=1),
|
||||
"ventuno virgola due")
|
||||
self.assertEqual(pronounce_number(21.234, lang="it", places=0),
|
||||
"ventuno")
|
||||
self.assertEqual(pronounce_number(21.234, lang="it", places=3),
|
||||
"ventuno virgola due tre quattro")
|
||||
self.assertEqual(pronounce_number(21.234, lang="it", places=4),
|
||||
"ventuno virgola due tre quattro")
|
||||
self.assertEqual(pronounce_number(21.234, lang="it", places=5),
|
||||
"ventuno virgola due tre quattro")
|
||||
self.assertEqual(pronounce_number(-21.234, lang="it"),
|
||||
"meno ventuno virgola due tre")
|
||||
self.assertEqual(pronounce_number(-21.234, lang="it", places=1),
|
||||
"meno ventuno virgola due")
|
||||
self.assertEqual(pronounce_number(-21.234, lang="it", places=0),
|
||||
"meno ventuno")
|
||||
self.assertEqual(pronounce_number(-21.234, lang="it", places=3),
|
||||
"meno ventuno virgola due tre quattro")
|
||||
self.assertEqual(pronounce_number(-21.234, lang="it", places=4),
|
||||
"meno ventuno virgola due tre quattro")
|
||||
self.assertEqual(pronounce_number(-21.234, lang="it", places=5),
|
||||
"meno ventuno virgola due tre quattro")
|
||||
|
||||
|
||||
# def nice_time(dt, lang="it-it", speech=True, use_24hour=False,
|
||||
# use_ampm=False):
|
||||
class TestNiceDateFormat(unittest.TestCase):
|
||||
def test_convert_times(self):
|
||||
dt = datetime.datetime(2017, 1, 31,
|
||||
13, 22, 3)
|
||||
|
||||
# Verify defaults haven't changed
|
||||
self.assertEqual(nice_time(dt, lang="it-it"),
|
||||
nice_time(dt, "it-it", True, False, False))
|
||||
|
||||
self.assertEqual(nice_time(dt, lang="it"),
|
||||
"una e ventidue")
|
||||
self.assertEqual(nice_time(dt, lang="it", use_ampm=True),
|
||||
"una e ventidue del pomeriggio")
|
||||
self.assertEqual(nice_time(dt, lang="it", speech=False), "1:22")
|
||||
self.assertEqual(nice_time(dt, lang="it", speech=False,
|
||||
use_ampm=True), "1:22 PM")
|
||||
self.assertEqual(nice_time(dt, lang="it", speech=False,
|
||||
use_24hour=True), "13:22")
|
||||
self.assertEqual(nice_time(dt, lang="it", speech=False,
|
||||
use_24hour=True, use_ampm=True), "13:22")
|
||||
self.assertEqual(nice_time(dt, lang="it", use_24hour=True,
|
||||
use_ampm=True), "tredici e ventidue")
|
||||
self.assertEqual(nice_time(dt, lang="it", use_24hour=True,
|
||||
use_ampm=False), "tredici e ventidue")
|
||||
|
||||
dt = datetime.datetime(2017, 1, 31,
|
||||
13, 0, 3)
|
||||
self.assertEqual(nice_time(dt, lang="it"),
|
||||
"una in punto")
|
||||
self.assertEqual(nice_time(dt, lang="it", use_ampm=True),
|
||||
"una del pomeriggio")
|
||||
self.assertEqual(nice_time(dt, lang="it", speech=False),
|
||||
"1:00")
|
||||
self.assertEqual(nice_time(dt, lang="it", speech=False,
|
||||
use_ampm=True), "1:00 PM")
|
||||
self.assertEqual(nice_time(dt, lang="it", speech=False,
|
||||
use_24hour=True), "13:00")
|
||||
self.assertEqual(nice_time(dt, lang="it", speech=False,
|
||||
use_24hour=True, use_ampm=True), "13:00")
|
||||
self.assertEqual(nice_time(dt, lang="it", use_24hour=True,
|
||||
use_ampm=True), "tredici e zerozero")
|
||||
self.assertEqual(nice_time(dt, lang="it", use_24hour=True,
|
||||
use_ampm=False), "tredici e zerozero")
|
||||
|
||||
dt = datetime.datetime(2017, 1, 31,
|
||||
13, 2, 3)
|
||||
self.assertEqual(nice_time(dt, lang="it", use_24hour=True),
|
||||
"tredici e zero due")
|
||||
self.assertEqual(nice_time(dt, lang="it", use_ampm=True),
|
||||
"una e zero due del pomeriggio")
|
||||
self.assertEqual(nice_time(dt, lang="it", speech=False),
|
||||
"1:02")
|
||||
self.assertEqual(nice_time(dt, lang="it", speech=False,
|
||||
use_ampm=True), "1:02 PM")
|
||||
self.assertEqual(nice_time(dt, lang="it", speech=False,
|
||||
use_24hour=True), "13:02")
|
||||
self.assertEqual(nice_time(dt, lang="it", speech=False,
|
||||
use_24hour=True, use_ampm=True), "13:02")
|
||||
self.assertEqual(nice_time(dt, lang="it", use_24hour=True,
|
||||
use_ampm=True), "tredici e zero due")
|
||||
self.assertEqual(nice_time(dt, lang="it", use_24hour=True,
|
||||
use_ampm=False), "tredici e zero due")
|
||||
|
||||
dt = datetime.datetime(2017, 1, 31,
|
||||
0, 2, 3)
|
||||
self.assertEqual(nice_time(dt, lang="it"),
|
||||
"mezzanotte e zero due")
|
||||
self.assertEqual(nice_time(dt, lang="it", use_ampm=True),
|
||||
"mezzanotte e zero due")
|
||||
self.assertEqual(nice_time(dt, lang="it", speech=False),
|
||||
"12:02")
|
||||
self.assertEqual(nice_time(dt, lang="it", speech=False,
|
||||
use_ampm=True), "12:02 AM")
|
||||
self.assertEqual(nice_time(dt, lang="it", speech=False,
|
||||
use_24hour=True), "00:02")
|
||||
self.assertEqual(nice_time(dt, lang="it", speech=False,
|
||||
use_24hour=True,
|
||||
use_ampm=True), "00:02")
|
||||
self.assertEqual(nice_time(dt, lang="it", use_24hour=True,
|
||||
use_ampm=True), "zerozero e zero due")
|
||||
self.assertEqual(nice_time(dt, lang="it", use_24hour=True,
|
||||
use_ampm=False), "zerozero e zero due")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
|
|
Loading…
Reference in New Issue