Resovle conflict

tests
Allan Point 3 years ago
commit ce7b2e57ef

@ -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,7 +18,10 @@ class Boat:
self.temperatures = temperatures
self.positions = positions
def __str__(self):
return f"{self.name}"
"""
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
@ -21,8 +30,15 @@ class Boat:
return self.boat_id == other.boat_id
def get_temp_mean(self):
return statistics.mean(list(filter(None, self.temperatures)))
"""
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}")

@ -1,5 +1,8 @@
#coding:utf-8
class BoatsLoader:
"""
Interface for all classes which wants to load boat
"""
def load_boats(year: int):
pass

@ -12,15 +12,21 @@ class Fleet:
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 +34,14 @@ class Fleet:
return best_boat, best_element_to_compare
def get_northiest(self):
try:
"""
Returns the boat which went the northiest and its coords.
"""
return self.compare_boats(Boat.get_northiest_coords, Position.is_norther_than)
except TypeError as e:
print(e)
return None, None;
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__)

@ -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:

@ -1,6 +1,9 @@
#coding:utf-8
class Position:
"""
Position's representation: [<latitude>; <longitude>]
"""
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 <postition>
"""
if position == None:
return True
return self.latitude >= position.latitude

@ -6,6 +6,9 @@ from boats_loader import BoatsLoader
import requests
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'
@ -13,6 +16,9 @@ class RestApiBoatsLoader(BoatsLoader):
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 <boat_id> in <year>.
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 <url> 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}")

Loading…
Cancel
Save