Guest User

Reddit Intermediate 90

a guest
Aug 22nd, 2012
78
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 2.86 KB | None | 0 0
  1. #!/usr/bin/python3
  2. # -*- coding: utf-8 -*-
  3.  
  4. unit_names = ('hertz', 'newton', 'pascal', 'joule', 'watt', 'coulomb',
  5.               'volt', 'farady', 'ohm', 'siemens', 'weber', 'tesla', 'henry',
  6.               'lumen', 'lux', 'becquerel', 'gray', 'sievert', 'katal', 'mass', 'velocity', 'celsius')
  7. unit_types = ('s^-1', 'kg m s^-2', 'kg m^-1 s^-2', 'kg m^2 s^-2', 'kg m^2 s^-3', 's A',
  8.               'kg m^2 s^-3 A^-1', 'kg^-1 m^-2 s^4 A^2', 'kg m^2 s^-3 A^-2', 'kg^-1 m^-2 s^3 A^2',
  9.               'kg m^2 s^-2 A^-1', 'kg s^-2 A^-1', 'kg m^2 s^-2 A^-2', 'cd', 'm^-2 cd', 's^-1',
  10.               'm^2 s^-2', 'm^2 s^-2', 's^-1 mol', 'kg', 'm s^-1', 'K')
  11.  
  12. def make_keys():
  13.     assert len(unit_names) == len(unit_types)
  14.     sort = lambda u: ' '.join(sorted(u.split()))
  15.     name_to_unit = {k: v for k, v in zip(unit_names, unit_types)}
  16.     unit_to_name = {k: v for k, v in zip(map(sort, unit_types), unit_names)}
  17.     return name_to_unit, unit_to_name
  18.  
  19. name_to_unit, unit_to_name = make_keys()
  20.  
  21. def count_segment(seg):
  22.     tmp = {}
  23.     if '*' in seg:
  24.         seg = seg.split('*')
  25.     else:
  26.         seg = seg.split()
  27.     for i in seg:
  28.         try:
  29.             b, count = i.split('^')
  30.         except ValueError:
  31.             b = i.split('^')[0]
  32.             count = None
  33.         try:
  34.             t = tmp[b]
  35.         except KeyError:
  36.             t = 0
  37.         if count:
  38.             tmp[b] = int(count) + t
  39.         else:
  40.             tmp[b] = 1 + t
  41.     return tmp
  42.  
  43. def check_name(*args):
  44.     new = []
  45.     for a in args:
  46.         try:
  47.             new.append(name_to_unit[a])
  48.         except KeyError:
  49.             new.append(a)
  50.     return ' '.join(new)
  51.  
  52. def determine_count(i, t):
  53.     if t == 1:
  54.         return i
  55.     elif t:
  56.         return '%s^%d' % (i, t)
  57.     return None
  58.  
  59. def add_others(top, bot):
  60.     t = set(top.keys())
  61.     b = set(bot.keys())
  62.     new = []
  63.     for k in t - b:
  64.         tmp = top[k]
  65.         new.append(determine_count(k, tmp))
  66.     return new
  67.  
  68. def check_units(s):
  69.     tmp = ' '.join(sorted(s.split()))
  70.     if tmp in unit_to_name:
  71.         return s + ' (%s)' % (unit_to_name[tmp])
  72.     return s
  73.  
  74. def translate(exp):
  75.     if '/' in exp:
  76.         top, bottom = exp.split('/')
  77.         top, bottom = check_name(*top.split('*')), check_name(*bottom.split('*'))
  78.         top_c, bot_c = count_segment(top), count_segment(bottom)
  79.         both = set(top_c.keys()) & set(bot_c.keys())
  80.         new = []
  81.         for b in both:
  82.             tmp = top_c[b] - bot_c[b]
  83.             new.append(determine_count(b, tmp))
  84.         new.extend(add_others(top_c, bot_c))
  85.         new.extend(add_others(bot_c, top_c))
  86.  
  87.     else:
  88.         exp = check_name(*exp.split('*'))
  89.         count = count_segment(exp)
  90.         new = []
  91.         for i in count:
  92.             tmp = count[i]
  93.             new.append(determine_count(i, tmp))
  94.  
  95.     return check_units(' '.join(a for a in new if a))
Add Comment
Please, Sign In to add comment