From 26a373e802607a7376db42a75d293bc4dc346f48 Mon Sep 17 00:00:00 2001 From: Allan Point Date: Sat, 5 Feb 2022 18:21:22 +0100 Subject: [PATCH 1/2] =?UTF-8?q?Correction=20bug:=20Tout=20les=200=20=C3=A9?= =?UTF-8?q?tait=20retir=C3=A9s?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/boat.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/boat.py b/src/boat.py index 7a480ed..730f51b 100644 --- a/src/boat.py +++ b/src/boat.py @@ -21,7 +21,7 @@ class Boat: return self.boat_id == other.boat_id def get_temp_mean(self): - return statistics.mean(list(filter(None, self.temperatures))) + return statistics.mean(list(filter(lambda v: v is not None, self.temperatures))) def get_northiest_coords(self): if len(self.positions) == 0: raise NothingToCompareError(f"{self.name} must have coords to compare") From 102ab2d34e943c553a0e183232f8486cb58d0f1f Mon Sep 17 00:00:00 2001 From: Allan Point Date: Sat, 5 Feb 2022 20:06:47 +0100 Subject: [PATCH 2/2] Ajout de documentation --- src/boat.py | 33 ++++++++++++++++++++++++++------- src/boats_loader.py | 3 +++ src/fleet.py | 25 ++++++++++++++++++------- src/main.py | 21 ++++++++++++++++++--- src/position.py | 6 ++++++ src/rest_api_boats_loader.py | 18 ++++++++++++++++-- 6 files changed, 87 insertions(+), 19 deletions(-) diff --git a/src/boat.py b/src/boat.py index 730f51b..c7e8c81 100644 --- a/src/boat.py +++ b/src/boat.py @@ -2,7 +2,13 @@ import statistics from custom_exception.nothing_to_compare_error import * + + class Boat: + """ + Representation of a boat. + A boat is defined by its name, ids, url, avatar, temperatures ans positions in the sea. + """ def __init__(self, boat_id: str, name: str, sismer_id: str, url: str, avatar:str , temperatures: list, positions: list): self.boat_id = boat_id self.name = name @@ -12,17 +18,27 @@ class Boat: self.temperatures = temperatures self.positions = positions def __str__(self): - return f"{self.name}" - def __eq__(self, other): - if other is None: - return False - if not isinstance(other, self.__class__): - return False - return self.boat_id == other.boat_id + """ + When a Boat goes to string, the returned value is simply the name of this Boat. + """ + return self.name + def __eq__(self, other): + if other is None: + return False + if not isinstance(other, self.__class__): + return False + return self.boat_id == other.boat_id def get_temp_mean(self): + """ + Process the average of temperatures with None values removed. + """ return statistics.mean(list(filter(lambda v: v is not None, self.temperatures))) def get_northiest_coords(self): + """ + From all positions send by the boat, return the one on the northiest. + Will raise a NothingToCompareError if the boat has no position saved + """ if len(self.positions) == 0: raise NothingToCompareError(f"{self.name} must have coords to compare") best = self.positions[0] @@ -32,4 +48,7 @@ class Boat: return best def print_details(self): + """ + Print the Boat with more details than __str__ + """ print(f"[{self.name}({self.boat_id})]\nSISMER ID: {self.sismer_id}\nURL: {self.url}\nAvatar: {self.avatar}") diff --git a/src/boats_loader.py b/src/boats_loader.py index bbf64e3..5e2d168 100644 --- a/src/boats_loader.py +++ b/src/boats_loader.py @@ -1,5 +1,8 @@ #coding:utf-8 class BoatsLoader: + """ + Interface for all classes which wants to load boat + """ def load_boats(year: int): pass diff --git a/src/fleet.py b/src/fleet.py index c288e8f..43ed425 100644 --- a/src/fleet.py +++ b/src/fleet.py @@ -7,20 +7,29 @@ from position import Position from custom_exception.nothing_to_compare_error import NothingToCompareError class Fleet: + """ + Contains all boats and can compare eache one + """ def __init__(self, year: int, loader :BoatsLoader): self.boats = loader.load_boats(year) def compare_boats(self, getter: callable, comparator: callable): + """ + Compare each boat with dynamic parameter + getter: This callable must be a methode from Boat and must have no parameters. It will allow to select data to compare. + comparator: This callable must have its twp parameters's type the same that the one return by getter. It will allow to compare data each other + """ if len(self.boats) == 0: raise NothingToCompareError("No boats to compare") best_boat = None best_element_to_compare = None for boat in self.boats: try: - if comparator(getter(boat), best_element_to_compare): + data = getter(boat) + if comparator(data, best_element_to_compare): best_boat = boat - best_element_to_compare = getter(boat) + best_element_to_compare = data except StatisticsError as e: continue except NothingToCompareError as e: @@ -28,12 +37,14 @@ class Fleet: return best_boat, best_element_to_compare def get_northiest(self): - try: - return self.compare_boats(Boat.get_northiest_coords, Position.is_norther_than) - except TypeError as e: - print(e) - return None, None; + """ + Returns the boat which went the northiest and its coords. + """ + return self.compare_boats(Boat.get_northiest_coords, Position.is_norther_than) def get_highiest_heat_mean(self): + """ + Returns the boat which saved the highiest heat average and this average. + """ return self.compare_boats(Boat.get_temp_mean, float.__ge__) diff --git a/src/main.py b/src/main.py index ccf6bc4..df11bb7 100644 --- a/src/main.py +++ b/src/main.py @@ -3,19 +3,34 @@ from sys import argv import fleet from rest_api_boats_loader import RestApiBoatsLoader -import custom_exception +# If the year give by user. if not print a message and exit if len(argv) <= 1: - raise custom_exception.MissingEntryArgumentError("You must give the year you want to get") -year = int(argv[1]) + print("You must give the year you want to get (eg. python3 main.py 2021)") + exit(1) +# Is the argument given a number. If not print a message and exit +try: + year = int(argv[1]) +except ValueError: + print("The year must be a number") + exit(1) + +# fleet loading with data from the year my_fleet = fleet.Fleet(year, RestApiBoatsLoader()) + +# Print detail for each boat from the fleet for boat in my_fleet.boats: boat.print_details() print() + +# get the boat which went the northiest northiest_boat, northiest_coords = my_fleet.get_northiest() + +# get the boat which have the highiest heat average saved hottiest_boat, heat_mean = my_fleet.get_highiest_heat_mean() +# Prints results if northiest_boat is None: print(f"No data to find the northiest boat for {year}") else: diff --git a/src/position.py b/src/position.py index 50abbb6..4a1f6ee 100644 --- a/src/position.py +++ b/src/position.py @@ -1,6 +1,9 @@ #coding:utf-8 class Position: + """ + Position's representation: [; ] + """ def __init__(self, latitude: float, longitude: float): self.latitude = latitude self.longitude = longitude @@ -8,6 +11,9 @@ class Position: def __str__(self): return f"[{self.latitude}; {self.longitude}]" def is_norther_than(self, position): + """ + Is the current instance of postition norther than + """ if position == None: return True return self.latitude >= position.latitude diff --git a/src/rest_api_boats_loader.py b/src/rest_api_boats_loader.py index 5320c04..e984426 100644 --- a/src/rest_api_boats_loader.py +++ b/src/rest_api_boats_loader.py @@ -5,14 +5,20 @@ from position import Position from boats_loader import BoatsLoader import requests -class RestApiBoatsLoader(BoatsLoader): +class RestApiBoatsLoader(BoatsLoader): + """ + Allows to load Boats from https://localisation.flotteoceanographique.fr/api/v2/vessels + """ def __init__(self): self.url = 'https://localisation.flotteoceanographique.fr/api/v2/vessels' self.search_begin = '-01-01T00:00:00.000Z' self.search_end = '-12-31T23:59:59.000Z' - + def load_boats(self, year: int): + """ + Create and return Boats with Loaded data fom flotteoceanographique.fr + """ raw_data = self.load_from_url(self.url) boats = [] for boat in raw_data.json(): @@ -20,7 +26,12 @@ class RestApiBoatsLoader(BoatsLoader): tmp_boat = Boat(boat['id'], boat['name'], boat['sismerId'], boat['url'], boat['avatar'], boat_data['temp'], boat_data['pos']) boats.append(tmp_boat) return boats + def _load_boat_data(self, boat_id: str, year: int): + """ + Collects all positions and sea temperatues send by in . + Return a Dictionary with 2 keys: 'pos' and 'temp' + """ json_data = self.load_from_url(self.url + f"/{boat_id}/positions?startDate={year}{self.search_begin}&endDate={year}{self.search_end}").json() data = {} data['pos'] = [] @@ -35,6 +46,9 @@ class RestApiBoatsLoader(BoatsLoader): return data def load_from_url(self, url: str): + """ + Send a GET request to and convert result in Response (see requests module) + """ data = requests.get(url) if(data.status_code != 200): raise custom_exception.HttpException(f"Error {data.status_code}")