import re
import dataclasses
TERM_RE = re.compile(r'''([0-9][0-9/]*')?-?([0-9][0-9/]*")?''')
@dataclasses.dataclass
class Dimension:
feet: float
inches: float
@dataclasses.dataclass
class Scale:
drawing: Dimension
actual: Dimension
def parse_scale(S):
if S.count('=') != 1:
raise ValueError('Invalid scale pattern')
left_term, right_term = map(str.strip, S.strip().split('='))
dimensions = []
for term in (left_term, right_term):
feet_s, inches_s = TERM_RE.match(term).groups()
feet_num_den = (feet_s or '').strip("'").split('/')
if len(feet_num_den) == 1:
feet = int(feet_num_den[0] or 0)
elif len(feet_num_den) == 2:
feet = int(feet_num_den[0]) / int(feet_num_den[1])
inches_num_den = (inches_s or '').strip('"').split('/')
if len(inches_num_den) == 1:
inches = int(inches_num_den[0] or 0)
elif len(inches_num_den) == 2:
inches = int(inches_num_den[0]) / int(inches_num_den[1])
dimensions.append(Dimension(feet, inches))
return Scale(*dimensions)
tests = list(filter(None, """
1' = 1'-0"
6" = 1'-0"
3" = 1'-0"
11/2" = 1'-0"
1" = 1'-0"
3/4" = 1'-0"
1/2" = 1'-0"
3/8" = 1'-0"
1/4" = 1'-0"
3/16" = 1'-0"
""".splitlines()))
for test in tests:
scale = parse_scale(test)
print(f'"{test}" -> {scale}')"1' = 1'-0"" -> Scale(drawing=Dimension(feet=1, inches=0), actual=Dimension(feet=1, inches=0)) "6" = 1'-0"" -> Scale(drawing=Dimension(feet=0, inches=6), actual=Dimension(feet=1, inches=0)) "3" = 1'-0"" -> Scale(drawing=Dimension(feet=0, inches=3), actual=Dimension(feet=1, inches=0)) "11/2" = 1'-0"" -> Scale(drawing=Dimension(feet=0, inches=5.5), actual=Dimension(feet=1, inches=0)) "1" = 1'-0"" -> Scale(drawing=Dimension(feet=0, inches=1), actual=Dimension(feet=1, inches=0)) "3/4" = 1'-0"" -> Scale(drawing=Dimension(feet=0, inches=0.75), actual=Dimension(feet=1, inches=0)) "1/2" = 1'-0"" -> Scale(drawing=Dimension(feet=0, inches=0.5), actual=Dimension(feet=1, inches=0)) "3/8" = 1'-0"" -> Scale(drawing=Dimension(feet=0, inches=0.375), actual=Dimension(feet=1, inches=0)) "1/4" = 1'-0"" -> Scale(drawing=Dimension(feet=0, inches=0.25), actual=Dimension(feet=1, inches=0)) "3/16" = 1'-0"" -> Scale(drawing=Dimension(feet=0, inches=0.1875), actual=Dimension(feet=1, inches=0))