qnty 0.0.1__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 ADDED
File without changes
qnty/dimension.py ADDED
@@ -0,0 +1,85 @@
1
+ """
2
+ Dimension System
3
+ ================
4
+
5
+ Compile-time dimensional analysis using type system for ultra-fast operations.
6
+ """
7
+
8
+ from typing import final
9
+ from dataclasses import dataclass
10
+ from enum import IntEnum
11
+
12
+ class BaseDimension(IntEnum):
13
+ """Base dimensions as prime numbers for efficient bit operations."""
14
+ LENGTH = 2
15
+ MASS = 3
16
+ TIME = 5
17
+ CURRENT = 7
18
+ TEMPERATURE = 11
19
+ AMOUNT = 13
20
+ LUMINOSITY = 17
21
+
22
+
23
+ @final
24
+ @dataclass(frozen=True)
25
+ class DimensionSignature:
26
+ """Immutable dimension signature for zero-cost dimensional analysis."""
27
+
28
+ # Store as bit pattern for ultra-fast comparison
29
+ _signature: int = 1
30
+
31
+ @classmethod
32
+ def create(cls, length=0, mass=0, time=0, current=0, temp=0, amount=0, luminosity=0):
33
+ """Create dimension from exponents."""
34
+ signature = 1
35
+ if length != 0:
36
+ signature *= BaseDimension.LENGTH ** length
37
+ if mass != 0:
38
+ signature *= BaseDimension.MASS ** mass
39
+ if time != 0:
40
+ signature *= BaseDimension.TIME ** time
41
+ if current != 0:
42
+ signature *= BaseDimension.CURRENT ** current
43
+ if temp != 0:
44
+ signature *= BaseDimension.TEMPERATURE ** temp
45
+ if amount != 0:
46
+ signature *= BaseDimension.AMOUNT ** amount
47
+ if luminosity != 0:
48
+ signature *= BaseDimension.LUMINOSITY ** luminosity
49
+
50
+ return cls(signature)
51
+
52
+ def __mul__(self, other):
53
+ return DimensionSignature(self._signature * other._signature)
54
+
55
+ def __truediv__(self, other):
56
+ return DimensionSignature(self._signature // other._signature)
57
+
58
+ def __pow__(self, power):
59
+ return DimensionSignature(self._signature ** power)
60
+
61
+ def is_compatible(self, other):
62
+ """Ultra-fast dimensional compatibility check."""
63
+ return self._signature == other._signature
64
+
65
+ def __eq__(self, other):
66
+ """Fast equality check for dimensions."""
67
+ return isinstance(other, DimensionSignature) and self._signature == other._signature
68
+
69
+ def __hash__(self):
70
+ """Enable dimensions as dictionary keys."""
71
+ return hash(self._signature)
72
+
73
+
74
+ # Pre-defined dimension constants
75
+ DIMENSIONLESS = DimensionSignature.create()
76
+ LENGTH = DimensionSignature.create(length=1)
77
+ MASS = DimensionSignature.create(mass=1)
78
+ TIME = DimensionSignature.create(time=1)
79
+ AREA = DimensionSignature.create(length=2)
80
+ VOLUME = DimensionSignature.create(length=3)
81
+ VELOCITY = DimensionSignature.create(length=1, time=-1)
82
+ ACCELERATION = DimensionSignature.create(length=1, time=-2)
83
+ FORCE = DimensionSignature.create(mass=1, length=1, time=-2)
84
+ PRESSURE = DimensionSignature.create(mass=1, length=-1, time=-2)
85
+ ENERGY = DimensionSignature.create(mass=1, length=2, time=-2)
qnty/setters.py ADDED
@@ -0,0 +1,89 @@
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/unit.py ADDED
@@ -0,0 +1,113 @@
1
+ """
2
+ Unit System
3
+ ===========
4
+
5
+ Unit definitions, constants and registry for the high-performance unit system.
6
+ """
7
+
8
+ from typing import Dict, Tuple, List
9
+ from dataclasses import dataclass
10
+ from .dimension import DimensionSignature, LENGTH, PRESSURE, DIMENSIONLESS
11
+
12
+
13
+ @dataclass(frozen=True)
14
+ class UnitDefinition:
15
+ """Immutable unit definition optimized for performance."""
16
+ name: str
17
+ symbol: str
18
+ dimension: DimensionSignature
19
+ si_factor: float
20
+ si_offset: float = 0.0
21
+
22
+
23
+ class UnitConstant:
24
+ """Unit constant that provides type safety and performance."""
25
+
26
+ def __init__(self, definition: UnitDefinition):
27
+ self.definition = definition
28
+ self.name = definition.name
29
+ self.symbol = definition.symbol
30
+ self.dimension = definition.dimension
31
+ self.si_factor = definition.si_factor
32
+
33
+ def __str__(self):
34
+ return self.symbol
35
+
36
+ def __eq__(self, other):
37
+ """Fast equality check for unit constants."""
38
+ return isinstance(other, UnitConstant) and self.name == other.name
39
+
40
+ def __hash__(self):
41
+ """Enable unit constants as dictionary keys."""
42
+ return hash(self.name)
43
+
44
+
45
+ class HighPerformanceRegistry:
46
+ """Ultra-fast registry with pre-computed conversion tables."""
47
+
48
+ def __init__(self):
49
+ self.units: Dict[str, UnitDefinition] = {}
50
+ self.conversion_table: Dict[Tuple[str, str], float] = {} # (from_unit, to_unit) -> factor
51
+ self.dimensional_groups: Dict[int, List[UnitDefinition]] = {}
52
+ self._dimension_cache: Dict[int, UnitConstant] = {} # Cache for common dimension mappings
53
+
54
+ self._initialize_units()
55
+ self._precompute_conversions()
56
+
57
+ def _initialize_units(self):
58
+ """Initialize with engineering units."""
59
+
60
+ # Length units
61
+ meter = UnitDefinition("meter", "m", LENGTH, 1.0)
62
+ millimeter = UnitDefinition("millimeter", "mm", LENGTH, 0.001)
63
+ centimeter = UnitDefinition("centimeter", "cm", LENGTH, 0.01)
64
+ inch = UnitDefinition("inch", "in", LENGTH, 0.0254)
65
+ foot = UnitDefinition("foot", "ft", LENGTH, 0.3048)
66
+
67
+ # Pressure units
68
+ pascal = UnitDefinition("pascal", "Pa", PRESSURE, 1.0)
69
+ kilopascal = UnitDefinition("kilopascal", "kPa", PRESSURE, 1000.0)
70
+ megapascal = UnitDefinition("megapascal", "MPa", PRESSURE, 1e6)
71
+ psi = UnitDefinition("psi", "psi", PRESSURE, 6894.757)
72
+ bar = UnitDefinition("bar", "bar", PRESSURE, 100000.0)
73
+
74
+ # Dimensionless units
75
+ dimensionless = UnitDefinition("dimensionless", "", DIMENSIONLESS, 1.0)
76
+
77
+ # Register all units
78
+ for unit_def in [meter, millimeter, centimeter, inch, foot,
79
+ pascal, kilopascal, megapascal, psi, bar, dimensionless]:
80
+ self.units[unit_def.name] = unit_def
81
+
82
+ # Group by dimension
83
+ dim_sig = unit_def.dimension._signature
84
+ if dim_sig not in self.dimensional_groups:
85
+ self.dimensional_groups[dim_sig] = []
86
+ self.dimensional_groups[dim_sig].append(unit_def)
87
+
88
+ def _precompute_conversions(self):
89
+ """Pre-compute all unit conversions for maximum speed."""
90
+ for group in self.dimensional_groups.values():
91
+ for from_unit in group:
92
+ for to_unit in group:
93
+ if from_unit != to_unit:
94
+ factor = from_unit.si_factor / to_unit.si_factor
95
+ key = (from_unit.name, to_unit.name)
96
+ self.conversion_table[key] = factor
97
+
98
+ def convert(self, value: float, from_unit: UnitConstant, to_unit: UnitConstant) -> float:
99
+ """Ultra-fast conversion using pre-computed table."""
100
+ if from_unit == to_unit:
101
+ return value
102
+
103
+ # O(1) lookup for pre-computed conversions
104
+ key = (from_unit.name, to_unit.name)
105
+ if key in self.conversion_table:
106
+ return value * self.conversion_table[key]
107
+
108
+ # Fallback (shouldn't happen for registered units)
109
+ return value * from_unit.si_factor / to_unit.si_factor
110
+
111
+
112
+ # Global high-performance registry
113
+ registry = HighPerformanceRegistry()
qnty/units.py ADDED
@@ -0,0 +1,47 @@
1
+ """
2
+ Predefined Unit Constants
3
+ =========================
4
+
5
+ Type-safe unit constants for common engineering units.
6
+ """
7
+
8
+ from .unit import UnitConstant, registry
9
+
10
+
11
+ # =====================================================================
12
+ # Type-Safe Unit Constants (No More Strings!)
13
+ # =====================================================================
14
+
15
+ class LengthUnits:
16
+ """Type-safe length unit constants."""
17
+ meter = UnitConstant(registry.units["meter"])
18
+ millimeter = UnitConstant(registry.units["millimeter"])
19
+ centimeter = UnitConstant(registry.units["centimeter"])
20
+ inch = UnitConstant(registry.units["inch"])
21
+ foot = UnitConstant(registry.units["foot"])
22
+
23
+ # Common aliases
24
+ m = meter
25
+ mm = millimeter
26
+ cm = centimeter
27
+ in_ = inch # 'in' is reserved
28
+ ft = foot
29
+
30
+
31
+ class PressureUnits:
32
+ """Type-safe pressure unit constants."""
33
+ pascal = UnitConstant(registry.units["pascal"])
34
+ kilopascal = UnitConstant(registry.units["kilopascal"])
35
+ megapascal = UnitConstant(registry.units["megapascal"])
36
+ psi = UnitConstant(registry.units["psi"])
37
+ bar = UnitConstant(registry.units["bar"])
38
+
39
+ # Common aliases
40
+ Pa = pascal
41
+ kPa = kilopascal
42
+ MPa = megapascal
43
+
44
+
45
+ class DimensionlessUnits:
46
+ """Type-safe dimensionless unit constants."""
47
+ dimensionless = UnitConstant(registry.units["dimensionless"])
qnty/variable.py ADDED
@@ -0,0 +1,198 @@
1
+ """
2
+ High-Performance Quantity and Variables
3
+ ========================================
4
+
5
+ FastQuantity class and type-safe variables optimized for engineering calculations
6
+ with dimensional safety.
7
+ """
8
+
9
+ from typing import Union, Optional, TypeVar, Generic, TYPE_CHECKING
10
+ from .dimension import DimensionSignature, DIMENSIONLESS, LENGTH, PRESSURE, AREA, VOLUME, FORCE, ENERGY
11
+ from .unit import UnitConstant, UnitDefinition, registry
12
+ from .units import DimensionlessUnits, LengthUnits, PressureUnits
13
+
14
+ if TYPE_CHECKING:
15
+ from .setters import TypeSafeSetter, LengthSetter, PressureSetter
16
+
17
+
18
+ DimensionType = TypeVar('DimensionType', bound='FastQuantity')
19
+ SetterType = TypeVar('SetterType')
20
+
21
+
22
+ class FastQuantity:
23
+ """High-performance quantity optimized for engineering calculations."""
24
+
25
+ __slots__ = ('value', 'unit', 'dimension', '_si_factor', '_dimension_sig')
26
+
27
+ def __init__(self, value: float, unit: UnitConstant):
28
+ self.value = float(value)
29
+ self.unit = unit
30
+ self.dimension = unit.dimension
31
+ # Cache commonly used values to avoid lookups
32
+ self._si_factor = unit.si_factor
33
+ self._dimension_sig = unit.dimension._signature
34
+
35
+ def __str__(self):
36
+ return f"{self.value} {self.unit.symbol}"
37
+
38
+ def __repr__(self):
39
+ return f"FastQuantity({self.value}, {self.unit.name})"
40
+
41
+ # Ultra-fast arithmetic with dimensional checking
42
+ def __add__(self, other: 'FastQuantity') -> 'FastQuantity':
43
+ # Fast dimension compatibility check using cached signatures
44
+ if self._dimension_sig != other._dimension_sig:
45
+ raise ValueError(f"Cannot add {self.unit.name} and {other.unit.name}")
46
+
47
+ # Fast path for same units - no conversion needed
48
+ if self.unit == other.unit:
49
+ return FastQuantity(self.value + other.value, self.unit)
50
+
51
+ # Convert other to self's units using cached SI factors
52
+ other_value = other.value * other._si_factor / self._si_factor
53
+ return FastQuantity(self.value + other_value, self.unit)
54
+
55
+ def __sub__(self, other: 'FastQuantity') -> 'FastQuantity':
56
+ # Fast dimension compatibility check using cached signatures
57
+ if self._dimension_sig != other._dimension_sig:
58
+ raise ValueError(f"Cannot subtract {other.unit.name} from {self.unit.name}")
59
+
60
+ # Fast path for same units - no conversion needed
61
+ if self.unit == other.unit:
62
+ return FastQuantity(self.value - other.value, self.unit)
63
+
64
+ # Convert other to self's units using cached SI factors
65
+ other_value = other.value * other._si_factor / self._si_factor
66
+ return FastQuantity(self.value - other_value, self.unit)
67
+
68
+ def __mul__(self, other: Union['FastQuantity', float, int]) -> 'FastQuantity':
69
+ if isinstance(other, (int, float)):
70
+ return FastQuantity(self.value * other, self.unit)
71
+
72
+ # Fast dimensional analysis using cached signatures
73
+ result_dimension_sig = self._dimension_sig * other._dimension_sig
74
+
75
+ # Use cached SI factors for conversion
76
+ self_si_value = self.value * self._si_factor
77
+ other_si_value = other.value * other._si_factor
78
+ result_si_value = self_si_value * other_si_value
79
+
80
+ # Fast path for common dimension combinations
81
+ result_unit = self._find_result_unit_fast(result_dimension_sig, self, other)
82
+ result_value = result_si_value / result_unit.si_factor
83
+
84
+ return FastQuantity(result_value, result_unit)
85
+
86
+ def __rmul__(self, other: Union[float, int]) -> 'FastQuantity':
87
+ """Reverse multiplication for cases like 2 * quantity."""
88
+ if isinstance(other, (int, float)):
89
+ return FastQuantity(other * self.value, self.unit)
90
+ return NotImplemented
91
+
92
+ def __truediv__(self, other: Union['FastQuantity', float, int]) -> 'FastQuantity':
93
+ if isinstance(other, (int, float)):
94
+ return FastQuantity(self.value / other, self.unit)
95
+
96
+ # Fast dimensional analysis using cached signatures
97
+ result_dimension_sig = self._dimension_sig // other._dimension_sig
98
+
99
+ # Use cached SI factors for conversion
100
+ self_si_value = self.value * self._si_factor
101
+ other_si_value = other.value * other._si_factor
102
+ result_si_value = self_si_value / other_si_value
103
+
104
+ # Fast path for common dimension combinations
105
+ result_unit = self._find_result_unit_fast(result_dimension_sig, self, other)
106
+ result_value = result_si_value / result_unit.si_factor
107
+
108
+ return FastQuantity(result_value, result_unit)
109
+
110
+ def _find_result_unit_fast(self, result_dimension_sig: int,
111
+ left_qty: 'FastQuantity', right_qty: 'FastQuantity') -> UnitConstant:
112
+ """Ultra-fast unit finding using cached dimension signatures."""
113
+
114
+ # Initialize dimension cache if empty
115
+ if not registry._dimension_cache:
116
+ registry._dimension_cache = {
117
+ DIMENSIONLESS._signature: DimensionlessUnits.dimensionless,
118
+ LENGTH._signature: LengthUnits.millimeter,
119
+ PRESSURE._signature: PressureUnits.Pa,
120
+ AREA._signature: LengthUnits.millimeter, # mmยฒ
121
+ VOLUME._signature: LengthUnits.millimeter, # mmยณ
122
+ FORCE._signature: UnitConstant(UnitDefinition("newton", "N", FORCE, 1.0)),
123
+ ENERGY._signature: UnitConstant(UnitDefinition("joule", "J", ENERGY, 1.0)),
124
+ }
125
+
126
+ # O(1) lookup for common dimensions
127
+ if result_dimension_sig in registry._dimension_cache:
128
+ return registry._dimension_cache[result_dimension_sig]
129
+
130
+ # For rare combined dimensions, create temporary unit
131
+ temp_unit = UnitDefinition(
132
+ name=f"combined_{result_dimension_sig}",
133
+ symbol="combined",
134
+ dimension=DimensionSignature(result_dimension_sig),
135
+ si_factor=1.0
136
+ )
137
+ result_unit = UnitConstant(temp_unit)
138
+
139
+ # Cache for future use
140
+ registry._dimension_cache[result_dimension_sig] = result_unit
141
+ return result_unit
142
+
143
+ def _find_result_unit(self, result_dimension: DimensionSignature,
144
+ left_qty: 'FastQuantity', right_qty: 'FastQuantity') -> UnitConstant:
145
+ """Legacy method - kept for compatibility."""
146
+ return self._find_result_unit_fast(result_dimension._signature, left_qty, right_qty)
147
+
148
+ # Ultra-fast comparisons
149
+ def __lt__(self, other: 'FastQuantity') -> bool:
150
+ if self._dimension_sig != other._dimension_sig:
151
+ raise ValueError("Cannot compare incompatible dimensions")
152
+
153
+ # Fast path for same units
154
+ if self.unit == other.unit:
155
+ return self.value < other.value
156
+
157
+ # Convert using cached SI factors
158
+ other_value = other.value * other._si_factor / self._si_factor
159
+ return self.value < other_value
160
+
161
+ def __eq__(self, other) -> bool:
162
+ if not isinstance(other, FastQuantity):
163
+ return False
164
+ if self._dimension_sig != other._dimension_sig:
165
+ return False
166
+
167
+ # Fast path for same units
168
+ if self.unit == other.unit:
169
+ return abs(self.value - other.value) < 1e-10
170
+
171
+ # Convert using cached SI factors
172
+ other_value = other.value * other._si_factor / self._si_factor
173
+ return abs(self.value - other_value) < 1e-10
174
+
175
+ def to(self, target_unit: UnitConstant) -> 'FastQuantity':
176
+ """Ultra-fast unit conversion."""
177
+ if self.unit == target_unit:
178
+ return FastQuantity(self.value, target_unit)
179
+
180
+ # Direct SI factor conversion - avoid registry lookup
181
+ converted_value = self.value * self._si_factor / target_unit.si_factor
182
+ return FastQuantity(converted_value, target_unit)
183
+
184
+
185
+ class TypeSafeVariable(Generic[DimensionType]):
186
+ """Type-safe variable with compile-time dimensional checking."""
187
+
188
+ def __init__(self, name: str, expected_dimension: DimensionSignature):
189
+ self.name = name
190
+ self.expected_dimension = expected_dimension
191
+ self.quantity: Optional[FastQuantity] = None
192
+
193
+ def set(self, value: float) -> Union['TypeSafeSetter', 'LengthSetter', 'PressureSetter']:
194
+ from .setters import TypeSafeSetter
195
+ return TypeSafeSetter(self, value)
196
+
197
+ def __str__(self):
198
+ return f"{self.name}: {self.quantity}" if self.quantity else f"{self.name}: unset"
qnty/variables.py ADDED
@@ -0,0 +1,31 @@
1
+ """
2
+ Specialized Variables
3
+ =====================
4
+
5
+ Dimension-specific variable classes with type safety.
6
+ """
7
+
8
+ from .dimension import LENGTH, PRESSURE
9
+ from .variable import TypeSafeVariable
10
+ from .setters import LengthSetter, PressureSetter
11
+
12
+
13
+ # Specialized variable types
14
+ class Length(TypeSafeVariable):
15
+ """Type-safe length variable."""
16
+
17
+ def __init__(self, name: str):
18
+ super().__init__(name, LENGTH)
19
+
20
+ def set(self, value: float) -> 'LengthSetter':
21
+ return LengthSetter(self, value)
22
+
23
+
24
+ class Pressure(TypeSafeVariable):
25
+ """Type-safe pressure variable."""
26
+
27
+ def __init__(self, name: str):
28
+ super().__init__(name, PRESSURE)
29
+
30
+ def set(self, value: float) -> 'PressureSetter':
31
+ return PressureSetter(self, value)
@@ -0,0 +1,268 @@
1
+ Metadata-Version: 2.3
2
+ Name: qnty
3
+ Version: 0.0.1
4
+ Summary: High-performance unit system library for Python with dimensional safety and fast unit conversions
5
+ License: Apache-2.0
6
+ Keywords: units,dimensional analysis,engineering,physics,quantities,measurements
7
+ Author: tn3wman
8
+ Requires-Python: >=3.11, <3.14
9
+ Classifier: Development Status :: 4 - Beta
10
+ Classifier: Intended Audience :: Developers
11
+ Classifier: Intended Audience :: Science/Research
12
+ Classifier: License :: OSI Approved :: Apache Software License
13
+ Classifier: Programming Language :: Python :: 3
14
+ Classifier: Programming Language :: Python :: 3.11
15
+ Classifier: Programming Language :: Python :: 3.12
16
+ Classifier: Programming Language :: Python :: 3.13
17
+ Classifier: Topic :: Scientific/Engineering
18
+ Classifier: Topic :: Scientific/Engineering :: Physics
19
+ Classifier: Topic :: Software Development :: Libraries :: Python Modules
20
+ Provides-Extra: benchmark
21
+ Provides-Extra: dev
22
+ Requires-Dist: Pint (>=0.24.4) ; extra == "benchmark"
23
+ Requires-Dist: numpy (>=2.3.2)
24
+ Requires-Dist: pytest (>=8.4.1) ; extra == "dev"
25
+ Requires-Dist: ruff (>=0.1.0) ; extra == "dev"
26
+ Project-URL: Bug Tracker, https://github.com/tn3wman/qnty/issues
27
+ Project-URL: Documentation, https://github.com/tn3wman/qnty#readme
28
+ Project-URL: Homepage, https://github.com/tn3wman/qnty
29
+ Project-URL: Repository, https://github.com/tn3wman/qnty
30
+ Description-Content-Type: text/markdown
31
+
32
+ # Qnty
33
+
34
+ **High-performance unit system library for Python with dimensional safety and fast unit conversions for engineering calculations.**
35
+
36
+ [![Python 3.10+](https://img.shields.io/badge/python-3.10+-blue.svg)](https://www.python.org/downloads/)
37
+ [![License: Apache-2.0](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0)
38
+ [![Development Status](https://img.shields.io/badge/status-beta-orange.svg)](https://pypi.org/project/qnty/)
39
+
40
+ ## โš ๏ธ Important Disclaimer
41
+
42
+ **๐Ÿšง Work in Progress**: Qnty is currently in active development and has not been thoroughly vetted for production engineering calculations. While we strive for accuracy, this library should not be used for critical engineering applications without independent verification.
43
+
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
+
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
+
48
+ *Use Qnty to help prevent unit errors, but always verify critical calculations through multiple methods.*
49
+
50
+ ---
51
+
52
+ Qnty is designed around **type safety** and **performance optimization** using compile-time dimensional analysis. It provides ultra-fast unit conversions and dimensional checking for engineering applications where performance matters.
53
+
54
+ ## โœจ Key Features
55
+
56
+ - **๐Ÿš€ Ultra-Fast Performance**: Prime number encoding and pre-computed conversion tables
57
+ - **๐Ÿ›ก๏ธ Type Safety**: Compile-time dimensional analysis prevents unit errors
58
+ - **โšก Zero-Cost Abstractions**: Optimized operations with `__slots__` and caching
59
+ - **๐Ÿ”— Fluent API**: Intuitive method chaining for readable code
60
+ - **๐Ÿงฎ Engineering-Focused**: Built for real-world engineering calculations
61
+ - **๐Ÿ“Š Comprehensive Testing**: 400+ tests with performance benchmarks
62
+
63
+ ## ๐Ÿš€ Quick Start
64
+
65
+ ### Installation
66
+
67
+ ```bash
68
+ pip install qnty
69
+ # or with Poetry
70
+ poetry add qnty
71
+ ```
72
+
73
+ ### Basic Usage
74
+
75
+ ```python
76
+ from qnty.variables import Length, Pressure
77
+ from qnty.variable import FastQuantity
78
+ from qnty.units import LengthUnits, PressureUnits
79
+
80
+ # Type-safe variables with fluent API
81
+ beam_length = Length("beam_length")
82
+ beam_length.set(100.0).millimeters
83
+ print(beam_length) # beam_length: 100.0 mm
84
+
85
+ # Convert units effortlessly
86
+ length_in_meters = beam_length.quantity.to(LengthUnits.meter)
87
+ print(length_in_meters) # 0.1 m
88
+
89
+ # High-performance calculations
90
+ pressure = FastQuantity(150.0, PressureUnits.psi)
91
+ area = FastQuantity(0.5, LengthUnits.meter) * FastQuantity(2.0, LengthUnits.meter)
92
+ force = pressure * area # Automatic dimensional analysis
93
+ ```
94
+
95
+ ### Engineering Example
96
+
97
+ ```python
98
+ from qnty.variables import Length, Pressure
99
+
100
+ # ASME pressure vessel calculation with mixed units
101
+ pressure = Pressure("internal_pressure")
102
+ diameter = Length("outer_diameter")
103
+ stress = Pressure("allowable_stress")
104
+
105
+ # Set values with different units - no manual conversion needed!
106
+ pressure.set(2900.75).psi # Imperial
107
+ diameter.set(168.275).millimeters # Metric
108
+ stress.set(137.895).MPa # SI
109
+
110
+ # Qnty handles all unit conversions automatically
111
+ thickness = (pressure.quantity * diameter.quantity) / (2 * stress.quantity)
112
+ print(f"Required thickness: {thickness}") # Automatically in correct units
113
+ ```
114
+
115
+ ## ๐Ÿ—๏ธ Architecture
116
+
117
+ ### Core Components
118
+
119
+ **๐Ÿ”ข Dimensional System**
120
+ - Prime number encoding for ultra-fast dimensional compatibility checks
121
+ - Zero-cost dimensional analysis at compile time
122
+ - Immutable dimension signatures for thread safety
123
+
124
+ **โš™๏ธ High-Performance Quantities**
125
+ - `FastQuantity`: Optimized for engineering calculations with `__slots__`
126
+ - Cached SI factors and dimension signatures
127
+ - Fast-path optimizations for same-unit operations
128
+
129
+ **๐ŸŽฏ Type-Safe Variables**
130
+ - `Length`, `Pressure`: Domain-specific variables with compile-time safety
131
+ - Fluent API with specialized setters
132
+ - Prevents dimensional errors at the type level
133
+
134
+ **๐Ÿ”„ Smart Unit System**
135
+ - Pre-computed conversion tables
136
+ - Automatic unit resolution for calculations
137
+ - Support for mixed-unit operations
138
+
139
+ ## ๐Ÿ“Š Performance
140
+
141
+ Qnty significantly outperforms other unit libraries with **23.7x average speedup** over Pint:
142
+
143
+ ### Real Benchmark Results (ฮผs per operation)
144
+
145
+ | Operation | Qnty | Pint | **Speedup** |
146
+ |-----------|------|------|-------------|
147
+ | Unit Conversion (m โ†’ mm) | 0.60 | 14.03 | **23.5x** |
148
+ | Mixed Unit Addition (mm + in) | 1.14 | 31.80 | **28.0x** |
149
+ | Multiplication (m ร— m) | 0.91 | 14.13 | **15.5x** |
150
+ | Division (psi รท mm) | 1.01 | 16.29 | **16.1x** |
151
+ | Complex ASME Equation | 5.46 | 180.95 | **33.1x** ๐Ÿš€ |
152
+ | Type-Safe Variables | 1.08 | 24.80 | **23.0x** |
153
+ | Chained Operations | 3.93 | 88.94 | **22.6x** |
154
+ | Loop (10 additions) | 6.49 | 118.21 | **18.2x** |
155
+ | **AVERAGE** | **2.58** | **61.14** | **23.7x** ๐Ÿ† |
156
+
157
+ *Benchmarks performed on typical engineering calculations. Run `pytest tests/test_benchmark.py -v -s` to verify on your system.*
158
+
159
+ ## ๐Ÿงช Advanced Features
160
+
161
+ ### Fluent API Design
162
+
163
+ ```python
164
+ # Method chaining for readable code
165
+ pipe_system = {
166
+ 'inlet': Pressure("inlet").set(150.0).psi,
167
+ 'outlet': Pressure("outlet").set(120.0).psi,
168
+ 'diameter': Length("diameter").set(6.0).inches,
169
+ 'length': Length("length").set(100.0).feet
170
+ }
171
+
172
+ pressure_drop = pipe_system['inlet'].quantity - pipe_system['outlet'].quantity
173
+ ```
174
+
175
+ ### Dimensional Safety
176
+
177
+ ```python
178
+ # This will raise a TypeError at assignment time
179
+ length = Length("distance")
180
+ try:
181
+ length.set(100.0).psi # Wrong! Pressure unit for length variable
182
+ except TypeError as e:
183
+ print(f"Caught error: {e}") # Unit psi incompatible with expected dimension
184
+
185
+ # Type checker catches this at development time
186
+ ```
187
+
188
+ ### Mixed Unit Calculations
189
+
190
+ ```python
191
+ # Automatically handles unit conversions in calculations
192
+ width = Length("width").set(100.0).millimeters
193
+ height = Length("height").set(4.0).inches # Different unit!
194
+
195
+ # Qnty automatically converts to compatible units
196
+ area = width.quantity * height.quantity
197
+ perimeter = 2 * (width.quantity + height.quantity)
198
+ ```
199
+
200
+ ## ๐Ÿ”ง Development
201
+
202
+ ### Setup Development Environment
203
+
204
+ ```bash
205
+ git clone https://github.com/your-username/qnty.git
206
+ cd qnty
207
+ pip install -r requirements.txt
208
+
209
+ # Run all tests
210
+ pytest
211
+
212
+ # Run specific test file
213
+ pytest tests/test_dimension.py -v
214
+
215
+ # Run benchmarks
216
+ python tests/test_benchmark.py
217
+ ```
218
+
219
+ ### Code Quality
220
+
221
+ ```bash
222
+ # Linting with ruff (200 character line length)
223
+ ruff check src/ tests/
224
+
225
+ # Type checking
226
+ mypy src/qnty/
227
+ ```
228
+
229
+ ## ๐Ÿ“š Documentation
230
+
231
+ ### Core Classes
232
+
233
+ - **`FastQuantity`**: High-performance quantity with value and unit
234
+ - **`TypeSafeVariable`**: Base class for dimension-specific variables
235
+ - **`Length`**, **`Pressure`**: Specialized variables with fluent setters
236
+ - **`DimensionSignature`**: Immutable dimension encoding system
237
+ - **`UnitConstant`**: Type-safe unit definitions
238
+
239
+ ### Unit Categories
240
+
241
+ - **Length**: meter, millimeter, inch, foot, etc.
242
+ - **Pressure**: pascal, psi, bar, kilopascal, megapascal, etc.
243
+ - **Dimensionless**: ratios, efficiency factors, etc.
244
+ - *More dimensions coming soon*
245
+
246
+ ## ๐Ÿค Contributing
247
+
248
+ We welcome contributions! Please see our contributing guidelines and:
249
+
250
+ 1. Fork the repository
251
+ 2. Create a feature branch
252
+ 3. Add tests for new functionality
253
+ 4. Ensure all tests pass: `pytest`
254
+ 5. Submit a pull request
255
+
256
+ ## ๐Ÿ“„ License
257
+
258
+ This project is licensed under the Apache License 2.0 - see the [LICENSE](LICENSE) file for details.
259
+
260
+ ## ๐Ÿ™ Acknowledgments
261
+
262
+ - Inspired by the [Pint](https://pint.readthedocs.io/) library
263
+ - Built for the engineering community
264
+ - Designed with performance-critical applications in mind
265
+
266
+ ---
267
+
268
+ **Ready to supercharge your engineering calculations?** Install Qnty today and experience the power of type-safe, high-performance unit handling! ๐Ÿš€
@@ -0,0 +1,10 @@
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,,
@@ -0,0 +1,4 @@
1
+ Wheel-Version: 1.0
2
+ Generator: poetry-core 2.1.3
3
+ Root-Is-Purelib: true
4
+ Tag: py3-none-any