+def titlecap(words):
+ """Perform English-language title capitalization."""
+ words = words.lower().strip()
+ for separator in [" ", "-", "'"]:
+ newwords = []
+ wordlist = words.split(separator)
+ for word in wordlist:
+ if word:
+ newwords.append(word[0].upper() + word[1:])
+ words = separator.join(newwords)
+ end = len(words)
+ for prefix in ["Mac", "Mc"]:
+ position = 0
+ offset = len(prefix)
+ while position < end:
+ position = words.find(prefix, position)
+ if position == -1:
+ position = end
+ position += offset
+ import string
+ if position < end and words[position] in string.letters:
+ words = words[:position] \
+ + words[position].upper() \
+ + words[position+1:]
+ return words
+
+def filter_units(line, units="imperial"):
+ """Filter or convert units in a line of text between US/UK and metric."""
+ import re
+ # filter lines with both pressures in the form of "X inches (Y hPa)" or
+ # "X in. Hg (Y hPa)"
+ dual_p = re.match(
+ "(.* )(\d*(\.\d+)? (inches|in\. Hg)) \((\d*(\.\d+)? hPa)\)(.*)",
+ line
+ )
+ if dual_p:
+ preamble, in_hg, i_fr, i_un, hpa, h_fr, trailer = dual_p.groups()
+ if units == "imperial": line = preamble + in_hg + trailer
+ elif units == "metric": line = preamble + hpa + trailer
+ # filter lines with both temperatures in the form of "X F (Y C)"
+ dual_t = re.match(
+ "(.* )(\d*(\.\d+)? F) \((\d*(\.\d+)? C)\)(.*)",
+ line
+ )
+ if dual_t:
+ preamble, fahrenheit, f_fr, celsius, c_fr, trailer = dual_t.groups()
+ if units == "imperial": line = preamble + fahrenheit + trailer
+ elif units == "metric": line = preamble + celsius + trailer
+ # if metric is desired, convert distances in the form of "X mile(s)" to
+ # "Y kilometer(s)"
+ if units == "metric":
+ imperial_d = re.match(
+ "(.* )(\d+)( mile\(s\))(.*)",
+ line
+ )
+ if imperial_d:
+ preamble, mi, m_u, trailer = imperial_d.groups()
+ line = preamble + str(int(round(int(mi)*1.609344))) \
+ + " kilometer(s)" + trailer
+ # filter speeds in the form of "X MPH (Y KT)" to just "X MPH"; if metric is
+ # desired, convert to "Z KPH"
+ imperial_s = re.match(
+ "(.* )(\d+)( MPH)( \(\d+ KT\))(.*)",
+ line
+ )
+ if imperial_s:
+ preamble, mph, m_u, kt, trailer = imperial_s.groups()
+ if units == "imperial": line = preamble + mph + m_u + trailer
+ elif units == "metric":
+ line = preamble + str(int(round(int(mph)*1.609344))) + " KPH" + \
+ trailer
+ # if imperial is desired, qualify given forcast temperatures like "X F"; if
+ # metric is desired, convert to "Y C"
+ imperial_t = re.match(
+ "(.* )(High |high |Low |low )(\d+)(\.|,)(.*)",
+ line
+ )
+ if imperial_t:
+ preamble, parameter, fahrenheit, sep, trailer = imperial_t.groups()
+ if units == "imperial":
+ line = preamble + parameter + fahrenheit + " F" + sep + trailer
+ elif units == "metric":
+ line = preamble + parameter \
+ + str(int(round((int(fahrenheit)-32)*5/9))) + " C" + sep + trailer
+ # hand off the resulting line
+ return line
+