-
Notifications
You must be signed in to change notification settings - Fork 0
/
turk_lib.py
95 lines (73 loc) · 3.51 KB
/
turk_lib.py
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
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
import sys, time, re
def print_log(log_string = '',log_to_file=True, noStdOut = True):
LOG_FILENAME = sys.argv[0].split('.')[0] + '.log'
timestamp = time.strftime("%m/%d/%y %H:%M:%S", time.localtime(time.time()))
if not noStdOut: print(f"[ {timestamp} ] {log_string}")
if(log_to_file):
with open(LOG_FILENAME, "a") as file:
file.write(f"[ {timestamp} ] {log_string}\n")
# Precomputed lists
ONES = ["", "one", "two", "three", "four", "five", "six", "seven", "eight", "nine"]
TEENS = ["ten", "eleven", "twelve", "thirteen", "fourteen", "fifteen", "sixteen", "seventeen", "eighteen", "nineteen"]
TENS = ["", "ten", "twenty", "thirty", "forty", "fifty", "sixty", "seventy", "eighty", "ninety"]
TEEN_REPLACEMENTS = {TEENS[i]: ONES[i] for i in range(1, 10)}
def replace_tens_teens_with_ones(input_string: str) -> str:
for teen, replacement in TEEN_REPLACEMENTS.items():
input_string = input_string.replace(teen, replacement)
for i in range(2, 10):
input_string = input_string.replace(TENS[i], ONES[i])
return input_string
def convert_to_words(number) -> str:
if number == 0:
return "zero"
if_negative = 'minus ' if number < 0 else ''
number = abs(number)
def convert_chunk(n):
if n < 10:
return ONES[n]
if n < 20:
return TEENS[n - 10]
if n < 100:
return TENS[n // 10] + (" " + ONES[n % 10] if n % 10 != 0 else "")
return ONES[n // 100] + " hundred" + (" " + convert_chunk(n % 100) if n % 100 != 0 else "")
# Handling large numbers (trillion and above) with direct computation
if number >= 1000000000000:
exponent = len(str(number)) - 1
mantissa = round(number / 10**exponent, 2)
high, low = divmod(int(mantissa * 100), 100)
return f"{if_negative}{convert_chunk(high)}{('' if mantissa == round(mantissa) else ' point ' + convert_chunk(low))} times ten to the power of {convert_chunk(exponent)}"
parts = []
for divisor, name in [(1000000000, "billion"), (1000000, "million"), (1000, "thousand")]:
if number >= divisor:
parts.append(convert_chunk(number // divisor) + " " + name)
number %= divisor
parts.append(convert_chunk(number))
return ' '.join(parts)
def number_to_words(input_str: str) -> str:
# if_negative = 'minus ' if input_str.startswith('-') else ''
# Handle negatives
if input_str.startswith('-'):
if_negative = 'minus '
input_str = input_str.lstrip('-')
else:
# Not negative; handle possible years
if_negative = ''
if ',' not in input_str and '.' not in input_str and len(input_str) == 4:
# Might be a year
year = int(input_str)
if year < 2000 or year > 2009:
return number_to_words(input_str[:2]) + ' ' + number_to_words(input_str[-2:])
parts = input_str.replace(',', '').split('.')
integer_part = int(parts[0])
words = if_negative + convert_to_words(integer_part)
if len(parts) > 1:
decimal_digits = [ONES[int(digit)] if digit != '0' else 'zero' for digit in parts[1]]
words += ' point ' + ' '.join(decimal_digits)
return words
def convert_complete_number_string(number_string: str) -> str:
number_regex = r'(?<!\d)-?\d+(?:,\d{3})*(?:\.\d+)?|\b-?\d*\.\d+\b'
def replace_match(match):
number_value = match.group(0)
return number_to_words(number_value)
return re.sub(number_regex, replace_match, number_string)
# if __name__ == '__main__':