qnty 0.0.1__py3-none-any.whl → 0.0.3__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.
- qnty/__init__.py +175 -0
- qnty/dimension.py +113 -14
- qnty/equation.py +216 -0
- qnty/expression.py +480 -0
- qnty/prefixes.py +229 -0
- qnty/unit.py +76 -8
- qnty/unit_types/__init__.py +0 -0
- qnty/unit_types/base.py +47 -0
- qnty/units.py +8078 -33
- qnty/variable.py +69 -29
- qnty/variable_types/__init__.py +0 -0
- qnty/variable_types/base.py +58 -0
- qnty/variable_types/expression_variable.py +68 -0
- qnty/variable_types/typed_variable.py +92 -0
- qnty/variables.py +2291 -19
- qnty/variables.pyi +6097 -0
- {qnty-0.0.1.dist-info → qnty-0.0.3.dist-info}/METADATA +109 -22
- qnty-0.0.3.dist-info/RECORD +19 -0
- qnty/setters.py +0 -89
- qnty-0.0.1.dist-info/RECORD +0 -10
- {qnty-0.0.1.dist-info → qnty-0.0.3.dist-info}/WHEEL +0 -0
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.3
|
2
2
|
Name: qnty
|
3
|
-
Version: 0.0.
|
3
|
+
Version: 0.0.3
|
4
4
|
Summary: High-performance unit system library for Python with dimensional safety and fast unit conversions
|
5
5
|
License: Apache-2.0
|
6
6
|
Keywords: units,dimensional analysis,engineering,physics,quantities,measurements
|
@@ -33,7 +33,7 @@ Description-Content-Type: text/markdown
|
|
33
33
|
|
34
34
|
**High-performance unit system library for Python with dimensional safety and fast unit conversions for engineering calculations.**
|
35
35
|
|
36
|
-
[](https://www.python.org/downloads/)
|
37
37
|
[](https://opensource.org/licenses/Apache-2.0)
|
38
38
|
[](https://pypi.org/project/qnty/)
|
39
39
|
|
@@ -43,7 +43,7 @@ Description-Content-Type: text/markdown
|
|
43
43
|
|
44
44
|
**📐 Accuracy Notice**: The authors are not responsible or liable for incorrect results, calculation errors, or any consequences arising from the use of this library. Always validate calculations independently using established engineering tools and practices.
|
45
45
|
|
46
|
-
**🚀 Learn from History**: Remember, even NASA's Mars Climate Orbiter had a $327 million oops moment due to unit conversion errors between metric and imperial systems. Don't let your project become the next cautionary tale - double-check everything!
|
46
|
+
**🚀 Learn from History**: Remember, even NASA's Mars Climate Orbiter had a $327 million oops moment due to unit conversion errors between metric and imperial systems. Don't let your project become the next cautionary tale - double-check everything!
|
47
47
|
|
48
48
|
*Use Qnty to help prevent unit errors, but always verify critical calculations through multiple methods.*
|
49
49
|
|
@@ -58,7 +58,9 @@ Qnty is designed around **type safety** and **performance optimization** using c
|
|
58
58
|
- **⚡ Zero-Cost Abstractions**: Optimized operations with `__slots__` and caching
|
59
59
|
- **🔗 Fluent API**: Intuitive method chaining for readable code
|
60
60
|
- **🧮 Engineering-Focused**: Built for real-world engineering calculations
|
61
|
-
-
|
61
|
+
- **🧬 Mathematical System**: Built-in equation solving and expression trees
|
62
|
+
- **📊 Comprehensive Testing**: 457 tests with performance benchmarks
|
63
|
+
- **🏗️ Clean Architecture**: Circular import-free design with strict dependency hierarchy
|
62
64
|
|
63
65
|
## 🚀 Quick Start
|
64
66
|
|
@@ -73,7 +75,7 @@ poetry add qnty
|
|
73
75
|
### Basic Usage
|
74
76
|
|
75
77
|
```python
|
76
|
-
from qnty
|
78
|
+
from qnty import Length, Pressure, Dimensionless
|
77
79
|
from qnty.variable import FastQuantity
|
78
80
|
from qnty.units import LengthUnits, PressureUnits
|
79
81
|
|
@@ -95,7 +97,7 @@ force = pressure * area # Automatic dimensional analysis
|
|
95
97
|
### Engineering Example
|
96
98
|
|
97
99
|
```python
|
98
|
-
from qnty
|
100
|
+
from qnty import Length, Pressure
|
99
101
|
|
100
102
|
# ASME pressure vessel calculation with mixed units
|
101
103
|
pressure = Pressure("internal_pressure")
|
@@ -112,47 +114,90 @@ thickness = (pressure.quantity * diameter.quantity) / (2 * stress.quantity)
|
|
112
114
|
print(f"Required thickness: {thickness}") # Automatically in correct units
|
113
115
|
```
|
114
116
|
|
117
|
+
### Mathematical Equations & Solving
|
118
|
+
|
119
|
+
```python
|
120
|
+
from qnty import Length, Pressure, Dimensionless
|
121
|
+
|
122
|
+
# Define engineering variables
|
123
|
+
T = Length("Wall Thickness", is_known=False) # Unknown to solve for
|
124
|
+
T_bar = Length(0.147, "inches", "Nominal Wall Thickness")
|
125
|
+
U_m = Dimensionless(0.125, "Mill Undertolerance")
|
126
|
+
|
127
|
+
# Create equation using fluent API: T = T_bar * (1 - U_m)
|
128
|
+
equation = T.equals(T_bar * (1 - U_m))
|
129
|
+
|
130
|
+
# Solve automatically
|
131
|
+
known_vars = {"T_bar": T_bar, "U_m": U_m}
|
132
|
+
result = equation.solve_for("T", known_vars)
|
133
|
+
print(f"Solved thickness: {result.quantity}") # 0.128625 inches
|
134
|
+
|
135
|
+
# Verify equation is satisfied
|
136
|
+
assert equation.check_residual(known_vars) is True
|
137
|
+
```
|
138
|
+
|
115
139
|
## 🏗️ Architecture
|
116
140
|
|
141
|
+
### Clean Dependency Design
|
142
|
+
|
143
|
+
Qnty features a carefully designed architecture that eliminates circular imports through a strict dependency hierarchy:
|
144
|
+
|
145
|
+
```python
|
146
|
+
variable → variables → expression → equation
|
147
|
+
```
|
148
|
+
|
149
|
+
This ensures clean type checking, maintainable code, and optimal performance throughout the system.
|
150
|
+
|
117
151
|
### Core Components
|
118
152
|
|
119
|
-
|
153
|
+
### 🔢 Dimensional System
|
154
|
+
|
120
155
|
- Prime number encoding for ultra-fast dimensional compatibility checks
|
121
156
|
- Zero-cost dimensional analysis at compile time
|
122
157
|
- Immutable dimension signatures for thread safety
|
123
158
|
|
124
|
-
|
159
|
+
### ⚙️ High-Performance Quantities
|
160
|
+
|
125
161
|
- `FastQuantity`: Optimized for engineering calculations with `__slots__`
|
126
162
|
- Cached SI factors and dimension signatures
|
127
163
|
- Fast-path optimizations for same-unit operations
|
128
164
|
|
129
|
-
|
130
|
-
|
165
|
+
### 🎯 Type-Safe Variables
|
166
|
+
|
167
|
+
- `Length`, `Pressure`, `Dimensionless`: Domain-specific variables with compile-time safety
|
131
168
|
- Fluent API with specialized setters
|
132
169
|
- Prevents dimensional errors at the type level
|
133
170
|
|
134
|
-
|
171
|
+
### 🔄 Smart Unit System
|
172
|
+
|
135
173
|
- Pre-computed conversion tables
|
136
174
|
- Automatic unit resolution for calculations
|
137
175
|
- Support for mixed-unit operations
|
138
176
|
|
177
|
+
### 🧬 Mathematical System
|
178
|
+
|
179
|
+
- Built-in equation solving with symbolic manipulation
|
180
|
+
- Expression trees for complex mathematical operations
|
181
|
+
- Automatic residual checking and validation
|
182
|
+
- Engineering equation support (ASME, pressure vessels, etc.)
|
183
|
+
|
139
184
|
## 📊 Performance
|
140
185
|
|
141
|
-
Qnty significantly outperforms other unit libraries with **
|
186
|
+
Qnty significantly outperforms other unit libraries with **18.9x average speedup** over Pint:
|
142
187
|
|
143
188
|
### Real Benchmark Results (μs per operation)
|
144
189
|
|
145
190
|
| Operation | Qnty | Pint | **Speedup** |
|
146
191
|
|-----------|------|------|-------------|
|
147
|
-
| Unit Conversion (m → mm) | 0.
|
148
|
-
| Mixed Unit Addition (mm + in) |
|
149
|
-
| Multiplication (m × m) | 0.
|
150
|
-
| Division (psi ÷ mm) |
|
151
|
-
| Complex ASME Equation |
|
152
|
-
| Type-Safe Variables |
|
153
|
-
| Chained Operations |
|
154
|
-
| Loop (10 additions) |
|
155
|
-
| **AVERAGE** | **
|
192
|
+
| Unit Conversion (m → mm) | 0.50 | 9.72 | **19.5x** |
|
193
|
+
| Mixed Unit Addition (mm + in) | 0.76 | 17.52 | **23.1x** |
|
194
|
+
| Multiplication (m × m) | 0.82 | 10.64 | **12.9x** |
|
195
|
+
| Division (psi ÷ mm) | 0.87 | 11.23 | **12.9x** |
|
196
|
+
| Complex ASME Equation | 4.07 | 106.17 | **26.1x** 🚀 |
|
197
|
+
| Type-Safe Variables | 0.98 | 9.65 | **9.8x** |
|
198
|
+
| Chained Operations | 1.83 | 42.22 | **23.1x** |
|
199
|
+
| Loop (10 additions) | 5.32 | 79.48 | **14.9x** |
|
200
|
+
| **AVERAGE** | **1.89** | **35.83** | **18.9x** 🏆 |
|
156
201
|
|
157
202
|
*Benchmarks performed on typical engineering calculations. Run `pytest tests/test_benchmark.py -v -s` to verify on your system.*
|
158
203
|
|
@@ -197,6 +242,44 @@ area = width.quantity * height.quantity
|
|
197
242
|
perimeter = 2 * (width.quantity + height.quantity)
|
198
243
|
```
|
199
244
|
|
245
|
+
### Equation Solving System
|
246
|
+
|
247
|
+
```python
|
248
|
+
from qnty import Length, Pressure, Dimensionless
|
249
|
+
|
250
|
+
# Multi-variable engineering equations
|
251
|
+
P = Pressure(90, "psi", "P") # Known
|
252
|
+
D = Length(0.84, "inches", "D") # Known
|
253
|
+
t = Length("t", is_known=False) # Unknown - solve for this
|
254
|
+
S = Pressure(20000, "psi", "S") # Known
|
255
|
+
|
256
|
+
# ASME pressure vessel equation: P = (S * t) / ((D/2) + 0.6*t)
|
257
|
+
# Rearranged to solve for t
|
258
|
+
equation = t.equals((P * D) / (2 * S - 1.2 * P))
|
259
|
+
|
260
|
+
# Solve automatically
|
261
|
+
known_variables = {"P": P, "D": D, "S": S}
|
262
|
+
thickness_result = equation.solve_for("t", known_variables)
|
263
|
+
print(f"Required thickness: {thickness_result.quantity}")
|
264
|
+
|
265
|
+
# Verify solution
|
266
|
+
assert equation.check_residual(known_variables) is True
|
267
|
+
```
|
268
|
+
|
269
|
+
### Import Strategy
|
270
|
+
|
271
|
+
Qnty provides a clean, minimal public API:
|
272
|
+
|
273
|
+
```python
|
274
|
+
# Preferred import style - clean public API
|
275
|
+
from qnty import Length, Pressure, Dimensionless
|
276
|
+
|
277
|
+
# Internal imports when needed for advanced usage
|
278
|
+
from qnty.variable import FastQuantity, TypeSafeVariable
|
279
|
+
from qnty.expression import Expression
|
280
|
+
from qnty.equation import Equation, EquationSystem
|
281
|
+
```
|
282
|
+
|
200
283
|
## 🔧 Development
|
201
284
|
|
202
285
|
### Setup Development Environment
|
@@ -221,6 +304,7 @@ python tests/test_benchmark.py
|
|
221
304
|
```bash
|
222
305
|
# Linting with ruff (200 character line length)
|
223
306
|
ruff check src/ tests/
|
307
|
+
ruff format src/ tests/
|
224
308
|
|
225
309
|
# Type checking
|
226
310
|
mypy src/qnty/
|
@@ -232,7 +316,9 @@ mypy src/qnty/
|
|
232
316
|
|
233
317
|
- **`FastQuantity`**: High-performance quantity with value and unit
|
234
318
|
- **`TypeSafeVariable`**: Base class for dimension-specific variables
|
235
|
-
- **`Length`**, **`Pressure`**: Specialized variables with fluent setters
|
319
|
+
- **`Length`**, **`Pressure`**, **`Dimensionless`**: Specialized variables with fluent setters
|
320
|
+
- **`Equation`**: Mathematical equations with solving capabilities
|
321
|
+
- **`Expression`**: Abstract base for mathematical expression trees
|
236
322
|
- **`DimensionSignature`**: Immutable dimension encoding system
|
237
323
|
- **`UnitConstant`**: Type-safe unit definitions
|
238
324
|
|
@@ -266,3 +352,4 @@ This project is licensed under the Apache License 2.0 - see the [LICENSE](LICENS
|
|
266
352
|
---
|
267
353
|
|
268
354
|
**Ready to supercharge your engineering calculations?** Install Qnty today and experience the power of type-safe, high-performance unit handling! 🚀
|
355
|
+
|
@@ -0,0 +1,19 @@
|
|
1
|
+
qnty/__init__.py,sha256=lZKInnpHg1LQ_3TRprI_xV0CatK8FC9RJiX0CpI5yIU,5536
|
2
|
+
qnty/dimension.py,sha256=PiRpZydh7QifD7YdzGCoJZ9EI1fixDsX5KWZj92IXdo,10826
|
3
|
+
qnty/equation.py,sha256=XgzM91jn__GomKbgslncoFJWPDJiMb4_VKD-8sdcFXc,9096
|
4
|
+
qnty/expression.py,sha256=UM0hCqOVD1gK_O5-Rsq7BWIPDTEL_kFORprV6LIqGcU,20890
|
5
|
+
qnty/prefixes.py,sha256=bRwcNbE_nX9gXI_WnJZLL-i7kQncIOZivCCSN8dur2g,6000
|
6
|
+
qnty/unit.py,sha256=ZTL_H5FqDCnbNRjPbVrIvhvZkyR6qmMatuVwM5OGqmQ,7071
|
7
|
+
qnty/unit_types/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
8
|
+
qnty/unit_types/base.py,sha256=Gk2Ab4TE-SfGBn-ko_p0vDI178PG9SyZOJ0cBOYEpdg,1620
|
9
|
+
qnty/units.py,sha256=d7qzWnD5y25EhGSd3Et-jBwZqJ4E0lO-yLZENHOZytA,302734
|
10
|
+
qnty/variable.py,sha256=YP4zSvsR0JjEGPiMAFuFbj21SPFeSf1YZ0LhJc-t1qI,9850
|
11
|
+
qnty/variable_types/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
12
|
+
qnty/variable_types/base.py,sha256=Otm7FOvuvi1gdlZm-djlTwqhlsSdzPIL46AXnB2cd18,1735
|
13
|
+
qnty/variable_types/expression_variable.py,sha256=sRQ4VUMLBEh6tPqOwh4gLtGQH9Y3XeeHGdLKo0E6mWc,2997
|
14
|
+
qnty/variable_types/typed_variable.py,sha256=ibmbUh8JCXk2XLc0yvpjMYAtAlpxvia0vB_3xaBqzkc,4345
|
15
|
+
qnty/variables.py,sha256=fc7CPLAgqxI7zjeB22PXrTTA6fnl_1gnaX74MYhXMFM,142963
|
16
|
+
qnty/variables.pyi,sha256=Sm99jqyVQmuxdPhctmxuSvYrMO9vz4XqhMzBDsr2uC8,217982
|
17
|
+
qnty-0.0.3.dist-info/METADATA,sha256=oEA22r6KeD2LnoEZCp4ibMXIEvzgJdP49dImBIW8qbk,12113
|
18
|
+
qnty-0.0.3.dist-info/WHEEL,sha256=b4K_helf-jlQoXBBETfwnf4B04YC67LOev0jo4fX5m8,88
|
19
|
+
qnty-0.0.3.dist-info/RECORD,,
|
qnty/setters.py
DELETED
@@ -1,89 +0,0 @@
|
|
1
|
-
"""
|
2
|
-
Specialized Setters
|
3
|
-
===================
|
4
|
-
|
5
|
-
Dimension-specific setters with fluent API and compile-time type safety.
|
6
|
-
"""
|
7
|
-
|
8
|
-
from typing import TYPE_CHECKING
|
9
|
-
from .variable import FastQuantity
|
10
|
-
from .units import LengthUnits, PressureUnits
|
11
|
-
from .unit import UnitConstant
|
12
|
-
|
13
|
-
if TYPE_CHECKING:
|
14
|
-
from .variables import Length, Pressure
|
15
|
-
from .variable import TypeSafeVariable
|
16
|
-
|
17
|
-
|
18
|
-
class TypeSafeSetter:
|
19
|
-
"""Type-safe setter that only accepts compatible units."""
|
20
|
-
|
21
|
-
def __init__(self, variable: 'TypeSafeVariable', value: float):
|
22
|
-
self.variable = variable
|
23
|
-
self.value = value
|
24
|
-
|
25
|
-
def with_unit(self, unit: UnitConstant) -> 'TypeSafeVariable':
|
26
|
-
"""Set with type-safe unit constant."""
|
27
|
-
if not self.variable.expected_dimension.is_compatible(unit.dimension):
|
28
|
-
raise TypeError(f"Unit {unit.name} incompatible with expected dimension")
|
29
|
-
|
30
|
-
self.variable.quantity = FastQuantity(self.value, unit)
|
31
|
-
return self.variable
|
32
|
-
|
33
|
-
|
34
|
-
class LengthSetter:
|
35
|
-
"""Length-specific setter with only length units."""
|
36
|
-
|
37
|
-
def __init__(self, variable: 'Length', value: float):
|
38
|
-
self.variable = variable
|
39
|
-
self.value = value
|
40
|
-
|
41
|
-
# Only length units available - compile-time safe!
|
42
|
-
@property
|
43
|
-
def meters(self) -> 'Length':
|
44
|
-
self.variable.quantity = FastQuantity(self.value, LengthUnits.meter)
|
45
|
-
return self.variable
|
46
|
-
|
47
|
-
@property
|
48
|
-
def millimeters(self) -> 'Length':
|
49
|
-
self.variable.quantity = FastQuantity(self.value, LengthUnits.millimeter)
|
50
|
-
return self.variable
|
51
|
-
|
52
|
-
@property
|
53
|
-
def inches(self) -> 'Length':
|
54
|
-
self.variable.quantity = FastQuantity(self.value, LengthUnits.inch)
|
55
|
-
return self.variable
|
56
|
-
|
57
|
-
@property
|
58
|
-
def feet(self) -> 'Length':
|
59
|
-
self.variable.quantity = FastQuantity(self.value, LengthUnits.foot)
|
60
|
-
return self.variable
|
61
|
-
|
62
|
-
|
63
|
-
class PressureSetter:
|
64
|
-
"""Pressure-specific setter with only pressure units."""
|
65
|
-
|
66
|
-
def __init__(self, variable: 'Pressure', value: float):
|
67
|
-
self.variable = variable
|
68
|
-
self.value = value
|
69
|
-
|
70
|
-
# Only pressure units available - compile-time safe!
|
71
|
-
@property
|
72
|
-
def psi(self) -> 'Pressure':
|
73
|
-
self.variable.quantity = FastQuantity(self.value, PressureUnits.psi)
|
74
|
-
return self.variable
|
75
|
-
|
76
|
-
@property
|
77
|
-
def kPa(self) -> 'Pressure':
|
78
|
-
self.variable.quantity = FastQuantity(self.value, PressureUnits.kilopascal)
|
79
|
-
return self.variable
|
80
|
-
|
81
|
-
@property
|
82
|
-
def MPa(self) -> 'Pressure':
|
83
|
-
self.variable.quantity = FastQuantity(self.value, PressureUnits.megapascal)
|
84
|
-
return self.variable
|
85
|
-
|
86
|
-
@property
|
87
|
-
def bar(self) -> 'Pressure':
|
88
|
-
self.variable.quantity = FastQuantity(self.value, PressureUnits.bar)
|
89
|
-
return self.variable
|
qnty-0.0.1.dist-info/RECORD
DELETED
@@ -1,10 +0,0 @@
|
|
1
|
-
qnty/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
2
|
-
qnty/dimension.py,sha256=6EBpexKOWNCjMnd-VPH8bbjEdbZwkpvRRxexBAI-aqQ,2782
|
3
|
-
qnty/setters.py,sha256=4rNLJQ0U7gAhXgaOWzGKes9iX8PnQeKI_RBmvgY4DHo,2793
|
4
|
-
qnty/unit.py,sha256=VhWw8Z3PKBI8jXhhiYmuzp5PF6wYQeZvh8GiV29kumw,4230
|
5
|
-
qnty/units.py,sha256=_iueuOZv-0mYMBfnswxmJ1okg1mRLz2M4UW2CN28x2w,1369
|
6
|
-
qnty/variable.py,sha256=cH0UawJ-mxFgdY7i3UVsdQ5P64EAnioYyhHppGxCJT8,8613
|
7
|
-
qnty/variables.py,sha256=yfeEewKHOgm-DRKPf7SEH5ZT5xW6SQcSzFz9NxcWy74,771
|
8
|
-
qnty-0.0.1.dist-info/METADATA,sha256=0q4UsvsoMxwAtg7RutwZXRAEhBmsAEBUsTfX8imaXKY,9432
|
9
|
-
qnty-0.0.1.dist-info/WHEEL,sha256=b4K_helf-jlQoXBBETfwnf4B04YC67LOev0jo4fX5m8,88
|
10
|
-
qnty-0.0.1.dist-info/RECORD,,
|
File without changes
|