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 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 1177 1178 1179 1180 1181 1182 1183 1184 1185 1186 1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 1203 1204 1205 1206 1207 1208 1209 1210 1211 1212 1213 1214 1215 1216 1217 1218 1219 1220 1221 1222 1223 1224 1225 1226 1227 1228 1229 1230 1231 1232 1233 1234 1235 1236 1237 1238 1239 1240 1241 1242 1243 1244 1245 1246 1247 1248 1249 1250 1251 1252 1253 1254 1255 1256 1257 1258 1259 1260 1261 1262 1263 1264 1265 1266 1267 1268 1269 1270 1271 1272 1273 1274 1275 1276 1277 1278 1279 1280 1281 1282 1283 1284 1285
|
#****************************************************************************
# This file has been modified from its original version. It has been
# formatted to fit your irc bot.
#
# The original version is a nifty PyQt application written by Douglas Bell,
# available at http://convertall.bellz.org/
#
# Below is the original copyright. Doug Bell rocks.
# The hijacker is Keith Jones, and he has no bomb in his shoe.
#
#****************************************************************************
import re
import copy
unitData = \
"""
#*****************************************************************************
#units.dat, the units data file, version 0.6.2
#
# ConvertAll, a units conversion program
# Copyright (C) 2016, Douglas W. Bell
#
# This is free software; you can redistribute it and/or modify it under the
# terms of the GNU General Public License, Version 2. This program is
# distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY.
#*****************************************************************************
#
# Units are defined by an optional quantity and an equivalent unit or unit
# combination. A Python expression may be used for the quantity, but is
# restricted to using only the following operators: *, /, +, -.
# Beware of integer division truncation: be sure to use a float for at least
# one of the values.
#
# The unit type must be placed in square brackets before a set of units. The
# first comment after the equivalent unit will be put in parenthesis after the
# unit name (usually used to give the full name of an abbreviated unit). The
# next comment will be used in the program list's comment column; later
# comments and full line comments are ignored.
#
# Non-linear units are indicated with an equivalent unit in square brackets,
# followed by either equations or equivalency lists for the definition. For
# equations, two are given, separated by a ';'. Both are functions of "x", the
# first going from the unit to the equivalent unit and the second one in
# reverse. Any valid Python expression returning a float (including the
# functions in the math module) should work. The equivalency list is a Python
# list of tuples giving points for linear interpolation.
#
# All units must reduce to primitive units, which are indicated by an
# equivalent unit starting with '!'. A special "unitless" primitve unit
# (usualty called "unit") has '!!' for an equivalent unit. Circular references
# must also be avoided.
#
# Primitive units: kg, m, s, K, A, mol, cd, rad, sr, bit, unit
#
##############################################################################
#
# mass units
#
[mass]
kg = ! # kilogram
kilogram = kg
key = kg # # drug slang
hectogram = 100 gram
dekagram = 10 gram
gram = 0.001 kg
g = gram # gram
decigram = 0.1 gram
centigram = 0.01 gram
milligram = 0.001 gram
mg = milligram # milligram
microgram = 0.001 mg
tonne = 1000 kg # # metric
metric ton = tonne
megagram = tonne
kilotonne = 1000 tonne # # metric
gigagram = 1e9 gram
teragram = 1e12 gram
carat = 0.2 gram
ct = carat # carat
amu = 1.66053873e-27 kg # atomic mass
atomic mass unit = amu
pound = 0.45359237 kg # # avoirdupois
lb = pound # pound # avoirdupois
lbm = pound # pound # avoirdupois
ounce = 1/16.0 pound # # avoirdupois
oz = ounce # ounce # avoirdupois
lid = ounce # # drug slang
dram = 1/16.0 ounce # # avoirdupois
pound troy = 5760 grain
lb troy = pound troy # pound troy
ounce troy = 1/12.0 lb troy
oz troy = ounce troy # ounce troy
ton = 2000 lb # # non-metric
kiloton = 1000 ton # # non-metric
long ton = 2240 lb # # Imperial
ton imperial = long ton
slug = lbf*s^2/ft
stone = 14 lb
grain = 1/7000.0 lb
pennyweight = 24 grain
hundredweight long = 112 lb # # Imperial
hundredweight short = 100 lb # # US & Canada
solar mass = 1.9891e30 kg
#
# length / distance units
#
[length]
m = ! # meter
meter = m
metre = m
dm = 0.1 m # decimeter
decimeter = dm
cm = 0.01 m # centimeter
centimeter = cm
mm = 0.001 m # millimeter
millimeter = mm
micrometer = 1e-6 m
micron = micrometer
nanometer = 1e-9 m
nm = nanometer # nanometer
dekameter = 10 m
hectometer = 100 m
km = 1000 m # kilometer
kilometer = km
megameter = 1000 km
angstrom = 1e-10 m
fermi = 1e-15 m # # nuclear sizes
inch = 2.54 cm
in = inch # inch
inches = inch
mil = 0.001 inch
microinch = 1e-6 inch
microinches = microinch
foot = 12 inch
ft = foot # foot
feet = foot
foot US survey = 1200/3937.0 m
Cape foot = 1.033 foot
yard = 3 ft
yd = yard # yard
mile = 5280 ft # # statute mile
mi = mile # mile # statute mile
nautical mile = 1852 m
nmi = nautical mile # nautical mile
mile US survey = 5280 foot US survey
league = 3 mile
chain = 66 ft
chain US survey = 66 foot US survey
link = 0.01 chain
fathom = 6 ft
cable = 0.1 nautical mile
rod = 5.5 yard
furlong = 40 rod
hand = 4 inch
cubit = 21.8 inch # # biblical unit
point = 1/72.0 inch # # desktop publishing point
pica = 12 point
caliber = 1.0 inch # # bullet sizes
rack unit = 1.75 in # # computing
smoot = 67 inch
football field = 100 yd
marathon = 46145 yd
mil Swedish = 10 km
versta = 3500 ft # # Russian unit
au = 1.49597870691e11 m # astronomical unit
astronomical unit = au
LD = 384400 km # lunar distance # astronomical
lunar distance = LD # # astronomical distance
light year = 365.25 light speed * day
light minute = light speed * min
light second = light speed * s
parsec = 3.0856775813e16 m
kiloparsec = 1000 parsec
megaparsec = 1000 kiloparsec
screw size = [in] 0.013*x + 0.06 ; (x - 0.06) / 0.013 \
# # Unified diameters, non-linear
AWG Dia = [in] pow(92.0,(36-x)/39.0)/200.0 ; \
36 - 39.0*log(200.0*x)/log(92.0) \
# American Wire Gauge \
# use -1, -2 for 00, 000; non-linear
American Wire Gauge Dia = [in] pow(92.0,(36-x)/39.0)/200.0 ; \
36 - 39.0*log(200.0*x)/log(92.0) \
# # use -1, -2 for 00, 000; non-linear
British Std Wire Gauge = [in] [(-6, .500), (-5, .464), (-3, .400), \
(-2, .372), (3, .252), (6, .192), (10, .128), \
(14, .080), (19, .040), (23, .024), (26, .018), \
(28, .0148), (30, .0124), (39, .0052), \
(49, .0012), (50, .001)] \
# # use -1, -2 for 2/0, 3/0; non-linear
standard gauge = [in] [(-5, .448350), (1, .269010), (14, .0747250), \
(16, .0597800), (17, .0538020), (20, .0358680), \
(26, .0179340), (31, .0104615), (36, .00672525), \
(38, .00597800)] # steel \
# Manufacturers Std. Gauge, non-linear
zinc gauge = [in] [(1, .002), (10, .02), (15, .04), (19, .06), \
(23, .1), (24, .125), (27, .5), (28, 1)] \
# # sheet metal thickness, non-linear
ring size = [in] 0.1018*x + 1.4216 ; (x - 1.4216) / 0.1018 \
# # US size, circum., non-linear
shoe size mens = [in] x/3.0 + 7 + 1/3.0 ; (x - 7 - 1/3.0) * 3 \
# # US sizes, non-linear
shoe size womens = [in] x/3.0 + 6 + 5/6.0 ; (x - 6 - 5/6.0) * 3 \
# # US sizes, non-linear
#
# time units
#
[time]
s = ! # second
sec = s # second
second = s
ms = 0.001 s # millisecond
millisecond = ms
microsecond = 1e-6 s
ns = 1e-9 s # nanosecond
nanosecond = ns
minute = 60 s
min = minute # minute
hour = 60 min
hr = hour # hour
bell = 30 min # # naval definition
watch = 4 hour
watches = watch
day = 24 hr
week = 7 day
wk = week # week
fortnight = 14 day
month = 1/12.0 year
year = 365.242198781 day
yr = year # year
calendar year = 365 day
decade = 10 year
century = 100 year
centuries = century
millennium = 1000 year
millennia = millennium
[scheduling]
man hour = 168/40.0 hour
man week = 40 man hour
man month = 1/12.0 man year
man year = 52 man week
#
# temperature
#
[temperature]
K = ! # Kelvin
Kelvin = K
deg K = K # Kelvin
degree Kelvin = K
C = [K] x + 273.15 ; x - 273.15 # Celsius # non-linear
Celsius = [K] x + 273.15 ; x - 273.15 # # non-linear
deg C = [K] x + 273.15 ; x - 273.15 # Celsius # non-linear
degree Celsius = [K] x + 273.15 ; x - 273.15 # # non-linear
R = 5/9.0 K # Rankine
Rankine = R
deg R = R # Rankine
F = [R] x + 459.67 ; x - 459.67 # Fahrenheit # non-linear
Fahrenheit = [R] x + 459.67 ; x - 459.67 # # non-linear
deg F = [R] x + 459.67 ; x - 459.67 # Fahrenheit # non-linear
degree Fahrenheit = [R] x + 459.67 ; x - 459.67 # # non-linear
[temp. diff.]
C deg = K # Celsius degree
Celsius degree = C deg
F deg = R # Fahrenheit deg.
Fahrenheit degree = F deg
#
# electrical units
#
[current]
A = ! # ampere
ampere = A
amp = A
milliampere = 0.001 A
milliamp = milliampere
mA = milliampere # milliampere
microampere = 0.001 mA
kiloampere = 1000 A
kA = kiloampere # kiloampere
[charge]
coulomb = A*s
amp hour = A*hr
mAh = 0.001 amp hour # milliamp hour
milliamp hour = mAh
[potential]
volt = W/A
V = volt # volt
millivolt = 0.001 volt
mV = millivolt # millivolt
kilovolt = 1000 volt
kV = kilovolt # kilovolt
[resistance]
ohm = V/A
milliohm = 0.001 ohm
microhm = 0.001 milliohm
kilohm = 1000 ohm
[conductance]
siemens = A/V
[capacitance]
farad = coulomb/V
millifarad = 0.001 farad
microfarad = 0.001 millifarad
nanofarad = 1e-9 farad
picofarad = 1e-12 farad
[magn. flux]
weber = V*s
Wb = weber # weber
maxwell = 1e-8 Wb
[inductance]
henry = Wb/A
H = henry # henry
millihenry = 0.001 henry
mH = millihenry # millihenry
microhenry = 0.001 mH
[flux density]
tesla = Wb/m^2
T = tesla # tesla
gauss = maxwell/cm^2
#
# molecular units
#
[molecular qty]
mol = ! # mole # gram mole
mole = mol # # gram mole
gram mole = mol
kilomole = 1000 mol
kmol = kilomole # kilomole
pound mole = mol*lbm/gram
lbmol = pound mole # pound mole
[size of a mol]
avogadro = gram/(amu*mol)
#
# Illumination units
#
[lum. intens.]
cd = ! # candela
candela = cd
[luminous flux]
lumen = cd * sr
lm = lumen # lumen
[illuminance]
lux = lumen/m^2
footcandle = lumen/ft^2
metercandle = lumen/m^2
[luminance]
lambert = cd/(pi*cm^2)
millilambert = 0.001 lambert
footlambert = cd/(pi*ft^2)
#
# angular units
#
[angle]
radian = !
rad = radian # radian
circle = 2 pi*radian
turn = circle
revolution = circle
rev = revolution # revolution
degree = 1/360.0 circle
deg = degree # degree
arc min = 1/60.0 degree # minute
arc minute = arc min
min arc = arc min # minute
minute arc = arc min
arc sec = 1/60.0 arc min # second
arc second = arc sec
sec arc = arc sec # second
second arc = arc sec
quadrant = 1/4.0 circle
right angle = quadrant
gradian = 0.01 quadrant
#
# solid angle units
#
[solid angle]
sr = ! # steradian
steradian = sr
sphere = 4 pi*sr
hemisphere = 1/2.0 sphere
#
# information units
#
[data]
bit = !
kilobit = 1000 bit # # based on power of 10
megabit = 1000 kilobit # # based on power of 10
byte = 8 bit
B = byte # byte
kilobyte = 1024 byte # # based on power of 2
kB = kilobyte # kilobyte # based on power of 2
megabyte = 1024 kB # # based on power of 2
MB = megabyte # megabyte # based on power of 2
gigabyte = 1024 MB # # based on power of 2
GB = gigabyte # gigabyte # based on power of 2
terabyte = 1024 GB # # based on power of 2
TB = terabyte # terabyte # based on power of 2
petabyte = 1024 TB # # based on power of 2
PB = petabyte # petabyte # based on power of 2
kilobyte IEC std = 1000 byte # # based on power of 10
kB IEC std = kilobyte IEC std # kilobyte # based on power of 10
megabyte IEC std = 1000 kB IEC std # # based on power of 10
MB IEC std = megabyte IEC std # megabyte # based on power of 10
gigabyte IEC std = 1000 MB IEC std # # based on power of 10
GB IEC std = gigabyte IEC std # gigabyte # based on power of 10
terabyte IEC std = 1000 GB IEC std # # based on power of 10
TB IEC std = terabyte IEC std # terabyte # based on power of 10
petabyte IEC std = 1000 TB IEC std # # based on power of 10
PB IEC std = petabyte IEC std # petabyte # based on power of 10
kibibyte = 1024 byte
KiB = kibibyte # kibibyte
mebibyte = 1024 KiB
MiB = mebibyte # mebibyte
gibibyte = 1024 MiB
GiB = gibibyte # gibibyte
tebibyte = 1024 GiB
TiB = tebibyte # tebibyte
pebibyte = 1024 TiB
PiB = pebibyte # pebibyte
[data transfer]
bps = bit/sec # bits / second
kbps = 1000 bps # kilobits / sec. # based on power of 10
#
# Unitless numbers
#
[quantity]
unit = !!
1 = unit # unit
pi = 3.14159265358979323846 unit
pair = 2 unit
hat trick = 3 unit # # sports
dozen = 12 unit
doz = dozen # dozen
bakers dozen = 13 unit
score = 20 unit
gross = 144 unit
great gross = 12 gross
ream = 500 unit
percent = 0.01 unit
% = percent
mill = 0.001 unit
[interest rate]
APR = [unit] log(1 + x/100) ; (exp(x) - 1)*100 \
# annual % rate # based on continuous compounding
[concentration]
proof = 1/200.0 unit # # alcohol content
ppm = 1e-6 unit # parts per million
parts per million = ppm
ppb = 1e-9 unit # parts per billion
parts per billion = ppb
ppt = 1e-12 unit # parts per trillion
parts per trillion = ppt
karat = 1/24.0 unit # # gold purity
carat gold = karat # # gold purity
#
# force units
#
[force]
newton = kg*m/s^2
N = newton # newton
dekanewton = 10 newton
kilonewton = 1000 N
kN = kilonewton # kilonewton
meganewton = 1000 kN
millinewton = 0.001 N
dyne = cm*g/s^2
kg force = kg * gravity # kilogram f
kgf = kg force # kilogram force
kilogram force = kg force
kp = kg force # kilopond
kilopond = kg force
gram force = g * gravity
pound force = lbm * gravity # # avoirdupois
lbf = pound force # pound force # avoirdupois
ton force = ton * gravity
ounce force = ounce * gravity
ozf = ounce force # ounce force
tonne force = tonne * gravity # # metric
pdl = lbm * ft / sec^2 # poundal # Imperial force
poundal = pdl # # Imperial force
#
# area units
#
[area]
barn = 1e-28 m^2 # # particle physics
are = 100 m^2
decare = 10 are
dekare = 10 are
hectare = 100 are
stremma = 1000 m^2
acre = 10 chain^2
section = mile^2
township = 36 section
homestead = 160 acre
square perch = 30.25 yd^2
rood = 0.25 acre
rai = 1600 m^2 # # Thai
ngaan = 400 m^2 # # Thai
circular inch = 1/4.0 pi*in^2 # # area of 1 inch circle
circular mil = 1/4.0 pi*mil^2 # # area of 1 mil circle
AWG Area = [in^2] pi/4*pow(pow(92.0,(36-x)/39.0)/200.0,2) ; \
36 - 39.0*log(200.0*sqrt(x*4.0/pi))/log(92.0) \
# American Wire Gauge \
# use -1, -2 for 00, 000; non-linear
American Wire Gauge Area = [in^2] pi/4*pow(pow(92.0,(36-x)/39.0)/200.0,2) ; \
36 - 39.0*log(200.0*sqrt(x*4.0/pi))/log(92.0) \
# # use -1, -2 for 00, 000; non-linear
#
# volume units
#
[volume]
cc = cm^3 # cubic centimeter
cubic centimeter = cc
liter = 1000 cc
l = liter # liter
litre = liter
deciliter = 0.1 liter
centiliter = 0.01 liter
milliliter = cc
ml = milliliter # milliliter
microliter = 1e-6 liter
dekaliter = 10 liter
hectoliter = 100 liter
kiloliter = 1000 liter
kl = kiloliter # kiloliter
megaliter = 1000 kiloliter
gallon = 231 in^3 # # US liquid
gal = gallon # gallon # US liquid
quart = 1/4.0 gallon # # US liquid
qt = quart # quart # US liquid
pint = 1/2.0 quart # # US liquid
pt = pint # pint # US liquid
fluid ounce = 1/16.0 pint # # US
fl oz = fluid ounce # fluid ounce # US
ounce fluid = fluid ounce # # US
fluid dram = 1/8.0 fluid ounce # # US
minim = 1/480.0 fluid ounce # # US
imperial gallon = 4.54609 liter
imp gal = imperial gallon # imperial gallon
gallon imperial = imperial gallon
imperial quart = 1/4.0 imp gal
imp qt = imperial quart # imperial quart
quart imperial = imperial quart
imperial pint = 1/8.0 imp gal
imp pt = imperial pint # imperial pint
pint imperial = imperial pint
imperial fluid ounce = 1/160.0 imp gal
imp fl oz = imperial fluid ounce # imperial fluid ounce
imperial fluid dram = 1/8.0 imp fl oz
imperial minim = 1/480.0 imp fl oz
cup = 8 fl oz
tablespoon = 1/16.0 cup
tbsp = tablespoon # tablespoon
teaspoon = 1/3.0 tbsp
tsp = teaspoon # teaspoon
barrel = 42 gallon
bbl = barrel # barrel
shot = 1.5 fl oz
fifth = 1/5.0 gallon # # alcohol
wine bottle = 750 ml
magnum = 1.5 liter # # alcohol
keg = 15.5 gallon # # beer
hogshead wine = 63 gal
hogshead beer = 54 gal
bushel = 2150.42 in^3
peck = 1/4.0 bushel
cord = 128 ft^3
board foot = ft^2*in
board feet = board foot
#
# velocity units
#
[velocity]
knot = nmi/hr
kt = knot # knot
light speed = 2.99792458e8 m/s
mph = mi/hr # miles/hour
kph = km/hr # kilometers/hour
mach = 340.29 m/s # # speed sound at STP
[rot. velocity]
rpm = rev/min # rev/min
rps = rev/sec # rev/sec
#
# flow rate units
#
[fluid flow]
gph = gal/hr # gallons/hour
gpm = gal/min # gallons/minute
cfs = ft^3/sec # cu ft/second
cfm = ft^3/min # cu ft/minute
lpm = l/min # liter/min
[gas flow]
sccm = atm*cc/min # std cc/min # pressure * flow
sccs = atm*cc/sec # std cc/sec # pressure * flow
slpm = atm*l/min # std liter/min # pressure * flow
slph = atm*l/hr # std liter/hour # pressure * flow
scfh = atm*ft^3/hour # std cu ft/hour # pressure * flow
scfm = atm*ft^3/min # std cu ft/min # pressure * flow
#
# pressure units
#
[pressure]
Pa = N/m^2 # pascal
pascal = Pa
hPa = 100 Pa # hectopascal
hectopascal = hPa
kPa = 1000 Pa # kilopascal
kilopascal = kPa
MPa = 1000 kPa # megapascal
megapascal = MPa
GPa = 1000 MPa # gigapascal
gigapascal = GPa
atm = 101325 Pa # atmosphere
atmosphere = atm
bar = 1e5 Pa
mbar = 0.001 bar # millibar
millibar = mbar
microbar = 0.001 mbar
decibar = 0.1 bar
kilobar = 1000 bar
megabar = 1000 kilobar
mm Hg = mm*density Hg*gravity
millimeter of Hg = mm Hg
torr = mm Hg
micron of Hg = micron*density Hg*gravity
in Hg = in*density Hg*gravity # inch of Hg
inch of Hg = in Hg
m water = m*density water*gravity # meter of H2O # fresh water
m H2O = m water # meter of H2O # fresh water
meter of water = m water # # fresh water
in water = in*density water*gravity # inch of H2O # fresh water
in H2O = in water # inch of H2O # fresh water
inch of water = in water # # fresh water
ft water = ft*density water*gravity # feet of H2O # fresh water
ft H2O = ft water # feet of H20 # fresh water
feet of water = ft water # # fresh water
foot of head = ft water # # fresh water
ft hd = ft water # foot of head # fresh water
psi = lbf/in^2 # pound / sq inch
pound per sq inch = psi
ksi = 1000 psi # 1000 lb / sq inch
#
# density units
#
[density]
density water = gram/cm^3
density sea water = 1.025 gram/cm^3
density Hg = 13.5950981 gram/cm^3
density air = 1.293 kg/m^3 # # at STP
density steel = 0.283 lb/in^3 # # carbon steel
density aluminum = 0.098 lb/in^3
density zinc = 0.230 lb/in^3
density brass = 0.310 lb/in^3 # # 80Cu-20Zn
density copper = 0.295 lb/in^3
density iron = 0.260 lb/in^3 # # cast iron
density nickel = 0.308 lb/in^3
density tin = 0.275 lb/in^3
density titanium = 0.170 lb/in^3
density silver = 0.379 lb/in^3
density nylon = 0.045 lb/in^3
density polycarbonate = 0.045 lb/in^3
#
# energy units
#
[energy]
joule = N*m
J = joule # joule
kilojoule = 1000 joule
kJ = kilojoule # kilojoule
megajoule = 1000 kilojoule
gigajoule = 1000 megajoule
millijoule = 0.001 joule
mJ = millijoule # millijoule
calorie = 4.1868 J
cal = calorie # calorie
kilocalorie = 1000 cal
kcal = kilocalorie # kilocalorie
calorie food = kilocalorie
thermie = 1000 kcal
Btu = cal*lb*R/(g*K) # British thermal unit
British thermal unit = Btu
therm = 100000 Btu
erg = cm*dyne
electronvolt = 1.602176462e-19 J
eV = electronvolt # electronvolt
kWh = kW*hour # kilowatt-hour
kilowatt hour = kWh
ton TNT = 4.184e9 J
tonne oil equivalent = 41.868 gigajoule
tonne coal equivalent = 7000000 kcal
#
# power units
#
[power]
watt = J/s
W = watt # watt
kilowatt = 1000 W
kW = kilowatt # kilowatt
megawatt = 1000 kW
MW = megawatt # megawatt
gigawatt = 1000 MW
GW = gigawatt # gigawatt
milliwatt = 0.001 W
horsepower = 550 ft*lbf/sec
hp = horsepower # horsepower
metric horsepower = 75 kgf*m/s
ton refrigeration = 12000 Btu/hr
MBH = 1000 Btu/hr # 1000 Btu/hr
#
# frequency
#
[frequency]
hertz = unit/sec
Hz = hertz # hertz
millihertz = 0.001 Hz
kilohertz = 1000 Hz
kHz = kilohertz # kilohertz
megahertz = 1000 kHz
MHz = megahertz # megahertz
gigahertz = 1000 MHz
GHz = gigahertz # gigahertz
#
# radioactivity
#
[radioactivity]
becquerel = unit/sec
Bq = becquerel # becquerel
curie = 3.7e10 Bq
millicurie = 0.001 curie
roentgen = 2.58e-4 coulomb/kg
[radiation dose]
gray = J/kg
Gy = gray # gray
centigray = 0.01 Gy
rad. abs. dose = 0.01 Gy # # commonly rad
sievert = J/kg # # equiv. dose
millisievert = 0.001 sievert # # equiv. dose
Sv = sievert # sievert # equiv. dose
rem = 0.01 Sv # # roentgen equiv mammal
millirem = 0.001 rem # # roentgen equiv mammal
#
# viscosity
#
[dyn viscosity]
poise = g/(cm*s)
P = poise # poise
centipoise = 0.01 poise
cP = centipoise # centipoise
[kin viscosity]
stokes = cm^2/s
St = stokes # stokes
centistokes = 0.01 stokes
cSt = centistokes # centistokes
#
# misc. units
#
[acceleration]
gravity = 9.80665 m/s^2
galileo = cm/s^2
[constant]
gravity constant = 6.673e-11 N*m^2/kg^2
gas constant = 8.314472 J/(mol*K) # R
[fuel consumpt.]
mpg = mi/gal # miles/gallon
mpg imp = mi/gallon imperial # miles/gallon imp
liter per 100 km = [mpg] 3.785411784 / (x * 0.01609344) ; \
3.785411784 / (x * 0.01609344) # # non-linear
[permeability]
darcy = 1 cm^2*centipoise/atm/s
millidarcy = 0.001 darcy
"""
class UnitGroup:
"Stores, updates and converts a group of units"
maxDecPlcs = 8
def __init__(self, unitData, option):
self.unitData = unitData
self.option = option
self.unitList = []
self.currentNum = 0
self.factor = 1.0
self.reducedList = []
self.linear = 1
def update(self, text, cursorPos=None):
"Decode user entered text into units"
self.unitList = self.parseGroup(text)
if cursorPos != None:
self.updateCurrentUnit(text, cursorPos)
else:
self.currentNum = len(self.unitList) - 1
def updateCurrentUnit(self, text, cursorPos):
"Set current unit number"
self.currentNum = len(re.findall(r'[\*/]', text[:cursorPos]))
def currentUnit(self):
"Return current unit if its a full match, o/w None"
if self.unitList and self.unitList[self.currentNum].equiv:
return self.unitList[self.currentNum]
return None
def currentPartialUnit(self):
"Return unit with at least a partial match, o/w None"
if not self.unitList:
return None
return self.unitData.findPartialMatch(self.unitList[self.currentNum]\
.name)
def currentSortPos(self):
"Return unit near current unit for sorting"
if not self.unitList:
return self.unitData[self.unitData.sortedKeys[0]]
return self.unitData.findSortPos(self.unitList[self.currentNum]\
.name)
def replaceCurrent(self, unit):
"Replace the current unit with unit"
if self.unitList:
exp = self.unitList[self.currentNum].exp
self.unitList[self.currentNum] = copy.copy(unit)
self.unitList[self.currentNum].exp = exp
else:
self.unitList.append(copy.copy(unit))
def completePartial(self):
"Replace a partial unit with a full one"
if self.unitList and not self.unitList[self.currentNum].equiv:
text = self.unitList[self.currentNum].name
unit = self.unitData.findPartialMatch(text)
if unit:
exp = self.unitList[self.currentNum].exp
self.unitList[self.currentNum] = copy.copy(unit)
self.unitList[self.currentNum].exp = exp
def moveToNext(self, upward):
"Replace unit with adjacent one based on match or sort position"
unit = self.currentSortPos()
num = self.unitData.sortedKeys.index(unit.name.\
replace(' ', '')) \
+ (upward and -1 or 1)
if 0 <= num < len(self.unitData.sortedKeys):
self.replaceCurrent(self.unitData[self.unitData.sortedKeys[num]])
def addOper(self, mult):
"Add new operator & blank unit after current, * if mult is true"
if self.unitList:
self.completePartial()
prevExp = self.unitList[self.currentNum].exp
self.currentNum += 1
self.unitList.insert(self.currentNum, Unit(''))
if (not mult and prevExp > 0) or (mult and prevExp < 0):
self.unitList[self.currentNum].exp = -1
def changeExp(self, newExp):
"Change the current unit's exponent"
if self.unitList:
self.completePartial()
if self.unitList[self.currentNum].exp > 0:
self.unitList[self.currentNum].exp = newExp
else:
self.unitList[self.currentNum].exp = -newExp
def clearUnit(self):
"Remove units"
self.unitList = []
def parseGroup(self, text):
"Return list of units from text string"
unitList = []
parts = [part.strip() for part in re.split(r'([\*/])', text)]
numerator = 1
while parts:
unit = self.parseUnit(parts.pop(0))
if not numerator:
unit.exp = -unit.exp
if parts and parts.pop(0) == '/':
numerator = not numerator
unitList.append(unit)
return unitList
def parseUnit(self, text):
"Return a valid or invalid unit with exponent from a text string"
parts = text.split('^', 1)
exp = 1
if len(parts) > 1: # has exponent
try:
exp = int(parts[1])
except ValueError:
if parts[1].lstrip().startswith('-'):
exp = -Unit.partialExp # tmp invalid exp
else:
exp = Unit.partialExp
unitText = parts[0].strip().replace(' ', '')
unit = copy.copy(self.unitData.get(unitText, None))
if not unit and unitText and unitText[-1] == 's' and not \
self.unitData.findPartialMatch(unitText): # check for plural
unit = copy.copy(self.unitData.get(unitText[:-1], None))
if not unit:
#unit = Unit(parts[0].strip()) # tmp invalid unit
raise UnitDataError('%s is not a valid unit.' % (unitText))
unit.exp = exp
return unit
def unitString(self, unitList=None):
"Return the full string for this group or a given group"
if unitList == None:
unitList = self.unitList[:]
fullText = ''
if unitList:
fullText = unitList[0].unitText(0)
numerator = 1
for unit in unitList[1:]:
if (numerator and unit.exp > 0) \
or (not numerator and unit.exp < 0):
fullText = '%s * %s' % (fullText, unit.unitText(1))
else:
fullText = '%s / %s' % (fullText, unit.unitText(1))
numerator = not numerator
return fullText
def groupValid(self):
"Return 1 if all unitself.reducedLists are valid"
if not self.unitList:
return 0
for unit in self.unitList:
if not unit.unitValid():
return 0
return 1
def reduceGroup(self):
"Update reduced list of units and factor"
self.linear = 1
self.reducedList = []
self.factor = 1.0
if not self.groupValid():
return
count = 0
tmpList = self.unitList[:]
while tmpList:
count += 1
if count > 5000:
raise UnitDataError('Circular unit definition')
unit = tmpList.pop(0)
if unit.equiv in ('!', '!!'):
self.reducedList.append(copy.copy(unit))
elif not unit.equiv:
raise UnitDataError('Invalid conversion for "%s"' % unit.name)
else:
if unit.fromEqn:
self.linear = 0
newList = self.parseGroup(unit.equiv)
for newUnit in newList:
newUnit.exp *= unit.exp
tmpList.extend(newList)
self.factor *= unit.factor**unit.exp
self.reducedList.sort()
tmpList = self.reducedList[:]
self.reducedList = []
for unit in tmpList:
if self.reducedList and unit == self.reducedList[-1]:
self.reducedList[-1].exp += unit.exp
else:
self.reducedList.append(unit)
self.reducedList = [unit for unit in self.reducedList if \
unit.name != 'unit' and unit.exp != 0]
def categoryMatch(self, otherGroup):
"Return 1 if unit types are equivalent"
if not self.checkLinear() or not otherGroup.checkLinear():
return 0
return self.reducedList == otherGroup.reducedList and \
[unit.exp for unit in self.reducedList] \
== [unit.exp for unit in otherGroup.reducedList]
def checkLinear(self):
"Return 1 if linear or acceptable non-linear"
if not self.linear:
if len(self.unitList) > 1 or self.unitList[0].exp != 1:
return 0
return 1
def compatStr(self):
"Return string with reduced unit or linear compatability problem"
if self.checkLinear():
return self.unitString(self.reducedList)
return 'Cannot combine non-linear units'
def convert(self, num, toGroup):
"Return num of this group converted to toGroup"
if self.linear:
num *= self.factor
else:
num = self.nonLinearCalc(num, 1) * self.factor
n2 = -1
if toGroup.linear:
n2 = num / toGroup.factor
else:
n2 = toGroup.nonLinearCalc(num / toGroup.factor, 0)
return n2
def nonLinearCalc(self, num, isFrom):
"Return result of non-linear calculation"
x = num
try:
if self.unitList[0].toEqn: # regular equations
if isFrom:
temp = float(eval(self.unitList[0].fromEqn))
return temp
temp = float(eval(self.unitList[0].toEqn))
return temp
data = list(eval(self.unitList[0].fromEqn)) # extrapolation list
if isFrom:
data = [(float(group[0]), float(group[1])) for group in data]
else:
data = [(float(group[1]), float(group[0])) for group in data]
data.sort()
pos = len(data) - 1
for i in range(len(data)):
if num <= data[i][0]:
pos = i
break
if pos == 0:
pos = 1
y = (num-data[pos-1][0]) / float(data[pos][0]-data[pos-1][0]) \
* (data[pos][1]-data[pos-1][1]) + data[pos-1][1]
return y
except OverflowError:
return 1e9999
except:
raise UnitDataError('Bad equation for %s' % self.unitList[0].name)
def convertStr(self, num, toGroup):
"Return formatted string of converted number"
return self.formatNumStr(self.convert(num, toGroup))
def formatNumStr(self, num):
"Return num string formatted per options"
decPlcs = self.option.intData('DecimalPlaces', 0, UnitGroup.maxDecPlcs)
if self.option.boolData('SciNotation'):
return ('%%0.%dE' % decPlcs) % num
if self.option.boolData('FixedDecimals'):
return ('%%0.%df' % decPlcs) % num
return ('%%0.%dG' % decPlcs) % num
class UnitDataError(Exception):
pass
class UnitData(dict):
def __init__(self):
dict.__init__(self)
self.sortedKeys = []
def readData(self):
"Read all unit data from file"
types = []
typeUnits = {}
lines = unitData.splitlines()
for i in range(len(lines)): # join continuation lines
delta = 1
while lines[i].rstrip().endswith('\\'):
lines[i] = ''.join([lines[i].rstrip()[:-1], lines[i+delta]])
lines[i+delta] = ''
delta += 1
units = [Unit(line) for line in lines if \
line.split('#', 1)[0].strip()] # remove comment lines
typeText = ''
for unit in units: # find & set headings
if unit.name.startswith('['):
typeText = unit.name[1:-1].strip()
types.append(typeText)
typeUnits[typeText] = []
unit.typeName = typeText
units = [unit for unit in units if unit.equiv] # keep valid units
for unit in units:
self[unit.name.replace(' ', '')] = unit
typeUnits[unit.typeName].append(unit.name)
self.sortedKeys = list(self.keys())
self.sortedKeys.sort()
if len(self.sortedKeys) < len(units):
raise UnitDataError('Duplicate unit names found')
return (types, typeUnits)
def findPartialMatch(self, text):
"Return first partially matching unit or None"
text = text.replace(' ', '')
if not text:
return None
for name in self.sortedKeys:
if name.startswith(text):
return self[name]
return None
def findSortPos(self, text):
"Return unit whose abbrev comes immediately after text"
text = text.replace(' ', '')
for name in self.sortedKeys:
if text <= name:
return self[name]
return self[self.sortedKeys[-1]]
class Unit:
"Reads and stores a single unit conversion"
partialExp = 1000
def __init__(self, dataStr):
dataList = dataStr.split('#')
unitList = dataList.pop(0).split('=', 1)
self.name = unitList.pop(0).strip()
self.equiv = ''
self.factor = 1.0
self.fromEqn = '' # used only for non-linear units
self.toEqn = '' # used only for non-linear units
if unitList:
self.equiv = unitList[0].strip()
if self.equiv[0] == '[': # used only for non-linear units
try:
self.equiv, self.fromEqn = re.match(r'\[(.*?)\](.*)', \
self.equiv).groups()
if ';' in self.fromEqn:
self.fromEqn, self.toEqn = self.fromEqn.split(';', 1)
self.toEqn = self.toEqn.strip()
self.fromEqn = self.fromEqn.strip()
except AttributeError:
raise UnitDataError('Bad equation for "%s"' % self.name)
else: # split factor and equiv unit for linear
parts = self.equiv.split(None, 1)
if len(parts) > 1 and re.search(r'[^\d\.eE\+\-\*/]', parts[0]) \
== None: # only allowed digits and operators
try:
self.factor = float(eval(parts[0]))
self.equiv = parts[1]
except:
pass
self.comments = [comm.strip() for comm in dataList]
self.comments.extend([''] * (2 - len(self.comments)))
self.exp = 1
self.viewLink = [None, None]
self.typeName = ''
def description(self):
"Return name and 1st comment (usu. full name) if applicable"
if self.comments[0]:
return '%s (%s)' % (self.name, self.comments[0])
return self.name
def unitValid(self):
"Return 1 if unit and exponent are valid"
if self.equiv and -Unit.partialExp < self.exp < Unit.partialExp:
return 1
return 0
def unitText(self, absExp=0):
"Return text for unit name with exponent or absolute value of exp"
exp = self.exp
if absExp:
exp = abs(self.exp)
if exp == 1:
return self.name
if -Unit.partialExp < exp < Unit.partialExp:
return '%s^%d' % (self.name, exp)
if exp > 1:
return '%s^' % self.name
else:
return '%s^-' % self.name
def __cmp__(self, other):
return cmp(self.name, other.name)
def __lt__(self, other):
return self.name < other.name
def __eq__(self, other):
return self.name == other.name
############################################################################
# Wrapper functionality
#
############################################################################
# Parse the data file, and set everything up for conversion
data = UnitData()
(types, unitsByType) = data.readData()
# At the moment, we're not handling options
option = None
# set up the objects for unit conversion
fromUnit = UnitGroup(data, option)
toUnit = UnitGroup(data, option)
def convert(num, unit1, unit2):
""" Convert from one unit to another
num is the factor for the first unit. Raises UnitDataError for
various errors.
"""
fromUnit.update(unit1)
toUnit.update(unit2)
fromUnit.reduceGroup()
toUnit.reduceGroup()
# Match up unit categories
if not fromUnit.categoryMatch(toUnit):
raise UnitDataError('unit categories did not match')
return fromUnit.convert(num, toUnit)
def units(type):
""" Return comma separated string list of units of given type, or
a list of types if the argument is not valid.
"""
if type in types:
return '%s units: %s' % (type, ', '.join(unitsByType[type]))
else:
return 'valid types: ' + ', '.join(types)
|