Skip to content

Commit 757ae98

Browse files
committed
Merge master fixes
2 parents ea3032c + 7f318fc commit 757ae98

File tree

4 files changed

+121
-63
lines changed

4 files changed

+121
-63
lines changed

README.md

Lines changed: 2 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -12,16 +12,6 @@ The uncertainty calculations are in accordance with gaussian’s propagation, as
1212

1313
Made by and for Physics Laboratory students in IFSC, who can't use uncertainties.py because of mean’s absolute deviation used in its calculation.
1414

15-
To get this library on google colaboratory:
16-
17-
```
18-
!curl --remote-name \
19-
20-
-H 'Accept: application/vnd.github.v3.raw' \
21-
22-
--location https://raw.githubusercontent.com/phisgroup/labfis.py/development/labfis/main.py
23-
```
24-
2515
## Usage
2616

2717
Just import with `from labfis import labfloat` and create an *labfloat* object, as this exemple below:
@@ -33,7 +23,8 @@ Just import with `from labfis import labfloat` and create an *labfloat* object,
3323
>>> a*b
3424
(2 ± 7)
3525
```
36-
Check the Wiki for more details
26+
27+
Check the [Wiki]() for more details.
3728

3829
## Instalation
3930

labfis/__init__.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,8 @@
33
# Copyright © 2020 labfis.py
44
# (see LICENSE for details)
55

6-
__version__ = '1.1.5'
6+
__version__ = '1.2.0b'
77

88
# Local imports
9-
from labfis.main import labfloat
10-
labfloat
9+
from labfis.uncertainty import labfloat
10+
labfloat

labfis/main.py renamed to labfis/uncertainty.py

Lines changed: 112 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -1,51 +1,107 @@
1-
from math import floor, ceil, trunc, log, log10, sqrt
1+
import logging
2+
from math import floor, ceil, trunc, log, log10, sqrt, cos, sin, tan
23
from numbers import Number
34

5+
logger = logging.getLogger(__name__)
6+
7+
try:
8+
import numpy
9+
except ImportError:
10+
numpy = None
11+
logger.warning(
12+
'Faild to import numpy; sqrt, sin, cos, tan and numpy.ndarray list method wont function')
13+
14+
15+
def skipif(condition, message):
16+
def decorator(fnc):
17+
def wrapper(*args, **kwargs):
18+
if condition:
19+
return fnc(*args, **kwargs)
20+
else:
21+
logger.info(message)
22+
pass
23+
return wrapper
24+
return decorator
25+
26+
427
class LabFloatError(Exception):
528
def __init__(self, *args):
629
if args:
730
if args[0] == 0:
8-
self.message = "Essa operação não é suportado nesta classe, apenas as operações mencionadas na apostila de Laboratório de Física 2 do IFSC."
31+
self.message = "This operation is not supported."
932
elif args[0] == 1:
10-
self.message = "Too many args in list, expected '[...,[val,err],...]' got '{0}'".format(args[1])
11-
elif isinstance(args[0],str):
12-
self.message = "{0}{1}".format(args[0],args[1])
33+
self.message = "Too many arguments, expected '(val,err)' or '([(val,err),...])' , got: '{0}'".format(
34+
args[1])
35+
elif args[0] == 2:
36+
self.message = "Mean list and Uncertainty list must have the same size, expected: '[[val1,val2,...,valn],[err1,err2,...,errn]]' , got: '{0}'".format(
37+
args[1:])
38+
elif args[0] == 3:
39+
self.message = "Uncertanty or mean list missing, expected: '[[val1,val2,...,valn],[err1,err2,...,errn],...]' , got: '{0}'".format(
40+
args[1])
41+
elif args[0] == 4:
42+
self.message = "Too many arguments, expected: '(precision)' or '(mean precision,err precision)' , got: '{0}'".format(
43+
args[1])
44+
elif isinstance(args[0], str):
45+
self.message = "{0}{1}".format(args[0], args[1:])
46+
else:
47+
self.message = None
1348
else:
1449
self.message = None
1550

1651
def __str__(self):
1752
if self.message:
18-
return '{0}'.format(self.message)
53+
return self.message
1954
else:
20-
return 'LabFloatError has been raised'
55+
return 'A generic LabFloatError has been raised'
56+
2157

2258
class labfloat:
59+
def __new__(cls, *args, **kwargs):
60+
listlabfloat = kwargs.get('list', [])
61+
if args:
62+
if numpy:
63+
if isinstance(args[0], (list, numpy.ndarray)):
64+
listlabfloat = args
65+
else:
66+
if isinstance(args[0], list):
67+
listlabfloat = args
68+
if listlabfloat != []:
69+
if len(listlabfloat) % 2 == 0:
70+
return cls.list(listlabfloat)
71+
else:
72+
raise LabFloatError(3, listlabfloat)
73+
74+
return object.__new__(cls)
75+
2376
def __init__(self, *args, **kwargs):
24-
mean = kwargs.get('mean',0.0)
25-
uncertainty = kwargs.get('uncertainty',0.0)
77+
mean = kwargs.get('mean', 0.0)
78+
uncertainty = kwargs.get('uncertainty', 0.0)
2679

2780
if args:
2881
if len(args) == 1:
2982
mean = args[0]
3083
elif len(args) == 2:
3184
mean = args[0]
3285
uncertainty = args[1]
33-
else:
34-
raise LabFloatError("Too many arguments, expected (val,err) or ([(val,err),...]), got: ",args)
86+
elif len(args) > 2:
87+
raise LabFloatError(1, args)
3588

3689
self.mean = float(mean)
3790
self.uncertainty = abs(float(uncertainty))
3891

3992
@classmethod
40-
def list(cls,listargs):
93+
def list(cls, listargs):
4194
listlabfloat = []
42-
for j in range(len(listargs)):
43-
if len(listargs[j]) == 2:
44-
listlabfloat += [cls(listargs[j][0],listargs[j][1])]
45-
elif len(listargs[j]) == 1:
46-
listlabfloat += [cls(listargs[j][0])]
47-
elif len(listargs[j]) > 2:
48-
raise LabFloatError(1,listargs[j])
95+
for j in range(0, len(listargs), 2):
96+
if len(listargs[j]) == len(listargs[j+1]):
97+
colum = []
98+
for k in range(len(listargs[j])):
99+
colum += [cls(listargs[j][k], listargs[j+1][k])]
100+
listlabfloat += [colum]
101+
else:
102+
raise LabFloatError(2, listargs[j], listargs[j+1])
103+
if len(listlabfloat) == 1:
104+
listlabfloat = listlabfloat[0]
49105
return(listlabfloat)
50106

51107
def format(self):
@@ -55,7 +111,7 @@ def format(self):
55111
r = - len(su) + 1
56112
m = round(self.mean, r)
57113
u = round(self.uncertainty, r)
58-
return((m,u))
114+
return((m, u))
59115
else:
60116
r = -i
61117
r += 1
@@ -65,32 +121,29 @@ def format(self):
65121
elif su[j+1] == "9" and r > 0:
66122
m = round(self.mean, r-1)
67123
u = round(self.uncertainty, r)
68-
return((m,u))
124+
return((m, u))
69125
elif su[j] != ".":
70126
m = round(self.mean, r)
71127
u = round(self.uncertainty, r)
72-
return((m,u))
128+
return((m, u))
73129

74130
m = round(self.mean, r)
75131
u = round(self.uncertainty, r)
76-
return((m,u))
132+
return((m, u))
77133

78134
def split(self):
79-
if self.uncertainty == 0:
80-
return(["{:g}".format(self.mean)])
81-
else:
82-
m, u = self.format()
83-
return(["{:g}".format(m),"{:g}".format(u)])
84-
85-
def tex(self,*args,**kwargs):
135+
m, u = self.format()
136+
return(["{:g}".format(m), "{:g}".format(u)])
137+
138+
def tex(self, *args, **kwargs):
86139
precision = kwargs.get('precision')
87140
if args:
88141
if len(args) == 2:
89142
precision = args
90143
elif len(args) > 2:
91-
raise LabFloatError("Too many arguments, expected: (precision) or (mean precision,err precision) got: ",args)
144+
raise LabFloatError(4, args)
92145
else:
93-
precision = [args[0],args[0]]
146+
precision = [args[0], args[0]]
94147

95148
if self.uncertainty == 0:
96149
if precision:
@@ -106,7 +159,7 @@ def tex(self,*args,**kwargs):
106159
return("{0}".format(m))
107160
else:
108161
if precision:
109-
precision = (str(precision[0]),str(precision[1]))
162+
precision = (str(precision[0]), str(precision[1]))
110163
m, u = self.format()
111164
m = eval("'{:."+precision[0]+"e}'.format(m)")
112165
u = eval("'{:."+precision[1]+"e}'.format(u)")
@@ -125,17 +178,13 @@ def tex(self,*args,**kwargs):
125178
return(r"({0}\, \pm \,{1})".format(m, u))
126179

127180
def __str__(self):
128-
val = self.split()
129-
if len(val) == 1:
130-
return("{0}".format(val[0]))
131-
else:
132-
return("({0} ± {1})".format(*val))
181+
return("({0} ± {1})".format(*self.split()))
133182

134183
def __repr__(self):
135184
return self.__str__()
136-
185+
137186
def __getitem__(self, idx):
138-
vals = [self.mean,self.uncertainty]
187+
vals = [self.mean, self.uncertainty]
139188
return vals[idx]
140189

141190
def __pos__(self):
@@ -171,25 +220,25 @@ def __ne__(self, other):
171220
if isinstance(other, Number):
172221
return abs(self.mean - other) > 3 * self.uncertainty
173222

174-
def __lt__(self,other):
223+
def __lt__(self, other):
175224
if isinstance(other, labfloat):
176225
return self.mean + self.uncertainty < other.mean - other.uncertainty
177226
if isinstance(other, Number):
178227
return self.mean + self.uncertainty < other
179228

180-
def __gt__(self,other):
229+
def __gt__(self, other):
181230
if isinstance(other, labfloat):
182231
return self.mean - self.uncertainty > other.mean + other.uncertainty
183232
if isinstance(other, Number):
184233
return self.mean - self.uncertainty > other
185234

186-
def __le__(self,other):
235+
def __le__(self, other):
187236
if isinstance(other, labfloat):
188237
return self.mean + self.uncertainty <= other.mean + other.uncertainty
189238
if isinstance(other, Number):
190239
return self.mean + self.uncertainty <= other
191240

192-
def __ge__(self,other):
241+
def __ge__(self, other):
193242
if isinstance(other, labfloat):
194243
return self.mean - self.uncertainty >= other.mean - other.uncertainty
195244
if isinstance(other, Number):
@@ -236,7 +285,7 @@ def __imul__(self, other):
236285

237286
def __div__(self, other):
238287
if isinstance(other, labfloat):
239-
return labfloat(self.mean / other.mean, sqrt((self.uncertainty / other.mean) ** 2 + (self.mean * other.uncertainty / (other.mean ** 2)) ** 2 ))
288+
return labfloat(self.mean / other.mean, sqrt((self.uncertainty / other.mean) ** 2 + (self.mean * other.uncertainty / (other.mean ** 2)) ** 2))
240289
if isinstance(other, Number):
241290
return labfloat(self.mean / other, abs(self.uncertainty / other))
242291

@@ -251,7 +300,7 @@ def __itruediv__(self, other):
251300

252301
def __rdiv__(self, other):
253302
if isinstance(other, labfloat):
254-
return labfloat(other.mean / self.mean, sqrt((other.uncertainty / self.mean) ** 2 + (other.mean * self.uncertainty / (self.mean ** 2)) ** 2 ))
303+
return labfloat(other.mean / self.mean, sqrt((other.uncertainty / self.mean) ** 2 + (other.mean * self.uncertainty / (self.mean ** 2)) ** 2))
255304
if isinstance(other, Number):
256305
return labfloat(other / self.mean, abs(other * self.uncertainty / self.mean ** 2))
257306

@@ -273,6 +322,22 @@ def __rpow__(self, other):
273322
def __ipow__(self, other):
274323
return self.__pow__(other)
275324

325+
@skipif(numpy, "The sqrt() method is not supported without numpy")
326+
def sqrt(self):
327+
return self.__pow__(0.5)
328+
329+
@skipif(numpy, "The cos() method is not supported without numpy")
330+
def cos(self):
331+
return labfloat(cos(self.mean), abs(-(sin(self.mean)) * self.uncertainty))
332+
333+
@skipif(numpy, "The sin() method is not supported without numpy")
334+
def sin(self):
335+
return labfloat(sin(self.mean), abs(cos(self.mean) * self.uncertainty))
336+
337+
@skipif(numpy, "The tan() method is not supported without numpy")
338+
def tan(self):
339+
return labfloat(tan(self.mean), sqrt((cos(self.mean) ** -4) * self.uncertainty ** 2))
340+
276341
def __int__(self):
277342
return int(self.mean)
278343

@@ -286,4 +351,4 @@ def __oct__(self):
286351
return oct(self.mean)
287352

288353
def __hex__(self):
289-
return hex(self.mean)
354+
return hex(self.mean)

setup.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -56,11 +56,12 @@ def find_version(*file_paths):
5656
'Operating System :: Microsoft :: Windows',
5757
'Operating System :: POSIX',
5858
'License :: OSI Approved :: MIT License',
59-
'Programming Language :: Python :: 2.7',
6059
'Programming Language :: Python :: 3',
6160
'Programming Language :: Python :: 3.8']
6261

63-
python_ver = '>=2.7'
62+
#requirements = ['numpy']
63+
64+
python_ver = '>=3.6'
6465

6566
setup(name=APP_NAME,
6667
version=version,
@@ -74,5 +75,6 @@ def find_version(*file_paths):
7475
long_description_content_type="text/markdown",
7576
packages=find_packages(),
7677
classifiers=classifiers,
78+
# install_requires=requirements,
7779
python_requires=python_ver,
7880
)

0 commit comments

Comments
 (0)