Coverage for koordinaatit/koordinaatit.py: 50.00%
60 statements
« prev ^ index » next coverage.py v7.4.1, created at 2024-02-04 19:07:06 +00:00
« prev ^ index » next coverage.py v7.4.1, created at 2024-02-04 19:07:06 +00:00
1# -*- coding: utf-8 -*-
2# pylint: disable=expression-not-assigned,line-too-long
3"""Coordinates API."""
4import math
5import os
6import sys
7from enum import Enum, auto
8from typing import List, Union
10DEBUG_VAR = 'KOORDINAATIT_DEBUG'
11DEBUG = os.getenv(DEBUG_VAR)
13ENCODING = 'utf-8'
14ENCODING_ERRORS_POLICY = 'ignore'
17class Dimension(Enum):
18 LAT = auto()
19 LON = auto()
20 ALT = auto()
23class Unit(Enum):
24 DEGREE = auto()
25 RADIAN = auto()
26 METER = auto()
27 FEET = auto()
30class Length:
31 """Provide conversions between meter and feet.
33 Internal representation of unit is meter.
34 """
36 WUN_METER = 0.3048 # feet
38 def __init__(self, value: Union[int, float], unit: Unit):
39 self.base_value = value
40 self.unit = unit
41 if self.unit is not Unit.METER and self.unit is not Unit.FEET:
42 raise ValueError('length unit neither meter nor feet')
44 if self.unit is Unit.FEET:
45 self.base_value /= Length.WUN_METER
48class Koordinaatit:
49 """Coordinate representations require handling.
51 Internal representation of value is as float.
52 """
54 def __init__(self, dimension: Dimension, value: Union[int, float, str], unit: Unit):
55 self.sexagesimal = None
56 self.decimal = None
57 self.na = math.nan
58 self.dimension = dimension
59 self.value = math.nan
60 self.unit = unit
61 if not self.unit_valid_for_dimension():
62 raise ValueError('unit not valid for dimension')
64 self.unit_label = self.label_unit()
65 self.what = self.label_dimension()
67 def is_latitide(self) -> bool:
68 """Service maybe YAGNI."""
69 return self.dimension is Dimension.LAT
71 def is_longitude(self) -> bool:
72 """Service maybe YAGNI."""
73 return self.dimension is Dimension.LON
75 def is_altitude(self) -> bool:
76 """Service maybe YAGNI."""
77 return self.dimension is Dimension.ALT
79 def label_dimension(self) -> str:
80 """Delegate labeling of dimension to the enumeration type."""
81 return self.dimension.name
83 def label_unit(self) -> str:
84 """Delegate labeling of unit to the enumeration type."""
85 return self.unit.name
87 def unit_valid_for_dimension(self) -> bool:
88 """Latitudes and altitude units must be degree or radian, altitudes meter or feet."""
89 if self.dimension is Dimension.ALT:
90 return self.unit is Unit.METER or self.unit is Unit.FEET
92 return self.unit is Unit.DEGREE or self.unit is Unit.RADIAN
95def main(argv: Union[List[str], None] = None) -> int:
96 """Drive the coordination."""
97 argv = argv if argv else sys.argv[1:]
98 if not argv: 98 ↛ 99line 98 didn't jump to line 99, because the condition on line 98 was never true
99 print('ERROR arguments expected.', file=sys.stderr)
100 return 2
102 return 0