From 5bfc936738c6a125a696180c4d86a915167ac919 Mon Sep 17 00:00:00 2001 From: HuangHuangHuangShiqing Date: Tue, 16 Mar 2021 04:50:33 +0800 Subject: [PATCH 1/5] aggregate --- COVID19Py/CaseByCountry.py | 37 +++++++++++++++++++++++++++++++++++++ COVID19Py/covid19.py | 38 +------------------------------------- 2 files changed, 38 insertions(+), 37 deletions(-) create mode 100644 COVID19Py/CaseByCountry.py diff --git a/COVID19Py/CaseByCountry.py b/COVID19Py/CaseByCountry.py new file mode 100644 index 0000000..1d14636 --- /dev/null +++ b/COVID19Py/CaseByCountry.py @@ -0,0 +1,37 @@ +from typing import Dict, List +#import COVID19Py +class CaseByCountry: + def __init__(self,Covid19Object=COVID19Py.COVID19()): + self.obj = Covid19Object + def getLocationByCountryCode(self, countryCode, timelines=False) -> List[Dict]: + """ + :param country_code: String denoting the ISO 3166-1 alpha-2 code (https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2) of the country + :param timelines: Whether timeline information should be returned as well. + :return: A list of areas that correspond to the country_code. If the country_code is invalid, it returns an empty list. + """ + data = None + if timelines: + data = self.obj._request("/v2/locations", {"country_code": country_code, "timelines": str(timelines).lower()}) + else: + data = self.obj._request("/v2/locations", {"country_code": country_code}) + return data["locations"] + def getLocationByCountryName(self, countryName, timelines=False) -> List[Dict]: + """ + :param country: String denoting name of the country + :param timelines: Whether timeline information should be returned as well. + :return: A list of areas that correspond to the country name. If the country is invalid, it returns an empty list. + """ + data = None + if timelines: + data = self.obj._request("/v2/locations", {"country": country, "timelines": str(timelines).lower()}) + else: + data = self.obj._request("/v2/locations", {"country": country}) + return data["locations"] + + def getLocationById(self, countryId: int): + """ + :param country_id: Country Id, an int + :return: A dictionary with case information for the specified location. + """ + data = self.obj._request("/v2/locations/" + str(country_id)) + return data["location"] diff --git a/COVID19Py/covid19.py b/COVID19Py/covid19.py index a68faa7..cb1ecae 100644 --- a/COVID19Py/covid19.py +++ b/COVID19Py/covid19.py @@ -32,12 +32,10 @@ def __init__(self, url="https://covid-tracker-us.herokuapp.com", data_source='jh # URL did not work, reset it and move on self.url = "" continue - # TODO: Should have a better health-check, this is way too hacky... if "jhu" in result: # We found a mirror that worked just fine, let's stick with it break - # None of the mirrors worked. Raise an error to inform the user. raise RuntimeError("No available API mirror was found.") @@ -67,7 +65,7 @@ def _getSources(self): def _request(self, endpoint, params=None): if params is None: params = {} - response = requests.get(self.url + endpoint, {**params, "source":self.data_source}) + response = requests.get(self.url + endpoint, {*params, "source":self.data_source}) #syntax error fixed response.raise_for_status() return response.json() @@ -122,37 +120,3 @@ def getLocations(self, timelines=False, rank_by: str = None) -> List[Dict]: data = ranked return data - - def getLocationByCountryCode(self, country_code, timelines=False) -> List[Dict]: - """ - :param country_code: String denoting the ISO 3166-1 alpha-2 code (https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2) of the country - :param timelines: Whether timeline information should be returned as well. - :return: A list of areas that correspond to the country_code. If the country_code is invalid, it returns an empty list. - """ - data = None - if timelines: - data = self._request("/v2/locations", {"country_code": country_code, "timelines": str(timelines).lower()}) - else: - data = self._request("/v2/locations", {"country_code": country_code}) - return data["locations"] - - def getLocationByCountry(self, country, timelines=False) -> List[Dict]: - """ - :param country: String denoting name of the country - :param timelines: Whether timeline information should be returned as well. - :return: A list of areas that correspond to the country name. If the country is invalid, it returns an empty list. - """ - data = None - if timelines: - data = self._request("/v2/locations", {"country": country, "timelines": str(timelines).lower()}) - else: - data = self._request("/v2/locations", {"country": country}) - return data["locations"] - - def getLocationById(self, country_id: int): - """ - :param country_id: Country Id, an int - :return: A dictionary with case information for the specified location. - """ - data = self._request("/v2/locations/" + str(country_id)) - return data["location"] From 0fa4508b1b2f41a58938f27646b43b489baf6274 Mon Sep 17 00:00:00 2001 From: Shiqing Huang Date: Tue, 16 Mar 2021 05:38:02 +0800 Subject: [PATCH 2/5] aggregate --- COVID19Py/OverViewOfCovid19.py | 60 ++++++++++++++++++++++++++++++++++ COVID19Py/covid19.py | 54 ++---------------------------- 2 files changed, 63 insertions(+), 51 deletions(-) create mode 100644 COVID19Py/OverViewOfCovid19.py diff --git a/COVID19Py/OverViewOfCovid19.py b/COVID19Py/OverViewOfCovid19.py new file mode 100644 index 0000000..9075b65 --- /dev/null +++ b/COVID19Py/OverViewOfCovid19.py @@ -0,0 +1,60 @@ +from typing import Dict, List +import COVID19Py +#aggregate OverViewOfCovid19 +class OverViewOfCovid19: + def __init__(self,Covid19Object): + self.obj = Covid19Object + + def getAll(self, timelines=False): + self.obj._update(timelines) + return self.obj.latestData + + def getLatestChanges(self): + changes = None + if self.obj.previousData: + changes = { + "confirmed": self.obj.latestData["latest"]["confirmed"] - self.obj.latestData["latest"]["confirmed"], + "deaths": self.obj.latestData["latest"]["deaths"] - self.obj.latestData["latest"]["deaths"], + "recovered": self.obj.latestData["latest"]["recovered"] - self.obj.latestData["latest"]["recovered"], + } + else: + changes = { + "confirmed": 0, + "deaths": 0, + "recovered": 0, + } + return changes + + def getLatest(self) -> List[Dict[str, int]]: + """ + :return: The latest amount of total confirmed cases, deaths, and recoveries. + """ + data = self.obj._request("/v2/latest") + return data["latest"] + + def getLocations(self, timelines=False, rank_by: str = None) -> List[Dict]: + """ + Gets all locations affected by COVID-19, as well as latest case data. + :param timelines: Whether timeline information should be returned as well. + :param rank_by: Category to rank results by. ex: confirmed + :return: List of dictionaries representing all affected locations. + """ + data = None + if timelines: + data = self.obj._request("/v2/locations", {"timelines": str(timelines).lower()}) + else: + data = self.obj._request("/v2/locations") + + data = data["locations"] + + ranking_criteria = ['confirmed', 'deaths', 'recovered'] + if rank_by is not None: + if rank_by not in ranking_criteria: + raise ValueError("Invalid ranking criteria. Expected one of: %s" % ranking_criteria) + + ranked = sorted(data, key=lambda i: i['latest'][rank_by], reverse=True) + data = ranked + + return data + + diff --git a/COVID19Py/covid19.py b/COVID19Py/covid19.py index cb1ecae..3360418 100644 --- a/COVID19Py/covid19.py +++ b/COVID19Py/covid19.py @@ -32,10 +32,12 @@ def __init__(self, url="https://covid-tracker-us.herokuapp.com", data_source='jh # URL did not work, reset it and move on self.url = "" continue + # TODO: Should have a better health-check, this is way too hacky... if "jhu" in result: # We found a mirror that worked just fine, let's stick with it break + # None of the mirrors worked. Raise an error to inform the user. raise RuntimeError("No available API mirror was found.") @@ -69,54 +71,4 @@ def _request(self, endpoint, params=None): response.raise_for_status() return response.json() - def getAll(self, timelines=False): - self._update(timelines) - return self.latestData - - def getLatestChanges(self): - changes = None - if self.previousData: - changes = { - "confirmed": self.latestData["latest"]["confirmed"] - self.latestData["latest"]["confirmed"], - "deaths": self.latestData["latest"]["deaths"] - self.latestData["latest"]["deaths"], - "recovered": self.latestData["latest"]["recovered"] - self.latestData["latest"]["recovered"], - } - else: - changes = { - "confirmed": 0, - "deaths": 0, - "recovered": 0, - } - return changes - - def getLatest(self) -> List[Dict[str, int]]: - """ - :return: The latest amount of total confirmed cases, deaths, and recoveries. - """ - data = self._request("/v2/latest") - return data["latest"] - - def getLocations(self, timelines=False, rank_by: str = None) -> List[Dict]: - """ - Gets all locations affected by COVID-19, as well as latest case data. - :param timelines: Whether timeline information should be returned as well. - :param rank_by: Category to rank results by. ex: confirmed - :return: List of dictionaries representing all affected locations. - """ - data = None - if timelines: - data = self._request("/v2/locations", {"timelines": str(timelines).lower()}) - else: - data = self._request("/v2/locations") - - data = data["locations"] - - ranking_criteria = ['confirmed', 'deaths', 'recovered'] - if rank_by is not None: - if rank_by not in ranking_criteria: - raise ValueError("Invalid ranking criteria. Expected one of: %s" % ranking_criteria) - - ranked = sorted(data, key=lambda i: i['latest'][rank_by], reverse=True) - data = ranked - - return data + From 7d67b26c0ab410c85319dee3bdd95525b8c07977 Mon Sep 17 00:00:00 2001 From: Shiqing Huang Date: Sat, 27 Mar 2021 02:39:47 +0800 Subject: [PATCH 3/5] Apply Builder Pattern --- COVID19Py/.DS_Store | Bin 0 -> 6148 bytes COVID19Py/CaseByCountry.py | 37 --------- COVID19Py/ObjectBuilder.py | 85 ++++++++++++++++++++ COVID19Py/OverViewOfCovid19.py | 60 -------------- COVID19Py/covid19.py | 138 ++++++++++++++++++++++----------- 5 files changed, 178 insertions(+), 142 deletions(-) create mode 100644 COVID19Py/.DS_Store delete mode 100644 COVID19Py/CaseByCountry.py create mode 100644 COVID19Py/ObjectBuilder.py delete mode 100644 COVID19Py/OverViewOfCovid19.py diff --git a/COVID19Py/.DS_Store b/COVID19Py/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..5008ddfcf53c02e82d7eee2e57c38e5672ef89f6 GIT binary patch literal 6148 zcmeH~Jr2S!425mzP>H1@V-^m;4Wg<&0T*E43hX&L&p$$qDprKhvt+--jT7}7np#A3 zem<@ulZcFPQ@L2!n>{z**++&mCkOWA81W14cNZlEfg7;MkzE(HCqgga^y>{tEnwC%0;vJ&^%eQ zLs35+`xjp>T0 List[Dict]: - """ - :param country_code: String denoting the ISO 3166-1 alpha-2 code (https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2) of the country - :param timelines: Whether timeline information should be returned as well. - :return: A list of areas that correspond to the country_code. If the country_code is invalid, it returns an empty list. - """ - data = None - if timelines: - data = self.obj._request("/v2/locations", {"country_code": country_code, "timelines": str(timelines).lower()}) - else: - data = self.obj._request("/v2/locations", {"country_code": country_code}) - return data["locations"] - def getLocationByCountryName(self, countryName, timelines=False) -> List[Dict]: - """ - :param country: String denoting name of the country - :param timelines: Whether timeline information should be returned as well. - :return: A list of areas that correspond to the country name. If the country is invalid, it returns an empty list. - """ - data = None - if timelines: - data = self.obj._request("/v2/locations", {"country": country, "timelines": str(timelines).lower()}) - else: - data = self.obj._request("/v2/locations", {"country": country}) - return data["locations"] - - def getLocationById(self, countryId: int): - """ - :param country_id: Country Id, an int - :return: A dictionary with case information for the specified location. - """ - data = self.obj._request("/v2/locations/" + str(country_id)) - return data["location"] diff --git a/COVID19Py/ObjectBuilder.py b/COVID19Py/ObjectBuilder.py new file mode 100644 index 0000000..83caaac --- /dev/null +++ b/COVID19Py/ObjectBuilder.py @@ -0,0 +1,85 @@ +from abc import ABCMeta,abstractmethod +from typing import Dict, List +import covid19 +import requests +import json + +"The Builder Interface" +class InterfaceBuilder(metaclass=ABCMeta): + @staticmethod + @abstractmethod + def setURL(): + "build url" + + @staticmethod + @abstractmethod + def setDataSource(): + "build data source" + + @staticmethod + @abstractmethod + def getProduct(): + "return the final product" + +"The concrete Builder" +class ObjectBuilder(InterfaceBuilder): + + def __init__(self): + self.product = covid19.COVID19() + + def setURL(self,url): + if url == self.product.default_url: + + # Load mirrors + response = requests.get(self.product.mirrors_source) + response.raise_for_status() + self.product.mirrors = response.json() + + # Try to get sources as a test + for mirror in self.product.mirrors: + # Set URL of mirror + self.product.url = mirror["url"] + result = None + + try: + result = self.product._getSources() + + except Exception as e: + + # URL did not work, reset it and move on + self.product.url = "" + continue + + # TODO: Should have a better health-check, this is way too hacky... + if "jhu" in result: + # We found a mirror that worked just fine, let's stick with it + break + + # None of the mirrors worked. Raise an error to inform the user. + raise RuntimeError("No available API mirror was found.") + + else: + self.product.url = url + + return self + + def setDataSource(self,data_source): + + self.product._valid_data_sources = self.product._getSources() + + if data_source not in self.product._valid_data_sources: + raise ValueError("Invalid data source. Expected one of: %s" % self._valid_data_sources) + self.product.data_source = data_source + + return self + + def getProduct(self): + return self.product + + +class Director: + @staticmethod + def construct(url="https://covid-tracker-us.herokuapp.com", dataSource='jhu'): + return ObjectBuilder().setURL(url).setDataSource(dataSource).getProduct() + + diff --git a/COVID19Py/OverViewOfCovid19.py b/COVID19Py/OverViewOfCovid19.py deleted file mode 100644 index 9075b65..0000000 --- a/COVID19Py/OverViewOfCovid19.py +++ /dev/null @@ -1,60 +0,0 @@ -from typing import Dict, List -import COVID19Py -#aggregate OverViewOfCovid19 -class OverViewOfCovid19: - def __init__(self,Covid19Object): - self.obj = Covid19Object - - def getAll(self, timelines=False): - self.obj._update(timelines) - return self.obj.latestData - - def getLatestChanges(self): - changes = None - if self.obj.previousData: - changes = { - "confirmed": self.obj.latestData["latest"]["confirmed"] - self.obj.latestData["latest"]["confirmed"], - "deaths": self.obj.latestData["latest"]["deaths"] - self.obj.latestData["latest"]["deaths"], - "recovered": self.obj.latestData["latest"]["recovered"] - self.obj.latestData["latest"]["recovered"], - } - else: - changes = { - "confirmed": 0, - "deaths": 0, - "recovered": 0, - } - return changes - - def getLatest(self) -> List[Dict[str, int]]: - """ - :return: The latest amount of total confirmed cases, deaths, and recoveries. - """ - data = self.obj._request("/v2/latest") - return data["latest"] - - def getLocations(self, timelines=False, rank_by: str = None) -> List[Dict]: - """ - Gets all locations affected by COVID-19, as well as latest case data. - :param timelines: Whether timeline information should be returned as well. - :param rank_by: Category to rank results by. ex: confirmed - :return: List of dictionaries representing all affected locations. - """ - data = None - if timelines: - data = self.obj._request("/v2/locations", {"timelines": str(timelines).lower()}) - else: - data = self.obj._request("/v2/locations") - - data = data["locations"] - - ranking_criteria = ['confirmed', 'deaths', 'recovered'] - if rank_by is not None: - if rank_by not in ranking_criteria: - raise ValueError("Invalid ranking criteria. Expected one of: %s" % ranking_criteria) - - ranked = sorted(data, key=lambda i: i['latest'][rank_by], reverse=True) - data = ranked - - return data - - diff --git a/COVID19Py/covid19.py b/COVID19Py/covid19.py index 3360418..9225423 100644 --- a/COVID19Py/covid19.py +++ b/COVID19Py/covid19.py @@ -3,51 +3,15 @@ import json class COVID19(object): - default_url = "https://covid-tracker-us.herokuapp.com" - url = "" - data_source = "" previousData = None latestData = None - _valid_data_sources = [] - - mirrors_source = "https://raw.github.com/Kamaropoulos/COVID19Py/master/mirrors.json" - mirrors = None - - def __init__(self, url="https://covid-tracker-us.herokuapp.com", data_source='jhu'): - # Skip mirror checking if custom url was passed - if url == self.default_url: - # Load mirrors - response = requests.get(self.mirrors_source) - response.raise_for_status() - self.mirrors = response.json() - - # Try to get sources as a test - for mirror in self.mirrors: - # Set URL of mirror - self.url = mirror["url"] - result = None - try: - result = self._getSources() - except Exception as e: - # URL did not work, reset it and move on - self.url = "" - continue - - # TODO: Should have a better health-check, this is way too hacky... - if "jhu" in result: - # We found a mirror that worked just fine, let's stick with it - break - - # None of the mirrors worked. Raise an error to inform the user. - raise RuntimeError("No available API mirror was found.") - - else: - self.url = url - - self._valid_data_sources = self._getSources() - if data_source not in self._valid_data_sources: - raise ValueError("Invalid data source. Expected one of: %s" % self._valid_data_sources) - self.data_source = data_source + def __init__(self): + self.default_url = "https://covid-tracker-us.herokuapp.com" + self.mirrors_source = "https://raw.github.com/Kamaropoulos/COVID19Py/master/mirrors.json" + self._valid_data_sources = [] + self.url = "https://covid-tracker-us.herokuapp.com" + self.data_source = "jhu" + self.mirrors = None def _update(self, timelines): latest = self.getLatest() @@ -67,8 +31,92 @@ def _getSources(self): def _request(self, endpoint, params=None): if params is None: params = {} - response = requests.get(self.url + endpoint, {*params, "source":self.data_source}) #syntax error fixed + response = requests.get(self.url + endpoint, {**params, "source":self.data_source}) #syntax error fixed response.raise_for_status() return response.json() - + def getAll(self, timelines=False): + self._update(timelines) + return self.latestData + + def getLatestChanges(self): + changes = None + if self.previousData: + changes = { + "confirmed": self.latestData["latest"]["confirmed"] - self.latestData["latest"]["confirmed"], + "deaths": self.latestData["latest"]["deaths"] - self.latestData["latest"]["deaths"], + "recovered": self.latestData["latest"]["recovered"] - self.latestData["latest"]["recovered"], + } + else: + changes = { + "confirmed": 0, + "deaths": 0, + "recovered": 0, + } + return changes + + def getLatest(self) -> List[Dict[str, int]]: + """ + :return: The latest amount of total confirmed cases, deaths, and recoveries. + """ + data = self._request("/v2/latest") + return data["latest"] + + def getLocations(self, timelines=False, rank_by: str = None) -> List[Dict]: + """ + Gets all locations affected by COVID-19, as well as latest case data. + :param timelines: Whether timeline information should be returned as well. + :param rank_by: Category to rank results by. ex: confirmed + :return: List of dictionaries representing all affected locations. + """ + data = None + if timelines: + data = self._request("/v2/locations", {"timelines": str(timelines).lower()}) + else: + data = self._request("/v2/locations") + + data = data["locations"] + + ranking_criteria = ['confirmed', 'deaths', 'recovered'] + if rank_by is not None: + if rank_by not in ranking_criteria: + raise ValueError("Invalid ranking criteria. Expected one of: %s" % ranking_criteria) + + ranked = sorted(data, key=lambda i: i['latest'][rank_by], reverse=True) + data = ranked + + return data + + def getLocationByCountryCode(self, country_code, timelines=False) -> List[Dict]: + """ + :param country_code: String denoting the ISO 3166-1 alpha-2 code (https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2) of the country + :param timelines: Whether timeline information should be returned as well. + :return: A list of areas that correspond to the country_code. If the country_code is invalid, it returns an empty list. + """ + data = None + if timelines: + data = self._request("/v2/locations", {"country_code": country_code, "timelines": str(timelines).lower()}) + else: + data = self._request("/v2/locations", {"country_code": country_code}) + return data["locations"] + + def getLocationByCountry(self, country, timelines=False) -> List[Dict]: + """ + :param country: String denoting name of the country + :param timelines: Whether timeline information should be returned as well. + :return: A list of areas that correspond to the country name. If the country is invalid, it returns an empty list. + """ + data = None + if timelines: + data = self._request("/v2/locations", {"country": country, "timelines": str(timelines).lower()}) + else: + data = self._request("/v2/locations", {"country": country}) + return data["locations"] + + def getLocationById(self, country_id: int): + """ + :param country_id: Country Id, an int + :return: A dictionary with case information for the specified location. + """ + data = self._request("/v2/locations/" + str(country_id)) + return data["location"] From 51ae5863287c9d1bf4a6ffc6d16bab56a89214bc Mon Sep 17 00:00:00 2001 From: Shiqing Huang Date: Sat, 27 Mar 2021 03:28:31 +0800 Subject: [PATCH 4/5] update on Builder Pattern --- COVID19Py/ObjectBuilder.py | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/COVID19Py/ObjectBuilder.py b/COVID19Py/ObjectBuilder.py index 83caaac..3d0d457 100644 --- a/COVID19Py/ObjectBuilder.py +++ b/COVID19Py/ObjectBuilder.py @@ -34,7 +34,6 @@ def setURL(self,url): response = requests.get(self.product.mirrors_source) response.raise_for_status() self.product.mirrors = response.json() - # Try to get sources as a test for mirror in self.product.mirrors: # Set URL of mirror @@ -66,7 +65,7 @@ def setURL(self,url): def setDataSource(self,data_source): self.product._valid_data_sources = self.product._getSources() - + if data_source not in self.product._valid_data_sources: raise ValueError("Invalid data source. Expected one of: %s" % self._valid_data_sources) self.product.data_source = data_source @@ -78,8 +77,15 @@ def getProduct(self): class Director: + @staticmethod - def construct(url="https://covid-tracker-us.herokuapp.com", dataSource='jhu'): - return ObjectBuilder().setURL(url).setDataSource(dataSource).getProduct() - + def constructURL(obj=ObjectBuilder(),url="https://covid-tracker-us.herokuapp.com"): + return obj.setURL(url) + @staticmethod + def constructDataSource(obj=ObjectBuilder(),dataSource='jhu'): + return obj.setDataSource(dataSource) + @staticmethod + def contructWholeProduct(obj=ObjectBuilder(),url="https://covid-tracker-us.herokuapp.com", dataSource='jhu'): + return obj.setURL(url).setDataSource(dataSource).getProduct() + From 05b7913b18e8ae45d06ef96b9c618431bbc7440e Mon Sep 17 00:00:00 2001 From: Shiqing Huang Date: Wed, 7 Apr 2021 20:23:40 +0800 Subject: [PATCH 5/5] abstract class for coronavirus --- .DS_Store | Bin 0 -> 6148 bytes Abstract class/abstractCoronavirus.py | 34 ++++++++++++++++++++++++++ COVID19Py/covid19.py | 3 ++- 3 files changed, 36 insertions(+), 1 deletion(-) create mode 100644 .DS_Store create mode 100644 Abstract class/abstractCoronavirus.py diff --git a/.DS_Store b/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..7aa18135c52148bbbc7e09e0a2fb3a083dcf70e5 GIT binary patch literal 6148 zcmeHK%}(1u5S~p^Sf?uFfJ9E!UV6(RE(pN^$qDAbsYtHqp{>Bi5wYZWqu3#W5aidO z&(d2@eS$tk-=VWVK|m;|mrAW>q}gwFc4pW6t+JZ|0M;GHE3(B22R0NGB(8 z4?{kENU~T?x^kSwxt=F51DreDIc_wkQ+H##CERUy))Ld5x9yhL+}N7U9KQa>-90!N zTwG4CX4f}{YKA{4Evpvi@CA)Wwt60nvQ%bgI6BXqXAlwt!~ikyfB}0=@Rtw#)FlRp z0b)Si4+2%8XR$P>uMTW<34mBbw-&TjEunIRMbBbs5Jym$NkufN%$69;q@!QhIL~5f z(4+&i#Rs!1Gh3lBy*kb>bT}~2AhpB*F>s%Os_8b=`@jGD`u~0s^@sst;J;#k)%?Kk z;+E{&y0AI*)(X@UR3$2|G D!?$_p literal 0 HcmV?d00001 diff --git a/Abstract class/abstractCoronavirus.py b/Abstract class/abstractCoronavirus.py new file mode 100644 index 0000000..e012d88 --- /dev/null +++ b/Abstract class/abstractCoronavirus.py @@ -0,0 +1,34 @@ +from abc import ABCMeta, abstractmethod + +class AbstractCoronavirus(metaclass=ABCMeta): + + @abstractmethod + def _update(): + pass + @abstractmethod + def _getSources(): + pass + @abstractmethod + def _request(): + pass + @abstractmethod + def getAll(): + pass + @abstractmethod + def getLatestChanges(): + pass + @abstractmethod + def getLatest(): + pass + @abstractmethod + def getLocations(): + pass + @abstractmethod + def getLocationByCountryCode(): + pass + @abstractmethod + def getLocationByCountry(): + pass + @abstractmethod + def getLocationById(): + pass diff --git a/COVID19Py/covid19.py b/COVID19Py/covid19.py index 9225423..558fd0c 100644 --- a/COVID19Py/covid19.py +++ b/COVID19Py/covid19.py @@ -1,8 +1,9 @@ from typing import Dict, List import requests import json +from abstractCoronavirus import AbstractCoronavirus -class COVID19(object): +class COVID19(AbstractCoronavirus): previousData = None latestData = None def __init__(self):