Skip to content

units

TemperatureUnit

Bases: Enum

Temperature scales. The value is (size of one degree in kelvin, name).

The name keeps C and K apart (both have a degree of the same size: with the bare number Enum made one an alias of the other). The scales differ by an offset, which :meth:UnitSystem.convert_temperature applies; differences of temperature need only the scale.

Source code in eurocodepy/units.py
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
class TemperatureUnit(Enum):
    """Temperature scales. The value is ``(size of one degree in kelvin, name)``.

    The name keeps ``C`` and ``K`` apart (both have a degree of the same size: with the bare
    number ``Enum`` made one an alias of the other). The scales differ by an offset, which
    :meth:`UnitSystem.convert_temperature` applies; differences of temperature need only the scale.
    """

    K = (1.0, "kelvin")
    C = (1.0, "celsius")
    F = (5.0 / 9.0, "fahrenheit")

    @property
    def scale(self) -> float:
        """Size of one degree of this scale in kelvin."""
        return self.value[0]

scale property

Size of one degree of this scale in kelvin.

UnitSystem dataclass

Source code in eurocodepy/units.py
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
@dataclass(frozen=True)
class UnitSystem:
    # multipliers to convert "your unit" -> SI
    force_unit: ForceUnit = ForceUnit.N
    distance_unit: LengthUnit = LengthUnit.m
    time_unit: TimeUnit = TimeUnit.s
    mass_unit: MassUnit = MassUnit.kg
    temperature_unit: TemperatureUnit = TemperatureUnit.K

    def convert_temperature(self,
            temperature: float,
            temp_to: TemperatureUnit) -> float:
        """Convert a temperature (a point on the scale, not a difference) to another scale.

        ``temperature`` is in this system's ``temperature_unit``; the result is in ``temp_to``.
        For differences of temperature use ``convert_to(..., UnitType.TEMPERATURE)``.
        """
        return _from_kelvin(_to_kelvin(temperature, self.temperature_unit), temp_to)

    # derived factors (your -> SI)
    @property
    def distance(self) -> float: return self.distance_unit.value

    @property
    def time(self) -> float: return self.time_unit.value

    @property
    def force(self) -> float: return self.force_unit.value

    @property
    def mass(self) -> float: return self.mass_unit.value

    @property
    def temperature(self) -> float: return self.temperature_unit.scale

    @property
    def area(self) -> float: return self.distance_unit.value ** 2

    @property
    def volume(self) -> float: return self.distance_unit.value ** 3

    @property
    def pressure(self) -> float: return self.force_unit.value / (self.distance_unit.value ** 2)

    @property
    def moment(self) -> float: return self.force_unit.value * self.distance_unit.value

    @property
    def force_length(self) -> float: return self.force_unit.value / self.distance_unit.value

    @property
    def force_volume(self) -> float: return self.force_unit.value / (self.distance_unit.value ** 3)

    @property
    def work(self) -> float:
        """Work factor: (your force * your length) -> J (N·m)."""
        return self.force_unit.value * self.distance_unit.value

    @property
    def energy(self) -> float:
        """Alias of work (in mechanics, same unit)."""
        return self.work

    @property
    def power(self) -> float:
        """Power factor: (your force * your length / your time) -> W."""
        return self.force_unit.value * self.distance_unit.value / self.time_unit.value

    @property
    def density(self) -> float:
        """Density factor: (your mass / your length^3) -> kg/m³."""
        return self.mass_unit.value / (self.distance_unit.value ** 3)

    @property
    def velocity(self) -> float:
        """Velocity factor: (your length / your time) -> m/s."""
        return self.distance_unit.value / self.time_unit.value

    @property
    def acceleration(self) -> float:
        """Acceleration factor: (your length / your time^2) -> m/s²."""
        return self.distance_unit.value / (self.time_unit.value ** 2)

    def convert_from(self, from_system: "UnitSystem", unit_type: UnitType) -> float:
        # convert to SI
        # convert from SI
        match unit_type:
            case UnitType.FORCE:
                return  from_system.force / self.force
            case UnitType.LENGTH:
                return  from_system.distance / self.distance
            case UnitType.PRESSURE:
                return  from_system.pressure / self.pressure
            case UnitType.MOMENT:
                return  from_system.moment / self.moment
            case UnitType.VELOCITY:
                return  from_system.velocity / self.velocity
            case UnitType.ACCELERATION:
                return  from_system.acceleration / self.acceleration
            case UnitType.AREA:
                return  from_system.area / self.area
            case UnitType.VOLUME:
                return  from_system.volume / self.volume
            case UnitType.TIME:
                return  from_system.time / self.time
            case UnitType.MASS:
                return  from_system.mass / self.mass
            case UnitType.FORCE_LENGTH:
                return  from_system.force_length / self.force_length
            case UnitType.FORCE_VOLUME:
                return  from_system.force_volume / self.force_volume
            case UnitType.WORK | UnitType.ENERGY:
                return  from_system.work / self.work
            case UnitType.POWER:
                return  from_system.power / self.power
            case UnitType.DENSITY:
                return  from_system.density / self.density
            case UnitType.TEMPERATURE:                  # temperature *difference*
                return  from_system.temperature / self.temperature
            case _:
                msg = f"unit type {unit_type!r} is not supported"
                raise ValueError(msg)

    def convert_to(self, to_system: "UnitSystem", unit_type: UnitType) -> float:
        # convert to SI
        # convert from SI
        match unit_type:
            case UnitType.FORCE:
                return self.force / to_system.force
            case UnitType.LENGTH:
                return self.distance / to_system.distance
            case UnitType.PRESSURE:
                return self.pressure / to_system.pressure
            case UnitType.MOMENT:
                return self.moment / to_system.moment
            case UnitType.VELOCITY:
                return self.velocity / to_system.velocity
            case UnitType.ACCELERATION:
                return self.acceleration / to_system.acceleration
            case UnitType.AREA:
                return self.area / to_system.area
            case UnitType.VOLUME:
                return self.volume / to_system.volume
            case UnitType.TIME:
                return self.time / to_system.time
            case UnitType.MASS:
                return self.mass / to_system.mass
            case UnitType.FORCE_LENGTH:
                return self.force_length / to_system.force_length
            case UnitType.FORCE_VOLUME:
                return self.force_volume / to_system.force_volume
            case UnitType.WORK | UnitType.ENERGY:
                return self.work / to_system.work
            case UnitType.POWER:
                return self.power / to_system.power
            case UnitType.DENSITY:
                return self.density / to_system.density
            case UnitType.TEMPERATURE:                  # temperature *difference*
                return self.temperature / to_system.temperature
            case _:
                msg = f"unit type {unit_type!r} is not supported"
                raise ValueError(msg)

    def to_si(self, value: float, factor: float) -> float:
        return value * factor

    def from_si(self, value_si: float, factor: float) -> float:
        return value_si / factor

acceleration property

Acceleration factor: (your length / your time^2) -> m/s².

density property

Density factor: (your mass / your length^3) -> kg/m³.

energy property

Alias of work (in mechanics, same unit).

power property

Power factor: (your force * your length / your time) -> W.

velocity property

Velocity factor: (your length / your time) -> m/s.

work property

Work factor: (your force * your length) -> J (N·m).

convert_temperature(temperature, temp_to)

Convert a temperature (a point on the scale, not a difference) to another scale.

temperature is in this system's temperature_unit; the result is in temp_to. For differences of temperature use convert_to(..., UnitType.TEMPERATURE).

Source code in eurocodepy/units.py
106
107
108
109
110
111
112
113
114
def convert_temperature(self,
        temperature: float,
        temp_to: TemperatureUnit) -> float:
    """Convert a temperature (a point on the scale, not a difference) to another scale.

    ``temperature`` is in this system's ``temperature_unit``; the result is in ``temp_to``.
    For differences of temperature use ``convert_to(..., UnitType.TEMPERATURE)``.
    """
    return _from_kelvin(_to_kelvin(temperature, self.temperature_unit), temp_to)