forked from hacktoolkit/django-htk
-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
4 changed files
with
212 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
from .distance import DistanceType | ||
from .weight import WeightType | ||
|
||
|
||
__all__ = [ | ||
'DistanceType', | ||
'WeightType', | ||
] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,73 @@ | ||
# Python Standard Library Imports | ||
from decimal import Decimal | ||
|
||
# Local Imports | ||
from .units import ( | ||
ConversionConstants, | ||
convert_unit, | ||
) | ||
|
||
|
||
C = ConversionConstants.Distance | ||
|
||
|
||
class DistanceType(Decimal): | ||
"""Class that represents a distance (e.g. length, width, height). | ||
Canonical unit is in meters. | ||
""" | ||
|
||
@classmethod | ||
def from_meters(cls, value: Decimal) -> 'DistanceType': | ||
return cls(value) | ||
|
||
@classmethod | ||
def from_kilometers(cls, value: Decimal) -> 'DistanceType': | ||
return cls(convert_unit(value, C.KM_TO_M)) | ||
|
||
@classmethod | ||
def from_feet(cls, value: Decimal) -> 'DistanceType': | ||
return cls(convert_unit(value, C.FT_TO_M)) | ||
|
||
@classmethod | ||
def from_yards(cls, value: Decimal) -> 'DistanceType': | ||
return cls(convert_unit(value, C.YD_TO_M)) | ||
|
||
@classmethod | ||
def from_miles(cls, value: Decimal) -> 'DistanceType': | ||
return cls(convert_unit(value, C.MI_TO_M)) | ||
|
||
## | ||
# NOTE: Lots of helper function follow, sorting rules: | ||
# | ||
# 1. Metric (SI), then Imperial | ||
# 2. Increasing unit sizes | ||
# | ||
|
||
@property | ||
def m(self) -> Decimal: | ||
return self | ||
|
||
@property | ||
def km(self) -> Decimal: | ||
return convert_unit(self, C.M_TO_KM) | ||
|
||
@property | ||
def in_(self) -> Decimal: | ||
return self.inch | ||
|
||
@property | ||
def inch(self) -> Decimal: | ||
return convert_unit(self, C.M_TO_IN) | ||
|
||
@property | ||
def ft(self) -> Decimal: | ||
return convert_unit(self, C.M_TO_FT) | ||
|
||
@property | ||
def yd(self) -> Decimal: | ||
return convert_unit(self, C.M_TO_YD) | ||
|
||
@property | ||
def mi(self) -> Decimal: | ||
return convert_unit(self, C.M_TO_MI) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,78 @@ | ||
# Python Standard Library Imports | ||
import typing as T | ||
from decimal import Decimal | ||
|
||
|
||
DecimalTypes = T.Union[str, int, float, Decimal] | ||
|
||
|
||
class ConversionConstants: | ||
"""Constants for converting between different units of measurement. | ||
Reference: https://www.nist.gov/system/files/documents/2019/12/03/00-20-h133-apdxE_final-17.pdf # noqa: E501 | ||
""" | ||
|
||
class Distance: | ||
"""Constants for converting between different units of distance. | ||
The canonical unit is meters. | ||
""" | ||
|
||
# Imperial to Imperial | ||
MI_TO_FT = Decimal('5280') | ||
YD_TO_FT = Decimal('3') | ||
FT_TO_IN = Decimal('12') | ||
IN_TO_FT = Decimal('1') / FT_TO_IN | ||
YD_TO_MI = YD_TO_FT / MI_TO_FT | ||
|
||
# Imperial to Metric | ||
IN_TO_M = Decimal('0.0254') | ||
FT_TO_M = Decimal('0.3048') | ||
YD_TO_M = Decimal('0.9144') | ||
MI_TO_M = Decimal('1609.347') | ||
|
||
# Metric to Metric | ||
M_TO_MM = Decimal('1000') | ||
M_TO_CM = Decimal('100') | ||
M_TO_M = Decimal('1') | ||
M_TO_KM = Decimal('0.001') | ||
|
||
MM_TO_M = Decimal('0.001') | ||
CM_TO_M = Decimal('0.01') | ||
KM_TO_M = Decimal('1000') | ||
|
||
# Metric to Imperial | ||
M_TO_FT = Decimal('1.0') / FT_TO_M | ||
M_TO_IN = Decimal('1.0') / IN_TO_M | ||
M_TO_YD = Decimal('1.0') / YD_TO_M | ||
# M_TO_MI = Decimal('1.0') / MI_TO_M | ||
M_TO_MI = Decimal('0.0006213712') # NIST value | ||
|
||
class Weight: | ||
"""Constants for converting between different units of weight. | ||
The canonical unit is grams. | ||
""" | ||
|
||
# Imperial to Imperial | ||
LB_TO_OZ = Decimal('16') | ||
OZ_TO_LB = Decimal('0.0625') | ||
|
||
# Metric to Imperial | ||
G_TO_OZ = Decimal('0.03527396') | ||
G_TO_LB = G_TO_OZ * OZ_TO_LB | ||
KG_TO_OZ = Decimal('35.27396') | ||
KG_TO_LB = Decimal('2.204623') | ||
|
||
# Imperial to Metric | ||
OZ_TO_G = Decimal('1.0') / G_TO_OZ | ||
LB_TO_G = LB_TO_OZ * OZ_TO_G | ||
OZ_TO_KG = Decimal('1.0') / KG_TO_OZ | ||
|
||
# Metric to Metric | ||
G_TO_KG = Decimal('0.001') | ||
KG_TO_G = Decimal('1000') | ||
|
||
|
||
def convert_unit(value: DecimalTypes, conversion_constant: DecimalTypes) -> Decimal: | ||
return Decimal(value) * Decimal(conversion_constant) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,53 @@ | ||
# Python Standard Library Imports | ||
from decimal import Decimal | ||
|
||
# Local Imports | ||
from .units import ( | ||
ConversionConstants, | ||
convert_unit, | ||
) | ||
|
||
|
||
C = ConversionConstants.Weight | ||
|
||
|
||
class WeightType(Decimal): | ||
"""Class that represents weight. | ||
Canonical unit is in grams. | ||
""" | ||
|
||
@classmethod | ||
def from_grams(cls, value: Decimal) -> 'WeightType': | ||
return cls(value) | ||
|
||
@classmethod | ||
def from_kilograms(cls, value: Decimal) -> 'WeightType': | ||
return cls(convert_unit(value, C.KG_TO_G)) | ||
|
||
@classmethod | ||
def from_pounds(cls, value: Decimal) -> 'WeightType': | ||
return cls(convert_unit(value, C.LB_TO_G)) | ||
|
||
## | ||
# NOTE: Lots of helper function follow, sorting rules: | ||
# | ||
# 1. Metric (SI), then Imperial | ||
# 2. Increasing unit sizes | ||
# | ||
|
||
@property | ||
def g(self) -> Decimal: | ||
return self | ||
|
||
@property | ||
def kg(self) -> Decimal: | ||
return convert_unit(self, C.G_TO_KG) | ||
|
||
@property | ||
def oz(self) -> Decimal: | ||
return convert_unit(self, C.G_TO_OZ) | ||
|
||
@property | ||
def lb(self) -> Decimal: | ||
return convert_unit(self, C.G_TO_LB) |