Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
205 changes: 186 additions & 19 deletions app/location/__init__.py
Original file line number Diff line number Diff line change
@@ -1,32 +1,205 @@
"""app.location"""
from ..coordinates import Coordinates

import copy

from ..utils import countries
from ..utils.populations import country_population

from abc import ABCMeta, abstractmethod

# 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.
class PrototypeLocations(metaclass=ABCMeta):
def __init__(self, id, country, province, coordinates, last_updated, confirmed, deaths, recovered, timelines):
self.id = None
self.country = None
self.province = None
self.coordinates = None

# Last update.
self.last_updated = None

# Statistics.
self.confirmed = None
self.deaths = None
self.recovered = None

# Set timelines.
self.timelines = None

def set_id(self, id):
self.id = id

def set_country(self, country):
self.country = country.strip()

def set_province(self, province):
self.province = province.strip()

def set_coordinates(self, coordinates):
self.coordinates = coordinates

# Last update.
def set_last_update(self, last_updated):
self.last_updated = last_updated

# Statistics.
def set_confirmed(self, confirmed):
self.confirmed = confirmed

def set_deaths(self, deaths):
self.deaths = deaths

def set_recovered(self, recovered):
self.recovered = recovered

def set_timelines(self, timelines):
self.timelines = timelines

def get_id(self):
return self.id

def get_country(self):
return self.country.strip()

def get_province(self):
return self.province.strip()

def get_coordinates(self):
return self.coordinates

def get_last_update(self):
return self.last_updated

def get_confirmed(self):
return self.confirmed

def get_deaths(self):
return self.deaths

def get_recovered(self):
return self.recovered

def get_timelines(self):
return self.timelines

def clone(self):
return copy.copy(self)

@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 __copy__(self):
"""
Create a shallow copy. This method will be called whenever someone calls
`copy.copy` with this object and the returned value is returned as the
new shallow copy.
"""

# First, let's create copies of the nested objects.
id = copy.deepcopy(self.id)
country = copy.copy(self.country)
province = copy.copy(self.province)
coordinates = copy.copy(self.coordinates)
last_updated = copy.copy(self.last_updated)
confirmed = copy.copy(self.confirmed)
deaths = copy.copy(self.deaths)
recovered = copy.copy(self.recovered)
timelines = copy.copy(self.timelines)

# Then, let's clone the object itself, using the prepared clones of the
# nested objects.
new = self.__class__(
id, country, province, coordinates, last_updated, confirmed, deaths, recovered, timelines
)
new.__dict__.update(self.__dict__)

return new

def __deepcopy__(self, memo=None):
"""
Create a deep copy. This method will be called whenever someone calls
`copy.deepcopy` with this object and the returned value is returned as
the new deep copy.

What is the use of the argument `memo`? Memo is the dictionary that is
used by the `deepcopy` library to prevent infinite recursive copies in
instances of circular references. Pass it to all the `deepcopy` calls
you make in the `__deepcopy__` implementation to prevent infinite
recursions.
"""

# First, let's create copies of the nested objects.
if memo is None:
memo = {}
id = copy.deepcopy(self.id, memo)
country = copy.deepcopy(self.country, memo)
province = copy.deepcopy(self.province, memo)
coordinates = copy.deepcopy(self.coordinates, memo)
last_updated = copy.deepcopy(self.last_updated, memo)
confirmed = copy.deepcopy(self.confirmed, memo)
deaths = copy.deepcopy(self.deaths, memo)
recovered = copy.deepcopy(self.recovered, memo)
timelines = copy.deepcopy(self.timelines, memo)

# Then, let's clone the object itself, using the prepared clones of the
# nested objects.
new = self.__class__(
id, country, province, coordinates, last_updated, confirmed, deaths, recovered, timelines
)
new.__dict__ = copy.deepcopy(self.__dict__, memo)

return new


class Location: # pylint: disable=too-many-instance-attributes
"""
A location in the world affected by the coronavirus.
"""

def __init__(self):
super().__init__()

@property
def country_code(self):
"""
Expand Down Expand Up @@ -80,14 +253,8 @@ class TimelinedLocation(Location):
"""

# pylint: disable=too-many-arguments
def __init__(self, id, country, province, coordinates, last_updated, timelines):
def __init__(self, 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,
Expand Down
15 changes: 13 additions & 2 deletions app/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,8 @@ class LatestResponse(BaseModel):
Response for latest.
"""

latest: Latest
def location(self, Latest):
latest: Latest


class Timeline(BaseModel):
Expand Down Expand Up @@ -88,5 +89,15 @@ class LocationsResponse(BaseModel):
Response for locations.
"""

latest: Latest
def location(self, Latest):
latest: Latest

locations: List[Location] = []


class ResponsedLocations:
def __init__(self, Latest):
self.Latest = Latest

def produceLatest(self):
self.location(self.Latest)