Merge pull request #1413 from forslund/feature/it-time-and-numbers

Add Italian nice_time() and pronounce_number()
pull/1407/merge
Åke 2018-02-08 11:23:31 +01:00 committed by GitHub
commit 9e8461b087
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 336 additions and 4 deletions

View File

@ -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)

View File

@ -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

View File

@ -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()