metrolopy 0.6.5__py3-none-any.whl → 1.0.0__py3-none-any.whl
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.
- metrolopy/__init__.py +5 -4
- metrolopy/budget.py +61 -50
- metrolopy/builtin_constants.py +903 -0
- metrolopy/constant.py +108 -104
- metrolopy/constcom.py +84 -83
- metrolopy/distributions.py +120 -39
- metrolopy/exceptions.py +7 -9
- metrolopy/fit.py +3 -3
- metrolopy/functions.py +4 -4
- metrolopy/gummy.py +554 -514
- metrolopy/indexed.py +69 -20
- metrolopy/logunit.py +1 -1
- metrolopy/mean.py +8 -9
- metrolopy/miscunits.py +21 -6
- metrolopy/nummy.py +208 -158
- metrolopy/offsetunit.py +2 -3
- metrolopy/prefixedunit.py +24 -23
- metrolopy/relunits.py +1 -2
- metrolopy/siunits.py +7 -5
- metrolopy/tests/__init__.py +6 -6
- metrolopy/tests/test_create.py +7 -6
- metrolopy/tests/test_gummy.py +5 -43
- metrolopy/tests/test_misc.py +1 -0
- metrolopy/tests/test_operations.py +3 -2
- metrolopy/tests/test_ubreakdown.py +3 -2
- metrolopy/ummy.py +889 -897
- metrolopy/unit.py +287 -182
- metrolopy/unitparser.py +40 -42
- metrolopy/unitutils.py +183 -159
- metrolopy/usunits.py +14 -13
- metrolopy/version.py +1 -1
- {metrolopy-0.6.5.dist-info → metrolopy-1.0.0.dist-info}/METADATA +20 -2
- metrolopy-1.0.0.dist-info/RECORD +45 -0
- metrolopy-0.6.5.dist-info/RECORD +0 -44
- {metrolopy-0.6.5.dist-info → metrolopy-1.0.0.dist-info}/WHEEL +0 -0
- {metrolopy-0.6.5.dist-info → metrolopy-1.0.0.dist-info}/licenses/LICENSE +0 -0
- {metrolopy-0.6.5.dist-info → metrolopy-1.0.0.dist-info}/top_level.txt +0 -0
- {metrolopy-0.6.5.dist-info → metrolopy-1.0.0.dist-info}/zip-safe +0 -0
metrolopy/unitparser.py
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
# module unitparser
|
|
4
4
|
|
|
5
|
-
# Copyright (C)
|
|
5
|
+
# Copyright (C) 2025 National Research Council Canada
|
|
6
6
|
# Author: Harold Parks
|
|
7
7
|
|
|
8
8
|
# This file is part of MetroloPy.
|
|
@@ -26,6 +26,36 @@ unit parser
|
|
|
26
26
|
|
|
27
27
|
from .exceptions import UnitLibError
|
|
28
28
|
import numpy as np
|
|
29
|
+
from fractions import Fraction
|
|
30
|
+
|
|
31
|
+
def _get_num(txt):
|
|
32
|
+
s = 1
|
|
33
|
+
txt = txt.strip()
|
|
34
|
+
if txt.startswith('-'):
|
|
35
|
+
s = -s
|
|
36
|
+
txt = txt[1:]
|
|
37
|
+
elif txt.startswith('+'):
|
|
38
|
+
txt = txt[1:]
|
|
39
|
+
txt = txt.lstrip(' (').rstrip(' )')
|
|
40
|
+
if txt.startswith('-'):
|
|
41
|
+
s = -s
|
|
42
|
+
txt = txt[1:]
|
|
43
|
+
elif txt.startswith('+'):
|
|
44
|
+
txt = txt[1:]
|
|
45
|
+
f = float(txt)
|
|
46
|
+
if np.modf(f)[0] == 0:
|
|
47
|
+
return s*int(f)
|
|
48
|
+
else:
|
|
49
|
+
return s*f
|
|
50
|
+
|
|
51
|
+
def _get_exp(txt):
|
|
52
|
+
txt = txt.split('/')
|
|
53
|
+
if len(txt) == 1:
|
|
54
|
+
return _get_num(txt[0])
|
|
55
|
+
elif len(txt) == 2:
|
|
56
|
+
return Fraction(_get_num(txt[0]),_get_num(txt[1]))
|
|
57
|
+
else:
|
|
58
|
+
raise UnitLibError('syntax error in exponent: ' + txt)
|
|
29
59
|
|
|
30
60
|
class _UnitParser:
|
|
31
61
|
def __init__(self,txt):
|
|
@@ -135,11 +165,7 @@ class _UnitParser:
|
|
|
135
165
|
if c == '(':
|
|
136
166
|
if par == 0:
|
|
137
167
|
if cl.isspace() or cl == '*':
|
|
138
|
-
|
|
139
|
-
if np.modf(f)[0] == 0:
|
|
140
|
-
return int(f)
|
|
141
|
-
else:
|
|
142
|
-
return f
|
|
168
|
+
return _get_exp(et)
|
|
143
169
|
raise UnitLibError('syntax error in: ' + self.txt)
|
|
144
170
|
else:
|
|
145
171
|
if par == -1:
|
|
@@ -148,39 +174,23 @@ class _UnitParser:
|
|
|
148
174
|
par += 1
|
|
149
175
|
elif c == '[':
|
|
150
176
|
if cl.isspace() or cl == '*':
|
|
151
|
-
|
|
152
|
-
if np.modf(f)[0] == 0:
|
|
153
|
-
return int(f)
|
|
154
|
-
else:
|
|
155
|
-
return f
|
|
177
|
+
return _get_exp(et)
|
|
156
178
|
raise UnitLibError('syntax error in: ' + self.txt )
|
|
157
179
|
elif c == ']':
|
|
158
180
|
raise UnitLibError('unmatched bracket: ' + self.txt)
|
|
159
181
|
elif c.isalpha():
|
|
160
182
|
if par > 0:
|
|
161
183
|
raise UnitLibError('syntax error in: ' + self.txt)
|
|
162
|
-
|
|
163
|
-
if np.modf(f)[0] == 0:
|
|
164
|
-
return int(f)
|
|
165
|
-
else:
|
|
166
|
-
return f
|
|
184
|
+
return _get_exp(et)
|
|
167
185
|
elif c == '/':
|
|
168
186
|
if par <= 0:
|
|
169
|
-
|
|
170
|
-
if np.modf(f)[0] == 0:
|
|
171
|
-
return int(f)
|
|
172
|
-
else:
|
|
173
|
-
return f
|
|
187
|
+
return _get_exp(et)
|
|
174
188
|
elif c == ')':
|
|
175
189
|
if par <= 0:
|
|
176
|
-
|
|
177
|
-
if np.modf(f)[0] == 0:
|
|
178
|
-
return int(f)
|
|
179
|
-
else:
|
|
180
|
-
return f
|
|
190
|
+
return _get_exp(et)
|
|
181
191
|
else:
|
|
182
192
|
par -= 1
|
|
183
|
-
elif c.isnumeric():
|
|
193
|
+
elif c.isnumeric() or c =='.':
|
|
184
194
|
stnum = True
|
|
185
195
|
elif c == '+' or c == '-':
|
|
186
196
|
if stnum and par <= 0:
|
|
@@ -190,30 +200,18 @@ class _UnitParser:
|
|
|
190
200
|
raise UnitLibError('syntax error in: ' + self.txt)
|
|
191
201
|
if par <= 0 and cl != '*' and self.txt[self.i+1] != '*':
|
|
192
202
|
self.i += 1
|
|
193
|
-
|
|
194
|
-
if np.modf(f)[0] == 0:
|
|
195
|
-
return int(f)
|
|
196
|
-
else:
|
|
197
|
-
return f
|
|
203
|
+
return _get_exp(et)
|
|
198
204
|
elif c.isspace():
|
|
199
205
|
if stnum and par <= 0:
|
|
200
206
|
self.i += 1
|
|
201
|
-
|
|
202
|
-
if np.modf(f)[0] == 0:
|
|
203
|
-
return int(f)
|
|
204
|
-
else:
|
|
205
|
-
return f
|
|
207
|
+
return _get_exp(et)
|
|
206
208
|
else:
|
|
207
209
|
if par <= 0:
|
|
208
210
|
raise UnitLibError('syntax error in: ' + self.txt)
|
|
209
211
|
self.i += 1
|
|
210
212
|
cl = c
|
|
211
213
|
et += c
|
|
212
|
-
|
|
213
|
-
if np.modf(f)[0] == 0:
|
|
214
|
-
return int(f)
|
|
215
|
-
else:
|
|
216
|
-
return f
|
|
214
|
+
return _get_exp(et)
|
|
217
215
|
|
|
218
216
|
elif not c.isspace():
|
|
219
217
|
return 1
|
metrolopy/unitutils.py
CHANGED
|
@@ -26,7 +26,7 @@ the search_units, shadow_units, and convert functions are defined here
|
|
|
26
26
|
from .gummy import gummy
|
|
27
27
|
from .ummy import ummy
|
|
28
28
|
from .unit import Unit,one,Quantity
|
|
29
|
-
from .printing import PrettyPrinter
|
|
29
|
+
from .printing import PrettyPrinter
|
|
30
30
|
|
|
31
31
|
|
|
32
32
|
def _mrtxt(txt,fmt):
|
|
@@ -36,17 +36,163 @@ def _mrtxt(txt,fmt):
|
|
|
36
36
|
txt = txt.replace('#','\\#')
|
|
37
37
|
return txt
|
|
38
38
|
|
|
39
|
-
class
|
|
40
|
-
|
|
41
|
-
|
|
39
|
+
class search_units_result(PrettyPrinter):
|
|
40
|
+
"""
|
|
41
|
+
A `search_units_result` instance emulates a list of units returned
|
|
42
|
+
from a 'search_units` function call, and pretty-prints the results to
|
|
43
|
+
the output
|
|
44
|
+
"""
|
|
45
|
+
|
|
46
|
+
def __init__(self,units,show_all):
|
|
42
47
|
self.show_all = show_all
|
|
43
|
-
self.
|
|
48
|
+
self._units = units
|
|
49
|
+
self.units = [u[1] for u in units]
|
|
44
50
|
|
|
45
51
|
def tostring(self,fmt='unicode',**kwds):
|
|
46
|
-
return search_units(self.search,fmt=fmt,show_all=self.show_all,
|
|
47
|
-
units=self.units,
|
|
52
|
+
#return search_units(self.search,fmt=fmt,show_all=self.show_all,
|
|
53
|
+
#units=self.units,converts_to=self.converts_to,
|
|
54
|
+
#prnt=False)
|
|
55
|
+
|
|
56
|
+
from .prefixedunit import PrefixedUnit
|
|
57
|
+
from .nonlinearunit import NonlinearUnit
|
|
58
|
+
from .offsetunit import OffsetUnit
|
|
59
|
+
from .logunit import LogUnit
|
|
60
|
+
from .unit import _CompositeUnit
|
|
61
|
+
|
|
62
|
+
if fmt == 'latex':
|
|
63
|
+
txt = "<ul style=\"font-family: 'Times New Roman', Times, serif;font-size:1.2em\">\n"
|
|
64
|
+
elif fmt == 'html':
|
|
65
|
+
txt = "<ul>\n"
|
|
66
|
+
else:
|
|
67
|
+
txt = ''
|
|
68
|
+
for u in self._units:
|
|
69
|
+
if fmt in ['latex','html']:
|
|
70
|
+
txt += "<li>"
|
|
71
|
+
try:
|
|
72
|
+
if u[0] != u[1].name:
|
|
73
|
+
txt += u[0] + ', alias for: '
|
|
74
|
+
if isinstance(u[1],_CompositeUnit):
|
|
75
|
+
stxt = u[1].tostring(fmt=fmt)
|
|
76
|
+
if fmt == 'latex':
|
|
77
|
+
txt += '$ ' + stxt + ' $'
|
|
78
|
+
else:
|
|
79
|
+
txt += stxt
|
|
80
|
+
else:
|
|
81
|
+
txt += _mrtxt(u[1].name,fmt)
|
|
82
|
+
else:
|
|
83
|
+
u = u[1]
|
|
84
|
+
txt += u.name
|
|
85
|
+
ttxt = ''
|
|
86
|
+
if isinstance(u,PrefixedUnit) and not self.show_all:
|
|
87
|
+
if not self.show_all:
|
|
88
|
+
if len(u.prefixes) == 1:
|
|
89
|
+
ttxt = '1 prefix'
|
|
90
|
+
else:
|
|
91
|
+
ttxt = str(len(u.prefixes)) + ' prefixes'
|
|
92
|
+
elif isinstance(u,LogUnit):
|
|
93
|
+
bse = u.conversion.log_base
|
|
94
|
+
if isinstance(bse,Quantity):
|
|
95
|
+
bse = bse.value
|
|
96
|
+
if isinstance(bse,ummy):
|
|
97
|
+
bse = bse.x
|
|
98
|
+
if (round(bse,3) - 2.718) < 0.001:
|
|
99
|
+
if fmt == 'latex':
|
|
100
|
+
ttxt += ', log base ' + PrettyPrinter.latex_math('e')
|
|
101
|
+
if fmt == 'html':
|
|
102
|
+
ttxt += ', log base <i>e</i>'
|
|
103
|
+
else:
|
|
104
|
+
ttxt += ', log base e'
|
|
105
|
+
else:
|
|
106
|
+
ttxt += ', log base ' + str(u.conversion.log_base)
|
|
107
|
+
ttxt += ', multiplier = ' + str(u.conversion.multiplier)
|
|
108
|
+
elif isinstance(u,NonlinearUnit):
|
|
109
|
+
ttxt += 'non-linear unit'
|
|
110
|
+
|
|
111
|
+
if ttxt.startswith(', '):
|
|
112
|
+
ttxt = ttxt[2:]
|
|
113
|
+
if ttxt != '':
|
|
114
|
+
txt += ' (' + ttxt + ')'
|
|
115
|
+
|
|
116
|
+
if u.conversion is not None:
|
|
117
|
+
try:
|
|
118
|
+
if isinstance(u,OffsetUnit):
|
|
119
|
+
g = gummy(0,unit=u)
|
|
120
|
+
elif isinstance(u,LogUnit):
|
|
121
|
+
g = gummy(u.conversion.offset,unit=u)
|
|
122
|
+
else:
|
|
123
|
+
g = gummy(1,unit=u)
|
|
124
|
+
gc = g.convert(u.conversion.unit)
|
|
125
|
+
ctxt = g.tostring(fmt=fmt)
|
|
126
|
+
if fmt == 'html':
|
|
127
|
+
ctxt += ' = '
|
|
128
|
+
else:
|
|
129
|
+
ctxt += ' = '
|
|
130
|
+
ctxt += gc.tostring(fmt=fmt)
|
|
131
|
+
if fmt == 'latex':
|
|
132
|
+
txt += ', $ ' + ctxt + ' $'
|
|
133
|
+
else:
|
|
134
|
+
txt += ', ' + ctxt
|
|
135
|
+
except:
|
|
136
|
+
raise
|
|
137
|
+
txt += ', ?? = ??'
|
|
138
|
+
elif u is not one:
|
|
139
|
+
if fmt == 'latex':
|
|
140
|
+
txt += ', symbol: $ ' + u.tostring(fmt=fmt) + ' $'
|
|
141
|
+
else:
|
|
142
|
+
txt += ', symbol: ' + u.tostring(fmt=fmt)
|
|
143
|
+
|
|
144
|
+
aliases = u.aliases
|
|
145
|
+
if len(aliases) == 1:
|
|
146
|
+
txt += ', alias: ' + _mrtxt(aliases.pop(),fmt)
|
|
147
|
+
if len(aliases) > 1:
|
|
148
|
+
txt += ', aliases: '
|
|
149
|
+
if u.short_name in aliases:
|
|
150
|
+
txt += _mrtxt(u.short_name,fmt) + ', '
|
|
151
|
+
aliases.remove(u.short_name)
|
|
152
|
+
txt += _mrtxt(', '.join(sorted(aliases,key=str.lower)),fmt)
|
|
153
|
+
|
|
154
|
+
saliases = u.shadowed_aliases
|
|
155
|
+
if len(saliases) > 0:
|
|
156
|
+
if len(aliases) > 0:
|
|
157
|
+
txt += '; '
|
|
158
|
+
else:
|
|
159
|
+
txt += ', '
|
|
160
|
+
if len(saliases) == 1:
|
|
161
|
+
txt += 'shadowed alias: ' + _mrtxt(saliases.pop(),fmt)
|
|
162
|
+
else:
|
|
163
|
+
txt += 'shadowed aliases: ' + _mrtxt(', '.join(sorted(saliases,key=str.lower)),fmt)
|
|
164
|
+
except:
|
|
165
|
+
raise
|
|
166
|
+
txt += '??'
|
|
167
|
+
|
|
168
|
+
if fmt == 'html' or fmt == 'latex':
|
|
169
|
+
txt += '</li>\n'
|
|
170
|
+
else:
|
|
171
|
+
txt += '\n'
|
|
172
|
+
|
|
173
|
+
txt = txt[:-1]
|
|
174
|
+
if fmt in ['latex','html']:
|
|
175
|
+
txt += '</ul>'
|
|
176
|
+
|
|
177
|
+
return txt
|
|
48
178
|
|
|
49
|
-
def
|
|
179
|
+
def __len__(self):
|
|
180
|
+
return len(self.units)
|
|
181
|
+
|
|
182
|
+
def __getitem__(self,i):
|
|
183
|
+
return self.units[i]
|
|
184
|
+
|
|
185
|
+
def __iter__(self):
|
|
186
|
+
return iter(self.units)
|
|
187
|
+
|
|
188
|
+
def __reversed__(self):
|
|
189
|
+
return reversed(self.units)
|
|
190
|
+
|
|
191
|
+
def __contains__(self,item):
|
|
192
|
+
return item in self.units
|
|
193
|
+
|
|
194
|
+
def search_units(search=None,fmt=None,show_all=False,units=None,
|
|
195
|
+
converts_to=None):
|
|
50
196
|
"""
|
|
51
197
|
Prints a list of all loaded units or all units that match the search terms.
|
|
52
198
|
|
|
@@ -72,23 +218,20 @@ def search_units(search=None,fmt=None,show_all=False,units=None,prnt=True):
|
|
|
72
218
|
A list of units to print. If this parameter is specified the values
|
|
73
219
|
of the search and `show_all` parameters are ignored.
|
|
74
220
|
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
221
|
+
Returns
|
|
222
|
+
-------
|
|
223
|
+
A `search_units_result` instance which emulates a list of the returned
|
|
224
|
+
constants and pretty-prints the results to the output or `None` if no
|
|
225
|
+
units are found.
|
|
78
226
|
"""
|
|
79
227
|
from importlib import import_module
|
|
80
|
-
|
|
81
|
-
from .nonlinearunit import NonlinearUnit
|
|
82
|
-
from .offsetunit import OffsetUnit
|
|
83
|
-
from .logunit import LogUnit
|
|
228
|
+
|
|
84
229
|
from .unit import _CompositeUnit
|
|
85
230
|
|
|
86
|
-
if fmt is None
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
if fmt == 'utf-8':
|
|
91
|
-
fmt = 'unicode'
|
|
231
|
+
if fmt is not None:
|
|
232
|
+
fmt = fmt.lower().strip()
|
|
233
|
+
if fmt == 'utf-8':
|
|
234
|
+
fmt = 'unicode'
|
|
92
235
|
|
|
93
236
|
if units is None:
|
|
94
237
|
while len(Unit._builtins_to_import) > 0:
|
|
@@ -96,12 +239,20 @@ def search_units(search=None,fmt=None,show_all=False,units=None,prnt=True):
|
|
|
96
239
|
|
|
97
240
|
units = set(Unit._builtin_lib.values()).union(set(Unit._lib.values()))
|
|
98
241
|
|
|
99
|
-
if
|
|
242
|
+
if converts_to is not None:
|
|
243
|
+
uf = set()
|
|
244
|
+
bunit = Unit.unit(converts_to)
|
|
245
|
+
if isinstance(bunit,_CompositeUnit):
|
|
246
|
+
raise TypeError('converts_to may not be a composite unit')
|
|
247
|
+
bunit = bunit.base
|
|
248
|
+
for u in units:
|
|
249
|
+
if not isinstance(u,_CompositeUnit) and u.base is bunit:
|
|
250
|
+
uf.add(u)
|
|
251
|
+
units = uf
|
|
252
|
+
elif search is None:
|
|
100
253
|
if len(units) == 0:
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
return
|
|
104
|
-
return ''
|
|
254
|
+
print('no units are loaded')
|
|
255
|
+
return None
|
|
105
256
|
else:
|
|
106
257
|
uf = set()
|
|
107
258
|
for u in units:
|
|
@@ -134,10 +285,8 @@ def search_units(search=None,fmt=None,show_all=False,units=None,prnt=True):
|
|
|
134
285
|
|
|
135
286
|
units = uf
|
|
136
287
|
if len(units) == 0:
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
return
|
|
140
|
-
return ''
|
|
288
|
+
print('no units found matching "' + search + '"')
|
|
289
|
+
return None
|
|
141
290
|
|
|
142
291
|
if not show_all:
|
|
143
292
|
units = [u for u in units if u.parent is None or u.parent not in units]
|
|
@@ -171,133 +320,12 @@ def search_units(search=None,fmt=None,show_all=False,units=None,prnt=True):
|
|
|
171
320
|
|
|
172
321
|
units = sorted(units,key=lambda u:u[0].lower())
|
|
173
322
|
|
|
174
|
-
|
|
175
|
-
txt = "<ul style=\"font-family: 'Times New Roman', Times, serif;font-size:1.2em\">\n"
|
|
176
|
-
elif fmt == 'html':
|
|
177
|
-
txt = "<ul>\n"
|
|
178
|
-
else:
|
|
179
|
-
txt = ''
|
|
180
|
-
for u in units:
|
|
181
|
-
if fmt in ['latex','html']:
|
|
182
|
-
txt += "<li>"
|
|
183
|
-
try:
|
|
184
|
-
if u[0] != u[1].name:
|
|
185
|
-
txt += u[0] + ', alias for: '
|
|
186
|
-
if isinstance(u[1],_CompositeUnit):
|
|
187
|
-
stxt = u[1].tostring(fmt=fmt)
|
|
188
|
-
if fmt == 'latex':
|
|
189
|
-
txt += '$ ' + stxt + ' $'
|
|
190
|
-
else:
|
|
191
|
-
txt += stxt
|
|
192
|
-
else:
|
|
193
|
-
txt += _mrtxt(u[1].name,fmt)
|
|
194
|
-
else:
|
|
195
|
-
u = u[1]
|
|
196
|
-
txt += u.name
|
|
197
|
-
ttxt = ''
|
|
198
|
-
if isinstance(u,PrefixedUnit) and not show_all:
|
|
199
|
-
if not show_all:
|
|
200
|
-
if len(u.prefixes) == 1:
|
|
201
|
-
ttxt = '1 prefix'
|
|
202
|
-
else:
|
|
203
|
-
ttxt = str(len(u.prefixes)) + ' prefixes'
|
|
204
|
-
elif isinstance(u,LogUnit):
|
|
205
|
-
bse = u.conversion.log_base
|
|
206
|
-
if isinstance(bse,Quantity):
|
|
207
|
-
bse = bse.value
|
|
208
|
-
if isinstance(bse,ummy):
|
|
209
|
-
bse = bse.x
|
|
210
|
-
if (round(bse,3) - 2.718) < 0.001:
|
|
211
|
-
if fmt == 'latex':
|
|
212
|
-
ttxt += ', log base ' + PrettyPrinter.latex_math('e')
|
|
213
|
-
if fmt == 'html':
|
|
214
|
-
ttxt += ', log base <i>e</i>'
|
|
215
|
-
else:
|
|
216
|
-
ttxt += ', log base e'
|
|
217
|
-
else:
|
|
218
|
-
ttxt += ', log base ' + str(u.conversion.log_base)
|
|
219
|
-
ttxt += ', multiplier = ' + str(u.conversion.multiplier)
|
|
220
|
-
elif isinstance(u,NonlinearUnit):
|
|
221
|
-
ttxt += 'non-linear unit'
|
|
222
|
-
|
|
223
|
-
if ttxt.startswith(', '):
|
|
224
|
-
ttxt = ttxt[2:]
|
|
225
|
-
if ttxt != '':
|
|
226
|
-
txt += ' (' + ttxt + ')'
|
|
227
|
-
|
|
228
|
-
if u.conversion is not None:
|
|
229
|
-
try:
|
|
230
|
-
if isinstance(u,OffsetUnit):
|
|
231
|
-
g = gummy(0,unit=u)
|
|
232
|
-
elif isinstance(u,LogUnit):
|
|
233
|
-
g = gummy(u.conversion.offset,unit=u)
|
|
234
|
-
else:
|
|
235
|
-
g = gummy(1,unit=u)
|
|
236
|
-
gc = g.convert(u.conversion.unit)
|
|
237
|
-
ctxt = g.tostring(fmt=fmt)
|
|
238
|
-
if fmt == 'html':
|
|
239
|
-
ctxt += ' = '
|
|
240
|
-
else:
|
|
241
|
-
ctxt += ' = '
|
|
242
|
-
ctxt += gc.tostring(fmt=fmt)
|
|
243
|
-
if fmt == 'latex':
|
|
244
|
-
txt += ', $ ' + ctxt + ' $'
|
|
245
|
-
else:
|
|
246
|
-
txt += ', ' + ctxt
|
|
247
|
-
except:
|
|
248
|
-
raise
|
|
249
|
-
txt += ', ?? = ??'
|
|
250
|
-
elif u is not one:
|
|
251
|
-
if fmt == 'latex':
|
|
252
|
-
txt += ', symbol: $ ' + u.tostring(fmt=fmt) + ' $'
|
|
253
|
-
else:
|
|
254
|
-
txt += ', symbol: ' + u.tostring(fmt=fmt)
|
|
255
|
-
|
|
256
|
-
aliases = u.aliases
|
|
257
|
-
if len(aliases) == 1:
|
|
258
|
-
txt += ', alias: ' + _mrtxt(aliases.pop(),fmt)
|
|
259
|
-
if len(aliases) > 1:
|
|
260
|
-
txt += ', aliases: '
|
|
261
|
-
if u.short_name in aliases:
|
|
262
|
-
txt += _mrtxt(u.short_name,fmt) + ', '
|
|
263
|
-
aliases.remove(u.short_name)
|
|
264
|
-
txt += _mrtxt(', '.join(sorted(aliases,key=str.lower)),fmt)
|
|
265
|
-
|
|
266
|
-
saliases = u.shadowed_aliases
|
|
267
|
-
if len(saliases) > 0:
|
|
268
|
-
if len(aliases) > 0:
|
|
269
|
-
txt += '; '
|
|
270
|
-
else:
|
|
271
|
-
txt += ', '
|
|
272
|
-
if len(saliases) == 1:
|
|
273
|
-
txt += 'shadowed alias: ' + _mrtxt(saliases.pop(),fmt)
|
|
274
|
-
else:
|
|
275
|
-
txt += 'shadowed aliases: ' + _mrtxt(', '.join(sorted(saliases,key=str.lower)),fmt)
|
|
276
|
-
except:
|
|
277
|
-
raise
|
|
278
|
-
txt += '??'
|
|
279
|
-
|
|
280
|
-
if fmt == 'html' or fmt == 'latex':
|
|
281
|
-
txt += '</li>\n'
|
|
282
|
-
else:
|
|
283
|
-
txt += '\n'
|
|
284
|
-
|
|
285
|
-
txt = txt[:-1]
|
|
286
|
-
if fmt in ['latex','html']:
|
|
287
|
-
txt += '</ul>'
|
|
288
|
-
|
|
289
|
-
if not prnt:
|
|
290
|
-
return txt
|
|
323
|
+
|
|
291
324
|
|
|
292
|
-
|
|
293
|
-
print_markdown(txt)
|
|
294
|
-
elif fmt == 'html' and ipython_installed:
|
|
295
|
-
print_html(txt)
|
|
296
|
-
else:
|
|
297
|
-
print(txt)
|
|
325
|
+
return search_units_result(units,show_all)
|
|
298
326
|
|
|
299
327
|
|
|
300
|
-
def shadowed_units(fmt=None
|
|
328
|
+
def shadowed_units(fmt=None):
|
|
301
329
|
"""
|
|
302
330
|
Lists any units which have a shadowed name or alias. Units may be shadowed
|
|
303
331
|
if the user has defined a new unit with the same name or alias as an
|
|
@@ -309,14 +337,10 @@ def shadowed_units(fmt=None,prnt=True):
|
|
|
309
337
|
The output format. If `None`, then the `gummy.printer` value is used.
|
|
310
338
|
If latex output is selected, Markdown is actually used with the unit
|
|
311
339
|
symbols and conversion displayed using inline LaTeX.
|
|
312
|
-
|
|
313
|
-
prnt: `bool`, optional
|
|
314
|
-
If this is `True`, the results are printed. If it is `False` the results
|
|
315
|
-
are returned as a string. The default is `True`.
|
|
316
340
|
"""
|
|
317
341
|
units = set(Unit._builtin_lib.values()).union(set(Unit._lib.values()))
|
|
318
342
|
units = [u for u in units if len(u.shadowed_aliases) > 0]
|
|
319
|
-
return search_units(fmt=fmt,units=units
|
|
343
|
+
return search_units(fmt=fmt,units=units)
|
|
320
344
|
|
|
321
345
|
|
|
322
346
|
def convert(amount,from_unit,to_unit):
|
metrolopy/usunits.py
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
# module usunits
|
|
4
4
|
|
|
5
|
-
# Copyright (C)
|
|
5
|
+
# Copyright (C) 2025 National Research Council Canada
|
|
6
6
|
# Author: Harold Parks
|
|
7
7
|
|
|
8
8
|
# This file is part of MetroloPy.
|
|
@@ -31,10 +31,9 @@ NIST Special Publication 1038, "The International System of Units (SI) –
|
|
|
31
31
|
Conversion Factors for General Use", May 2006.
|
|
32
32
|
"""
|
|
33
33
|
|
|
34
|
-
from .unit import Unit,Conversion
|
|
34
|
+
from .unit import Unit,Conversion,MFraction
|
|
35
35
|
from .offsetunit import OffsetUnit,OffsetConversion
|
|
36
36
|
from .prefixedunit import PrefixedUnit
|
|
37
|
-
from .ummy import MFraction
|
|
38
37
|
|
|
39
38
|
with Unit._builtin():
|
|
40
39
|
_in = PrefixedUnit('inch','in',Conversion('m',MFraction('0.0254')),prefixes=['micro'],
|
|
@@ -74,15 +73,15 @@ with Unit._builtin():
|
|
|
74
73
|
|
|
75
74
|
_gal = Unit('gallon','gal',Conversion(_in**3,231),add_symbol=True,description='unit of volume')
|
|
76
75
|
Unit.alias('liquid gallon',_gal)
|
|
77
|
-
Unit.alias('liquid
|
|
76
|
+
Unit.alias('liquid-gal',_gal)
|
|
78
77
|
|
|
79
78
|
_qt = Unit('quart','qt',Conversion(_gal,MFraction(1,4)),add_symbol=True,description='unit of volume')
|
|
80
79
|
Unit.alias('liquid quart',_qt)
|
|
81
|
-
Unit.alias('liquid
|
|
80
|
+
Unit.alias('liquid-qt',_qt)
|
|
82
81
|
|
|
83
82
|
_pt = Unit('pint','pt',Conversion(_qt,MFraction(1,2)),add_symbol=True,description='unit of volume')
|
|
84
83
|
Unit.alias('liquid pint',_pt)
|
|
85
|
-
Unit.alias('liquid
|
|
84
|
+
Unit.alias('liquid-pt',_pt)
|
|
86
85
|
|
|
87
86
|
_cp = Unit('cup','cp',Conversion(_pt,MFraction(1,2)),add_symbol=True,description='unit of volume')
|
|
88
87
|
_gi = Unit('gill','gi',Conversion(_cp,MFraction(1,2)),add_symbol=True,description='unit of volume')
|
|
@@ -97,7 +96,7 @@ with Unit._builtin():
|
|
|
97
96
|
|
|
98
97
|
_bbl = Unit('barrel','bbl',Conversion(_gal,MFraction('31.5')),add_symbol=True,description='unit of volume')
|
|
99
98
|
Unit.alias('liquid barrel',_bbl)
|
|
100
|
-
Unit.alias('liquid
|
|
99
|
+
Unit.alias('liquid-bbl',_bbl)
|
|
101
100
|
|
|
102
101
|
Unit('oil barrel','bbl',Conversion(_gal,42),add_symbol=False,description='unit of volume')
|
|
103
102
|
Unit('hogshead','hogshead',Conversion(_gal,65),add_symbol=True,description='unit of volume')
|
|
@@ -116,7 +115,7 @@ with Unit._builtin():
|
|
|
116
115
|
_lb = PrefixedUnit('pound','lb',Conversion('kg',MFraction('0.45359237')),add_symbol=True,
|
|
117
116
|
prefixes=['micro'],description='unit of mass')
|
|
118
117
|
Unit.alias('avoirdupois pound',_lb)
|
|
119
|
-
Unit.alias('avdp
|
|
118
|
+
Unit.alias('avdp-lb',_lb)
|
|
120
119
|
Unit.alias('lbm',_lb)
|
|
121
120
|
Unit.alias('pound mass',_lb)
|
|
122
121
|
Unit.alias('ulbm','ulb')
|
|
@@ -124,7 +123,7 @@ with Unit._builtin():
|
|
|
124
123
|
|
|
125
124
|
_oz = Unit('ounce','oz',Conversion(_lb,MFraction('0.0625')),add_symbol=True,description='unit of mass')
|
|
126
125
|
Unit.alias('avoirdupois ounce',_oz)
|
|
127
|
-
Unit.alias('avdp
|
|
126
|
+
Unit.alias('avdp-oz',_oz)
|
|
128
127
|
|
|
129
128
|
Unit('dram','dr',Conversion(_oz,MFraction('0.0625')),add_symbol=True,description='unit of mass')
|
|
130
129
|
|
|
@@ -147,14 +146,16 @@ with Unit._builtin():
|
|
|
147
146
|
_degR = Unit('degree Rankine','\u00B0R',Conversion('K',MFraction(5,9)),
|
|
148
147
|
latex_symbol='^{\\circ}R',ascii_symbol='degR',add_symbol=True,
|
|
149
148
|
description='unit of temperature')
|
|
150
|
-
Unit.alias('
|
|
151
|
-
Unit.alias('
|
|
149
|
+
Unit.alias('degreeR',_degR)
|
|
150
|
+
Unit.alias('degree-R',_degR)
|
|
151
|
+
Unit.alias('deg-R',_degR)
|
|
152
152
|
|
|
153
153
|
_degF = OffsetUnit('degree Fahrenheit','\u00B0F',OffsetConversion('degR',MFraction('459.67')),
|
|
154
154
|
latex_symbol='^{\\circ}F',ascii_symbol='degF',add_symbol=True,
|
|
155
155
|
description='unit of temperature')
|
|
156
|
-
Unit.alias('
|
|
157
|
-
Unit.alias('
|
|
156
|
+
Unit.alias('degreeF',_degF)
|
|
157
|
+
Unit.alias('degree-F',_degF)
|
|
158
|
+
Unit.alias('deg-F',_degF)
|
|
158
159
|
|
|
159
160
|
Unit('pound per square inch','psi',Conversion(_lbf*_in**-2),add_symbol=True,
|
|
160
161
|
description='unit of pressure')
|
metrolopy/version.py
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: metrolopy
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 1.0.0
|
|
4
4
|
Summary: tools for dealing with measured quantities: uncertainty propagation and unit conversion
|
|
5
5
|
Home-page: http://nrc-cnrc.github.io/MetroloPy/
|
|
6
6
|
Author: Harold Parks, National Research Council Canada
|
|
@@ -14,7 +14,7 @@ Classifier: License :: OSI Approved :: GNU General Public License v3 (GPLv3)
|
|
|
14
14
|
Classifier: Intended Audience :: Science/Research
|
|
15
15
|
Classifier: Intended Audience :: Education
|
|
16
16
|
Classifier: Topic :: Scientific/Engineering :: Physics
|
|
17
|
-
Requires-Python: >=3.
|
|
17
|
+
Requires-Python: >=3.6
|
|
18
18
|
Description-Content-Type: text/markdown
|
|
19
19
|
License-File: LICENSE
|
|
20
20
|
Requires-Dist: numpy>=1.13
|
|
@@ -73,6 +73,24 @@ MetroloPy can do much more including Monte-Carlo uncertainty propagation, genera
|
|
|
73
73
|
* [a list of the units built into MetroloPy](https://nrc-cnrc.github.io/MetroloPy/_static/units.html)
|
|
74
74
|
* [a list of the physical constants built into MetroloPy](https://nrc-cnrc.github.io/MetroloPy/_static/constants.html)
|
|
75
75
|
|
|
76
|
+
## new in version 1.0.0
|
|
77
|
+
|
|
78
|
+
* The calculation of effective degrees of freedom has been improved. In
|
|
79
|
+
previous versions, in a multi-step calculation, the effective degree of freedom
|
|
80
|
+
were calculated at each step based on the degrees of freedom calculated for the
|
|
81
|
+
previous step (using a modified Welch-Satterthwaite approximation). Now
|
|
82
|
+
effective degrees of freedom are alway calculated directly from the independent
|
|
83
|
+
variables using the Welch-Satterthwaite equation.
|
|
84
|
+
|
|
85
|
+
* CODATA 2022 values instead of 2018 values are used in the Constants module.
|
|
86
|
+
|
|
87
|
+
* The significance value in budget table has been redefined from
|
|
88
|
+
(sensitivity coefficient * standard uncertainty/combined uncertainty) to the
|
|
89
|
+
square of that value so that the significance value sum to one.
|
|
90
|
+
|
|
91
|
+
* Units can now be raised to a fractional power and many other bug fixes.
|
|
92
|
+
|
|
93
|
+
|
|
76
94
|
## new in version 0.6.0
|
|
77
95
|
|
|
78
96
|
* A constant library has been added with physical constants that can be accessed
|