geoeq 0.0.1__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.
@@ -0,0 +1,28 @@
1
+ # Changelog
2
+
3
+ All notable changes to this project will be documented in this file.
4
+
5
+ The format is based on [Keep a Changelog](https://keepachangelog.com/),
6
+ and this project adheres to [Semantic Versioning](https://semver.org/).
7
+
8
+ ---
9
+
10
+ ## [0.0.1] - 2026-03-27
11
+
12
+ ### Added
13
+
14
+ - `geoeq.soil.properties` module with 16 soil phase-relationship functions:
15
+ - void ratio / porosity conversions
16
+ - degree of saturation
17
+ - water content
18
+ - dry, saturated, bulk, and submerged unit weights
19
+ - dry and bulk density
20
+ - void ratio from water content and from dry unit weight
21
+ - relative density
22
+ - plasticity index, liquidity index, consistency index
23
+ - `geoeq.core.validation` module with input validation helpers
24
+ - `geoeq.core.constants` module with physical constants (gravity, gamma_w)
25
+ - `geoeq.core.types` module with `Soil` dataclass
26
+ - Test suite with 43 tests covering all public functions
27
+ - MIT license
28
+ - README with installation, usage, API reference, and roadmap
geoeq-0.0.1/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Ripon Chandra Malo
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,3 @@
1
+ include LICENSE
2
+ include README.md
3
+ include CHANGELOG.md
geoeq-0.0.1/PKG-INFO ADDED
@@ -0,0 +1,203 @@
1
+ Metadata-Version: 2.4
2
+ Name: geoeq
3
+ Version: 0.0.1
4
+ Summary: A Python library for geotechnical engineering calculations.
5
+ Author: Ripon Chandra Malo
6
+ License-Expression: MIT
7
+ Project-URL: Homepage, https://github.com/riponcm/geoeq
8
+ Project-URL: Repository, https://github.com/riponcm/geoeq
9
+ Project-URL: Changelog, https://github.com/riponcm/geoeq/blob/main/CHANGELOG.md
10
+ Project-URL: Issues, https://github.com/riponcm/geoeq/issues
11
+ Keywords: geoeq,geotechnical,soil mechanics,civil engineering,geotechnical engineering,soil properties,geotechnical interpretation,geotechnical formulas,bearing capacity,foundation,settlement
12
+ Classifier: Development Status :: 2 - Pre-Alpha
13
+ Classifier: Intended Audience :: Education
14
+ Classifier: Intended Audience :: Science/Research
15
+ Classifier: Operating System :: OS Independent
16
+ Classifier: Programming Language :: Python :: 3
17
+ Classifier: Programming Language :: Python :: 3.9
18
+ Classifier: Programming Language :: Python :: 3.10
19
+ Classifier: Programming Language :: Python :: 3.11
20
+ Classifier: Programming Language :: Python :: 3.12
21
+ Classifier: Programming Language :: Python :: 3.13
22
+ Classifier: Topic :: Scientific/Engineering
23
+ Requires-Python: >=3.9
24
+ Description-Content-Type: text/markdown
25
+ License-File: LICENSE
26
+ Provides-Extra: dev
27
+ Requires-Dist: pytest>=7.0; extra == "dev"
28
+ Requires-Dist: pytest-cov; extra == "dev"
29
+ Requires-Dist: build; extra == "dev"
30
+ Requires-Dist: twine; extra == "dev"
31
+ Dynamic: license-file
32
+
33
+ # geoeq
34
+
35
+ A Python library for geotechnical engineering calculations.
36
+
37
+ **geoeq** brings common geotechnical formulas into one consistent, validated,
38
+ and well-documented Python package. It is built for engineers, students, and
39
+ researchers who want to replace repetitive spreadsheet work with clean,
40
+ reusable code.
41
+
42
+ ---
43
+
44
+ ## Status
45
+
46
+ This is **v0.0.1**, the first public release. It covers **soil property and
47
+ phase-relationship formulas** -- the building blocks for everything else in
48
+ geotechnical engineering.
49
+
50
+ Future releases will add effective stress, bearing capacity, settlement,
51
+ consolidation, earth pressure, slope stability, pile capacity, liquefaction
52
+ assessment, and more.
53
+
54
+ ---
55
+
56
+ ## Installation
57
+
58
+ ```bash
59
+ pip install geoeq
60
+ ```
61
+
62
+ Requires Python 3.9 or later. No external dependencies.
63
+
64
+ ---
65
+
66
+ ## Quick start
67
+
68
+ ```python
69
+ from geoeq.soil import properties as sp
70
+
71
+ # Dry unit weight from specific gravity and void ratio
72
+ gamma_d = sp.dry_unit_weight(Gs=2.65, e=0.72)
73
+ print(f"Dry unit weight: {gamma_d:.2f} kN/m3")
74
+
75
+ # Saturated and submerged unit weights
76
+ gamma_sat = sp.saturated_unit_weight(Gs=2.65, e=0.72)
77
+ gamma_sub = sp.submerged_unit_weight(Gs=2.65, e=0.72)
78
+
79
+ # Phase relations
80
+ n = sp.porosity_from_void_ratio(0.72)
81
+ S = sp.degree_of_saturation(w=0.18, Gs=2.65, e=0.72)
82
+ w = sp.water_content(S=0.80, Gs=2.65, e=0.72)
83
+ e = sp.void_ratio_from_porosity(0.42)
84
+
85
+ # Relative density
86
+ Dr = sp.relative_density(e=0.60, e_max=0.85, e_min=0.45)
87
+
88
+ # Atterberg limits
89
+ PI = sp.plasticity_index(LL=48, PL=22)
90
+ LI = sp.liquidity_index(w=35, PL=22, PI=26)
91
+ CI = sp.consistency_index(w=35, LL=48, PI=26)
92
+ ```
93
+
94
+ ---
95
+
96
+ ## What is included in v0.0.1
97
+
98
+ ### Soil property and phase-relationship formulas
99
+
100
+ All functions validate inputs, document units in docstrings, and reference
101
+ their source methods.
102
+
103
+ **Void ratio and porosity**
104
+ - `void_ratio_from_porosity(n)` -- convert porosity to void ratio
105
+ - `porosity_from_void_ratio(e)` -- convert void ratio to porosity
106
+
107
+ **Degree of saturation and water content**
108
+ - `degree_of_saturation(w, Gs, e)` -- compute S from water content, Gs, and e
109
+ - `water_content(S, Gs, e)` -- compute w from saturation, Gs, and e
110
+
111
+ **Unit weights**
112
+ - `dry_unit_weight(Gs, e)` -- dry unit weight (kN/m3)
113
+ - `saturated_unit_weight(Gs, e)` -- saturated unit weight (kN/m3)
114
+ - `bulk_unit_weight(Gs, e, S)` -- moist/total unit weight (kN/m3)
115
+ - `submerged_unit_weight(Gs, e)` -- buoyant unit weight (kN/m3)
116
+
117
+ **Density**
118
+ - `dry_density(Gs, e)` -- dry density (kg/m3)
119
+ - `bulk_density(Gs, e, S)` -- bulk density (kg/m3)
120
+
121
+ **Void ratio from other quantities**
122
+ - `void_ratio_from_water_content(w, Gs, S)` -- compute e from w, Gs, S
123
+ - `void_ratio_from_dry_unit_weight(gamma_d, Gs)` -- compute e from gamma_d
124
+
125
+ **Relative density**
126
+ - `relative_density(e, e_max, e_min)` -- density index for granular soils
127
+
128
+ **Atterberg limits and consistency**
129
+ - `plasticity_index(LL, PL)` -- PI = LL - PL
130
+ - `liquidity_index(w, PL, PI)` -- LI
131
+ - `consistency_index(w, LL, PI)` -- CI
132
+
133
+ ### Core utilities
134
+
135
+ - **Validation** -- input checking (positive, non-negative, range, fraction, angle)
136
+ - **Constants** -- gravity, unit weight of water, atmospheric pressure
137
+ - **Types** -- `Soil` dataclass for passing soil properties between functions
138
+
139
+ ---
140
+
141
+ ## Design principles
142
+
143
+ - **Validated inputs.** Every function checks that values are physically
144
+ meaningful. Negative void ratios, impossible saturation, and bad angles
145
+ raise clear errors.
146
+ - **Documented units.** Every docstring states what units are expected and
147
+ returned.
148
+ - **Traceable methods.** Docstrings reference the source formula or textbook.
149
+ - **No hidden dependencies.** v0.0.1 uses only the Python standard library.
150
+ - **Tested.** Every formula is tested against hand-calculated values and
151
+ textbook examples.
152
+
153
+ ---
154
+
155
+ ## Roadmap
156
+
157
+ | Version | Scope |
158
+ |---------|-------|
159
+ | v0.0.1 | Soil properties and phase relations |
160
+ | v0.1.x | Effective stress, pore pressure, seepage |
161
+ | v0.2.x | Shallow foundations, bearing capacity, settlement |
162
+ | v0.3.x | Soil classification (USCS), SPT/CPT correlations |
163
+ | v0.4.x | Earth pressure, consolidation, slope stability |
164
+ | v0.5.x | Pile capacity, liquefaction, advanced methods |
165
+ | v1.0.0 | Stable API, full documentation, examples |
166
+
167
+ ---
168
+
169
+ ## Running the tests
170
+
171
+ From a clone of this repository:
172
+
173
+ ```bash
174
+ pip install -e ".[dev]"
175
+ pytest
176
+ ```
177
+
178
+ If you only install pytest, tests still run from the project root (see `pythonpath` in `pyproject.toml`):
179
+
180
+ ```bash
181
+ pip install pytest
182
+ pytest
183
+ ```
184
+
185
+ The wheel on PyPI does not include the test files; run tests from a source checkout.
186
+
187
+ ---
188
+
189
+ ## Contributing
190
+
191
+ The repository is **private** until around **v0.5**; it will then be opened for
192
+ public contributions. Until then, feedback and feature requests are appreciated.
193
+
194
+ Every contribution should include the code, a test, a documentation update,
195
+ and a reference for the method.
196
+
197
+ ---
198
+
199
+ ## License
200
+
201
+ MIT License. See [LICENSE](LICENSE) for details.
202
+
203
+ Copyright (c) 2026 Ripon Chandra Malo
geoeq-0.0.1/README.md ADDED
@@ -0,0 +1,171 @@
1
+ # geoeq
2
+
3
+ A Python library for geotechnical engineering calculations.
4
+
5
+ **geoeq** brings common geotechnical formulas into one consistent, validated,
6
+ and well-documented Python package. It is built for engineers, students, and
7
+ researchers who want to replace repetitive spreadsheet work with clean,
8
+ reusable code.
9
+
10
+ ---
11
+
12
+ ## Status
13
+
14
+ This is **v0.0.1**, the first public release. It covers **soil property and
15
+ phase-relationship formulas** -- the building blocks for everything else in
16
+ geotechnical engineering.
17
+
18
+ Future releases will add effective stress, bearing capacity, settlement,
19
+ consolidation, earth pressure, slope stability, pile capacity, liquefaction
20
+ assessment, and more.
21
+
22
+ ---
23
+
24
+ ## Installation
25
+
26
+ ```bash
27
+ pip install geoeq
28
+ ```
29
+
30
+ Requires Python 3.9 or later. No external dependencies.
31
+
32
+ ---
33
+
34
+ ## Quick start
35
+
36
+ ```python
37
+ from geoeq.soil import properties as sp
38
+
39
+ # Dry unit weight from specific gravity and void ratio
40
+ gamma_d = sp.dry_unit_weight(Gs=2.65, e=0.72)
41
+ print(f"Dry unit weight: {gamma_d:.2f} kN/m3")
42
+
43
+ # Saturated and submerged unit weights
44
+ gamma_sat = sp.saturated_unit_weight(Gs=2.65, e=0.72)
45
+ gamma_sub = sp.submerged_unit_weight(Gs=2.65, e=0.72)
46
+
47
+ # Phase relations
48
+ n = sp.porosity_from_void_ratio(0.72)
49
+ S = sp.degree_of_saturation(w=0.18, Gs=2.65, e=0.72)
50
+ w = sp.water_content(S=0.80, Gs=2.65, e=0.72)
51
+ e = sp.void_ratio_from_porosity(0.42)
52
+
53
+ # Relative density
54
+ Dr = sp.relative_density(e=0.60, e_max=0.85, e_min=0.45)
55
+
56
+ # Atterberg limits
57
+ PI = sp.plasticity_index(LL=48, PL=22)
58
+ LI = sp.liquidity_index(w=35, PL=22, PI=26)
59
+ CI = sp.consistency_index(w=35, LL=48, PI=26)
60
+ ```
61
+
62
+ ---
63
+
64
+ ## What is included in v0.0.1
65
+
66
+ ### Soil property and phase-relationship formulas
67
+
68
+ All functions validate inputs, document units in docstrings, and reference
69
+ their source methods.
70
+
71
+ **Void ratio and porosity**
72
+ - `void_ratio_from_porosity(n)` -- convert porosity to void ratio
73
+ - `porosity_from_void_ratio(e)` -- convert void ratio to porosity
74
+
75
+ **Degree of saturation and water content**
76
+ - `degree_of_saturation(w, Gs, e)` -- compute S from water content, Gs, and e
77
+ - `water_content(S, Gs, e)` -- compute w from saturation, Gs, and e
78
+
79
+ **Unit weights**
80
+ - `dry_unit_weight(Gs, e)` -- dry unit weight (kN/m3)
81
+ - `saturated_unit_weight(Gs, e)` -- saturated unit weight (kN/m3)
82
+ - `bulk_unit_weight(Gs, e, S)` -- moist/total unit weight (kN/m3)
83
+ - `submerged_unit_weight(Gs, e)` -- buoyant unit weight (kN/m3)
84
+
85
+ **Density**
86
+ - `dry_density(Gs, e)` -- dry density (kg/m3)
87
+ - `bulk_density(Gs, e, S)` -- bulk density (kg/m3)
88
+
89
+ **Void ratio from other quantities**
90
+ - `void_ratio_from_water_content(w, Gs, S)` -- compute e from w, Gs, S
91
+ - `void_ratio_from_dry_unit_weight(gamma_d, Gs)` -- compute e from gamma_d
92
+
93
+ **Relative density**
94
+ - `relative_density(e, e_max, e_min)` -- density index for granular soils
95
+
96
+ **Atterberg limits and consistency**
97
+ - `plasticity_index(LL, PL)` -- PI = LL - PL
98
+ - `liquidity_index(w, PL, PI)` -- LI
99
+ - `consistency_index(w, LL, PI)` -- CI
100
+
101
+ ### Core utilities
102
+
103
+ - **Validation** -- input checking (positive, non-negative, range, fraction, angle)
104
+ - **Constants** -- gravity, unit weight of water, atmospheric pressure
105
+ - **Types** -- `Soil` dataclass for passing soil properties between functions
106
+
107
+ ---
108
+
109
+ ## Design principles
110
+
111
+ - **Validated inputs.** Every function checks that values are physically
112
+ meaningful. Negative void ratios, impossible saturation, and bad angles
113
+ raise clear errors.
114
+ - **Documented units.** Every docstring states what units are expected and
115
+ returned.
116
+ - **Traceable methods.** Docstrings reference the source formula or textbook.
117
+ - **No hidden dependencies.** v0.0.1 uses only the Python standard library.
118
+ - **Tested.** Every formula is tested against hand-calculated values and
119
+ textbook examples.
120
+
121
+ ---
122
+
123
+ ## Roadmap
124
+
125
+ | Version | Scope |
126
+ |---------|-------|
127
+ | v0.0.1 | Soil properties and phase relations |
128
+ | v0.1.x | Effective stress, pore pressure, seepage |
129
+ | v0.2.x | Shallow foundations, bearing capacity, settlement |
130
+ | v0.3.x | Soil classification (USCS), SPT/CPT correlations |
131
+ | v0.4.x | Earth pressure, consolidation, slope stability |
132
+ | v0.5.x | Pile capacity, liquefaction, advanced methods |
133
+ | v1.0.0 | Stable API, full documentation, examples |
134
+
135
+ ---
136
+
137
+ ## Running the tests
138
+
139
+ From a clone of this repository:
140
+
141
+ ```bash
142
+ pip install -e ".[dev]"
143
+ pytest
144
+ ```
145
+
146
+ If you only install pytest, tests still run from the project root (see `pythonpath` in `pyproject.toml`):
147
+
148
+ ```bash
149
+ pip install pytest
150
+ pytest
151
+ ```
152
+
153
+ The wheel on PyPI does not include the test files; run tests from a source checkout.
154
+
155
+ ---
156
+
157
+ ## Contributing
158
+
159
+ The repository is **private** until around **v0.5**; it will then be opened for
160
+ public contributions. Until then, feedback and feature requests are appreciated.
161
+
162
+ Every contribution should include the code, a test, a documentation update,
163
+ and a reference for the method.
164
+
165
+ ---
166
+
167
+ ## License
168
+
169
+ MIT License. See [LICENSE](LICENSE) for details.
170
+
171
+ Copyright (c) 2026 Ripon Chandra Malo
@@ -0,0 +1,65 @@
1
+ [build-system]
2
+ requires = ["setuptools>=68.0", "wheel"]
3
+ build-backend = "setuptools.build_meta"
4
+
5
+ [project]
6
+ name = "geoeq"
7
+ version = "0.0.1"
8
+ description = "A Python library for geotechnical engineering calculations."
9
+ readme = "README.md"
10
+ license = "MIT"
11
+ requires-python = ">=3.9"
12
+ authors = [
13
+ {name = "Ripon Chandra Malo"},
14
+ ]
15
+ keywords = [
16
+ "geoeq",
17
+ "geotechnical",
18
+ "soil mechanics",
19
+ "civil engineering",
20
+ "geotechnical engineering",
21
+ "soil properties",
22
+ "geotechnical interpretation",
23
+ "geotechnical formulas",
24
+ "bearing capacity",
25
+ "foundation",
26
+ "settlement",
27
+ ]
28
+ classifiers = [
29
+ "Development Status :: 2 - Pre-Alpha",
30
+ "Intended Audience :: Education",
31
+ "Intended Audience :: Science/Research",
32
+ "Operating System :: OS Independent",
33
+ "Programming Language :: Python :: 3",
34
+ "Programming Language :: Python :: 3.9",
35
+ "Programming Language :: Python :: 3.10",
36
+ "Programming Language :: Python :: 3.11",
37
+ "Programming Language :: Python :: 3.12",
38
+ "Programming Language :: Python :: 3.13",
39
+ "Topic :: Scientific/Engineering",
40
+ ]
41
+ dependencies = []
42
+
43
+ [project.optional-dependencies]
44
+ dev = [
45
+ "pytest>=7.0",
46
+ "pytest-cov",
47
+ "build",
48
+ "twine",
49
+ ]
50
+
51
+ [project.urls]
52
+ Homepage = "https://github.com/riponcm/geoeq"
53
+ Repository = "https://github.com/riponcm/geoeq"
54
+ Changelog = "https://github.com/riponcm/geoeq/blob/main/CHANGELOG.md"
55
+ Issues = "https://github.com/riponcm/geoeq/issues"
56
+
57
+ [tool.setuptools.packages.find]
58
+ where = ["src"]
59
+
60
+ [tool.setuptools.package-data]
61
+ geoeq = ["py.typed"]
62
+
63
+ [tool.pytest.ini_options]
64
+ testpaths = ["tests"]
65
+ pythonpath = ["src"]
geoeq-0.0.1/setup.cfg ADDED
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+
@@ -0,0 +1,19 @@
1
+ """
2
+ geoeq -- A Python library for geotechnical engineering calculations.
3
+
4
+ Version 0.0.1 provides soil property and phase-relationship formulas.
5
+ Future versions will add effective stress, bearing capacity, settlement,
6
+ consolidation, earth pressure, slope stability, pile capacity,
7
+ and liquefaction assessment.
8
+
9
+ Quick start
10
+ -----------
11
+ >>> from geoeq.soil import properties as sp
12
+ >>> sp.dry_unit_weight(Gs=2.65, e=0.72)
13
+ 15.11...
14
+ """
15
+
16
+ __version__ = "0.0.1"
17
+
18
+ from . import core
19
+ from . import soil
@@ -0,0 +1,13 @@
1
+ """
2
+ geoeq.core -- constants, validation, and types.
3
+ """
4
+
5
+ from .constants import GRAVITY, GAMMA_WATER, DENSITY_WATER, ATMOSPHERIC_PRESSURE
6
+ from .validation import (
7
+ check_positive,
8
+ check_non_negative,
9
+ check_range,
10
+ check_fraction,
11
+ check_angle_degrees,
12
+ )
13
+ from .types import Soil
@@ -0,0 +1,22 @@
1
+ """
2
+ Physical and engineering constants used across geoeq.
3
+
4
+ All values are in SI units unless stated otherwise.
5
+ """
6
+
7
+ import math
8
+
9
+ # Acceleration due to gravity (m/s^2).
10
+ GRAVITY = 9.81
11
+
12
+ # Unit weight of water (kN/m^3).
13
+ GAMMA_WATER = 9.81
14
+
15
+ # Density of water (kg/m^3).
16
+ DENSITY_WATER = 1000.0
17
+
18
+ # Atmospheric pressure (kPa).
19
+ ATMOSPHERIC_PRESSURE = 101.325
20
+
21
+ # Pi.
22
+ PI = math.pi
@@ -0,0 +1,47 @@
1
+ """
2
+ Common data structures for geoeq.
3
+
4
+ Using dataclasses keeps data structured and inspectable rather than
5
+ passing around bare dictionaries.
6
+ """
7
+
8
+ from dataclasses import dataclass
9
+ from typing import Optional
10
+
11
+
12
+ @dataclass
13
+ class Soil:
14
+ """
15
+ Represents a soil with basic engineering properties.
16
+
17
+ Parameters
18
+ ----------
19
+ gamma : float
20
+ Total unit weight (kN/m^3). Default 18.0.
21
+ phi : float
22
+ Effective friction angle (degrees). Default 30.0.
23
+ c : float
24
+ Effective cohesion (kPa). Default 0.0.
25
+ e : float or None
26
+ Void ratio. Default ``None``.
27
+ Gs : float
28
+ Specific gravity of solids. Default 2.65.
29
+ w : float or None
30
+ Water content as a decimal (e.g. 0.25 for 25 %). Default ``None``.
31
+ gamma_d : float or None
32
+ Dry unit weight (kN/m^3). Default ``None``.
33
+ Su : float or None
34
+ Undrained shear strength (kPa). Default ``None``.
35
+ description : str
36
+ Free-text label. Default ``""``.
37
+ """
38
+
39
+ gamma: float = 18.0
40
+ phi: float = 30.0
41
+ c: float = 0.0
42
+ e: Optional[float] = None
43
+ Gs: float = 2.65
44
+ w: Optional[float] = None
45
+ gamma_d: Optional[float] = None
46
+ Su: Optional[float] = None
47
+ description: str = ""
@@ -0,0 +1,50 @@
1
+ """
2
+ Input validation utilities for geoeq.
3
+
4
+ Every public function should validate its inputs before computing.
5
+ These helpers raise ``ValueError`` with clear messages when inputs
6
+ fall outside physically meaningful ranges.
7
+ """
8
+
9
+
10
+ def check_positive(value: float, name: str) -> None:
11
+ """Raise ``ValueError`` if *value* is not strictly positive."""
12
+ if value <= 0:
13
+ raise ValueError(f"{name} must be positive, got {value}")
14
+
15
+
16
+ def check_non_negative(value: float, name: str) -> None:
17
+ """Raise ``ValueError`` if *value* is negative."""
18
+ if value < 0:
19
+ raise ValueError(f"{name} must be non-negative, got {value}")
20
+
21
+
22
+ def check_range(
23
+ value: float,
24
+ name: str,
25
+ low: float,
26
+ high: float,
27
+ inclusive: bool = True,
28
+ ) -> None:
29
+ """Raise ``ValueError`` if *value* is outside [low, high] (or (low, high))."""
30
+ if inclusive:
31
+ if value < low or value > high:
32
+ raise ValueError(f"{name} must be in [{low}, {high}], got {value}")
33
+ else:
34
+ if value <= low or value >= high:
35
+ raise ValueError(f"{name} must be in ({low}, {high}), got {value}")
36
+
37
+
38
+ def check_fraction(value: float, name: str) -> None:
39
+ """Raise ``ValueError`` if *value* is not in [0, 1]."""
40
+ check_range(value, name, 0.0, 1.0)
41
+
42
+
43
+ def check_angle_degrees(
44
+ value: float,
45
+ name: str,
46
+ low: float = 0.0,
47
+ high: float = 90.0,
48
+ ) -> None:
49
+ """Raise ``ValueError`` if an angle in degrees is outside [low, high]."""
50
+ check_range(value, name, low, high)
File without changes
@@ -0,0 +1,6 @@
1
+ """
2
+ geoeq.soil -- soil property formulas.
3
+ """
4
+
5
+ from . import properties
6
+ from geoeq.core.types import Soil