diff --git a/app/location/__init__.py b/app/location/__init__.py index 1da5e9e5..ee88460d 100644 --- a/app/location/__init__.py +++ b/app/location/__init__.py @@ -3,122 +3,304 @@ from ..utils import countries from ..utils.populations import country_population +#parts -# 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. +# put confirmed cases, deaths cases, recovered cases into one class +# Inseated of using confirmed cases, deaths cases, recovered cases as attributes, we can use CaseNumbers class instance as attribute +class CaseNumbers: + def __init__(self, confirmed = 0, deaths = 0, recovered = 0): 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() +#put all location information into one class +#CaseNumbers, Locationinfo, coordinates and Location forms one aggregate +class Locationinfo: + def __init__(self, country, province, coordinates): + #self.id = id + self.country = country.strip() + self.province = province.strip() + self.coordinates = coordinates + #get countrycode and population so no extra methods are needed + self.country_code = (countries.country_code(self.locationinfo.country) or countries.DEFAULT_COUNTRY_CODE).upper() + self.population = country_population(self.country_code) - @property - def country_population(self): - """ - Gets the population of this location. +#timelines is a parts as well +class timeline: + timeline = None - :returns: The population. - :rtype: int - """ - return country_population(self.country_code) + +# Base info every location has, id, last_updated and serialize +class BaseLocation: + def __init__(self, id, last_updated): + self.id = id + self.last_updated = last_updated def serialize(self): """ Serializes the location into a dict. - :returns: The serialized location. :rtype: dict """ return { # General info. - "id": self.id, - "country": self.country, + "id": self.locationinfo.id, + "country": self.locationinfo.country, "country_code": self.country_code, "country_population": self.country_population, - "province": self.province, + "province": self.locationinfo.province, # Coordinates. - "coordinates": self.coordinates.serialize(), + "coordinates": self.locationinfo.coordinates.serialize(), # Last updated. "last_updated": self.last_updated, # Latest data (statistics). "latest": { - "confirmed": self.confirmed, - "deaths": self.deaths, - "recovered": self.recovered, + "confirmed": self.casenumbers.confirmed, + "deaths": self.casenumbers.deaths, + "recovered": self.casenumbers.recovered, }, } + + +# The origional code has Location and Timelined location +# Timelined location is a subclass(similar) of Location +# Apply builder pattern here so only one constructor will be called +# It would be more useful if we have more Location class variation here +# For example, if some location class only requires cases and some location classes only require info +from abc import abstractmethod +class Builder: + # Builder class, used to create different parts of Location + # A location has info, casenumbers and timelines(if needed) + def baseinfo_builder(self) -> None: + pass + def casenumber_builder(self) -> None: + pass + def loaction_info_builder(self) -> None: + pass + def timeline_builder(self) -> None: + pass -class TimelinedLocation(Location): - """ - A location with timelines. - """ +#whole product 1 Location +class Location: + def __init__(self): + self.casenumbers = None + self.baseinfo = None + self.locationinfo = None - # 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. + def build_casenumber(self, casenumber): + self.casenumbers = casenumber + + def build_baseinfo(self, baseinfo): + self.baseinfo = baseinfo + + def build_loaction_info(self, locationinfo): + self.locationinfo = locationinfo + +#whole product 2 Timelined Location +class TimelinedLocation: + def __init__(self): + self.casenumbers = None + self.baseinfo = None + self.locationinfo = None + self.timelines = None + + def build_casenumber(self, casenumber): + self.casenumbers = casenumber + + def build_baseinfo(self, baseinfo): + self.baseinfo = baseinfo + + def build_loaction_infor(self, locationinfo): + self.locationinfo = locationinfo + + def build_timeline(self, timelines): self.timelines = timelines + - # pylint: disable=arguments-differ - def serialize(self, timelines=False): - """ - Serializes the location into a dict. +class BuildLocation(Builder): + def __init__(self) -> None: + self.reset() + + def reset(self) -> None: + self._location = Location() - :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 + @property + def location(self) -> Location: + location = self._location + self.reset() + return location + + def casenumber_builder(self) -> None: + self._location.build_casenumber + + def baseinfo_builder(self) -> None: + self._location.build_baseinfo + + def loaction_info_builder(self) -> None: + self._location.build_loaction_info + +class BuildTimeLinedLocation(Builder): + def __init__(self) -> None: + self.reset() + + def reset(self) -> None: + self.timelined_location = TimelinedLocation() + + @property + def Timelinedlocation(self) -> TimelinedLocation: + timelined_location = self._timelined_location + self.reset() + return timelined_location + + def casenumber_builder(self) -> None: + self.timelined_location.build_casenumber + + def baseinfo_builder(self) -> None: + self.timelined_location.build_baseinfo + + def loaction_info_builder(self) -> None: + self.timelined_location.build_loaction_infor + + def timeline_builder(self) -> None: + self.timelined_location.build_timeline + +class Director: + def __init__(self) -> None: + self._builder = None + + def set_builder(self, builder: Builder) -> None: + self._builder = builder + + def buildLoaction(self) -> None: + self._builder.baseinfo_builder() + self._builder.casenumber_builder() + self._builder.loaction_info_builder() + + def buildTimelinedLocation(self) -> None: + self._builder.loaction_info_builder() + self._builder.baseinfo_builder() + self._builder.casenumber_builder() + self._builder.timeline_builder() + + + +# 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 diff --git a/app/location/nyt.py b/app/location/nyt.py index ad92212e..9f881cac 100644 --- a/app/location/nyt.py +++ b/app/location/nyt.py @@ -1,5 +1,6 @@ """app.locations.nyt.py""" -from . import TimelinedLocation +from Commit1 import BaseInfo, Director, TimelinedLocation_Builder +from . import BuildTimeLinedLocation, TimelinedLocation, Director, BaseLocation, Locationinfo, CaseNumbers class NYTLocation(TimelinedLocation): @@ -9,10 +10,17 @@ class NYTLocation(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) + """ super().__init__(id, "US", state, coordinates, last_updated, timelines) self.state = state - self.county = county + self.county = county """ + + director = Director() + base = BaseInfo(id=id,last_updated=last_updated) + locationinfo = Locationinfo(country="US", province=state, coordinates=coordinates) + builder = BuildTimeLinedLocation(baseinfo=base, geoinfo=locationinfo, timelines=timelines) + director.set_builder(builder) + nyt = director.build_location def serialize(self, timelines=False): # pylint: disable=arguments-differ,unused-argument """