Skip to content
This repository has been archived by the owner on Mar 23, 2024. It is now read-only.

Implement UnitConverter class #35

Merged
merged 15 commits into from
Oct 7, 2023
Merged
Show file tree
Hide file tree
Changes from 9 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
106 changes: 97 additions & 9 deletions boat_simulator/common/unit_conversions.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
"""Unit conversion logic, mostly contained in the `UnitConverter` class."""

from __future__ import annotations
from boat_simulator.common.types import EnumAttr, Scalar

import math
from enum import Enum
from typing import Dict

from boat_simulator.common.types import EnumAttr, Scalar


class ConversionFactor:
"""Performs unit conversions from one unit to another. Both directions of unit conversion are
Expand Down Expand Up @@ -92,15 +95,90 @@ class ConversionFactors(Enum):
that will be performed.

Attributes:
<UNIT A>2<UNIT B> (EnumAttr): `ConversionFactor` classes to perform unit
<UNIT A>_to_<UNIT B> (EnumAttr): `ConversionFactor` classes to perform unit
conversions going from unit A to B.

Attributes in this class must follow the above naming convention.
"""

sec2min = ConversionFactor(factor=1 / 60)
sec2hr = sec2min * ConversionFactor(factor=1 / 60)
min2sec = sec2min.inverse()
# Length

km_to_m = ConversionFactor(factor=1000)
m_to_km = km_to_m.inverse()

m_to_cm = ConversionFactor(factor=100)
cm_to_m = m_to_cm.inverse()

km_to_cm = km_to_m * m_to_cm
cm_to_km = km_to_cm.inverse()

m_to_ft = ConversionFactor(factor=3.28084)
ft_to_m = m_to_ft.inverse()

mi_to_ft = ConversionFactor(factor=5280)
ft_to_mi = mi_to_ft.inverse()

mi_to_m = ConversionFactor(factor=1609.344)
m_to_mi = mi_to_m.inverse()

mi_to_km = mi_to_m * m_to_km
km_to_mi = mi_to_km.inverse()

nautical_mi_to_mi = ConversionFactor(factor=1.15078)
mi_to_nautical_mi = nautical_mi_to_mi.inverse()

nautical_mi_to_km = ConversionFactor(factor=1.852)
km_to_nautical_mi = nautical_mi_to_km.inverse()

# Time
min_to_sec = ConversionFactor(factor=60)
sec_to_min = min_to_sec.inverse()

h_to_min = ConversionFactor(factor=60)
min_to_h = h_to_min.inverse()

h_to_sec = h_to_min * min_to_sec
sec_to_h = h_to_sec.inverse()

# Speed
miPh_to_kmPh = ConversionFactor(factor=1.609344)
kmPh_to_miPh = miPh_to_kmPh.inverse()

mPs_to_kmPh = ConversionFactor(factor=3.6)
kmPh_to_mPs = mPs_to_kmPh.inverse()

knots_to_kmPh = ConversionFactor(factor=1.852)
kmPh_to_knots = knots_to_kmPh.inverse()

knots_to_miPh = ConversionFactor(factor=1.15077945)
miPh_to_knots = knots_to_miPh.inverse()

# Acceleration

miPs2_to_mPs2 = mi_to_m
mPs2_to_miPs2 = m_to_mi

kmPs2_to_mPs2 = km_to_m
mPs2_to_kmPs2 = m_to_km

mPs2_to_knotsPs2 = ConversionFactor(factor=1.94384466)
knotsPs2_to_mPs2 = mPs2_to_knotsPs2.inverse()

# Mass

kg_to_g = ConversionFactor(factor=1000)
g_to_kg = kg_to_g.inverse()

lb_to_g = ConversionFactor(factor=453.59237)
g_to_lb = lb_to_g.inverse()

kg_to_lb = ConversionFactor(factor=2.2046226218)
lb_to_kg = kg_to_lb.inverse()

# Rotation

degrees_to_rad = ConversionFactor(factor=math.pi / 180)
rad_to_degrees = degrees_to_rad.inverse()


class UnitConverter:
Expand All @@ -120,12 +198,15 @@ def __init__(self, **kwargs: EnumAttr):
values are class attribute values. Dictionary values are strictly class attributes
belonging to `ConversionFactors`.
"""
# TODO Implement this function to accept keys as class attributes and conversion enums
pass
for attr_name, attr_val in kwargs.items():
setattr(self, attr_name, attr_val)

def convert(self, **kwargs: Scalar) -> Dict[str, Scalar]:
"""Perform unit conversions for multiple specified values.

Pre-Condition:
Unit conversions are only done on comparable units. Ex: Length to length

Args:
kwargs (Dict[str, Scalar]): Dictionary keys are strictly names of attributes belonging
to this class. Dictionary values are the values to be converted, using the
Expand All @@ -135,5 +216,12 @@ def convert(self, **kwargs: Scalar) -> Dict[str, Scalar]:
Dict[str, Scalar]: Converted values. Dictionary keys are class attribute names
corresponding to the converted value. Dictionary values are the converted values.
"""
# TODO Implement this function
raise NotImplementedError()
converted_values = {}

for attr_name, attr_val in kwargs.items():
conversion_factor = getattr(self, attr_name, None).value
converted_values[attr_name] = (
None if conversion_factor is None else conversion_factor.forward_convert(attr_val)
)

return converted_values
Loading