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

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 

9 

10DEBUG_VAR = 'KOORDINAATIT_DEBUG' 

11DEBUG = os.getenv(DEBUG_VAR) 

12 

13ENCODING = 'utf-8' 

14ENCODING_ERRORS_POLICY = 'ignore' 

15 

16 

17class Dimension(Enum): 

18 LAT = auto() 

19 LON = auto() 

20 ALT = auto() 

21 

22 

23class Unit(Enum): 

24 DEGREE = auto() 

25 RADIAN = auto() 

26 METER = auto() 

27 FEET = auto() 

28 

29 

30class Length: 

31 """Provide conversions between meter and feet. 

32 

33 Internal representation of unit is meter. 

34 """ 

35 

36 WUN_METER = 0.3048 # feet 

37 

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') 

43 

44 if self.unit is Unit.FEET: 

45 self.base_value /= Length.WUN_METER 

46 

47 

48class Koordinaatit: 

49 """Coordinate representations require handling. 

50 

51 Internal representation of value is as float. 

52 """ 

53 

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') 

63 

64 self.unit_label = self.label_unit() 

65 self.what = self.label_dimension() 

66 

67 def is_latitide(self) -> bool: 

68 """Service maybe YAGNI.""" 

69 return self.dimension is Dimension.LAT 

70 

71 def is_longitude(self) -> bool: 

72 """Service maybe YAGNI.""" 

73 return self.dimension is Dimension.LON 

74 

75 def is_altitude(self) -> bool: 

76 """Service maybe YAGNI.""" 

77 return self.dimension is Dimension.ALT 

78 

79 def label_dimension(self) -> str: 

80 """Delegate labeling of dimension to the enumeration type.""" 

81 return self.dimension.name 

82 

83 def label_unit(self) -> str: 

84 """Delegate labeling of unit to the enumeration type.""" 

85 return self.unit.name 

86 

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 

91 

92 return self.unit is Unit.DEGREE or self.unit is Unit.RADIAN 

93 

94 

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 

101 

102 return 0