Bladeren bron

11.10 added Station classes

Olesya Ivanova 3 jaren geleden
bovenliggende
commit
d817f6345c
5 gewijzigde bestanden met toevoegingen van 170 en 26 verwijderingen
  1. 1 0
      plib/__init__.py
  2. 6 3
      plib/base.py
  3. 41 0
      plib/station.py
  4. 5 10
      tests/test_point.py
  5. 117 13
      tests/test_station.py

+ 1 - 0
plib/__init__.py

@@ -1 +1,2 @@
 from .base import Point, PointError
+from .station import Station, StationError, StationMap

+ 6 - 3
plib/base.py

@@ -1,10 +1,14 @@
+# указываем, что можно либо int, либо float
+from typing import Union
+
+
 class PointError(Exception):
     pass
 
 
 class Point:
-    def __init__(self, x: int, y: int) -> None:
-        if not isinstance(x, int) or not isinstance(y, int):
+    def __init__(self, x: Union[int, float], y: Union[int, float]) -> None:
+        if not isinstance(x, (int, float)) or not isinstance(y, (int, float)):
             raise PointError("x,y should be an integer type")
         self.x = x
         self.y = y
@@ -23,4 +27,3 @@ class Point:
     def distance_to(self, other: "Point") -> float:
         p = self - other
         return (p.x ** 2 + p.y ** 2) ** 0.5
-

+ 41 - 0
plib/station.py

@@ -0,0 +1,41 @@
+from typing import List, Union
+from plib import Point
+
+
+class StationError(Exception):
+    pass
+
+
+class Station:
+    def __init__(self, code: Union[str, None] = None,
+                 height: Union[float, None] = None,
+                 location: Union[List[float], None] = None,
+                 status: Union[str, None] = None,
+                 xyz: Union[List[float], None] = None):
+        if code is None or height is None or location is None or status is None or xyz is None:
+            raise StationError
+        self.code = code
+        self.height = height
+        self.location = Point(location['lat'], location['lon'])
+        self.status = status
+        self.xyz = xyz
+
+    def distance_to(self, other: "Station") -> float:
+        return self.location.distance_to(other.location)
+
+
+class StationMap:
+    def __init__(self, stations: Union[List[Station], None] = None):
+        if stations is None:
+            raise StationError
+        self.stations = stations
+
+    @classmethod
+    def from_json(cls, text):
+        stations = []
+        for st in text:
+            stations.append(dict(st))
+        return cls(stations)
+
+    def to_json(self, stations):
+        return stations

+ 5 - 10
tests/test_point.py

@@ -12,9 +12,8 @@ class TestPoint:
     def test_creation(self):
         p = Point(1, 2)
         assert p.x == 1 and p.y == 2
-
-        with pytest.raises(PointError):
-            Point(1, 1.5)
+        p = Point(1.5, 1.5)
+        assert p.x == 1.5 and p.y == 1.5
         with pytest.raises(PointError):
             Point("a", 10)
 
@@ -36,13 +35,9 @@ class TestPoint:
         assert p1.distance_to(p2) == pytest.approx(distance, 1)
 
     def test_eq_with_other_type(self):
-        p = Point(0,0)
-        try:
-            p == {0,0}
-
-        except NotImplementedError:
-            assert False
-        assert True
+        p = Point(0, 0)
+        with pytest.raises(NotImplementedError):
+            p == {0, 0}
 
 
 

+ 117 - 13
tests/test_station.py

@@ -1,35 +1,139 @@
 import pytest
 from copy import deepcopy
+from plib import Station, StationError, StationMap
 
 
 @pytest.fixture
-def station_data():
+def js1():
     js = {
-        "code": "abdl",
-        "height": 162.27803882118315,
+        "code": "abkn",
+        "height": 219.23325751908123,
         "status": "new",
         "location": {
-            "lat": 53.68908284179442,
-            "lon": 53.64383132493483
+            "lat": 0.0,
+            "lon": 15.5
         },
         "xyz": [
-            2243908.9008,
-            3048443.7188,
-            5116457.9962
+            -90768.799,
+            3777267.336,
+            5121588.168
         ]
     }
+
     return js
 
 
+@pytest.fixture
+def js2():
+    js = {
+        "code": "abkn",
+        "height": 219.23325751908123,
+        "status": "new",
+        "location": {
+            "lat": 0.0,
+            "lon": 0.0
+        },
+        "xyz": [
+            -90768.799,
+            3777267.336,
+            5121588.168
+        ]
+    }
+    return js
+
+
+@pytest.fixture
+def json_data():
+    text = [
+        {
+            "code": "akya",
+            "height": 330.27589765004814,
+            "status": "new",
+            "location": {
+                "lat": 0.0,
+                "lon": 0.0
+            },
+            "xyz": [
+                2078592.977,
+                3354438.194,
+                4994390.812
+            ]
+        },
+        {
+            "code": "alek",
+            "height": 174.47401913441718,
+            "location": {
+                "lat": 10.0,
+                "lon": 0.0
+            },
+            "status": "new",
+            "xyz": [
+                2959560.1322,
+                2236904.702,
+                5171064.6737
+            ]
+        },
+        {
+            "code": "abdl",
+            "height": 86.10842919163406,
+            "status": "new",
+            "location": {
+                "lat": 15.5,
+                "lon": 15.5
+            },
+            "xyz": [
+                3025653.429,
+                2742460.808,
+                4883170.747
+            ]
+        }
+    ]
+    return text
+
+
 class TestStation:
-    def test_creation(self):
+    def test_creation(self, js1):
         try:
-            Station(**js)
+            Station(**js1)
         except Exception as e:
             pytest.fail(f"Failed with exception  '{type(e)} - {e}'")
 
         for field in ["code", "height", "status", "location"]:
-            js_copy = deepcopy(js)
-            del js["location"]
+            js_copy = deepcopy(js1)
+            del js1["location"]
             with pytest.raises(StationError):
-                Station(**js)
+                Station(**js1)
+
+    def test_manual_creator(self):
+        st = Station()
+
+    def test_distance_to(self, js1, js2):
+        s1 = Station(**js1)
+        s2 = Station(**js2)
+        assert s1.distance_to(s2) == 15.5
+
+
+class TestStationMap:
+    def test_creation(self, js1, js2):
+        st1 = Station(**js1)
+        st2 = Station(**js2)
+        stations = StationMap([st1, st2])
+        assert stations["abdl"] == st1
+
+    def test_load_from_json(self, json_data):
+        stations = StationMap.from_json(json_data)
+        assert len(stations) == 3
+        names = list(stations)
+
+        import json
+        js = json.loads(json_data)
+        names_js = [item["code"] for item in js]
+        assert names == names_js
+
+    def test_save_to_json(self, json_data):
+        text = StationMap.from_json(json_data).to_json()
+        assert text == json_data
+
+    def test_nearest_station(self, json_data):
+        stations = StationMap.from_json(json_data)
+        assert stations.nearest("abdl").code == "alek"