qnty 0.0.8__py3-none-any.whl → 0.0.9__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.
Files changed (74) hide show
  1. qnty/__init__.py +140 -58
  2. qnty/_backup/problem_original.py +1251 -0
  3. qnty/_backup/quantity.py +63 -0
  4. qnty/codegen/cli.py +125 -0
  5. qnty/codegen/generators/data/unit_data.json +8807 -0
  6. qnty/codegen/generators/data_processor.py +345 -0
  7. qnty/codegen/generators/dimensions_gen.py +434 -0
  8. qnty/codegen/generators/doc_generator.py +141 -0
  9. qnty/codegen/generators/out/dimension_mapping.json +974 -0
  10. qnty/codegen/generators/out/dimension_metadata.json +123 -0
  11. qnty/codegen/generators/out/units_metadata.json +223 -0
  12. qnty/codegen/generators/quantities_gen.py +159 -0
  13. qnty/codegen/generators/setters_gen.py +178 -0
  14. qnty/codegen/generators/stubs_gen.py +167 -0
  15. qnty/codegen/generators/units_gen.py +295 -0
  16. qnty/codegen/generators/utils/__init__.py +0 -0
  17. qnty/equations/__init__.py +4 -0
  18. qnty/{equation.py → equations/equation.py} +78 -118
  19. qnty/equations/system.py +127 -0
  20. qnty/expressions/__init__.py +61 -0
  21. qnty/expressions/cache.py +94 -0
  22. qnty/expressions/functions.py +96 -0
  23. qnty/{expression.py → expressions/nodes.py} +209 -216
  24. qnty/generated/__init__.py +0 -0
  25. qnty/generated/dimensions.py +514 -0
  26. qnty/generated/quantities.py +6003 -0
  27. qnty/generated/quantities.pyi +4192 -0
  28. qnty/generated/setters.py +12210 -0
  29. qnty/generated/units.py +9798 -0
  30. qnty/problem/__init__.py +91 -0
  31. qnty/problem/base.py +142 -0
  32. qnty/problem/composition.py +385 -0
  33. qnty/problem/composition_mixin.py +382 -0
  34. qnty/problem/equations.py +413 -0
  35. qnty/problem/metaclass.py +302 -0
  36. qnty/problem/reconstruction.py +1016 -0
  37. qnty/problem/solving.py +180 -0
  38. qnty/problem/validation.py +64 -0
  39. qnty/problem/variables.py +239 -0
  40. qnty/quantities/__init__.py +6 -0
  41. qnty/quantities/expression_quantity.py +314 -0
  42. qnty/quantities/quantity.py +428 -0
  43. qnty/quantities/typed_quantity.py +215 -0
  44. qnty/solving/__init__.py +0 -0
  45. qnty/solving/manager.py +90 -0
  46. qnty/solving/order.py +355 -0
  47. qnty/solving/solvers/__init__.py +20 -0
  48. qnty/solving/solvers/base.py +92 -0
  49. qnty/solving/solvers/iterative.py +185 -0
  50. qnty/solving/solvers/simultaneous.py +547 -0
  51. qnty/units/__init__.py +0 -0
  52. qnty/{prefixes.py → units/prefixes.py} +54 -33
  53. qnty/{unit.py → units/registry.py} +73 -32
  54. qnty/utils/__init__.py +0 -0
  55. qnty/utils/logging.py +40 -0
  56. qnty/validation/__init__.py +0 -0
  57. qnty/validation/registry.py +0 -0
  58. qnty/validation/rules.py +167 -0
  59. qnty-0.0.9.dist-info/METADATA +199 -0
  60. qnty-0.0.9.dist-info/RECORD +63 -0
  61. qnty/dimension.py +0 -186
  62. qnty/unit_types/base.py +0 -47
  63. qnty/units.py +0 -8113
  64. qnty/variable.py +0 -300
  65. qnty/variable_types/base.py +0 -58
  66. qnty/variable_types/expression_variable.py +0 -106
  67. qnty/variable_types/typed_variable.py +0 -87
  68. qnty/variables.py +0 -2298
  69. qnty/variables.pyi +0 -6148
  70. qnty-0.0.8.dist-info/METADATA +0 -355
  71. qnty-0.0.8.dist-info/RECORD +0 -19
  72. /qnty/{unit_types → codegen}/__init__.py +0 -0
  73. /qnty/{variable_types → codegen/generators}/__init__.py +0 -0
  74. {qnty-0.0.8.dist-info → qnty-0.0.9.dist-info}/WHEEL +0 -0
@@ -0,0 +1,199 @@
1
+ Metadata-Version: 2.3
2
+ Name: qnty
3
+ Version: 0.0.9
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.11+](https://img.shields.io/badge/python-3.11+-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
+ *Use Qnty to help prevent unit errors, but always verify critical calculations through multiple methods.*
47
+
48
+ ---
49
+
50
+ ## ✨ Key Features
51
+
52
+ - **🚀 Ultra-Fast Performance**: Prime number encoding and pre-computed conversion tables
53
+ - **🛡️ Type Safety**: Compile-time dimensional analysis prevents unit errors
54
+ - **⚡ Zero-Cost Abstractions**: Optimized operations with `__slots__` and caching
55
+ - **🔗 Fluent API**: Intuitive method chaining for readable code
56
+ - **🧮 Engineering-Focused**: Built for real-world engineering calculations
57
+ - **🧬 Mathematical System**: Built-in equation solving and expression trees
58
+ - **📊 Comprehensive Testing**: 187 tests with performance benchmarks
59
+
60
+ ## 🚀 Quick Start
61
+
62
+ ### Installation
63
+
64
+ ```bash
65
+ pip install qnty
66
+ ```
67
+
68
+ ### Basic Usage
69
+
70
+ ```python
71
+ from qnty import Length, Pressure, Area
72
+
73
+ # Create quantities with dimensional safety
74
+ width = Length(3, "meter", "Width")
75
+ height = Length(2, "meter", "Height")
76
+
77
+ # Solve mathematical expressions
78
+ area = Area("area", is_known=False)
79
+ area.solve_from(width * height)
80
+ print(f"Area: {area}") # Area: 6.0 m²
81
+ ```
82
+
83
+ ### Engineering Example
84
+
85
+ ```python
86
+ from qnty import Problem, Length, Pressure
87
+
88
+ class PipeThickness(Problem):
89
+ """Calculate pipe wall thickness"""
90
+
91
+ # Known parameters
92
+ pressure = Pressure(150, "pound_force_per_square_inch", "Internal Pressure")
93
+ diameter = Length(6, "inch", "Pipe Diameter")
94
+ allowable_stress = Pressure(20000, "pound_force_per_square_inch", "Allowable Stress")
95
+
96
+ # Unknown to solve for
97
+ thickness = Length("thickness", is_known=False)
98
+
99
+ # Engineering equation: t = (P × D) / (2 × S)
100
+ equation = thickness.equals((pressure * diameter) / (2 * allowable_stress))
101
+
102
+ # Solve the problem
103
+ problem = PipeThickness()
104
+ problem.solve()
105
+ print(f"Required thickness: {problem.thickness}")
106
+ ```
107
+
108
+ ### Mathematical Operations
109
+
110
+ ```python
111
+ from qnty import Length, sqrt, Area
112
+
113
+ # Dimensional analysis with mathematical functions
114
+ area = Area(25, "square_meter", "Square Area")
115
+ side = Length("side", is_known=False)
116
+ side.solve_from(sqrt(area)) # Returns Length, not Area!
117
+ print(f"Side length: {side}") # Side length: 5.0 m
118
+ ```
119
+
120
+ ## 📚 Documentation
121
+
122
+ - **[📖 Tutorial](docs/TUTORIAL.md)** - Step-by-step learning guide
123
+ - **[📋 API Reference](docs/API_REFERENCE.md)** - Complete API documentation
124
+ - **[🏗️ Examples](examples/)** - Real-world engineering examples
125
+ - **[📁 Full Documentation](docs/)** - Complete documentation index
126
+
127
+ ## 🚀 Performance
128
+
129
+ Qnty significantly outperforms other unit libraries with **18.9x average speedup** over Pint:
130
+
131
+ | Operation | Qnty | Pint | **Speedup** |
132
+ |-----------|------|------|-------------|
133
+ | Mixed Unit Addition | 0.76 μs | 17.52 μs | **23.1x** |
134
+ | Complex ASME Equation | 4.07 μs | 106.17 μs | **26.1x** 🚀 |
135
+ | Type-Safe Variables | 0.98 μs | 9.65 μs | **9.8x** |
136
+ | **AVERAGE** | **1.89 μs** | **35.83 μs** | **18.9x** 🏆 |
137
+
138
+ *Run `pytest tests/test_benchmark.py -v -s` to verify on your system.*
139
+
140
+ ## 🧮 100+ Engineering Quantities
141
+
142
+ Qnty provides comprehensive coverage of engineering domains:
143
+
144
+ ```python
145
+ from qnty import (
146
+ # Mechanical
147
+ Length, Area, Volume, Mass, Force, Pressure, Temperature,
148
+ # Electrical
149
+ ElectricPotential, ElectricCurrentIntensity, ElectricResistance,
150
+ # Thermal
151
+ ThermalConductivity, HeatTransferCoefficient,
152
+ # Fluid Dynamics
153
+ ViscosityDynamic, MassFlowRate, VolumetricFlowRate,
154
+ # And 80+ more...
155
+ )
156
+ ```
157
+
158
+ ## 🔧 Development
159
+
160
+ ```bash
161
+ # Install dependencies
162
+ pip install -r requirements.txt
163
+
164
+ # Run tests
165
+ pytest
166
+
167
+ # Run specific test
168
+ pytest tests/test_dimension.py -v
169
+
170
+ # Run benchmarks
171
+ python tests/test_benchmark.py
172
+
173
+ # Lint code
174
+ ruff check src/ tests/
175
+ ruff format src/ tests/
176
+ ```
177
+
178
+ ## 📄 License
179
+
180
+ This project is licensed under the Apache License 2.0 - see the [LICENSE](LICENSE) file for details.
181
+
182
+ ## 🤝 Contributing
183
+
184
+ We welcome contributions! Please see [CLAUDE.md](CLAUDE.md) for development guidelines and:
185
+
186
+ 1. Fork the repository
187
+ 2. Create a feature branch
188
+ 3. Add tests for new functionality
189
+ 4. Ensure all tests pass: `pytest`
190
+ 5. Submit a pull request
191
+
192
+ ---
193
+
194
+ **Ready to supercharge your engineering calculations?** 🚀
195
+
196
+ - Start with the **[Tutorial](docs/TUTORIAL.md)**
197
+ - Browse the **[API Reference](docs/API_REFERENCE.md)**
198
+ - Try the **[Examples](examples/)**
199
+
@@ -0,0 +1,63 @@
1
+ qnty/__init__.py,sha256=nixvrkyF4sIwtLCPVIfADSEKkQoKlFZs_7TbpuBFWXE,5563
2
+ qnty/_backup/problem_original.py,sha256=M58iUTiWBO1sS3rM3aQSlpIwxbSRiW2LICYK-Lnoz90,56698
3
+ qnty/_backup/quantity.py,sha256=oD-TNDkxK1Tfa6S_sxNnDWyv1_SuW0TrNKz01e45fxg,1509
4
+ qnty/codegen/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
5
+ qnty/codegen/cli.py,sha256=C66IQ-je69UP0llVy7kgSrfUYM3PHuantcefYvFBDHw,4092
6
+ qnty/codegen/generators/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
7
+ qnty/codegen/generators/data/unit_data.json,sha256=KbJHRv5U2bF_uS_Az9G-uFSjwvxCcvmn1ZCxR5H0uGI,253446
8
+ qnty/codegen/generators/data_processor.py,sha256=3Cibqkegi48KuaD9I9i1QinP2h7Fi76EOJ2hwmZq6ug,13741
9
+ qnty/codegen/generators/dimensions_gen.py,sha256=03Ryq8CPIU3gMSOZNnOjc2JMR3Vi-lgVmBYFnOliL8w,16379
10
+ qnty/codegen/generators/doc_generator.py,sha256=zmhDWwxODII5d-_FlKskhMTHHBmS8NRZOzOyPzPMyTs,6184
11
+ qnty/codegen/generators/out/dimension_mapping.json,sha256=_YRPCzMvT9RW_YhURbuHH8gKhYtdu8gaYSqJ-bZxSAE,23864
12
+ qnty/codegen/generators/out/dimension_metadata.json,sha256=-2uXcB8grYMZew9A6mDSajrJ9yCoegrTx23g70QTK_Y,2929
13
+ qnty/codegen/generators/out/units_metadata.json,sha256=5MMDsT6Y99tthus8YT5Xu6iaG4cn99sP-JomKYZ084k,5890
14
+ qnty/codegen/generators/quantities_gen.py,sha256=9Nf_3PUpTf0A1yLe8L4CodrpsD4Oz7DTXX3E-sssj3I,6271
15
+ qnty/codegen/generators/setters_gen.py,sha256=u76OwdH7Sl6XsIDGZn6ID8Xp0VEptBXO1QJ4h6sne1c,7145
16
+ qnty/codegen/generators/stubs_gen.py,sha256=F6ZEk48W9C8nRKP6_pKoGPO3gnDtGfvn-42XgrhA4uk,6659
17
+ qnty/codegen/generators/units_gen.py,sha256=iESIFLCVNWi_4Ftss2_s2QTGTOTutInAeltLQdMjrI8,10592
18
+ qnty/codegen/generators/utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
19
+ qnty/equations/__init__.py,sha256=ngficq_uwosz7O2BaqDH-G6dqp1burjfkcwE4MnGyIo,108
20
+ qnty/equations/equation.py,sha256=dv527D-fE_0jLmK6BJI5SNCjIgzql1JpBcxZkej06-A,10848
21
+ qnty/equations/system.py,sha256=mgslAh_YgEU1V_y48Yy1_eHIFO37vDsSG4Gb3zeuPxc,5115
22
+ qnty/expressions/__init__.py,sha256=qo5I-Z3O1hP9Kk1Jgf5r7x4tAzMLS-a96rY5cqRNVKc,917
23
+ qnty/expressions/cache.py,sha256=ahJ-AyxJJQyGAVQWSEcQAng1TdQ2qysBPiujk9hhink,3413
24
+ qnty/expressions/functions.py,sha256=X7Cfchmc4qY3JE3NnacI5DomYE0jPbAAQHOsrxG3vqk,3618
25
+ qnty/expressions/nodes.py,sha256=bTmpJ36sjnlxgKb2npJfh56K1arN-FOxoiI30Gx31-g,23394
26
+ qnty/generated/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
27
+ qnty/generated/dimensions.py,sha256=WHVr28Ou2DB2QuZCDcxLY2AcauqdE4QGrNFNUJ2EDXY,20661
28
+ qnty/generated/quantities.py,sha256=1FC1P_hIcXotUgDiJXy28P9OCq2jdWEmO5aVZJepNpY,245345
29
+ qnty/generated/quantities.pyi,sha256=URYr8K2JVeXlwbSnUvOLoLYS9beVhGrL33A7Y1hs1Hs,151386
30
+ qnty/generated/setters.py,sha256=Go62i_TlfcBztI8rI7h2FMWGmtoVPGc3JTx6ZmJMrWI,446272
31
+ qnty/generated/units.py,sha256=WXkSL_G4hKzbTiGmN3jreWCuUyutyGb50tRwfT0Xje4,285245
32
+ qnty/problem/__init__.py,sha256=9bML5bjM-uPAHet8n98_OwQLivEs2mzaHjZhENbA7sE,3140
33
+ qnty/problem/base.py,sha256=jepN3vmMyh9eXptJrAQfPICHbDPLQsD2g9k4EY7IqrA,5680
34
+ qnty/problem/composition.py,sha256=DUdJ7oMl1d4ETqgR4rDflqfBOdE2ykr-f6qONOErfZQ,13894
35
+ qnty/problem/composition_mixin.py,sha256=hH9bEZyWc5vz5LfLb7GM2K6WDP7SUgHWUu_Vx4BtEM0,17603
36
+ qnty/problem/equations.py,sha256=QefhpWBQt9OD0vUeYRZs54iv7kQ9xkO0XBtYBtOjfPE,19334
37
+ qnty/problem/metaclass.py,sha256=00T4fg3ACeTo7w1njRgZyOGP2jZm2P2_yxO0rZlnwhE,11944
38
+ qnty/problem/reconstruction.py,sha256=hE7L5Eh2OH3nR_3PFKsSiNRHDSbgSumrhXxPRESmJXI,40042
39
+ qnty/problem/solving.py,sha256=DJ_Dj63vn2ykdFUp77QNxEGOWmPrAzpLe7A_mnCkMzs,6657
40
+ qnty/problem/validation.py,sha256=1Kbebn4JvYO0qw2VOhfeyzzkuSmnTpOANpvVmsXcNuU,2157
41
+ qnty/problem/variables.py,sha256=Fmhc-GmW-tHMQk1YVtHgOQlfvRJxH1le94Nc0HmeyBY,9911
42
+ qnty/quantities/__init__.py,sha256=C8Z032FGpMVt9-PvtIQLNZkxmXjbHUm2OHoytebUL1g,107
43
+ qnty/quantities/expression_quantity.py,sha256=khJ5izSaj497-rd6Ci1p8XyBidwAoXFlqpBiOqVbi3A,13278
44
+ qnty/quantities/quantity.py,sha256=PK1vGMZv55fy87ysvakVipO0lWK_XySKZCobJfKMjTQ,18855
45
+ qnty/quantities/typed_quantity.py,sha256=-PL_6qhJvOLdGXoxJjCHiCx3ZB5Oao9l-e2zrON3cug,9681
46
+ qnty/solving/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
47
+ qnty/solving/manager.py,sha256=FfG3DOrwAKeR0vHll46RtkLB9ZuWN43mthYHnr5AW98,3594
48
+ qnty/solving/order.py,sha256=Z7I_7QonCaGC47DthC2O0m77On34GcaD7nn2oLIFmqs,14411
49
+ qnty/solving/solvers/__init__.py,sha256=CBI2PGLhnQ3AVsfJPfBB7b0ff_BlPCRamGUIHjEMStM,501
50
+ qnty/solving/solvers/base.py,sha256=KYACgawfo8GoRaXEduZRQjJeo948QNFU76N2VrCwcA4,3041
51
+ qnty/solving/solvers/iterative.py,sha256=5SxIGMdP1HkAKsT6cXZR7Lxv3LIgM7dXY3PsTn0w_d4,8139
52
+ qnty/solving/solvers/simultaneous.py,sha256=pqYUwh067z26kP49Nxq8HcCxsxB0dirPaVHMWG4QMTE,23225
53
+ qnty/units/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
54
+ qnty/units/prefixes.py,sha256=U-dGj5ZdseErwFIzvz_RC3fID0D-DazE6ozD6vn4DSs,7442
55
+ qnty/units/registry.py,sha256=rnKnEaG8rZg56ejK1nGl9xpe9hm1WmWAtD8tJ0A0MvA,7524
56
+ qnty/utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
57
+ qnty/utils/logging.py,sha256=QSYgZg6w1n9L-lIj5c3Ufee84E8VvRZOUgoW84vTUbA,1159
58
+ qnty/validation/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
59
+ qnty/validation/registry.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
60
+ qnty/validation/rules.py,sha256=4X3pR6bl9YA5skT2vRmJFB78FR588Rz_cSTTJXD0BDI,6285
61
+ qnty-0.0.9.dist-info/METADATA,sha256=AKPCK06zvVod4ss5nmYHmCgActFnehcUGRF8b7cIfLo,6761
62
+ qnty-0.0.9.dist-info/WHEEL,sha256=b4K_helf-jlQoXBBETfwnf4B04YC67LOev0jo4fX5m8,88
63
+ qnty-0.0.9.dist-info/RECORD,,
qnty/dimension.py DELETED
@@ -1,186 +0,0 @@
1
- """
2
- Dimension System
3
- ================
4
-
5
- Compile-time dimensional analysis using type system for ultra-fast operations.
6
- """
7
-
8
- from dataclasses import dataclass
9
- from enum import IntEnum
10
- from typing import final
11
-
12
-
13
- class BaseDimension(IntEnum):
14
- """Base dimensions as prime numbers for efficient bit operations."""
15
- LENGTH = 2
16
- MASS = 3
17
- TIME = 5
18
- CURRENT = 7
19
- TEMPERATURE = 11
20
- AMOUNT = 13
21
- LUMINOSITY = 17
22
- DIMENSIONLESS = 1 # Must be 1 to act as multiplicative identity
23
-
24
-
25
- @final
26
- @dataclass(frozen=True)
27
- class DimensionSignature:
28
- """Immutable dimension signature for zero-cost dimensional analysis."""
29
-
30
- # Store as bit pattern for ultra-fast comparison
31
- _signature: int | float = 1
32
-
33
- @classmethod
34
- def create(cls, length=0, mass=0, time=0, current=0, temp=0, amount=0, luminosity=0):
35
- """Create dimension from exponents."""
36
- signature = 1
37
- if length != 0:
38
- signature *= BaseDimension.LENGTH ** length
39
- if mass != 0:
40
- signature *= BaseDimension.MASS ** mass
41
- if time != 0:
42
- signature *= BaseDimension.TIME ** time
43
- if current != 0:
44
- signature *= BaseDimension.CURRENT ** current
45
- if temp != 0:
46
- signature *= BaseDimension.TEMPERATURE ** temp
47
- if amount != 0:
48
- signature *= BaseDimension.AMOUNT ** amount
49
- if luminosity != 0:
50
- signature *= BaseDimension.LUMINOSITY ** luminosity
51
-
52
- return cls(signature)
53
-
54
- def __mul__(self, other):
55
- return DimensionSignature(self._signature * other._signature)
56
-
57
- def __truediv__(self, other):
58
- return DimensionSignature(self._signature / other._signature)
59
-
60
- def __pow__(self, power):
61
- return DimensionSignature(self._signature ** power)
62
-
63
- def is_compatible(self, other):
64
- """Ultra-fast dimensional compatibility check."""
65
- return self._signature == other._signature
66
-
67
- def __eq__(self, other):
68
- """Fast equality check for dimensions."""
69
- return isinstance(other, DimensionSignature) and self._signature == other._signature
70
-
71
- def __hash__(self):
72
- """Enable dimensions as dictionary keys."""
73
- return hash(self._signature)
74
-
75
-
76
- # Pre-defined dimension constants (alphabetically ordered)
77
- ABSORBED_DOSE = DimensionSignature.create(length=2, time=-2) # L^2 T^-2
78
- ACCELERATION = DimensionSignature.create(length=1, time=-2) # L T^-2
79
- ACTIVATION_ENERGY = DimensionSignature.create(amount=-1, length=2, time=-2) # N^-1 L^2 T^-2
80
- AMOUNT = DimensionSignature.create(amount=1) # N
81
- AMOUNT_OF_SUBSTANCE = DimensionSignature.create(amount=1) # N
82
- ANGLE_PLANE = DimensionSignature(BaseDimension.DIMENSIONLESS) # Dimensionless
83
- ANGLE_SOLID = DimensionSignature(BaseDimension.DIMENSIONLESS) # Dimensionless
84
- ANGULAR_ACCELERATION = DimensionSignature.create(time=-2) # T^-2
85
- ANGULAR_MOMENTUM = DimensionSignature.create(length=2, mass=1, time=-1) # L^2 M T^-1
86
- AREA = DimensionSignature.create(length=2) # L^2
87
- AREA_PER_UNIT_VOLUME = DimensionSignature.create(length=-1) # L^-1
88
- ATOMIC_WEIGHT = DimensionSignature.create(amount=-1, mass=1) # N^-1 M
89
- CONCENTRATION = DimensionSignature.create(length=-3, mass=1) # L^-3 M
90
- CURRENT = DimensionSignature.create(current=1) # A
91
- DIMENSIONLESS = DimensionSignature(BaseDimension.DIMENSIONLESS) # Dimensionless
92
- DYNAMIC_FLUIDITY = DimensionSignature.create(length=1, mass=-1, time=1) # L M^-1 T
93
- ELECTRICAL_CONDUCTANCE = DimensionSignature.create(current=2, length=-2, mass=-1, time=3) # A^2 L^-2 M^-1 T^3
94
- ELECTRICAL_PERMITTIVITY = DimensionSignature.create(current=2, length=-3, mass=-1, time=4) # A^2 L^-3 M^-1 T^4
95
- ELECTRICAL_RESISTIVITY = DimensionSignature.create(current=-2, length=3, mass=1, time=-3) # A^-2 L^3 M T^-3
96
- ELECTRIC_CAPACITANCE = DimensionSignature.create(current=2, length=-2, mass=-1, time=4) # A^2 L^-2 M^-1 T^4
97
- ELECTRIC_CHARGE = DimensionSignature.create(amount=-1, current=1, time=1) # N^-1 A T
98
- ELECTRIC_CURRENT_INTENSITY = DimensionSignature.create(current=1) # A
99
- ELECTRIC_DIPOLE_MOMENT = DimensionSignature.create(current=1, length=1, time=1) # A L T
100
- ELECTRIC_FIELD_STRENGTH = DimensionSignature.create(current=-1, length=1, mass=1, time=-3) # A^-1 L M T^-3
101
- ELECTRIC_INDUCTANCE = DimensionSignature.create(current=-2, length=2, mass=1, time=-2) # A^-2 L^2 M T^-2
102
- ELECTRIC_POTENTIAL = DimensionSignature.create(current=-1, length=2, mass=1, time=-3) # A^-1 L^2 M T^-3
103
- ELECTRIC_RESISTANCE = DimensionSignature.create(current=-2, length=2, mass=1, time=-3) # A^-2 L^2 M T^-3
104
- ENERGY_FLUX = DimensionSignature.create(mass=1, time=-3) # M T^-3
105
- ENERGY_HEAT_WORK = DimensionSignature.create(length=2, mass=1, time=-2) # L^2 M T^-2
106
- ENERGY_PER_UNIT_AREA = DimensionSignature.create(mass=1, time=-2) # M T^-2
107
- FORCE = DimensionSignature.create(length=1, mass=1, time=-2) # L M T^-2
108
- FORCE_BODY = DimensionSignature.create(length=-2, mass=1, time=-2) # L^-2 M T^-2
109
- FORCE_PER_UNIT_MASS = DimensionSignature.create(length=1, time=-2) # L T^-2
110
- FREQUENCY_VOLTAGE_RATIO = DimensionSignature.create(current=1, length=-2, mass=-1, time=3) # A L^-2 M^-1 T^3
111
- FUEL_CONSUMPTION = DimensionSignature.create(length=-2) # L^-2
112
- HEAT_OF_COMBUSTION = DimensionSignature.create(length=2, time=-2) # L^2 T^-2
113
- HEAT_OF_FUSION = DimensionSignature.create(length=2, time=-2) # L^2 T^-2
114
- HEAT_OF_VAPORIZATION = DimensionSignature.create(length=2, time=-2) # L^2 T^-2
115
- HEAT_TRANSFER_COEFFICIENT = DimensionSignature.create(mass=1, temp=-1, time=-3) # M Θ^-1 T^-3
116
- ILLUMINANCE = DimensionSignature.create(length=-2, luminosity=1) # L^-2 J
117
- KINETIC_ENERGY_OF_TURBULENCE = DimensionSignature.create(length=2, time=-2) # L^2 T^-2
118
- LENGTH = DimensionSignature.create(length=1) # L
119
- LINEAR_MASS_DENSITY = DimensionSignature.create(length=-1, mass=1) # L^-1 M
120
- LINEAR_MOMENTUM = DimensionSignature.create(length=1, mass=1, time=-1) # L M T^-1
121
- LUMINANCE_SELF = DimensionSignature.create(length=-2, luminosity=1) # L^-2 J
122
- LUMINOSITY = DimensionSignature.create(luminosity=1) # J
123
- LUMINOUS_FLUX = DimensionSignature.create(luminosity=1) # J
124
- LUMINOUS_INTENSITY = DimensionSignature.create(luminosity=1) # J
125
- MAGNETIC_FIELD = DimensionSignature.create(current=1, length=-1) # A L^-1
126
- MAGNETIC_FLUX = DimensionSignature.create(current=-1, length=2, mass=1, time=-2) # A^-1 L^2 M T^-2
127
- MAGNETIC_INDUCTION_FIELD_STRENGTH = DimensionSignature.create(current=-1, mass=1, time=-2) # A^-1 M T^-2
128
- MAGNETIC_MOMENT = DimensionSignature.create(current=1, length=2) # A L^2
129
- MAGNETIC_PERMEABILITY = DimensionSignature.create(current=-2, length=2, mass=1, time=-2) # A^-2 L^2 M T^-2
130
- MAGNETOMOTIVE_FORCE = DimensionSignature.create(current=1) # A
131
- MASS = DimensionSignature.create(mass=1) # M
132
- MASS_DENSITY = DimensionSignature.create(length=-3, mass=1) # L^-3 M
133
- MASS_FLOW_RATE = DimensionSignature.create(mass=1, time=-1) # M T^-1
134
- MASS_FLUX = DimensionSignature.create(length=-2, mass=1, time=-1) # L^-2 M T^-1
135
- MASS_FRACTION_OF_I = DimensionSignature(BaseDimension.DIMENSIONLESS) # Dimensionless
136
- MASS_TRANSFER_COEFFICIENT = DimensionSignature.create(length=-2, mass=1, time=-1) # L^-2 M T^-1
137
- MOLALITY_OF_SOLUTE_I = DimensionSignature.create(amount=1, mass=-1) # N M^-1
138
- MOLARITY_OF_I = DimensionSignature.create(amount=1, length=-3) # N L^-3
139
- MOLAR_CONCENTRATION_BY_MASS = DimensionSignature.create(amount=1) # N
140
- MOLAR_FLOW_RATE = DimensionSignature.create(amount=1, time=-1) # N T^-1
141
- MOLAR_FLUX = DimensionSignature.create(amount=1, length=-2, time=-1) # N L^-2 T^-1
142
- MOLAR_HEAT_CAPACITY = DimensionSignature.create(amount=-1, length=2, temp=-1, time=-2) # N^-1 L^2 Θ^-1 T^-2
143
- MOLE_FRACTION_OF_I = DimensionSignature(BaseDimension.DIMENSIONLESS) # Dimensionless
144
- MOMENTUM_FLOW_RATE = DimensionSignature.create(length=1, mass=1, time=-2) # L M T^-2
145
- MOMENTUM_FLUX = DimensionSignature.create(length=-1, mass=1, time=-2) # L^-1 M T^-2
146
- MOMENT_OF_INERTIA = DimensionSignature.create(length=2, mass=1) # L^2 M
147
- NORMALITY_OF_SOLUTION = DimensionSignature.create(amount=1, length=-3) # N L^-3
148
- PARTICLE_DENSITY = DimensionSignature.create(length=-3) # L^-3
149
- PERCENT = DimensionSignature(BaseDimension.DIMENSIONLESS) # Dimensionless
150
- PERMEABILITY = DimensionSignature.create(length=2) # L^2
151
- PHOTON_EMISSION_RATE = DimensionSignature.create(length=-2, time=-1) # L^-2 T^-1
152
- POWER_PER_UNIT_MASS = DimensionSignature.create(length=2, time=-3) # L^2 T^-3
153
- POWER_PER_UNIT_VOLUME = DimensionSignature.create(length=-1, mass=1, time=-3) # L^-1 M T^-3
154
- POWER_THERMAL_DUTY = DimensionSignature.create(length=2, mass=1, time=-3) # L^2 M T^-3
155
- PRESSURE = DimensionSignature.create(length=-1, mass=1, time=-2) # L^-1 M T^-2
156
- RADIATION_DOSE_EQUIVALENT = DimensionSignature.create(length=2, time=-2) # L^2 T^-2
157
- RADIATION_EXPOSURE = DimensionSignature.create(current=1, mass=-1, time=1) # A M^-1 T
158
- RADIOACTIVITY = DimensionSignature.create(time=-1) # T^-1
159
- SECOND_MOMENT_OF_AREA = DimensionSignature.create(length=4) # L^4
160
- SECOND_RADIATION_CONSTANT_PLANCK = DimensionSignature.create(length=1, temp=1) # L Θ
161
- SPECIFIC_ENTHALPY = DimensionSignature.create(length=2, time=-2) # L^2 T^-2
162
- SPECIFIC_GRAVITY = DimensionSignature(BaseDimension.DIMENSIONLESS) # Dimensionless
163
- SPECIFIC_HEAT_CAPACITY_CONSTANT_PRESSURE = DimensionSignature.create(length=2, mass=1, temp=-1, time=-2) # L^2 M Θ^-1 T^-2
164
- SPECIFIC_LENGTH = DimensionSignature.create(length=1, mass=-1) # L M^-1
165
- SPECIFIC_SURFACE = DimensionSignature.create(length=2, mass=-1) # L^2 M^-1
166
- SPECIFIC_VOLUME = DimensionSignature.create(length=3, mass=-1) # L^3 M^-1
167
- STRESS = DimensionSignature.create(length=-1, mass=1, time=-2) # L^-1 M T^-2
168
- SURFACE_MASS_DENSITY = DimensionSignature.create(length=-2, mass=1) # L^-2 M
169
- SURFACE_TENSION = DimensionSignature.create(mass=1, time=-2) # M T^-2
170
- TEMPERATURE = DimensionSignature.create(temp=1) # Θ
171
- THERMAL_CONDUCTIVITY = DimensionSignature.create(length=1, mass=1, temp=1, time=-3) # L M Θ T^-3
172
- TIME = DimensionSignature.create(time=1) # T
173
- TORQUE = DimensionSignature.create(length=2, mass=1, time=-2) # L^2 M T^-2
174
- TURBULENCE_ENERGY_DISSIPATION_RATE = DimensionSignature.create(length=2, time=-3) # L^2 T^-3
175
- VELOCITY_ANGULAR = DimensionSignature.create(time=-1) # T^-1
176
- VELOCITY_LINEAR = DimensionSignature.create(length=1, time=-1) # L T^-1
177
- VISCOSITY_DYNAMIC = DimensionSignature.create(length=-1, mass=1, time=-1) # L^-1 M T^-1
178
- VISCOSITY_KINEMATIC = DimensionSignature.create(length=2, time=-1) # L^2 T^-1
179
- VOLUME = DimensionSignature.create(length=3) # L^3
180
- VOLUMETRIC_CALORIFIC_HEATING_VALUE = DimensionSignature.create(length=-1, mass=1, time=-2) # L^-1 M T^-2
181
- VOLUMETRIC_COEFFICIENT_OF_EXPANSION = DimensionSignature.create(length=-3, mass=1, temp=-1) # L^-3 M Θ^-1
182
- VOLUMETRIC_FLOW_RATE = DimensionSignature.create(length=3, time=-1) # L^3 T^-1
183
- VOLUMETRIC_FLUX = DimensionSignature.create(length=1, time=-1) # L T^-1
184
- VOLUMETRIC_MASS_FLOW_RATE = DimensionSignature.create(length=-3, mass=1, time=-1) # L^-3 M T^-1
185
- VOLUME_FRACTION_OF_I = DimensionSignature(BaseDimension.DIMENSIONLESS) # Dimensionless
186
- WAVENUMBER = DimensionSignature.create(length=-1) # L^-1
qnty/unit_types/base.py DELETED
@@ -1,47 +0,0 @@
1
- """
2
- Base Unit Module Definition
3
- ===========================
4
-
5
- Provides abstract base class for unit modules and registration functionality.
6
- """
7
-
8
- from abc import ABC, abstractmethod
9
- from typing import Any
10
-
11
- from ..unit import UnitDefinition
12
-
13
-
14
- class UnitModule(ABC):
15
- """Abstract base class for unit modules."""
16
-
17
- @abstractmethod
18
- def get_unit_definitions(self) -> list[UnitDefinition]:
19
- """Return list of unit definitions for this module."""
20
- pass
21
-
22
- @abstractmethod
23
- def get_units_class(self) -> type[Any]:
24
- """Return the units class for this module."""
25
- pass
26
-
27
- def register_to_registry(self, unit_registry):
28
- """Register all unit definitions to the given registry."""
29
- from ..unit import UnitConstant
30
-
31
- for unit_def in self.get_unit_definitions():
32
- if unit_def.name not in unit_registry.units:
33
- unit_registry.register_unit(unit_def)
34
-
35
- # Populate the units class with constants from registry
36
- units_class = self.get_units_class()
37
- for unit_def in self.get_unit_definitions():
38
- unit_constant = UnitConstant(unit_registry.units[unit_def.name])
39
- setattr(units_class, unit_def.name, unit_constant)
40
-
41
- # Add any aliases
42
- if unit_def.symbol and unit_def.symbol != unit_def.name:
43
- setattr(units_class, unit_def.symbol, unit_constant)
44
-
45
- # Special case for inch - add in_ alias since 'in' is a Python keyword
46
- if unit_def.name == "inch":
47
- units_class.in_ = unit_constant