UnitValues 0.1.3__tar.gz → 0.1.5__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {unitvalues-0.1.3/src/UnitValues.egg-info → unitvalues-0.1.5}/PKG-INFO +3 -2
- {unitvalues-0.1.3 → unitvalues-0.1.5}/pyproject.toml +1 -1
- {unitvalues-0.1.3 → unitvalues-0.1.5/src/UnitValues.egg-info}/PKG-INFO +3 -2
- {unitvalues-0.1.3 → unitvalues-0.1.5}/src/unitvalue/units.py +237 -91
- {unitvalues-0.1.3 → unitvalues-0.1.5}/LICENSE +0 -0
- {unitvalues-0.1.3 → unitvalues-0.1.5}/README.md +0 -0
- {unitvalues-0.1.3 → unitvalues-0.1.5}/setup.cfg +0 -0
- {unitvalues-0.1.3 → unitvalues-0.1.5}/src/UnitValues.egg-info/SOURCES.txt +0 -0
- {unitvalues-0.1.3 → unitvalues-0.1.5}/src/UnitValues.egg-info/dependency_links.txt +0 -0
- {unitvalues-0.1.3 → unitvalues-0.1.5}/src/UnitValues.egg-info/requires.txt +0 -0
- {unitvalues-0.1.3 → unitvalues-0.1.5}/src/UnitValues.egg-info/top_level.txt +0 -0
- {unitvalues-0.1.3 → unitvalues-0.1.5}/src/unitvalue/__init__.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
Metadata-Version: 2.
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
2
|
Name: UnitValues
|
|
3
|
-
Version: 0.1.
|
|
3
|
+
Version: 0.1.5
|
|
4
4
|
Summary: A small package for using units in Python. Allows for computation with dimensioned qauntities and allows you to convert between different units. Do anything you would do with regular floats or integers in Python except now with units. Package is compatible with NumPy, SciPy + Pandas are in the works. I think you'll find this implementation more elegant then most other unit packages.
|
|
5
5
|
Author-email: Brody Howard <brody.howard@mail.utoronto.ca>
|
|
6
6
|
Project-URL: Homepage, https://github.com/BroRocket/unitvalue/
|
|
@@ -12,6 +12,7 @@ Requires-Python: >=3.10
|
|
|
12
12
|
Description-Content-Type: text/markdown
|
|
13
13
|
License-File: LICENSE
|
|
14
14
|
Requires-Dist: numpy>=1.23.2
|
|
15
|
+
Dynamic: license-file
|
|
15
16
|
|
|
16
17
|
# UnitValues Package
|
|
17
18
|
## Introduction
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
Metadata-Version: 2.
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
2
|
Name: UnitValues
|
|
3
|
-
Version: 0.1.
|
|
3
|
+
Version: 0.1.5
|
|
4
4
|
Summary: A small package for using units in Python. Allows for computation with dimensioned qauntities and allows you to convert between different units. Do anything you would do with regular floats or integers in Python except now with units. Package is compatible with NumPy, SciPy + Pandas are in the works. I think you'll find this implementation more elegant then most other unit packages.
|
|
5
5
|
Author-email: Brody Howard <brody.howard@mail.utoronto.ca>
|
|
6
6
|
Project-URL: Homepage, https://github.com/BroRocket/unitvalue/
|
|
@@ -12,6 +12,7 @@ Requires-Python: >=3.10
|
|
|
12
12
|
Description-Content-Type: text/markdown
|
|
13
13
|
License-File: LICENSE
|
|
14
14
|
Requires-Dist: numpy>=1.23.2
|
|
15
|
+
Dynamic: license-file
|
|
15
16
|
|
|
16
17
|
# UnitValues Package
|
|
17
18
|
## Introduction
|
|
@@ -2,11 +2,105 @@
|
|
|
2
2
|
This module allows you to easly store numbers with units and easily convert the units and value of the numbers.
|
|
3
3
|
The two supported systems currently are Imperial and Metric.
|
|
4
4
|
Typically used units are supported and more can be added upon request or in your instance.
|
|
5
|
+
|
|
6
|
+
AUTHOR: Brody Howard
|
|
7
|
+
|
|
5
8
|
'''
|
|
6
9
|
import warnings
|
|
7
10
|
import numpy as np
|
|
8
11
|
|
|
9
|
-
|
|
12
|
+
|
|
13
|
+
class _gauge_pressure():
|
|
14
|
+
'''
|
|
15
|
+
This class is used for specifc units which can have guage versus absolute values and facilatest the conversion of these values to absolute or back to gauge.
|
|
16
|
+
Mainly useful for pressure. Do not use outside of this file
|
|
17
|
+
'''
|
|
18
|
+
def __init__(self, unit_conversion_to_SI: float|int, conv_to_absolute: float|int) -> None:
|
|
19
|
+
'''
|
|
20
|
+
Args:
|
|
21
|
+
unit_conversion_to_SI (float|int): value to multiply the non gauge unit value by to convert it to the standard SI unit.
|
|
22
|
+
conv_to_absolute (float|int): value to add to get from gauge to absolute value, note this value must be negative if you subtract to convert to absolute from gauge
|
|
23
|
+
'''
|
|
24
|
+
self.__to_SI = unit_conversion_to_SI
|
|
25
|
+
self.__to_ABSOLUTE = conv_to_absolute
|
|
26
|
+
|
|
27
|
+
def __mul__(self, m) -> int|float:
|
|
28
|
+
'''
|
|
29
|
+
Used in unit class to convert the unit to SI. Thus converts the guage value to absolute and then SI base unit.
|
|
30
|
+
|
|
31
|
+
Args:
|
|
32
|
+
d : the current value of the gauge unit.
|
|
33
|
+
|
|
34
|
+
Returns:
|
|
35
|
+
float|int : The base SI absolute value of the gauge value
|
|
36
|
+
'''
|
|
37
|
+
absolute_value = m + self.__to_ABSOLUTE
|
|
38
|
+
return absolute_value * self.__to_SI
|
|
39
|
+
|
|
40
|
+
__rmul__ = __mul__
|
|
41
|
+
|
|
42
|
+
def __truediv__(self, d):
|
|
43
|
+
'''
|
|
44
|
+
Used in unit class to convert to the gauge unit. Thus converts the absolute base SI value to the gauge unit value.
|
|
45
|
+
|
|
46
|
+
Args:
|
|
47
|
+
d : the current value of theabsolute SI unit.
|
|
48
|
+
|
|
49
|
+
Returns:
|
|
50
|
+
float|int : The base SI absolute value of the gauge value
|
|
51
|
+
'''
|
|
52
|
+
new_unit_value = d / self.__to_SI
|
|
53
|
+
return new_unit_value - self.__to_ABSOLUTE
|
|
54
|
+
|
|
55
|
+
__rtruediv__ = __truediv__
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
class metric_temperature():
|
|
59
|
+
def __init__(self, unit_conversion_to_SI) -> None:
|
|
60
|
+
self.__to_SI = unit_conversion_to_SI
|
|
61
|
+
|
|
62
|
+
def __mul__(self, m) -> int|float:
|
|
63
|
+
return m + self.__to_SI
|
|
64
|
+
|
|
65
|
+
__rmul__ = __mul__
|
|
66
|
+
|
|
67
|
+
def __truediv__(self, d):
|
|
68
|
+
return d - self.__to_SI
|
|
69
|
+
|
|
70
|
+
__rtruediv__ = __truediv__
|
|
71
|
+
|
|
72
|
+
class farenheit():
|
|
73
|
+
def __init__(self) -> None:
|
|
74
|
+
pass
|
|
75
|
+
|
|
76
|
+
def __mul__(self, m) -> int|float:
|
|
77
|
+
kelvin = ((m - 32) * (5/9)) + 273.15
|
|
78
|
+
return kelvin
|
|
79
|
+
|
|
80
|
+
__rmul__ = __mul__
|
|
81
|
+
|
|
82
|
+
def __truediv__(self, d):
|
|
83
|
+
val = ((d - 273.15) / (5/9)) + 32
|
|
84
|
+
return val
|
|
85
|
+
|
|
86
|
+
__rtruediv__ = __truediv__
|
|
87
|
+
|
|
88
|
+
class rankine():
|
|
89
|
+
def __init__(self) -> None:
|
|
90
|
+
pass
|
|
91
|
+
|
|
92
|
+
def __mul__(self, m) -> int|float:
|
|
93
|
+
return m *(5/9)
|
|
94
|
+
|
|
95
|
+
__rmul__ = __mul__
|
|
96
|
+
|
|
97
|
+
def __truediv__(self, d):
|
|
98
|
+
return d * 1.8
|
|
99
|
+
|
|
100
|
+
__rtruediv__ = __truediv__
|
|
101
|
+
|
|
102
|
+
|
|
103
|
+
class UnitValue:
|
|
10
104
|
"""
|
|
11
105
|
Represents a value with dimension/units.
|
|
12
106
|
|
|
@@ -15,16 +109,16 @@ class UnitValue: # add specific heat
|
|
|
15
109
|
__dimension (str): The dimension of the unit (e.g., LENGTH, MASS).
|
|
16
110
|
__unit (str): The unit of the value (e.g., m, kg).
|
|
17
111
|
value (float): The numerical value.
|
|
18
|
-
"""
|
|
112
|
+
"""
|
|
19
113
|
UNITS = {"IMPERIAL": {
|
|
20
114
|
"DISTANCE": {"in": 0.0254, "mi": 1609.34, "yd": 0.9144, "ft": 0.3048},
|
|
21
|
-
"PRESSURE": {"psi": 6894.76, "psf": 47.8803},
|
|
115
|
+
"PRESSURE": {"psi": 6894.76, "psig": _gauge_pressure(6894.76, 14.696), "psf": 47.8803},
|
|
22
116
|
"MASS": {"lb": 0.453592, "ton": 907.1847, "slug": 14.59390, "st": 6.35029, "oz": 0.0283495},
|
|
23
117
|
"VELOCITY": {"ft/s": 0.3048, "mi/s": 1609.34, "mph": 0.44704, "in/s": 0.0254},
|
|
24
118
|
"DENSITY": {"lb/in^3": 27679.9, "lb/ft^3": 16.0185, "lb/yd^3": 0.593276},
|
|
25
119
|
"VOLUME": {"gal": 0.00378541, "yd^3": 0.764555, "ft^3": 0.0283168, "in^3": 0.0000163871},
|
|
26
120
|
"AREA": {"in^2": 0.00064516, "mi^2": 2590000, "yd^2": 0.836127, "ft^2": 0.092903},
|
|
27
|
-
"TEMPERATURE": {"f":
|
|
121
|
+
"TEMPERATURE": {"f": farenheit(), "R": rankine()},
|
|
28
122
|
"MASS FLOW RATE": {"lb/s": 0.453592, "ton/s": 907.1847, "st/s": 6.35029, "oz": 0.0283495, "lb/min": 0.00755987},
|
|
29
123
|
"ENERGY": {"BTU": 1055.05585, "ftlb": 1.35582, "kcal": 4184, "cal": 4.184},
|
|
30
124
|
"TIME": {"s": 1, "h": 3600, "min": 60, "ms": 0.001},
|
|
@@ -35,21 +129,21 @@ class UnitValue: # add specific heat
|
|
|
35
129
|
"ENERGY PER UNIT MASS": {"ft^2/s^2": 0.09290304},
|
|
36
130
|
"MASS PER UNIT LENGTH": {"lb/ft": 1.48816, "oz/in": 1.11612},
|
|
37
131
|
"MASS PER AREA": {"lb/ft^2": 4.88243},
|
|
38
|
-
"VOLUMETRIC FLOW RATE": {"ft^3/s": 0.0283168, "gal/s": 0.00378541, "ft^3/min": 0.000471947},
|
|
132
|
+
"VOLUMETRIC FLOW RATE": {"ft^3/s": 0.0283168, "gal/s": 0.00378541, "ft^3/min": 0.000471947, "SCFM": None},
|
|
39
133
|
"DYNAMIC VISCOCITY": {"lb/fts": 1.488163943568},
|
|
40
134
|
"KINEMATIC VISCOCITY": {"ft^2/s": 0.092903},
|
|
41
135
|
"MASS FLUX": {"lb/ft^2s": 4.88243},
|
|
42
|
-
"
|
|
136
|
+
"GAS CONSTANTS": {"BTU/lbf": 4186.8000000087}
|
|
43
137
|
},
|
|
44
138
|
"METRIC": {
|
|
45
139
|
"DISTANCE": {"m": 1, "km": 1000, "cm": 0.01, "mm": 0.001},
|
|
46
|
-
"PRESSURE": {"kg/ms^2": 1, "MPa": 1000000, "bar": 100000, "kPa": 1000, "hPa": 100, "Pa": 1},
|
|
140
|
+
"PRESSURE": {"kg/ms^2": 1, "MPa": 1000000, "atm": 101325, "bar": 100000, "kPa": 1000, "hPa": 100, "Pa": 1},
|
|
47
141
|
"MASS": {"kg": 1, "tonne": 1000, "g": 0.001},
|
|
48
142
|
"VELOCITY": {"m/s": 1, "km/s": 1000, "km/h": 0.277778, "cm/s": 0.01, "mm/s": 0.001},
|
|
49
143
|
"DENSITY": {"kg/m^3": 1, "t/m^3": 1000, "g/m^3": 0.001},
|
|
50
144
|
"VOLUME": {"m^3": 1, "L": 0.001, "cm^3": 0.000001, "mL": 0.000001, "mm^3": 0.000000001},
|
|
51
145
|
"AREA": {"m^2": 1, "km^2": 1000000, "cm^2": 0.0001, "mm^2": 0.000001},
|
|
52
|
-
"TEMPERATURE": {"K":
|
|
146
|
+
"TEMPERATURE": {"K": 1, "c": metric_temperature(273.15)},
|
|
53
147
|
"MASS FLOW RATE": {"kg/s": 1, "t/s": 1000, "kg/min": 0.0166667, "g/s": 0.001},
|
|
54
148
|
"ENERGY": {"kgm^2/s^2": 1, "MJ": 1000000, "kJ": 1000, "Nm": 1, "J": 1, "eV": 1.602177e-19},
|
|
55
149
|
"TIME": {"s": 1, "h": 3600, "min": 60, "ms": 0.001},
|
|
@@ -60,20 +154,21 @@ class UnitValue: # add specific heat
|
|
|
60
154
|
"ENERGY PER UNIT MASS": {"m^2/s^2": 1},
|
|
61
155
|
"MASS PER LENGTH": {"kg/m": 1, "kg/cm": 100, "g/cm": 0.1},
|
|
62
156
|
"MASS PER AREA": {"kg/m^2": 1, "g/cm^2": 10},
|
|
63
|
-
"VOLUMETRIC FLOW RATE": {"m^3/s": 1, "cm^3/s": 0.000001},
|
|
157
|
+
"VOLUMETRIC FLOW RATE": {"m^3/s": 1, "cm^3/s": 0.000001, "L/min": 0.001/60, "SLPM": None},
|
|
64
158
|
"DYNAMIC VISCOCITY": {"kg/ms": 1, "g/cms":0.1},
|
|
65
159
|
"KINEMATIC VISCOCITY": {"m^2/s": 1, "cm^2/s": 0.0001},
|
|
66
160
|
"MASS FLUX": {"kg/m^2s": 1},
|
|
67
|
-
"
|
|
161
|
+
"GAS CONSTANTS": {"m^2/s^2K": 1, "J/kgK": 1, "J/kgc": 1},
|
|
162
|
+
"MOLECULAR COUNT": {'Mol': 1, "kMol": 1000}
|
|
68
163
|
}
|
|
69
164
|
}
|
|
70
165
|
|
|
71
|
-
SPELLING_MAP = {'mtr': 'm', 'meters': 'm', 'mtr.': 'm', 'metres': 'm', 'metre': 'm', 'm ': 'm', 'meter': 'm', 'kilometer': 'km', 'kilometre': 'km', 'kilo meter': 'km', 'k meter': 'km', 'klometer': 'km', 'km ': 'km', 'kmeter': 'km', 'kmtr': 'km', 'centemeter': 'cm', 'centimetre': 'cm', 'cn': 'cm', 'c meter': 'cm', 'cm ': 'cm', 'centi meter': 'cm', 'centimeter': 'cm', 'cmeter': 'cm', 'cmtr': 'cm', 'mmeter': 'mm', 'millimeter': 'mm', 'milimeter': 'mm', 'milli meter': 'mm', 'millimetre': 'mm', 'm meter': 'mm', 'mn': 'mm', 'mmtr': 'mm', 'mm ': 'mm', 'g ': 'g', 'gramme': 'g', 'grm': 'g', 'gms': 'g', 'gram': 'g', 'gm': 'g', 'gramm': 'g', 'gram ': 'g', 'kilograms': 'kg', 'k gram': 'kg', 'kilogramme': 'kg', 'kilogram ': 'kg', 'kilogramme ': 'kg', 'kilogrammes': 'kg', 'kg ': 'kg', 'kilogram': 'kg', 'kilo gram': 'kg', 'kgrm': 'kg', 'liters': 'L', 'l': 'L', 'litres': 'L', 'ltrs': 'L', 'liter': 'L', 'litre ': 'L', 'litre': 'L', 'liters ': 'L', 'liter ': 'L', 'litter': 'L', 'ltr': 'L', 'ml': 'mL', 'milliliter': 'mL', 'mlitres': 'mL', 'millilitre': 'mL', 'milli litre': 'mL', 'mliters': 'mL', 'milli liter': 'mL', 'mltr': 'mL', 'sec': 's', 'seconds': 's', 'sedonds': 's', 'sconds': 's', 'second': 's', 'secs': 's', 'secnd': 's', 'minute': 'min', 'minuts': 'min', 'mins': 'min', 'minutes': 'min', 'min': 'min', 'minut': 'min', 'hours': 'h', 'hr': 'h', 'howr': 'h', 'houer': 'h', 'hour': 'h', 'hou': 'h', 'hrs': 'h', 'square meters': 'm^2', 'square meter': 'm^2', 'sqr meter': 'm^2', 'square metre': 'm^2', 'sq meter': 'm^2', 'sqmetre': 'm^2', 'sq metres': 'm^2', 'sqm': 'm^2', 'cube meter': 'm^3', 'cu meter': 'm^3', 'cbm': 'm^3', 'cubic meters': 'm^3', 'cubic metre': 'm^3', 'cubic meter': 'm^3', 'cu m': 'm^3', 'C': 'c','degree centigrade': 'c', 'degree celsius': 'c', 'celcius': 'c', 'deg celsius': 'c', 'celsius degree': 'c', 'celsus': 'c', 'celsius': 'c', 'deg c': 'c', 'fahrenheit degree': 'f', 'deg f': 'f', 'deg fahrenheit': 'f', 'fahrenhiet': 'f', 'degree fahrenheit': 'f', 'farhenheit': 'f', 'force': 'kgm/s^2', 'Newton': 'kgm/s^2', 'newtn': 'kgm/s^2', 'nwton': 'kgm/s^2', 'nwt': 'kgm/s^2', 'newton': 'kgm/s^2', 'joule': 'kgm^2/s^2', 'energy': 'kgm^2/s^2', 'juole': 'kgm^2/s^2', 'jl': 'kgm^2/s^2', 'joules': 'kgm^2/s^2', 'juul': 'kgm^2/s^2', 'inck': 'in', 'inche': 'in', 'inch': 'in', 'inc': 'in', 'inch ': 'in', 'inchh': 'in', 'foot': 'ft', 'foott': 'ft', 'fot': 'ft', 'foor': 'ft', 'foot ': 'ft', 'feet': 'ft', 'yardd': 'yd', 'yad': 'yd', 'yarrd': 'yd', 'yard ': 'yd', 'yard': 'yd', 'mille': 'mi', 'mile ': 'mi', 'milee': 'mi', 'mil': 'mi', 'mile': 'mi', 'pounds': 'lb', 'pounnd': 'lb', 'pound ': 'lb', 'pound': 'lb', 'lbs': 'lb', 'poundd': 'lb', 'galln': 'gal', 'gllon': 'gal', 'gallon': 'gal', 'galllon': 'gal', 'gallon ': 'gal', 'ounze': 'oz', 'ouncce': 'oz', 'ounce ': 'oz', 'ozs': 'oz', 'ounce': 'oz', 'ounc': 'oz', 'ounc ': 'oz', 'stn': 'st', 'stone ': 'st', 'sts': 'st', 'stone': 'st', 'st ': 'st', 'ft2': 'ft^2', 'square foot': 'ft^2', 'sqft': 'ft^2', 'square feet': 'ft^2', 'sq foot': 'ft^2', 'ft3': 'ft^3', 'cft': 'ft^3', 'cubic foot': 'ft^3', 'cu ft': 'ft^3', 'cubic feet': 'ft^3'}
|
|
166
|
+
SPELLING_MAP = {'mtr': 'm', 'meters': 'm', 'mtr.': 'm', 'metres': 'm', 'metre': 'm', 'm ': 'm', 'meter': 'm', 'kilometer': 'km', 'kilometre': 'km', 'kilo meter': 'km', 'k meter': 'km', 'klometer': 'km', 'km ': 'km', 'kmeter': 'km', 'kmtr': 'km', 'centemeter': 'cm', 'centimetre': 'cm', 'cn': 'cm', 'c meter': 'cm', 'cm ': 'cm', 'centi meter': 'cm', 'centimeter': 'cm', 'cmeter': 'cm', 'cmtr': 'cm', 'mmeter': 'mm', 'millimeter': 'mm', 'milimeter': 'mm', 'milli meter': 'mm', 'millimetre': 'mm', 'm meter': 'mm', 'mn': 'mm', 'mmtr': 'mm', 'mm ': 'mm', 'g ': 'g', 'gramme': 'g', 'grm': 'g', 'gms': 'g', 'gram': 'g', 'gm': 'g', 'gramm': 'g', 'gram ': 'g', 'kilograms': 'kg', 'k gram': 'kg', 'kilogramme': 'kg', 'kilogram ': 'kg', 'kilogramme ': 'kg', 'kilogrammes': 'kg', 'kg ': 'kg', 'kilogram': 'kg', 'kilo gram': 'kg', 'kgrm': 'kg', 'liters': 'L', 'l': 'L', 'litres': 'L', 'ltrs': 'L', 'liter': 'L', 'litre ': 'L', 'litre': 'L', 'liters ': 'L', 'liter ': 'L', 'litter': 'L', 'ltr': 'L', 'ml': 'mL', 'milliliter': 'mL', 'mlitres': 'mL', 'millilitre': 'mL', 'milli litre': 'mL', 'mliters': 'mL', 'milli liter': 'mL', 'mltr': 'mL', 'sec': 's', 'seconds': 's', 'sedonds': 's', 'sconds': 's', 'second': 's', 'secs': 's', 'secnd': 's', 'minute': 'min', 'minuts': 'min', 'mins': 'min', 'minutes': 'min', 'min': 'min', 'minut': 'min', 'hours': 'h', 'hr': 'h', 'howr': 'h', 'houer': 'h', 'hour': 'h', 'hou': 'h', 'hrs': 'h', 'square meters': 'm^2', 'square meter': 'm^2', 'sqr meter': 'm^2', 'square metre': 'm^2', 'sq meter': 'm^2', 'sqmetre': 'm^2', 'sq metres': 'm^2', 'sqm': 'm^2', 'cube meter': 'm^3', 'cu meter': 'm^3', 'cbm': 'm^3', 'cubic meters': 'm^3', 'cubic metre': 'm^3', 'cubic meter': 'm^3', 'cu m': 'm^3', 'C': 'c','degree centigrade': 'c', 'degree celsius': 'c', 'celcius': 'c', 'deg celsius': 'c', 'celsius degree': 'c', 'celsus': 'c', 'celsius': 'c', 'deg c': 'c', 'fahrenheit degree': 'f', 'deg f': 'f', 'deg fahrenheit': 'f', 'fahrenhiet': 'f', 'degree fahrenheit': 'f', 'farhenheit': 'f', 'force': 'kgm/s^2', 'Newton': 'kgm/s^2', 'newtn': 'kgm/s^2', 'nwton': 'kgm/s^2', 'nwt': 'kgm/s^2', 'newton': 'kgm/s^2', 'joule': 'kgm^2/s^2', 'energy': 'kgm^2/s^2', 'juole': 'kgm^2/s^2', 'jl': 'kgm^2/s^2', 'joules': 'kgm^2/s^2', 'juul': 'kgm^2/s^2', 'inck': 'in', 'inche': 'in', 'inch': 'in', 'inc': 'in', 'inch ': 'in', 'inchh': 'in', 'foot': 'ft', 'foott': 'ft', 'fot': 'ft', 'foor': 'ft', 'foot ': 'ft', 'feet': 'ft', 'yardd': 'yd', 'yad': 'yd', 'yarrd': 'yd', 'yard ': 'yd', 'yard': 'yd', 'mille': 'mi', 'mile ': 'mi', 'milee': 'mi', 'mil': 'mi', 'mile': 'mi', 'pounds': 'lb', 'pounnd': 'lb', 'pound ': 'lb', 'pound': 'lb', 'lbs': 'lb', 'poundd': 'lb', 'galln': 'gal', 'gllon': 'gal', 'gallon': 'gal', 'galllon': 'gal', 'gallon ': 'gal', 'ounze': 'oz', 'ouncce': 'oz', 'ounce ': 'oz', 'ozs': 'oz', 'ounce': 'oz', 'ounc': 'oz', 'ounc ': 'oz', 'stn': 'st', 'stone ': 'st', 'sts': 'st', 'stone': 'st', 'st ': 'st', 'ft2': 'ft^2', 'square foot': 'ft^2', 'sqft': 'ft^2', 'square feet': 'ft^2', 'sq foot': 'ft^2', 'ft3': 'ft^3', 'cft': 'ft^3', 'cubic foot': 'ft^3', 'cu ft': 'ft^3', 'cubic feet': 'ft^3', 'mol': 'Mol', 'moles': 'Mol', 'mols': 'Mol', 'Moles': 'Mol', 'Mols': 'Mol'}
|
|
72
167
|
|
|
73
168
|
@classmethod
|
|
74
169
|
def add_custom_unit(cls, system: str, dimension:str, unit:str, conversion_factor: float) -> None:
|
|
75
170
|
"""
|
|
76
|
-
Add your own units to the package instance
|
|
171
|
+
Add your own units to the package instance which you can then use in conversion and arithmatic. Note there is a small chance new SI/Metric units will mess with unit conversion during arithmatic.
|
|
77
172
|
|
|
78
173
|
Args:
|
|
79
174
|
system (str): The measurement system ('IMPERIAL' or 'METRIC').
|
|
@@ -141,7 +236,7 @@ class UnitValue: # add specific heat
|
|
|
141
236
|
@classmethod
|
|
142
237
|
def create_unit(cls, unit: str, value: float=0) -> 'UnitValue':
|
|
143
238
|
"""
|
|
144
|
-
Create a UnitValue object based on the unit and value. Will also account for
|
|
239
|
+
Create a UnitValue object based on the unit and value. Will also account for spelling mistakes/alternate names of units.
|
|
145
240
|
|
|
146
241
|
Args:
|
|
147
242
|
unit (str): The unit of the value.
|
|
@@ -184,7 +279,7 @@ class UnitValue: # add specific heat
|
|
|
184
279
|
raise ValueError("First element of string could not be converted to number, ensure string of the form e.g., '10 kg'")
|
|
185
280
|
|
|
186
281
|
@classmethod
|
|
187
|
-
def
|
|
282
|
+
def unit_from_dict(cls, data: dict) -> 'UnitValue':
|
|
188
283
|
"""
|
|
189
284
|
Create a UnitValue object from a dictionary.
|
|
190
285
|
|
|
@@ -262,7 +357,10 @@ class UnitValue: # add specific heat
|
|
|
262
357
|
continue
|
|
263
358
|
elif unit_str[i] == "k":
|
|
264
359
|
key = unit_str[i:i+2]
|
|
265
|
-
i += 1
|
|
360
|
+
i += 1
|
|
361
|
+
elif unit_str[i] == "M":
|
|
362
|
+
key = unit_str[i:i+3]
|
|
363
|
+
i += 2
|
|
266
364
|
else:
|
|
267
365
|
key = unit_str[i]
|
|
268
366
|
|
|
@@ -301,6 +399,13 @@ class UnitValue: # add specific heat
|
|
|
301
399
|
units = {}
|
|
302
400
|
self.__process_unit(self.__unit, units, 1)
|
|
303
401
|
self.__process_unit(m.__unit, units, 1)
|
|
402
|
+
|
|
403
|
+
empty_units = []
|
|
404
|
+
for unit, count in units.items():
|
|
405
|
+
if count == 0:
|
|
406
|
+
empty_units.append(unit)
|
|
407
|
+
for unit in empty_units:
|
|
408
|
+
units.pop(unit)
|
|
304
409
|
|
|
305
410
|
for dimension, units_dict in UnitValue.UNITS["METRIC"].items():
|
|
306
411
|
temp = {}
|
|
@@ -347,6 +452,13 @@ class UnitValue: # add specific heat
|
|
|
347
452
|
self.__process_unit(self.__unit, units, 1)
|
|
348
453
|
self.__process_unit(d.__unit, units, -1)
|
|
349
454
|
|
|
455
|
+
empty_units = []
|
|
456
|
+
for unit, count in units.items():
|
|
457
|
+
if count == 0:
|
|
458
|
+
empty_units.append(unit)
|
|
459
|
+
for unit in empty_units:
|
|
460
|
+
units.pop(unit)
|
|
461
|
+
|
|
350
462
|
for dimension, units_dict in UnitValue.UNITS["METRIC"].items():
|
|
351
463
|
temp = {}
|
|
352
464
|
self.__process_unit(list(units_dict)[0], temp, 1)
|
|
@@ -389,6 +501,13 @@ class UnitValue: # add specific heat
|
|
|
389
501
|
self.__process_unit(self.__unit, units, -1)
|
|
390
502
|
self.__process_unit(d.__unit, units, 1)
|
|
391
503
|
|
|
504
|
+
empty_units = []
|
|
505
|
+
for unit, count in units.items():
|
|
506
|
+
if count == 0:
|
|
507
|
+
empty_units.append(unit)
|
|
508
|
+
for unit in empty_units:
|
|
509
|
+
units.pop(unit)
|
|
510
|
+
|
|
392
511
|
for dimension, units_dict in UnitValue.UNITS["METRIC"].items():
|
|
393
512
|
temp = {}
|
|
394
513
|
self.__process_unit(list(units_dict)[0], temp, 1)
|
|
@@ -446,6 +565,8 @@ class UnitValue: # add specific heat
|
|
|
446
565
|
"""
|
|
447
566
|
Raises UnitValue object to the power of a float or interger.
|
|
448
567
|
"""
|
|
568
|
+
if self.value < 0 and p < 1.0 and not p < -1:
|
|
569
|
+
raise ValueError("Trying to take root of a a negative number")
|
|
449
570
|
if isinstance(p, (int, float)):
|
|
450
571
|
if p == 1:
|
|
451
572
|
return self
|
|
@@ -491,6 +612,10 @@ class UnitValue: # add specific heat
|
|
|
491
612
|
if self.__unit != a.__unit:
|
|
492
613
|
raise TypeError(f"Cannot add unit {self.__unit} and unit {a.__unit}")
|
|
493
614
|
return UnitValue(self.__system, self.__dimension, self.__unit, self.value + a.value)
|
|
615
|
+
if self.__dimension == "TEMPERATURE" and self.__unit != "K" or a.__unit != "K":
|
|
616
|
+
self.convert_base_metric()
|
|
617
|
+
a.convert_base_metric()
|
|
618
|
+
return UnitValue(self.__system, self.__dimension, self.__unit, self.value + a.value - 273.15)
|
|
494
619
|
self.convert_base_metric()
|
|
495
620
|
a.convert_base_metric()
|
|
496
621
|
return UnitValue(self.__system, self.__dimension, self.__unit, self.value + a.value)
|
|
@@ -515,6 +640,10 @@ class UnitValue: # add specific heat
|
|
|
515
640
|
if self.__unit != s.__unit:
|
|
516
641
|
raise TypeError(f"Cannot subtract unit {self.__unit} and unit {s.__unit}")
|
|
517
642
|
return UnitValue(self.__system, self.__dimension, self.__unit, self.value - s.value)
|
|
643
|
+
if self.__dimension == "TEMPERATURE" and self.__unit != "K" or s.__unit != "K":
|
|
644
|
+
self.convert_base_metric()
|
|
645
|
+
s.convert_base_metric()
|
|
646
|
+
return UnitValue(self.__system, self.__dimension, self.__unit, self.value - s.value + 273.15)
|
|
518
647
|
self.convert_base_metric()
|
|
519
648
|
s.convert_base_metric()
|
|
520
649
|
return UnitValue(self.__system, self.__dimension, self.__unit, self.value - s.value)
|
|
@@ -620,10 +749,10 @@ class UnitValue: # add specific heat
|
|
|
620
749
|
|
|
621
750
|
def __round__(self, ndigits: int=0) -> 'UnitValue':
|
|
622
751
|
"""
|
|
623
|
-
|
|
752
|
+
Returns Rounded UnitValue to ndigts
|
|
624
753
|
"""
|
|
625
|
-
|
|
626
|
-
return self
|
|
754
|
+
value = round(self.value, ndigits)
|
|
755
|
+
return UnitValue(self.__system, self.__dimension, self.__unit, value)
|
|
627
756
|
|
|
628
757
|
def __repr__(self) -> str:
|
|
629
758
|
return f"{self.value} {self.__unit}"
|
|
@@ -674,7 +803,7 @@ class UnitValue: # add specific heat
|
|
|
674
803
|
if func is np.concatenate:
|
|
675
804
|
unit_cache = []
|
|
676
805
|
for arr in args[0]:
|
|
677
|
-
unit_cache += [item.
|
|
806
|
+
unit_cache += [item.unit if isinstance(item, UnitValue) else None for item in arr]
|
|
678
807
|
for i in range(len(arr)):
|
|
679
808
|
arr[i] = arr[i].value if isinstance(arr[i], UnitValue) else arr[i]
|
|
680
809
|
new_array = np.concatenate(args[0], **kwargs)
|
|
@@ -710,58 +839,8 @@ class UnitValue: # add specific heat
|
|
|
710
839
|
self.__unit = unit
|
|
711
840
|
else:
|
|
712
841
|
raise Exception(f"Unit {unit} invalid: Unit must be {list(UnitValue.UNITS[self.__system][self.__dimension].keys())} for {self.__system} {self.__dimension}")
|
|
713
|
-
|
|
714
|
-
def copy(self) -> 'UnitValue':
|
|
715
|
-
return UnitValue(self.__system, self.__dimension, self.__unit, self.value)
|
|
716
842
|
|
|
717
|
-
def
|
|
718
|
-
if new_unit == "K":
|
|
719
|
-
if old_unit == "c":
|
|
720
|
-
self.value += 273.15
|
|
721
|
-
elif old_unit == "f":
|
|
722
|
-
self.value = (self.value - 32) * (5/9) + 273.15
|
|
723
|
-
elif old_unit == "R":
|
|
724
|
-
self.value *= 5/9
|
|
725
|
-
elif new_unit == "c":
|
|
726
|
-
if old_unit == "K":
|
|
727
|
-
self.value -= 273.15
|
|
728
|
-
elif old_unit == "f":
|
|
729
|
-
self.value = (self.value - 32) * (5/9)
|
|
730
|
-
elif old_unit == "R":
|
|
731
|
-
self.value = (self.value - 491.67) * (5/9)
|
|
732
|
-
elif new_unit == "f":
|
|
733
|
-
if old_unit == "K":
|
|
734
|
-
self.value = ((self.value -273.15) / (5/9)) + 32
|
|
735
|
-
elif old_unit == "c":
|
|
736
|
-
self.value = (self.value / (5/9)) + 32
|
|
737
|
-
elif old_unit == "R":
|
|
738
|
-
self.value -= 459.67
|
|
739
|
-
elif new_unit == "R":
|
|
740
|
-
if old_unit == "c":
|
|
741
|
-
self.value = self.value * (9/5) + 491.67
|
|
742
|
-
elif old_unit == "f":
|
|
743
|
-
self.value += 459.67
|
|
744
|
-
elif old_unit == "K":
|
|
745
|
-
self.value *= 1.8
|
|
746
|
-
|
|
747
|
-
def __convert_temp(self, change_system: bool, unit: str=""):
|
|
748
|
-
if change_system:
|
|
749
|
-
self.__system = "IMPERIAL" if self.__system == "METRIC" else "METRIC"
|
|
750
|
-
if unit in UnitValue.UNITS[self.__system][self.__dimension].keys():
|
|
751
|
-
self.__temperature_handler(self.__unit, unit)
|
|
752
|
-
self.__unit = unit
|
|
753
|
-
else:
|
|
754
|
-
raise Exception(f"Unit {unit} invalid: Unit must be {list(UnitValue.UNITS[self.__system][self.__dimension].keys())} for {self.__system} {self.__dimension}")
|
|
755
|
-
elif unit:
|
|
756
|
-
if unit in UnitValue.UNITS[self.__system][self.__dimension].keys():
|
|
757
|
-
self.__temperature_handler(self.__unit, unit)
|
|
758
|
-
self.__unit = unit
|
|
759
|
-
else:
|
|
760
|
-
raise Exception(f"Unit {unit} invalid: Unit must be {list(UnitValue.UNITS[self.__system][self.__dimension].keys())} for {self.__system} {self.__dimension}")
|
|
761
|
-
else:
|
|
762
|
-
raise Exception("No conversion performed as change_system was false and unit was empty")
|
|
763
|
-
|
|
764
|
-
def convert_base_metric(self) -> 'UnitValue':
|
|
843
|
+
def convert_base_metric(self, **kwargs) -> 'UnitValue':
|
|
765
844
|
"""
|
|
766
845
|
Convert the current value to it's base SI/Metric unit.
|
|
767
846
|
|
|
@@ -770,17 +849,74 @@ class UnitValue: # add specific heat
|
|
|
770
849
|
"""
|
|
771
850
|
if self.__system is None:
|
|
772
851
|
return
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
|
|
852
|
+
|
|
853
|
+
if self.__unit == "SCFM" or self.__unit == "SLPM":
|
|
854
|
+
try:
|
|
855
|
+
return self.__standard_flowrate_handler("m^3/s", kwargs["temperature"], kwargs["pressure"])
|
|
856
|
+
except Exception as e:
|
|
857
|
+
raise ValueError(f"Was unable to convert flow rate to standard metric unit. You have ommited the required key word arguments (temperature and pressure) when converting from or to SLPM or SCFM. Occured Error: {e}")
|
|
858
|
+
|
|
859
|
+
self.value *= UnitValue.UNITS[self.__system][self.__dimension][self.__unit]
|
|
860
|
+
self.__system = "METRIC"
|
|
861
|
+
self.__unit = list(UnitValue.UNITS[self.__system][self.__dimension].keys())[0]
|
|
862
|
+
return self
|
|
863
|
+
|
|
864
|
+
def __standard_flowrate_handler(self, unit:str, temperature: 'UnitValue', pressure: 'UnitValue') -> 'UnitValue':
|
|
865
|
+
'''Handles the standard flow rate conversions which involve knwoing orher properties opf the fluid'''
|
|
866
|
+
std_temp = UnitValue("METRIC", "TEMPERATURE", "K", 273.15)
|
|
867
|
+
std_pressure = UnitValue("IMPERIAL", "PRESSURE", "psi", 14.504)
|
|
868
|
+
if self.__unit == "SLPM":
|
|
869
|
+
if unit == "SCFM":
|
|
870
|
+
self.value /= 28.316847
|
|
871
|
+
self.__dimension = "IMPERIAL"
|
|
872
|
+
self.__unit = "SCFM"
|
|
873
|
+
return self
|
|
874
|
+
|
|
875
|
+
self.value = (self.value * (temperature/std_temp) * (std_pressure/pressure)) / 60000 # converted to base metric
|
|
876
|
+
other_system = "IMPERIAL" if self.__system == "METRIC" else "METRIC"
|
|
877
|
+
if unit in UnitValue.UNITS[self.__system][self.__dimension]:
|
|
878
|
+
self.value /= UnitValue.UNITS[self.__system][self.__dimension][unit]
|
|
879
|
+
elif unit in UnitValue.UNITS[other_system][self.__dimension]:
|
|
880
|
+
self.value /= UnitValue.UNITS[other_system][self.__dimension][unit]
|
|
881
|
+
self.__system = other_system
|
|
882
|
+
else:
|
|
883
|
+
raise TypeError(f"Cannot convert unit of dimension {self.__dimension} to {unit}")
|
|
884
|
+
self.__unit = unit
|
|
885
|
+
|
|
886
|
+
elif self.__unit == "SCFM":
|
|
887
|
+
if unit == "SLPM":
|
|
888
|
+
self.value *= 28.316847
|
|
889
|
+
self.__dimension = "METRIC"
|
|
890
|
+
self.__unit = "SLPM"
|
|
891
|
+
return self
|
|
892
|
+
|
|
893
|
+
self.value = ((self.value*28.316847) * (temperature/std_temp) * (std_pressure/pressure)) / 60000 # converted to base metric
|
|
894
|
+
other_system = "IMPERIAL" if self.__system == "METRIC" else "METRIC"
|
|
895
|
+
if unit in UnitValue.UNITS[self.__system][self.__dimension]:
|
|
896
|
+
self.value /= UnitValue.UNITS[self.__system][self.__dimension][unit]
|
|
897
|
+
elif unit in UnitValue.UNITS[other_system][self.__dimension]:
|
|
898
|
+
self.value /= UnitValue.UNITS[other_system][self.__dimension][unit]
|
|
899
|
+
self.__system = other_system
|
|
900
|
+
else:
|
|
901
|
+
raise TypeError(f"Cannot convert unit of dimension {self.__dimension} to {unit}")
|
|
902
|
+
self.__unit = unit
|
|
903
|
+
|
|
777
904
|
else:
|
|
778
|
-
self.
|
|
779
|
-
|
|
780
|
-
|
|
905
|
+
self.value *= UnitValue.UNITS[self.__system][self.__dimension][self.__unit]
|
|
906
|
+
if unit == "SLPM":
|
|
907
|
+
self.value = (self.value * 60000) * (std_temp/temperature) * (pressure/std_pressure)
|
|
908
|
+
self.__system = "METRIC"
|
|
909
|
+
self.__unit = "SLPM"
|
|
910
|
+
|
|
911
|
+
elif unit == "SCFM":
|
|
912
|
+
self.value = ((self.value * 60000) * (std_temp/temperature) * (pressure/std_pressure)) / 28.316847
|
|
913
|
+
self.__system = "IMPERIAL"
|
|
914
|
+
self.__unit = "SCFM"
|
|
915
|
+
|
|
781
916
|
return self
|
|
917
|
+
|
|
782
918
|
|
|
783
|
-
def to(self, unit:str) -> 'UnitValue':
|
|
919
|
+
def to(self, unit:str, **kwargs) -> 'UnitValue':
|
|
784
920
|
"""
|
|
785
921
|
Convert the current value to a new unit.
|
|
786
922
|
|
|
@@ -794,23 +930,28 @@ class UnitValue: # add specific heat
|
|
|
794
930
|
Exception: If the unit is not recognized or conversion is not possible.
|
|
795
931
|
"""
|
|
796
932
|
u = UnitValue.SPELLING_MAP.get(unit)
|
|
797
|
-
if u: unit
|
|
933
|
+
if u: unit = u
|
|
934
|
+
|
|
935
|
+
if unit == self.unit: return self
|
|
936
|
+
|
|
937
|
+
other_system = "IMPERIAL" if self.__system == "METRIC" else "METRIC"
|
|
798
938
|
|
|
799
939
|
cache_key = (self.__system, self.__dimension, self.__unit, unit)
|
|
800
940
|
if cache_key in self._conversion_cache:
|
|
801
941
|
cached_value = self._conversion_cache[cache_key]
|
|
802
|
-
|
|
942
|
+
if unit in UnitValue.UNITS[self.__system][self.__dimension]:
|
|
943
|
+
return UnitValue(self.__system, self.__dimension, unit, cached_value)
|
|
944
|
+
else:
|
|
945
|
+
return UnitValue(other_system, self.__dimension, unit, cached_value)
|
|
946
|
+
|
|
947
|
+
if unit == "SCFM" or unit == "SLPM" or self.__unit == "SCFM" or self.__unit == "SLPM":
|
|
948
|
+
try:
|
|
949
|
+
return self.__standard_flowrate_handler(unit, kwargs["temperature"], kwargs["pressure"])
|
|
950
|
+
except Exception as e:
|
|
951
|
+
raise ValueError(f"Was unable to convert flow rate to standard metric unit. You have ommited the required key word arguments (temperature and pressure) when converting from or to SLPM or SCFM. Occured Error: {e}")
|
|
803
952
|
|
|
804
|
-
other_system = "IMPERIAL" if self.__system == "METRIC" else "METRIC"
|
|
805
953
|
if self.__system is None:
|
|
806
954
|
raise Exception(f"Invalid unit {self.__unit}: this unit is not currently supported by the module")
|
|
807
|
-
elif self.__dimension == "TEMPERATURE":
|
|
808
|
-
if unit in UnitValue.UNITS[self.__system][self.__dimension]:
|
|
809
|
-
self.__convert_temp(False, unit)
|
|
810
|
-
elif unit in UnitValue.UNITS[other_system][self.__dimension]:
|
|
811
|
-
self.__convert_temp(True, unit)
|
|
812
|
-
else:
|
|
813
|
-
raise TypeError(f"Cannot convert unit of dimension {self.__dimension} to {unit}")
|
|
814
955
|
else:
|
|
815
956
|
if unit in UnitValue.UNITS[self.__system][self.__dimension]:
|
|
816
957
|
self.__convert_unit(unit)
|
|
@@ -821,6 +962,10 @@ class UnitValue: # add specific heat
|
|
|
821
962
|
|
|
822
963
|
self._conversion_cache[cache_key] = self.value
|
|
823
964
|
return self
|
|
965
|
+
|
|
966
|
+
def copy(self) -> 'UnitValue':
|
|
967
|
+
'''Returns copy of the unit that can be used without changing the original unit, i.e. not a soft copy'''
|
|
968
|
+
return UnitValue(self.__system, self.__dimension, self.__unit, self.value)
|
|
824
969
|
|
|
825
970
|
def to_dict(self) -> dict:
|
|
826
971
|
"""
|
|
@@ -837,14 +982,15 @@ class UnitValue: # add specific heat
|
|
|
837
982
|
}
|
|
838
983
|
|
|
839
984
|
@property
|
|
840
|
-
def
|
|
985
|
+
def unit(self) -> str:
|
|
841
986
|
return self.__unit
|
|
842
987
|
|
|
843
988
|
@property
|
|
844
|
-
def
|
|
989
|
+
def dimension(self) -> str:
|
|
845
990
|
return self.__dimension
|
|
846
991
|
|
|
847
992
|
@property
|
|
848
|
-
def
|
|
993
|
+
def system(self) -> str:
|
|
849
994
|
return self.__system
|
|
850
995
|
|
|
996
|
+
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|