geolysis 0.8.0__tar.gz → 0.9.0__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.
- {geolysis-0.8.0 → geolysis-0.9.0}/PKG-INFO +1 -1
- {geolysis-0.8.0 → geolysis-0.9.0}/geolysis/__init__.py +1 -1
- {geolysis-0.8.0 → geolysis-0.9.0}/geolysis/bearing_capacity/abc/cohl/_core.py +3 -4
- {geolysis-0.8.0 → geolysis-0.9.0}/geolysis/bearing_capacity/abc/cohl/bowles_abc.py +3 -3
- {geolysis-0.8.0 → geolysis-0.9.0}/geolysis/bearing_capacity/abc/cohl/meyerhof_abc.py +3 -3
- {geolysis-0.8.0 → geolysis-0.9.0}/geolysis/bearing_capacity/abc/cohl/terzaghi_abc.py +3 -3
- {geolysis-0.8.0 → geolysis-0.9.0}/geolysis/bearing_capacity/ubc/__init__.py +1 -1
- {geolysis-0.8.0 → geolysis-0.9.0}/geolysis/bearing_capacity/ubc/_core.py +6 -17
- {geolysis-0.8.0 → geolysis-0.9.0}/geolysis/foundation.py +33 -10
- {geolysis-0.8.0 → geolysis-0.9.0}/geolysis/soil_classifier.py +13 -8
- {geolysis-0.8.0 → geolysis-0.9.0}/geolysis/utils/__init__.py +6 -5
- geolysis-0.9.0/geolysis/utils/exceptions.py +65 -0
- geolysis-0.9.0/geolysis/utils/validators.py +119 -0
- {geolysis-0.8.0 → geolysis-0.9.0}/geolysis.egg-info/PKG-INFO +1 -1
- {geolysis-0.8.0 → geolysis-0.9.0}/tests/test_foundation.py +4 -4
- {geolysis-0.8.0 → geolysis-0.9.0}/tests/test_soil_classifier.py +5 -4
- geolysis-0.8.0/geolysis/utils/exceptions.py +0 -52
- geolysis-0.8.0/geolysis/utils/validators.py +0 -129
- {geolysis-0.8.0 → geolysis-0.9.0}/LICENSE.txt +0 -0
- {geolysis-0.8.0 → geolysis-0.9.0}/README.md +0 -0
- {geolysis-0.8.0 → geolysis-0.9.0}/geolysis/bearing_capacity/__init__.py +0 -0
- {geolysis-0.8.0 → geolysis-0.9.0}/geolysis/bearing_capacity/abc/__init__.py +0 -0
- {geolysis-0.8.0 → geolysis-0.9.0}/geolysis/bearing_capacity/abc/cohl/__init__.py +0 -0
- {geolysis-0.8.0 → geolysis-0.9.0}/geolysis/bearing_capacity/ubc/hansen_ubc.py +0 -0
- {geolysis-0.8.0 → geolysis-0.9.0}/geolysis/bearing_capacity/ubc/terzaghi_ubc.py +0 -0
- {geolysis-0.8.0 → geolysis-0.9.0}/geolysis/bearing_capacity/ubc/vesic_ubc.py +0 -0
- {geolysis-0.8.0 → geolysis-0.9.0}/geolysis/spt.py +0 -0
- {geolysis-0.8.0 → geolysis-0.9.0}/geolysis.egg-info/SOURCES.txt +0 -0
- {geolysis-0.8.0 → geolysis-0.9.0}/geolysis.egg-info/dependency_links.txt +0 -0
- {geolysis-0.8.0 → geolysis-0.9.0}/geolysis.egg-info/requires.txt +0 -0
- {geolysis-0.8.0 → geolysis-0.9.0}/geolysis.egg-info/top_level.txt +0 -0
- {geolysis-0.8.0 → geolysis-0.9.0}/pyproject.toml +0 -0
- {geolysis-0.8.0 → geolysis-0.9.0}/setup.cfg +0 -0
- {geolysis-0.8.0 → geolysis-0.9.0}/setup.py +0 -0
- {geolysis-0.8.0 → geolysis-0.9.0}/tests/test_spt.py +0 -0
@@ -1,7 +1,6 @@
|
|
1
1
|
from abc import ABC, abstractmethod
|
2
2
|
|
3
|
-
from geolysis.foundation import
|
4
|
-
from geolysis.utils import exceptions as exc
|
3
|
+
from geolysis.foundation import Foundation
|
5
4
|
from geolysis.utils import validators
|
6
5
|
|
7
6
|
|
@@ -11,7 +10,7 @@ class AllowableBearingCapacity(ABC):
|
|
11
10
|
|
12
11
|
def __init__(self, corrected_spt_n_value: float,
|
13
12
|
tol_settlement: float,
|
14
|
-
foundation_size:
|
13
|
+
foundation_size: Foundation) -> None:
|
15
14
|
self.corrected_spt_n_value = corrected_spt_n_value
|
16
15
|
self.tol_settlement = tol_settlement
|
17
16
|
self.foundation_size = foundation_size
|
@@ -32,7 +31,7 @@ class AllowableBearingCapacity(ABC):
|
|
32
31
|
return self._tol_settlement
|
33
32
|
|
34
33
|
@tol_settlement.setter
|
35
|
-
@validators.le(25.4
|
34
|
+
@validators.le(25.4)
|
36
35
|
def tol_settlement(self, tol_settlement: float) -> None:
|
37
36
|
self._tol_settlement = tol_settlement
|
38
37
|
|
@@ -1,4 +1,4 @@
|
|
1
|
-
from geolysis.foundation import
|
1
|
+
from geolysis.foundation import Foundation
|
2
2
|
from geolysis.utils import round_
|
3
3
|
|
4
4
|
from ._core import AllowableBearingCapacity
|
@@ -34,7 +34,7 @@ class BowlesABC4PadFoundation(AllowableBearingCapacity):
|
|
34
34
|
|
35
35
|
def __init__(self, corrected_spt_n_value: float,
|
36
36
|
tol_settlement: float,
|
37
|
-
foundation_size:
|
37
|
+
foundation_size: Foundation) -> None:
|
38
38
|
"""
|
39
39
|
:param corrected_spt_n_value: Statistical average of corrected SPT
|
40
40
|
N-value (55% energy with overburden
|
@@ -46,7 +46,7 @@ class BowlesABC4PadFoundation(AllowableBearingCapacity):
|
|
46
46
|
:type tol_settlement: float
|
47
47
|
|
48
48
|
:param foundation_size: Size of the foundation.
|
49
|
-
:type foundation_size:
|
49
|
+
:type foundation_size: Foundation
|
50
50
|
"""
|
51
51
|
super().__init__(corrected_spt_n_value=corrected_spt_n_value,
|
52
52
|
tol_settlement=tol_settlement,
|
@@ -1,4 +1,4 @@
|
|
1
|
-
from geolysis.foundation import
|
1
|
+
from geolysis.foundation import Foundation
|
2
2
|
from geolysis.utils import round_
|
3
3
|
|
4
4
|
from ._core import AllowableBearingCapacity
|
@@ -33,7 +33,7 @@ class MeyerhofABC4PadFoundation(AllowableBearingCapacity):
|
|
33
33
|
|
34
34
|
def __init__(self, corrected_spt_n_value: float,
|
35
35
|
tol_settlement: float,
|
36
|
-
foundation_size:
|
36
|
+
foundation_size: Foundation):
|
37
37
|
"""
|
38
38
|
:param corrected_spt_n_value: Average uncorrected SPT N-value (60%
|
39
39
|
energy with dilatancy (water) correction
|
@@ -46,7 +46,7 @@ class MeyerhofABC4PadFoundation(AllowableBearingCapacity):
|
|
46
46
|
:type tol_settlement: float
|
47
47
|
|
48
48
|
:param foundation_size: Size of the foundation.
|
49
|
-
:type foundation_size:
|
49
|
+
:type foundation_size: Foundation
|
50
50
|
"""
|
51
51
|
super().__init__(corrected_spt_n_value=corrected_spt_n_value,
|
52
52
|
tol_settlement=tol_settlement,
|
@@ -1,4 +1,4 @@
|
|
1
|
-
from geolysis.foundation import
|
1
|
+
from geolysis.foundation import Foundation
|
2
2
|
from geolysis.utils import round_
|
3
3
|
|
4
4
|
from ._core import AllowableBearingCapacity
|
@@ -40,7 +40,7 @@ class TerzaghiABC4PadFoundation(AllowableBearingCapacity):
|
|
40
40
|
|
41
41
|
def __init__(self, corrected_spt_n_value: float,
|
42
42
|
tol_settlement: float,
|
43
|
-
foundation_size:
|
43
|
+
foundation_size: Foundation) -> None:
|
44
44
|
"""
|
45
45
|
:param corrected_spt_n_value: Lowest (or average) uncorrected SPT
|
46
46
|
N-value (60% energy) within the foundation
|
@@ -52,7 +52,7 @@ class TerzaghiABC4PadFoundation(AllowableBearingCapacity):
|
|
52
52
|
:type tol_settlement: float
|
53
53
|
|
54
54
|
:param foundation_size: Size of the foundation.
|
55
|
-
:type foundation_size:
|
55
|
+
:type foundation_size: Foundation
|
56
56
|
"""
|
57
57
|
super().__init__(corrected_spt_n_value=corrected_spt_n_value,
|
58
58
|
tol_settlement=tol_settlement,
|
@@ -135,6 +135,7 @@ def create_ultimate_bearing_capacity(friction_angle: float,
|
|
135
135
|
width=width,
|
136
136
|
length=length,
|
137
137
|
eccentricity=eccentricity,
|
138
|
+
load_angle=load_angle,
|
138
139
|
ground_water_level=ground_water_level,
|
139
140
|
shape=shape)
|
140
141
|
|
@@ -147,6 +148,5 @@ def create_ultimate_bearing_capacity(friction_angle: float,
|
|
147
148
|
cohesion=cohesion,
|
148
149
|
moist_unit_wgt=moist_unit_wgt,
|
149
150
|
foundation_size=fnd_size,
|
150
|
-
load_angle=load_angle,
|
151
151
|
apply_local_shear=apply_local_shear)
|
152
152
|
return ubc
|
@@ -1,6 +1,6 @@
|
|
1
1
|
from abc import ABC, abstractmethod
|
2
2
|
|
3
|
-
from geolysis.foundation import
|
3
|
+
from geolysis.foundation import Foundation
|
4
4
|
from geolysis.utils import arctan, round_, tan, validators
|
5
5
|
|
6
6
|
|
@@ -8,8 +8,8 @@ class UltimateBearingCapacity(ABC):
|
|
8
8
|
def __init__(self, friction_angle: float,
|
9
9
|
cohesion: float,
|
10
10
|
moist_unit_wgt: float,
|
11
|
-
foundation_size:
|
12
|
-
load_angle: float = 0.0,
|
11
|
+
foundation_size: Foundation,
|
12
|
+
# load_angle: float = 0.0,
|
13
13
|
apply_local_shear: bool = False) -> None:
|
14
14
|
r"""
|
15
15
|
:param friction_angle: Internal angle of friction for general shear
|
@@ -23,11 +23,7 @@ class UltimateBearingCapacity(ABC):
|
|
23
23
|
:type moist_unit_wgt: float
|
24
24
|
|
25
25
|
:param foundation_size: Size of the foundation.
|
26
|
-
:type foundation_size:
|
27
|
-
|
28
|
-
:param load_angle: Inclination of the applied load with the vertical
|
29
|
-
(:math:`\alpha^{\circ}`), defaults to 0.0.
|
30
|
-
:type load_angle: float, optional
|
26
|
+
:type foundation_size: Foundation
|
31
27
|
|
32
28
|
:param apply_local_shear: Indicate whether bearing capacity failure is
|
33
29
|
general shear or local shear failure,
|
@@ -37,7 +33,6 @@ class UltimateBearingCapacity(ABC):
|
|
37
33
|
self.friction_angle = friction_angle
|
38
34
|
self.cohesion = cohesion
|
39
35
|
self.moist_unit_wgt = moist_unit_wgt
|
40
|
-
self.load_angle = load_angle
|
41
36
|
self.foundation_size = foundation_size
|
42
37
|
self.apply_local_shear = apply_local_shear
|
43
38
|
|
@@ -97,15 +92,9 @@ class UltimateBearingCapacity(ABC):
|
|
97
92
|
self._moist_unit_wgt = val
|
98
93
|
|
99
94
|
@property
|
100
|
-
def load_angle(self)
|
95
|
+
def load_angle(self):
|
101
96
|
"""Inclination of the applied load with the vertical."""
|
102
|
-
return self.
|
103
|
-
|
104
|
-
@load_angle.setter
|
105
|
-
@validators.le(90.0)
|
106
|
-
@validators.ge(0.0)
|
107
|
-
def load_angle(self, val: float):
|
108
|
-
self._load_angle = val
|
97
|
+
return self.foundation_size.load_angle
|
109
98
|
|
110
99
|
@property
|
111
100
|
def s_c(self) -> float:
|
@@ -8,7 +8,7 @@ from .utils import enum_repr, inf, isclose, validators
|
|
8
8
|
from .utils.exceptions import ErrorMsg, ValidationError
|
9
9
|
|
10
10
|
__all__ = ["create_foundation",
|
11
|
-
"
|
11
|
+
"Foundation",
|
12
12
|
"FoundationType",
|
13
13
|
"Shape",
|
14
14
|
"StripFooting",
|
@@ -216,15 +216,16 @@ class RectangularFooting(FootingSize):
|
|
216
216
|
self._length = val
|
217
217
|
|
218
218
|
|
219
|
-
class
|
219
|
+
class Foundation:
|
220
220
|
"""A simple class representing a foundation structure."""
|
221
221
|
|
222
222
|
def __init__(self, depth: float,
|
223
223
|
footing_size: FootingSize,
|
224
224
|
eccentricity: float = 0.0,
|
225
|
+
load_angle: float = 0.0,
|
225
226
|
ground_water_level: Optional[float] = None,
|
226
227
|
foundation_type: FoundationType = FoundationType.PAD) -> None:
|
227
|
-
"""
|
228
|
+
r"""
|
228
229
|
:param depth: Depth of foundation (m).
|
229
230
|
:type depth: float
|
230
231
|
|
@@ -238,6 +239,10 @@ class FoundationSize:
|
|
238
239
|
foundation footing.
|
239
240
|
:type eccentricity: float, optional
|
240
241
|
|
242
|
+
:param load_angle: Inclination of the applied load with the vertical
|
243
|
+
(:math:`\alpha^{\circ}`), defaults to 0.0.
|
244
|
+
:type load_angle: float, optional
|
245
|
+
|
241
246
|
:param ground_water_level: Depth of the water below ground level (m),
|
242
247
|
defaults to None.
|
243
248
|
:type ground_water_level: float, optional
|
@@ -249,6 +254,7 @@ class FoundationSize:
|
|
249
254
|
self.depth = depth
|
250
255
|
self.footing_size = footing_size
|
251
256
|
self.eccentricity = eccentricity
|
257
|
+
self.load_angle = load_angle
|
252
258
|
|
253
259
|
self._ground_water_level = ground_water_level
|
254
260
|
self._foundation_type = foundation_type
|
@@ -298,6 +304,17 @@ class FoundationSize:
|
|
298
304
|
def eccentricity(self, val: float) -> None:
|
299
305
|
self._eccentricity = val
|
300
306
|
|
307
|
+
@property
|
308
|
+
def load_angle(self) -> float:
|
309
|
+
"""Inclination of the applied load with the vertical."""
|
310
|
+
return self._load_angle
|
311
|
+
|
312
|
+
@load_angle.setter
|
313
|
+
@validators.le(90.0)
|
314
|
+
@validators.ge(0.0)
|
315
|
+
def load_angle(self, val: float):
|
316
|
+
self._load_angle = val
|
317
|
+
|
301
318
|
@property
|
302
319
|
def ground_water_level(self) -> Optional[float]:
|
303
320
|
"""Depth of the water below ground level (m)."""
|
@@ -336,10 +353,11 @@ def create_foundation(depth: float,
|
|
336
353
|
width: float,
|
337
354
|
length: Optional[float] = None,
|
338
355
|
eccentricity: float = 0.0,
|
356
|
+
load_angle: float = 0.0,
|
339
357
|
ground_water_level: Optional[float] = None,
|
340
358
|
foundation_type: FoundationType = FoundationType.PAD,
|
341
|
-
shape: Shape | str = Shape.SQUARE) ->
|
342
|
-
"""A factory function that encapsulate the creation of a foundation.
|
359
|
+
shape: Shape | str = Shape.SQUARE) -> Foundation:
|
360
|
+
r"""A factory function that encapsulate the creation of a foundation.
|
343
361
|
|
344
362
|
:param depth: Depth of foundation (m).
|
345
363
|
:type depth: float
|
@@ -358,6 +376,10 @@ def create_foundation(depth: float,
|
|
358
376
|
foundation footing .
|
359
377
|
:type eccentricity: float, optional
|
360
378
|
|
379
|
+
:param load_angle: Inclination of the applied load with the vertical
|
380
|
+
(:math:`\alpha^{\circ}`), defaults to 0.0.
|
381
|
+
:type load_angle: float, optional
|
382
|
+
|
361
383
|
:param ground_water_level: Depth of the water below ground level (m),
|
362
384
|
defaults to None.
|
363
385
|
:type ground_water_level: float, optional
|
@@ -398,8 +420,9 @@ def create_foundation(depth: float,
|
|
398
420
|
raise ValidationError(msg)
|
399
421
|
footing_size = RectangularFooting(width=width, length=length)
|
400
422
|
|
401
|
-
return
|
402
|
-
|
403
|
-
|
404
|
-
|
405
|
-
|
423
|
+
return Foundation(depth=depth,
|
424
|
+
eccentricity=eccentricity,
|
425
|
+
load_angle=load_angle,
|
426
|
+
ground_water_level=ground_water_level,
|
427
|
+
foundation_type=foundation_type,
|
428
|
+
footing_size=footing_size)
|
@@ -117,9 +117,6 @@ class AtterbergLimits:
|
|
117
117
|
3mm thick. (molded without breaking)
|
118
118
|
:type plastic_limit: float
|
119
119
|
"""
|
120
|
-
if liquid_limit < plastic_limit:
|
121
|
-
raise ValueError("liquid_limit cannot be less than plastic_limit")
|
122
|
-
|
123
120
|
self.liquid_limit = liquid_limit
|
124
121
|
self.plastic_limit = plastic_limit
|
125
122
|
|
@@ -141,6 +138,14 @@ class AtterbergLimits:
|
|
141
138
|
@plastic_limit.setter
|
142
139
|
@validators.ge(0.0)
|
143
140
|
def plastic_limit(self, val: float) -> None:
|
141
|
+
if self.liquid_limit < val:
|
142
|
+
msg = ErrorMsg(param_name="plastic_limit",
|
143
|
+
param_value=val,
|
144
|
+
param_value_bound=f"<{self.liquid_limit}",
|
145
|
+
msg=f"plastic_limit: {val} cannot be greater than "
|
146
|
+
f"liquid_limit: {self.liquid_limit}")
|
147
|
+
raise ValidationError(msg)
|
148
|
+
|
144
149
|
self._plastic_limit = val
|
145
150
|
|
146
151
|
@property
|
@@ -421,12 +426,12 @@ class AASHTO:
|
|
421
426
|
plasticity_idx = self.atterberg_limits.plasticity_index
|
422
427
|
fines = self.fines
|
423
428
|
|
424
|
-
|
425
|
-
|
426
|
-
|
427
|
-
|
429
|
+
x_1 = 1.0 if (x_0 := fines - 35.0) < 0.0 else min(x_0, 40.0)
|
430
|
+
x_2 = 1.0 if (x_0 := liquid_lmt - 40.0) < 0.0 else min(x_0, 20.0)
|
431
|
+
x_3 = 1.0 if (x_0 := fines - 15.0) < 0.0 else min(x_0, 40.0)
|
432
|
+
x_4 = 1.0 if (x_0 := plasticity_idx - 10.0) < 0.0 else min(x_0, 20.0)
|
428
433
|
|
429
|
-
return
|
434
|
+
return x_1 * (0.2 + 0.005 * x_2) + 0.01 * x_3 * x_4
|
430
435
|
|
431
436
|
def classify(self) -> SoilClf:
|
432
437
|
"""Return the AASHTO classification of the soil."""
|
@@ -67,18 +67,19 @@ def enum_repr(cls):
|
|
67
67
|
return cls
|
68
68
|
|
69
69
|
|
70
|
-
def round_(ndigits: int
|
70
|
+
def round_(ndigits: int) -> Callable:
|
71
71
|
"""A decorator that rounds the result of a callable to a specified number
|
72
72
|
of decimal places.
|
73
73
|
|
74
74
|
The returned value of the callable should support the ``__round__`` dunder
|
75
|
-
method and should be a numeric value.
|
76
|
-
which will indicate the number of decimal places to round to or a
|
77
|
-
callable. If ``ndigits`` is callable the default decimal places is 2.
|
75
|
+
method and should be a numeric value.
|
78
76
|
|
79
|
-
TypeError is raised when ``ndigits`` is
|
77
|
+
TypeError is raised when ``ndigits`` is not an int.
|
80
78
|
"""
|
81
79
|
|
80
|
+
if not isinstance(ndigits, int):
|
81
|
+
raise TypeError("ndigits must be an int")
|
82
|
+
|
82
83
|
def dec(fn) -> Callable[..., float]:
|
83
84
|
@functools.wraps(fn)
|
84
85
|
def wrapper(*args, **kwargs) -> float:
|
@@ -0,0 +1,65 @@
|
|
1
|
+
from collections import UserString
|
2
|
+
from typing import Any
|
3
|
+
|
4
|
+
|
5
|
+
class ErrorMsg(UserString):
|
6
|
+
def __init__(self, *, param_name: str = None,
|
7
|
+
param_value: Any = None,
|
8
|
+
symbol: str = None,
|
9
|
+
param_value_bound: Any = None,
|
10
|
+
msg: str = None):
|
11
|
+
if not msg:
|
12
|
+
msg = f"{param_name}: {param_value!r} must be {symbol} {param_value_bound}"
|
13
|
+
|
14
|
+
super().__init__(msg)
|
15
|
+
|
16
|
+
self.param_name = param_name
|
17
|
+
self.param_value = param_value
|
18
|
+
self.symbol = symbol
|
19
|
+
self.param_value_bound = param_value_bound
|
20
|
+
|
21
|
+
@property
|
22
|
+
def msg(self):
|
23
|
+
return self.data
|
24
|
+
|
25
|
+
def __add__(self, other):
|
26
|
+
msg = self.msg + str(other)
|
27
|
+
return self.__class__(param_name=self.param_name,
|
28
|
+
param_value=self.param_value,
|
29
|
+
symbol=self.symbol,
|
30
|
+
param_value_bound=self.param_value_bound,
|
31
|
+
msg=msg)
|
32
|
+
|
33
|
+
def __radd__(self, other):
|
34
|
+
msg = str(other) + self.msg
|
35
|
+
return self.__class__(param_name=self.param_name,
|
36
|
+
param_value=self.param_value,
|
37
|
+
symbol=self.symbol,
|
38
|
+
param_value_bound=self.param_value_bound,
|
39
|
+
msg=msg)
|
40
|
+
|
41
|
+
def __repr__(self) -> str:
|
42
|
+
return f"ErrorMsg(param_name={self.param_name}, " \
|
43
|
+
f"param_value={self.param_value}, " \
|
44
|
+
f"symbol={self.symbol}, " \
|
45
|
+
f"param_value_bound={self.param_value_bound}, msg={self.msg!r})"
|
46
|
+
|
47
|
+
def to_dict(self) -> dict:
|
48
|
+
return {
|
49
|
+
"param_name": self.param_name,
|
50
|
+
"param_value": self.param_value,
|
51
|
+
"symbol": self.symbol,
|
52
|
+
"param_value_bound": self.param_value_bound,
|
53
|
+
"message": self.msg
|
54
|
+
}
|
55
|
+
|
56
|
+
|
57
|
+
class ValidationError(ValueError):
|
58
|
+
"""Exception raised when a validation error occurs."""
|
59
|
+
|
60
|
+
def __init__(self, error: ErrorMsg):
|
61
|
+
super().__init__(error)
|
62
|
+
self.error = error
|
63
|
+
|
64
|
+
def __repr__(self):
|
65
|
+
return f"ValidationError(error={self.error!r})"
|
@@ -0,0 +1,119 @@
|
|
1
|
+
"""validators"""
|
2
|
+
import operator
|
3
|
+
from functools import wraps
|
4
|
+
from typing import Any, Callable, Iterable, TypeAlias, List, Tuple, Sequence
|
5
|
+
|
6
|
+
from .exceptions import ErrorMsg, ValidationError
|
7
|
+
|
8
|
+
Number: TypeAlias = int | float
|
9
|
+
|
10
|
+
|
11
|
+
class _Validator:
|
12
|
+
|
13
|
+
def __init__(self, bound: Any, /, *,
|
14
|
+
symbol: str,
|
15
|
+
check: Callable,
|
16
|
+
exc_type: Callable,
|
17
|
+
err_msg: str):
|
18
|
+
self.bound = bound
|
19
|
+
self.symbol = symbol
|
20
|
+
self.check = check
|
21
|
+
self.exc_type = exc_type
|
22
|
+
self.err_msg = err_msg
|
23
|
+
|
24
|
+
def check_val(self, val, fname: str):
|
25
|
+
raise NotImplementedError
|
26
|
+
|
27
|
+
def __call__(self, fn):
|
28
|
+
@wraps(fn)
|
29
|
+
def wrapper(obj, val):
|
30
|
+
if isinstance(val, List | Tuple):
|
31
|
+
for v in val:
|
32
|
+
self.check_val(v, fn.__name__)
|
33
|
+
else:
|
34
|
+
self.check_val(val, fn.__name__)
|
35
|
+
|
36
|
+
fn(obj, val)
|
37
|
+
|
38
|
+
return wrapper
|
39
|
+
|
40
|
+
|
41
|
+
class _NumValidator(_Validator):
|
42
|
+
|
43
|
+
def check_val(self, v: Number, fname: str):
|
44
|
+
if not self.check(v, self.bound):
|
45
|
+
msg = ErrorMsg(msg=self.err_msg,
|
46
|
+
param_name=fname,
|
47
|
+
param_value=v,
|
48
|
+
symbol=self.symbol,
|
49
|
+
param_value_bound=self.bound)
|
50
|
+
raise self.exc_type(msg)
|
51
|
+
|
52
|
+
|
53
|
+
class _LenValidator(_Validator):
|
54
|
+
|
55
|
+
def __call__(self, fn):
|
56
|
+
@wraps(fn)
|
57
|
+
def wrapper(obj, val: Sequence):
|
58
|
+
if not self.check(len(val), self.bound):
|
59
|
+
msg = ErrorMsg(msg=self.err_msg,
|
60
|
+
param_name=fn.__name__,
|
61
|
+
param_value=val,
|
62
|
+
symbol=self.symbol,
|
63
|
+
param_value_bound=self.bound)
|
64
|
+
msg = "Length of " + msg
|
65
|
+
raise self.exc_type(msg)
|
66
|
+
fn(obj, val)
|
67
|
+
|
68
|
+
return wrapper
|
69
|
+
|
70
|
+
|
71
|
+
class _InValidator(_Validator):
|
72
|
+
def check_val(self, v, fname):
|
73
|
+
if not self.check(self.bound, v):
|
74
|
+
msg = ErrorMsg(msg=self.err_msg,
|
75
|
+
param_name=fname,
|
76
|
+
param_value=v,
|
77
|
+
symbol=self.symbol,
|
78
|
+
param_value_bound=self.bound)
|
79
|
+
raise self.exc_type(msg)
|
80
|
+
|
81
|
+
|
82
|
+
def in_(bound: Iterable[Any], /, *, exc_type=ValidationError, err_msg=None):
|
83
|
+
return _InValidator(bound, symbol="in", check=operator.contains,
|
84
|
+
exc_type=exc_type, err_msg=err_msg)
|
85
|
+
|
86
|
+
|
87
|
+
def min_len(bound: int, /, *, exc_type=ValidationError, err_msg=None):
|
88
|
+
return _LenValidator(bound, symbol=">=", check=operator.ge,
|
89
|
+
exc_type=exc_type, err_msg=err_msg)
|
90
|
+
|
91
|
+
|
92
|
+
def lt(bound: Number, /, *, exc_type=ValidationError, err_msg=None):
|
93
|
+
return _NumValidator(bound, symbol="<", check=operator.lt,
|
94
|
+
exc_type=exc_type, err_msg=err_msg)
|
95
|
+
|
96
|
+
|
97
|
+
def le(bound: Number, /, *, exc_type=ValidationError, err_msg=None):
|
98
|
+
return _NumValidator(bound, symbol="<=", check=operator.le,
|
99
|
+
exc_type=exc_type, err_msg=err_msg)
|
100
|
+
|
101
|
+
|
102
|
+
def eq(bound: Number, /, *, exc_type=ValidationError, err_msg=None):
|
103
|
+
return _NumValidator(bound, symbol="==", check=operator.eq,
|
104
|
+
exc_type=exc_type, err_msg=err_msg)
|
105
|
+
|
106
|
+
|
107
|
+
def ne(bound: Number, /, *, exc_type=ValidationError, err_msg=None):
|
108
|
+
return _NumValidator(bound, symbol="!=", check=operator.ne,
|
109
|
+
exc_type=exc_type, err_msg=err_msg)
|
110
|
+
|
111
|
+
|
112
|
+
def ge(bound: Number, /, *, exc_type=ValidationError, err_msg=None):
|
113
|
+
return _NumValidator(bound, symbol=">=", check=operator.ge,
|
114
|
+
exc_type=exc_type, err_msg=err_msg)
|
115
|
+
|
116
|
+
|
117
|
+
def gt(bound: Number, /, *, exc_type=ValidationError, err_msg=None):
|
118
|
+
return _NumValidator(bound, symbol=">", check=operator.gt,
|
119
|
+
exc_type=exc_type, err_msg=err_msg)
|
@@ -1,6 +1,6 @@
|
|
1
1
|
import unittest
|
2
2
|
|
3
|
-
from geolysis.foundation import (CircularFooting,
|
3
|
+
from geolysis.foundation import (CircularFooting, Foundation,
|
4
4
|
RectangularFooting, Shape, SquareFooting,
|
5
5
|
StripFooting, create_foundation)
|
6
6
|
|
@@ -53,9 +53,9 @@ class TestFoundation(unittest.TestCase):
|
|
53
53
|
|
54
54
|
def test_foundation_size(self):
|
55
55
|
footing = StripFooting(width=2.0)
|
56
|
-
foundation =
|
57
|
-
|
58
|
-
|
56
|
+
foundation = Foundation(depth=1.5,
|
57
|
+
footing_size=footing,
|
58
|
+
eccentricity=0.1)
|
59
59
|
self.assertEqual(foundation.depth, 1.5)
|
60
60
|
self.assertEqual(foundation.width, 2.0)
|
61
61
|
self.assertEqual(foundation.length, float('inf'))
|
@@ -4,22 +4,22 @@ from geolysis.soil_classifier import (PSD, AtterbergLimits,
|
|
4
4
|
create_soil_classifier)
|
5
5
|
|
6
6
|
|
7
|
-
def
|
7
|
+
def test_create_soil_classifier_errors():
|
8
|
+
# Did not provide a classification (clf_type) value
|
8
9
|
with pytest.raises(ValueError):
|
9
|
-
# Did not provide a classification (clf_type) value
|
10
10
|
create_soil_classifier(liquid_limit=30.4,
|
11
11
|
plastic_limit=15.9,
|
12
12
|
fines=40.20)
|
13
13
|
|
14
|
+
# Provided a wrong value for clf_type
|
14
15
|
with pytest.raises(ValueError):
|
15
|
-
# Provided a wrong value for clf_type
|
16
16
|
create_soil_classifier(liquid_limit=30.4,
|
17
17
|
plastic_limit=15.9,
|
18
18
|
fines=40.20,
|
19
19
|
clf_type="IS")
|
20
20
|
|
21
|
+
# Did not provide sand for USCS classification
|
21
22
|
with pytest.raises(ValueError):
|
22
|
-
# Did not provide sand for USCS classification
|
23
23
|
create_soil_classifier(liquid_limit=30.4,
|
24
24
|
plastic_limit=15.9,
|
25
25
|
fines=40.20,
|
@@ -57,6 +57,7 @@ class TestAtterbergLimits:
|
|
57
57
|
assert al.consistency_index(nmc=nmc) == pytest.approx(expected)
|
58
58
|
|
59
59
|
def test_errors(self):
|
60
|
+
# Plastic limit is greater than liquid limit
|
60
61
|
with pytest.raises(ValueError):
|
61
62
|
AtterbergLimits(liquid_limit=15.0, plastic_limit=25.0)
|
62
63
|
|
@@ -1,52 +0,0 @@
|
|
1
|
-
from collections import UserString
|
2
|
-
from typing import Any
|
3
|
-
|
4
|
-
|
5
|
-
class _ErrorMsg(UserString):
|
6
|
-
def __init__(self, param_name: str = None,
|
7
|
-
param_value: Any = None,
|
8
|
-
symbol: str = None,
|
9
|
-
param_value_bound: Any = None,
|
10
|
-
msg: str = None):
|
11
|
-
if not msg:
|
12
|
-
msg = f"{param_name}: {param_value!r} must be {symbol} {param_value_bound}"
|
13
|
-
|
14
|
-
self.param_name = param_name
|
15
|
-
self.param_value = param_value
|
16
|
-
self.symbol = symbol
|
17
|
-
self.param_value_bound = param_value_bound
|
18
|
-
self.msg = msg
|
19
|
-
|
20
|
-
super().__init__(msg)
|
21
|
-
|
22
|
-
def __add__(self, other):
|
23
|
-
if isinstance(other, str):
|
24
|
-
self.data = self.data + other
|
25
|
-
self.msg = self.data
|
26
|
-
return self
|
27
|
-
return NotImplemented
|
28
|
-
|
29
|
-
def __radd__(self, other):
|
30
|
-
if isinstance(other, str):
|
31
|
-
self.data = other + self.data
|
32
|
-
self.msg = self.data
|
33
|
-
return self
|
34
|
-
return NotImplemented
|
35
|
-
|
36
|
-
|
37
|
-
class ErrorMsg(_ErrorMsg):
|
38
|
-
pass
|
39
|
-
|
40
|
-
|
41
|
-
class ValidationError(ValueError):
|
42
|
-
"""Exception raised when a validation error occurs."""
|
43
|
-
|
44
|
-
def __init__(self, error: ErrorMsg):
|
45
|
-
super().__init__(error)
|
46
|
-
self.error = error
|
47
|
-
|
48
|
-
|
49
|
-
class SettlementError(ValidationError):
|
50
|
-
"""Raised when tolerable settlement is greater than the maximum
|
51
|
-
allowable settlement.
|
52
|
-
"""
|
@@ -1,129 +0,0 @@
|
|
1
|
-
"""validators"""
|
2
|
-
import operator
|
3
|
-
from functools import wraps
|
4
|
-
from typing import Any, Callable, Iterable, TypeAlias
|
5
|
-
|
6
|
-
from .exceptions import ErrorMsg, ValidationError
|
7
|
-
|
8
|
-
Number: TypeAlias = int | float
|
9
|
-
|
10
|
-
|
11
|
-
class _Validator:
|
12
|
-
|
13
|
-
def __init__(self, bound: Any, /, *,
|
14
|
-
symbol: str,
|
15
|
-
func: Callable,
|
16
|
-
exc_type: Callable,
|
17
|
-
err_msg: str):
|
18
|
-
"""
|
19
|
-
|
20
|
-
"""
|
21
|
-
self.bound = bound
|
22
|
-
self.symbol = symbol
|
23
|
-
self.func = func
|
24
|
-
self.exc_type = exc_type
|
25
|
-
self.err_msg = err_msg
|
26
|
-
|
27
|
-
|
28
|
-
class _NumValidator(_Validator):
|
29
|
-
|
30
|
-
def _check_val(self, v: Number, fname: str):
|
31
|
-
if not self.func(v, self.bound):
|
32
|
-
msg = ErrorMsg(msg=self.err_msg,
|
33
|
-
param_name=fname,
|
34
|
-
param_value=v,
|
35
|
-
symbol=self.symbol,
|
36
|
-
param_value_bound=self.bound)
|
37
|
-
raise self.exc_type(msg)
|
38
|
-
|
39
|
-
def __call__(self, fn):
|
40
|
-
@wraps(fn)
|
41
|
-
def wrapper(obj, val):
|
42
|
-
if isinstance(val, Iterable):
|
43
|
-
for v in val:
|
44
|
-
self._check_val(v, fn.__name__)
|
45
|
-
else:
|
46
|
-
self._check_val(val, fn.__name__)
|
47
|
-
|
48
|
-
fn(obj, val)
|
49
|
-
|
50
|
-
return wrapper
|
51
|
-
|
52
|
-
|
53
|
-
class _LenValidator(_Validator):
|
54
|
-
def _check_val(self, v: Iterable[Any], fname: str):
|
55
|
-
if not self.func(len(v), self.bound):
|
56
|
-
msg = ErrorMsg(msg=self.err_msg,
|
57
|
-
param_name=fname,
|
58
|
-
param_value=v,
|
59
|
-
symbol=self.symbol,
|
60
|
-
param_value_bound=self.bound)
|
61
|
-
msg = "Length of " + msg
|
62
|
-
raise self.exc_type(msg)
|
63
|
-
|
64
|
-
def __call__(self, fn):
|
65
|
-
@wraps(fn)
|
66
|
-
def wrapper(obj, val: Iterable):
|
67
|
-
self._check_val(val, fn.__name__)
|
68
|
-
fn(obj, val)
|
69
|
-
|
70
|
-
return wrapper
|
71
|
-
|
72
|
-
|
73
|
-
class _InValidator(_Validator):
|
74
|
-
def _check_val(self, v, fname):
|
75
|
-
if not self.func(self.bound, v):
|
76
|
-
msg = ErrorMsg(msg=self.err_msg,
|
77
|
-
param_name=fname,
|
78
|
-
param_value=v,
|
79
|
-
symbol=self.symbol,
|
80
|
-
param_value_bound=self.bound)
|
81
|
-
raise self.exc_type(msg)
|
82
|
-
|
83
|
-
def __call__(self, fn):
|
84
|
-
@wraps(fn)
|
85
|
-
def wrapper(obj, val):
|
86
|
-
self._check_val(val, fn.__name__)
|
87
|
-
fn(obj, val)
|
88
|
-
|
89
|
-
return wrapper
|
90
|
-
|
91
|
-
|
92
|
-
def in_(val: Iterable[Any], /, *, exc_type=ValidationError, err_msg=None):
|
93
|
-
return _InValidator(val, symbol="in", func=operator.contains,
|
94
|
-
exc_type=exc_type, err_msg=err_msg)
|
95
|
-
|
96
|
-
|
97
|
-
def min_len(val: int, /, *, exc_type=ValidationError, err_msg=None):
|
98
|
-
return _LenValidator(val, symbol=">=", func=operator.ge,
|
99
|
-
exc_type=exc_type, err_msg=err_msg)
|
100
|
-
|
101
|
-
|
102
|
-
def lt(val: Number, /, *, exc_type=ValidationError, err_msg=None):
|
103
|
-
return _NumValidator(val, symbol="<", func=operator.lt,
|
104
|
-
exc_type=exc_type, err_msg=err_msg)
|
105
|
-
|
106
|
-
|
107
|
-
def le(val: Number, /, *, exc_type=ValidationError, err_msg=None):
|
108
|
-
return _NumValidator(val, symbol="<=", func=operator.le,
|
109
|
-
exc_type=exc_type, err_msg=err_msg)
|
110
|
-
|
111
|
-
|
112
|
-
def eq(val: Number, /, *, exc_type=ValidationError, err_msg=None):
|
113
|
-
return _NumValidator(val, symbol="==", func=operator.eq,
|
114
|
-
exc_type=exc_type, err_msg=err_msg)
|
115
|
-
|
116
|
-
|
117
|
-
def ne(val: Number, /, *, exc_type=ValidationError, err_msg=None):
|
118
|
-
return _NumValidator(val, symbol="!=", func=operator.ne,
|
119
|
-
exc_type=exc_type, err_msg=err_msg)
|
120
|
-
|
121
|
-
|
122
|
-
def ge(val: Number, /, *, exc_type=ValidationError, err_msg=None):
|
123
|
-
return _NumValidator(val, symbol=">=", func=operator.ge,
|
124
|
-
exc_type=exc_type, err_msg=err_msg)
|
125
|
-
|
126
|
-
|
127
|
-
def gt(val: Number, /, *, exc_type=ValidationError, err_msg=None):
|
128
|
-
return _NumValidator(val, symbol=">", func=operator.gt,
|
129
|
-
exc_type=exc_type, err_msg=err_msg)
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|