Repository navigation
Releases: sinagilassi/PyCUC
Release list
PyCUC v3.0.0
New: dimensional unit conversion
PyCUC 3.0.0 adds pycuc.from_to(), a general-purpose converter for
dimensionally compatible unit expressions. It is intended for equation
outputs and engineering expressions which were not practical to enumerate in
the legacy fixed-reference tables.
import pycuc
pycuc.from_to(1, "kg.m/s^2", "N") # 1.0
pycuc.from_to(1, "kg/(m.s^2)", "Pa") # 1.0
pycuc.from_to(1, "kJ/(mol.K)", "J/(mol.K)") # 1000.0
pycuc.from_to(1, "kg.m^2/s^3", "W") # 1.0The engine parses every atom, recursively reduces it to the seven SI base
dimensions, checks dimensional compatibility, then applies the factor ratio.
It does not treat a complete engineering expression as an opaque lookup key.
Independent RefsX catalog
The new engine uses pycuc.docs.refsx.RefsX, an independent catalog of SI,
derived, process-engineering, and legacy-compatible unit definitions. It does
not depend on the legacy Refs category tables, so from_to() is suitable for
blind dimensional conversion of supported units.
Examples of supported engineering conversions:
# Heat-transfer coefficient; both denominator styles are accepted.
pycuc.from_to(1, "W/(m^2.K)", "BTU/(hr.ft^2.F)")
# 0.176110183682...
pycuc.from_to(1, "BTU/hr/ft^2/F", "W/m^2/K")
# 5.67826334111...
# Pressure, energy, viscosity, flow, and power.
pycuc.from_to(1, "torr", "Pa") # 133.322368421...
pycuc.from_to(1, "kg/cm2", "bar") # 0.980665
pycuc.from_to(1, "erg", "J") # 1e-7
pycuc.from_to(1, "cP", "Pa.s") # 0.001
pycuc.from_to(10, "gal(US)/min", "L/min") # 37.85411784
pycuc.from_to(1, "hp", "W") # 745.699871582...Expression syntax
# Multiplication: `.` and `*` are equivalent.
pycuc.from_to(1, "kg.m/s^2", "N")
pycuc.from_to(1, "kg*m/s^2", "N")
# Integer powers: caret and legacy compact forms.
pycuc.from_to(1, "m^2", "cm2")
pycuc.from_to(1, "kg.m2/s2", "J")
# Parentheses and repeated division.
pycuc.from_to(1, "(m/s)^2", "m^2/s^2")
pycuc.from_to(1, "kg/m/s^2", "Pa")At one expression level, factors following the first / remain in the
denominator. Thus kg/m/s^2 means kg/(m.s^2). Parentheses may be used to
make grouping explicit.
Unicode superscripts are deliberately rejected. Write m^2, not a Unicode
superscript form such as square-metre notation.
Concentration names
The catalog uses clear, case-sensitive concentration symbols:
pycuc.from_to(1, "M", "mol/L") # molar concentration
pycuc.from_to(1, "ML", "mol/kg") # molal concentration
pycuc.from_to(1, "molality", "mol/kg")m remains metre and is never overloaded as molality.
Rules for blind conversion
from_to() is a blind dimensional converter. It can convert without a
quantity category only when every rule below is satisfied:
- Both expressions use units defined by
RefsX(including documented SI
prefixes and expression aliases). - Both expressions parse under the strict grammar: units,
.or*,/,
balanced parentheses, and integer exponents. - Both expressions reduce to exactly the same seven-element SI dimension
vector. - The conversion is multiplicative; no unprovided material property,
reference condition, density, gravity convention, or semantic assumption is
required. - The caller supplies the intended target unit. Matching dimensions do not
prove physical meaning--for example,JandN.mshare dimensions but can
represent energy and torque respectively.
When a rule is not met, the converter raises a precise error such as
UnknownUnitError, UnitSyntaxError, or DimensionMismatchError rather than
guessing.
Explicit non-blind cases
Absolute temperature is affine and must continue to use the existing API:
pycuc.convert_from_to(25, "C", "K") # 298.15For temperature intervals, use explicit delta-style symbols:
pycuc.from_to(1, "dC", "dK") # 1.0
pycuc.from_to(1, "dF", "dC") # 0.555555...Likewise, ppm is a dimensionless ratio. Converting ppm directly to
mg/L is not blind because it requires a density assumption; provide that
assumption in the calling calculation instead.
🚀 Mapper Input Data
🚀 Mapper: mapper.py
We’ve added a new example script, mapper.py, to help users understand and utilize the mapping and reference-checking features of PyCUC! Here’s what’s included:
🧩 Reference Checking
Easily check for reference types, available units, and unit availability using PyCUC’s built-in functions:
# Check if a reference exists
print(pycuc.check_reference('PRESSURE'))
# List all units for a reference
print(pycuc.all_units('PRESSURE'))
# List all available reference units
print(pycuc.all_units())
# Check if a unit is available for a reference
print(pycuc.is_unit_available('bar', 'PRESSURE'))
print(pycuc.is_unit_available('C', 'TEMPERATURE'))
print(pycuc.is_unit_available('kg/m3'))These functions help you validate and explore the supported references and units in your application.
🔄 Mapping Inputs to References
Map your input data to a reference schema, handling unit conversions and symbol mapping automatically:
from pycuc.utils.tools import map_to_reference
inputs = {
'Tc': {'value': 0, 'unit': 'K', 'symbol': 'Tc'},
'T': {'value': None, 'unit': 'K', 'symbol': 'T'}
}
reference = {
'Tc': {'name': 'critical temperature', 'symbol': 'Tc', 'unit': 'C'},
'T': {'name': 'temperature', 'symbol': 'T', 'unit': 'F'}
}
print(map_to_reference(inputs=inputs, reference=reference, verbose=True))
# Output:
{'Tc': {'value': -273.15, 'symbol': 'Tc', 'unit': 'C'}, 'T': {'value': None, 'symbol': 'T', 'unit': 'F'}}This example shows how to align your input data with a reference definition, including unit conversion and symbol matching, with detailed output when verbose=True.
📚 Usage Guide
- The script is well-commented and structured for easy understanding.
- Use it as a template to integrate PyCUC’s mapping and reference utilities into your own projects.
New References
New Features:
We updated the reference with the following sections: density, energy, heat capacity, volume, mass, power, length, and force.
Example Usage:
- Check references:
print(pycuc.check_reference('PRESSURE'))
print(pycuc.check_reference('TEMPERATURE'))
print(pycuc.check_reference('DENSITY'))
print(pycuc.check_reference('ENERGY'))
print(pycuc.check_reference('HEAT_CAPACITY'))
print(pycuc.check_reference('VOLUME'))
print(pycuc.check_reference('MASS'))
print(pycuc.check_reference('POWER'))
print(pycuc.check_reference('LENGTH'))
print(pycuc.check_reference('FORCE'))- Convert from to (short format)
# ! pressure
print(pycuc.to(125, 'MPa => Pa'))
# ! temperature
print(pycuc.to(360, 'K => C'))
print(pycuc.to(250, 'C => K'))
# same unit test
print(pycuc.to(275, 'K => K'))
# ! density
print(pycuc.to(1, 'g/cm3 => kg/m3'))
# ! energy
print(pycuc.to(1, 'kcal => J'))
# ! heat capacity
print(pycuc.to(1, 'J/kg.K => kJ/kg.K'))
# ! volume
print(pycuc.to(1, 'L => m3'))
# ! mass
print(pycuc.to(1, 'kg => g'))
# ! power
print(pycuc.to(1, 'kW => W'))
# ! length
print(pycuc.to(1, 'cm => m'))
# ! force
print(pycuc.to(1, 'N => kN'))