diff --git a/app/location/__init__.py b/app/location/__init__.py index 1da5e9e5..da399738 100644 --- a/app/location/__init__.py +++ b/app/location/__init__.py @@ -1,124 +1,255 @@ -"""app.location""" -from ..coordinates import Coordinates -from ..utils import countries -from ..utils.populations import country_population - - -# pylint: disable=redefined-builtin,invalid-name -class Location: # pylint: disable=too-many-instance-attributes - """ - A location in the world affected by the coronavirus. - """ - - def __init__( - self, id, country, province, coordinates, last_updated, confirmed, deaths, recovered, - ): # pylint: disable=too-many-arguments - # General info. - self.id = id - self.country = country.strip() - self.province = province.strip() - self.coordinates = coordinates - - # Last update. - self.last_updated = last_updated - - # Statistics. - self.confirmed = confirmed - self.deaths = deaths - self.recovered = recovered - - @property - def country_code(self): - """ - Gets the alpha-2 code represention of the country. Returns 'XX' if none is found. - - :returns: The country code. - :rtype: str - """ - return (countries.country_code(self.country) or countries.DEFAULT_COUNTRY_CODE).upper() - - @property - def country_population(self): - """ - Gets the population of this location. - - :returns: The population. - :rtype: int - """ - return country_population(self.country_code) - - def serialize(self): - """ - Serializes the location into a dict. - - :returns: The serialized location. - :rtype: dict - """ - return { - # General info. - "id": self.id, - "country": self.country, - "country_code": self.country_code, - "country_population": self.country_population, - "province": self.province, - # Coordinates. - "coordinates": self.coordinates.serialize(), - # Last updated. - "last_updated": self.last_updated, - # Latest data (statistics). - "latest": { - "confirmed": self.confirmed, - "deaths": self.deaths, - "recovered": self.recovered, - }, - } - - -class TimelinedLocation(Location): - """ - A location with timelines. - """ - - # pylint: disable=too-many-arguments - def __init__(self, id, country, province, coordinates, last_updated, timelines): - super().__init__( - # General info. - id, - country, - province, - coordinates, - last_updated, - # Statistics (retrieve latest from timelines). - confirmed=timelines.get("confirmed").latest or 0, - deaths=timelines.get("deaths").latest or 0, - recovered=timelines.get("recovered").latest or 0, - ) - - # Set timelines. - self.timelines = timelines - - # pylint: disable=arguments-differ - def serialize(self, timelines=False): - """ - Serializes the location into a dict. - - :param timelines: Whether to include the timelines. - :returns: The serialized location. - :rtype: dict - """ - serialized = super().serialize() - - # Whether to include the timelines or not. - if timelines: - serialized.update( - { - "timelines": { - # Serialize all the timelines. - key: value.serialize() - for (key, value) in self.timelines.items() - } - } - ) - - # Return the serialized location. - return serialized +"""app.location""" +from ..coordinates import Coordinates +from ..utils import countries +from ..utils.populations import country_population +from abc import ABCMeta + +# pylint: disable=redefined-builtin,invalid-name + + +class Location: # pylint: disable=too-many-instance-attributes + """ + A location in the world affected by the coronavirus. + """ + + def __init__( + self, id, country, province, coordinates, last_updated, confirmed, deaths, recovered, + ): # pylint: disable=too-many-arguments + # General info. + self.id = id + self.country = country.strip() + self.province = province.strip() + self.coordinates = coordinates + + # Last update. + self.last_updated = last_updated + + # Statistics. + self.confirmed = confirmed + self.deaths = deaths + self.recovered = recovered + + @property + def country_code(self): + """ + Gets the alpha-2 code represention of the country. Returns 'XX' if none is found. + :returns: The country code. + :rtype: str + """ + return (countries.country_code(self.country) or countries.DEFAULT_COUNTRY_CODE).upper() + + @property + def country_population(self): + """ + Gets the population of this location. + :returns: The population. + :rtype: int + """ + return country_population(self.country_code) + + def serialize(self): + """ + Serializes the location into a dict. + :returns: The serialized location. + :rtype: dict + """ + return { + # General info. + "id": self.id, + "country": self.country, + "country_code": self.country_code, + "country_population": self.country_population, + "province": self.province, + # Coordinates. + "coordinates": self.coordinates.serialize(), + # Last updated. + "last_updated": self.last_updated, + # Latest data (statistics). + "latest": { + "confirmed": self.confirmed, + "deaths": self.deaths, + "recovered": self.recovered, + }, + } + + +class TimelinedLocation(Location): + """ + A location with timelines. + """ + + # pylint: disable=too-many-arguments + def __init__(self, id, country, province, coordinates, last_updated, timelines): + super().__init__( + # General info. + id, + country, + province, + coordinates, + last_updated, + # Statistics (retrieve latest from timelines). + confirmed=timelines.get("confirmed").latest or 0, + deaths=timelines.get("deaths").latest or 0, + recovered=timelines.get("recovered").latest or 0, + ) + + # Set timelines. + self.timelines = timelines + + # pylint: disable=arguments-differ + def serialize(self, timelines=False): + """ + Serializes the location into a dict. + :param timelines: Whether to include the timelines. + :returns: The serialized location. + :rtype: dict + """ + serialized = super().serialize() + + # Whether to include the timelines or not. + if timelines: + serialized.update( + { + "timelines": { + # Serialize all the timelines. + key: value.serialize() + for (key, value) in self.timelines.items() + } + } + ) + + # Return the serialized location. + return serialized + + +class LocationBuilderInterface(metaclass=ABCMeta): # pylint: disable=too-many-instance-attributes + """ + The Abstract Location Builder Interface + """ + + def __init__( + self, id, country, province, coordinates, last_updated, confirmed, deaths, recovered, + ): # pylint: disable=too-many-arguments + # General info. + self.id = id + self.country = country.strip() + self.province = province.strip() + self.coordinates = coordinates + + # Last update. + self.last_updated = last_updated + + # Statistics. + self.confirmed = confirmed + self.deaths = deaths + self.recovered = recovered + + @property + def country_code(self): + """ + Gets the alpha-2 code represention of the country. Returns 'XX' if none is found. + :returns: The country code. + :rtype: str + """ + return (countries.country_code(self.country) or countries.DEFAULT_COUNTRY_CODE).upper() + + @property + def country_population(self): + """ + Gets the population of this location. + :returns: The population. + :rtype: int + """ + return country_population(self.country_code) + + def serialize(self): + """ + Serializes the location into a dict. + :returns: The serialized location. + :rtype: dict + """ + return { + # General info. + "id": self.id, + "country": self.country, + "country_code": self.country_code, + "country_population": self.country_population, + "province": self.province, + # Coordinates. + "coordinates": self.coordinates.serialize(), + # Last updated. + "last_updated": self.last_updated, + # Latest data (statistics). + "latest": { + "confirmed": self.confirmed, + "deaths": self.deaths, + "recovered": self.recovered, + }, + } + + # def build_part_a(): + # "Build part a, such as id" + # + # def build_part_b(): + # "Build part b, such as state" + # ... + # def get_result(): + # "Return final product" + + +class TimelinedLocationBuilderInterface(LocationBuilderInterface): + """ + The Abstract Timelined Location Builder Interface + """ + + # pylint: disable=too-many-arguments + def __init__(self, id, country, province, coordinates, last_updated, timelines): + super().__init__( + # General info. + id, + country, + province, + coordinates, + last_updated, + # Statistics (retrieve latest from timelines). + confirmed=timelines.get("confirmed").latest or 0, + deaths=timelines.get("deaths").latest or 0, + recovered=timelines.get("recovered").latest or 0, + ) + + # Set timelines. + self.timelines = timelines + + # pylint: disable=arguments-differ + def serialize(self, timelines=False): + """ + Serializes the location into a dict. + :param timelines: Whether to include the timelines. + :returns: The serialized location. + :rtype: dict + """ + serialized = super().serialize() + + # Whether to include the timelines or not. + if timelines: + serialized.update( + { + "timelines": { + # Serialize all the timelines. + key: value.serialize() + for (key, value) in self.timelines.items() + } + } + ) + + # Return the serialized location. + return serialized + + # def build_part_a(): + # "Build part a, such as id" + # + # def build_part_b(): + # "Build part b, such as state" + # ... + # def get_result(): + # "Return final product" \ No newline at end of file diff --git a/app/location/csbs.py b/app/location/csbs.py index 649e8b22..61c6320d 100644 --- a/app/location/csbs.py +++ b/app/location/csbs.py @@ -1,43 +1,120 @@ -"""app.locations.csbs.py""" -from . import Location - - -class CSBSLocation(Location): - """ - A CSBS (county) location. - """ - - # pylint: disable=too-many-arguments,redefined-builtin - def __init__(self, id, state, county, coordinates, last_updated, confirmed, deaths): - super().__init__( - # General info. - id, - "US", - state, - coordinates, - last_updated, - # Statistics. - confirmed=confirmed, - deaths=deaths, - recovered=0, - ) - - self.state = state - self.county = county - - def serialize(self, timelines=False): # pylint: disable=arguments-differ,unused-argument - """ - Serializes the location into a dict. - - :returns: The serialized location. - :rtype: dict - """ - serialized = super().serialize() - - # Update with new fields. - serialized.update( - {"state": self.state, "county": self.county,} - ) - - # Return the serialized location. - return serialized +"""app.locations.csbs.py""" +from . import Location +from . import LocationBuilderInterface + + +class CSBSLocation(Location): + """ + A CSBS (county) location. + """ + + # pylint: disable=too-many-arguments,redefined-builtin + def __init__(self, id, state, county, coordinates, last_updated, confirmed, deaths): + super().__init__( + # General info. + id, + "US", + state, + coordinates, + last_updated, + # Statistics. + confirmed=confirmed, + deaths=deaths, + recovered=0, + ) + + self.state = state + self.county = county + + def serialize(self, timelines=False): # pylint: disable=arguments-differ,unused-argument + """ + Serializes the location into a dict. + + :returns: The serialized location. + :rtype: dict + """ + serialized = super().serialize() + + # Update with new fields. + serialized.update( + {"state": self.state, "county": self.county, } + ) + + # Return the serialized location. + return serialized + + +class CSBSLocationBuilder(LocationBuilderInterface): + """" + The Concrete Builder for CSBS + """ + + # pylint: disable=too-many-arguments,redefined-builtin + def __init__(self, id, state, county, coordinates, last_updated, confirmed, deaths): + super().__init__( + # General info. + id, + "US", + state, + coordinates, + last_updated, + # Statistics. + confirmed=confirmed, + deaths=deaths, + recovered=0, + ) + + self.state = state + self.county = county + self.product = CSBSProduct() + + def serialize(self, timelines=False): # pylint: disable=arguments-differ,unused-argument + """ + Serializes the location into a dict. + + :returns: The serialized location. + :rtype: dict + """ + serialized = super().serialize() + + # Update with new fields. + serialized.update( + {"state": self.state, "county": self.county, } + ) + + # Return the serialized location. + return serialized + + #def build_part_a(self): + # #this should actually puts the "part" inside the object, part being id, state, country, etc. + # self.product.parts.append('additional parts') + #return self + +class CSBSDirector: + """ + The Director, building a complex representation. + """ + def construct(): + return CSBSLocationBuilder()#\ + # # build and add part_a, ie. id; part_b, ie. state; etc. + # .build_part_a() + + +class CSBSProduct(): + """ + The Product + """ + def __init__(self): + """ + the CSBS product should be empty when the init method is first called + containing a parts attribute + which is of type dictionary + """ + self.parts = {} + pass + + +# # The Client +# #client code that initiates the construction process +# #this should belong where all the other client codes are +# PRODUCT = CSBSDirector.construct() \ No newline at end of file diff --git a/app/location/nyt.py b/app/location/nyt.py index ad92212e..7bf62a19 100644 --- a/app/location/nyt.py +++ b/app/location/nyt.py @@ -1,32 +1,98 @@ -"""app.locations.nyt.py""" -from . import TimelinedLocation - - -class NYTLocation(TimelinedLocation): - """ - A NYT (county) Timelinedlocation. - """ - - # pylint: disable=too-many-arguments,redefined-builtin - def __init__(self, id, state, county, coordinates, last_updated, timelines): - super().__init__(id, "US", state, coordinates, last_updated, timelines) - - self.state = state - self.county = county - - def serialize(self, timelines=False): # pylint: disable=arguments-differ,unused-argument - """ - Serializes the location into a dict. - - :returns: The serialized location. - :rtype: dict - """ - serialized = super().serialize(timelines) - - # Update with new fields. - serialized.update( - {"state": self.state, "county": self.county,} - ) - - # Return the serialized location. - return serialized +"""app.locations.nyt.py""" +from . import TimelinedLocation +from . import TimelinedLocationBuilderInterface + + +class NYTLocation(TimelinedLocation): + """ + A NYT (county) Timelinedlocation. + """ + + # pylint: disable=too-many-arguments,redefined-builtin + def __init__(self, id, state, county, coordinates, last_updated, timelines): + super().__init__(id, "US", state, coordinates, last_updated, timelines) + + self.state = state + self.county = county + + def serialize(self, timelines=False): # pylint: disable=arguments-differ,unused-argument + """ + Serializes the location into a dict. + + :returns: The serialized location. + :rtype: dict + """ + serialized = super().serialize(timelines) + + # Update with new fields. + serialized.update( + {"state": self.state, "county": self.county,} + ) + + # Return the serialized location. + return serialized + + +class NYTLocationBuilder(TimelinedLocationBuilderInterface): + """ + The Concrete Builder for NYT + """ + + # pylint: disable=too-many-arguments,redefined-builtin + def __init__(self, id, state, county, coordinates, last_updated, timelines): + super().__init__(id, "US", state, coordinates, last_updated, timelines) + + self.state = state + self.county = county + self.product = NYTProduct() + + def serialize(self, timelines=False): # pylint: disable=arguments-differ,unused-argument + """ + Serializes the location into a dict. + + :returns: The serialized location. + :rtype: dict + """ + serialized = super().serialize(timelines) + + # Update with new fields. + serialized.update( + {"state": self.state, "county": self.county,} + ) + + # Return the serialized location. + return serialized + + # def build_part_a(self): + # #this should actually puts the "part" inside the object, part being id, state, country, etc. + # self.product.parts.append('additional parts') + # return self + +class NYTDirector: + """ + The Director, building a complex representation. + """ + def construct(): + return NYTLocationBuilder()#\ + # # build and add part_a, ie. id; part_b, ie. state; etc. + # .build_part_a() + + +class NYTProduct(): + """ + The Product + """ + def __init__(self): + """ + the NYT product should be empty when the init method is first called + containing a parts attribute + which is of type dictionary + """ + self.parts = {} + pass + + +# # The Client +# #client code that initiates the construction process +# #this should belong where all the other client codes are +# PRODUCT = NYTDirector.construct() \ No newline at end of file