Kopiuj
from json import loads as parseJSON
from html.parser import HTMLParser
import locale
import re
import string
import subprocess
import sys
from urllib.request import Request
from urllib.request import urlopen as makeRequest
from urllib.parse import urlencode as encodeURL
class DuckDuckGoAnswerExtractor(HTMLParser):
def __init__(self):
super(DuckDuckGoAnswerExtractor, self).__init__()
self.status = "pre"
self.data = ""
def handle_starttag(self, tag, attrs):
if self.status != "pre": return
if tag != "td": return
attrs = dict(attrs)
if ("class" not in attrs) or (attrs["class"] != "result-snippet"): return
self.status = "in"
def handle_endtag(self, tag):
if self.status != "in": return
if tag != "td": return
self.status = "post"
def handle_data(self, data):
if self.status != "in": return
self.data += data
def get_answer(self):
return self.data
def fetch(url):
req = Request(url)
req.add_header('User-Agent', 'Mozilla/5.0 (X11; Linux x86_64; rv:70.0) Gecko/20100101 Firefox/70.0')
return makeRequest(req).read().decode('utf-8')
def ask_duck_duck_go(question, parse_func=None):
url = 'https://duckduckgo.com/lite?' + encodeURL({"q": question})
extractor = DuckDuckGoAnswerExtractor()
extractor.feed(fetch(url))
answer = extractor.get_answer()
return parse_func(answer) if parse_func is not None else answer
def runProgram(program, inputData):
proc = subprocess.run(args=[program], input=inputData, encoding="utf-8", capture_output=True)
status = proc.returncode
stdout = proc.stdout.split("\n")
stderr = proc.stderr.split("\n")
return status, stdout, stderr
def calculate(mpg, mile_to_km, gallon_to_litres):
code = f"""
scale=2;
mpg={mpg};
mile={mile_to_km};
gallon={gallon_to_litres};
100 / ((mpg * mile) / gallon)
"""
_, out, _ = runProgram("/usr/bin/bc", code)
return out[0]
def number_to_words(number, forms, decimals=False):
if number >= 100:
prefix = number_to_words(number // 100, forms, decimals) + " hundred "
number %= 100
if int(number) == 0:
return prefix + forms[1]
else:
prefix = ""
belowTwenty = [
"zero",
"one",
"two",
"three",
"four",
"five",
"six",
"seven",
"eight",
"nine",
"ten",
"eleven",
"twelve",
"thirteen",
"fourteen",
"fifteen",
"sixteen",
"seventeen",
"eighteen",
"nineteen",
]
if decimals:
sub = int((number * 100) % 100)
if sub == 75:
suffix = " and three quarters " + forms[2]
elif sub == 66:
suffix = " and two thirds " + forms[2]
elif sub == 50:
suffix = " and a half " + forms[2]
elif sub == 33:
suffix = " and a third " + forms[2]
elif sub == 25:
suffix = " and a quarter " + forms[2]
elif sub == 10:
suffix = " and one tenth " + forms[2]
elif sub > 10:
suffix = " and " + belowTwenty[sub // 10] + " tenths " + forms[2]
else:
suffix = ""
else:
suffix = ""
number = int(number)
if number < 20:
if suffix == "":
suffix = " " + forms[0 if number < 2 else 1]
return prefix + belowTwenty[number] + suffix
tens = [
"aughty",
"onety",
"twenty",
"thirty",
"fourty",
"fifty",
"sixty",
"seventy",
"eighty",
"ninety",
]
t = number // 10
s = number % 10
if suffix == "": suffix = " " + forms[1]
if s == 0:
return prefix + tens[t] + suffix
else:
return prefix + tens[t] + "-" + belowTwenty[s] + suffix
def get_user_locale():
lang, encoding = locale.getdefaultlocale()
for delim in ['.', '_']:
dpos = lang.find(delim)
if dpos > 0: lang = lang[:dpos]
return lang
def google_translate(fromLang, toLang, text):
params = encodeURL({
"client": "gtx",
"sl": fromLang,
"tl": toLang,
"dt": "t",
"q": text,
})
url = "https://translate.googleapis.com/translate_a/single?" + params
data = fetch(url)
data = data.replace('\\n', '')
data = data[data.find('[') : ]
data = data[: data.rfind(']')+1]
return parseJSON(data)[0][0][0]
if __name__ == "__main__":
if len(sys.argv) != 2:
print("Usage: mpg-to-lpk MPG\n MPG should be an integer number describing the car's mileage per gallon.", file=sys.stderr)
exit(1)
mpg = int(sys.argv[1])
mile_to_km = ask_duck_duck_go('1 mile to kilometres', lambda x: re.search("([0-9.]*)\s*kilometers", x).group(1) )
gallon_to_litres = ask_duck_duck_go('1 us gallon to litres', lambda x: re.search("([0-9.]*)\s*liters", x).group(1) )
litres_per_100km = calculate(mpg, mile_to_km, gallon_to_litres)
text = "{} to a gallon is {} per one hundred kilometres".format(
number_to_words(mpg, ["mile", "miles", "mile"]),
number_to_words(float(litres_per_100km), ["litre", "litres", "of a litre"], True)
)
text = text.split(" ")
text = string.capwords(text[0]) + " " + " ".join(text[1:]) + "."
lang = get_user_locale()
if lang != "en":
print(google_translate("en", get_user_locale(), text))
else:
print(text)
UglyManPipes