from collections import defaultdict
import logging
import warnings
import country_converter as coco
from covsirphy.util.validator import Validator
[docs]
class Term(object):
"""
Term definition.
"""
# Variables of SIR-derived model
N = "Population"
S = "Susceptible"
C = "Confirmed"
CI = "Infected"
F = "Fatal"
R = "Recovered"
FR = "Fatal or Recovered"
E = "Exposed"
W = "Waiting"
# PCR tests
TESTS = "Tests"
TESTS_DIFF = "Tests_diff"
# Severity
MODERATE = "Moderate"
SEVERE = "Severe"
# Vaccination
VAC = "Vaccinations"
V = "Vaccinated"
V_ONCE = f"{V}_once"
V_FULL = f"{V}_full"
VAC_BOOSTERS = f"{VAC}_boosters"
PRODUCT = "Product"
# Column names
DATE = "Date"
START = "Start"
END = "End"
T = "Elapsed"
TS = "t"
TAU = "tau"
COUNTRY = "Country"
ISO3 = "ISO3"
PROVINCE = "Province"
CITY = "City"
STEP_N = "step_n"
Y0_DICT = "y0_dict"
PARAM_DICT = "param_dict"
ID = "ID"
_PH = "Phase_ID"
_SIRF = [S, CI, R, F]
AREA_COLUMNS = [COUNTRY, PROVINCE]
STR_COLUMNS = [DATE, *AREA_COLUMNS]
COLUMNS = [*STR_COLUMNS, C, CI, F, R]
NLOC_COLUMNS = [DATE, C, CI, F, R]
SUB_COLUMNS = [DATE, C, CI, F, R, S]
VALUE_COLUMNS = [C, CI, F, R]
FIG_COLUMNS = [CI, F, R, FR, V, E, W]
MONO_COLUMNS = [C, F, R]
AREA_ABBR_COLS = [ISO3, *AREA_COLUMNS]
DSIFR_COLUMNS = [DATE, S, CI, F, R]
# Date format: 22Jan2020 etc.
DATE_FORMAT = "%d%b%Y"
DATE_FORMAT_DESC = "DDMmmYYYY"
# Separator of country and province
SEP = "/"
# EDA
RATE_COLUMNS = [
"Fatal per Confirmed",
"Recovered per Confirmed",
"Fatal per (Fatal or Recovered)"
]
# Optimization
A = "_actual"
P = "_predicted"
ACTUAL = "Actual"
FITTED = "Fitted"
# Phase name
SUFFIX_DICT = defaultdict(lambda: "th")
SUFFIX_DICT.update({1: "st", 2: "nd", 3: "rd"})
# Summary of phases
TENSE = "Type"
PAST = "Past"
FUTURE = "Future"
INITIAL = "Initial"
ODE = "ODE"
RT = "Rt"
RT_FULL = "Reproduction number"
TRIALS = "Trials"
RUNTIME = "Runtime"
# Scenario analysis
PHASE = "Phase"
SERIES = "Scenario"
MAIN = "Main"
# Flag
NA = "-"
OTHERS = "Others"
[docs]
@classmethod
def num2str(cls, num):
"""
Convert numbers to 1st, 2nd etc.
Args:
num (int): number
Returns:
str
"""
num = Validator(num, "num").int(value_range=(0, None))
q, mod = divmod(num, 10)
suffix = "th" if q % 10 == 1 else cls.SUFFIX_DICT[mod]
return f"{num}{suffix}"
[docs]
@staticmethod
def str2num(string, name="phase names"):
"""
Convert 1st to 1 and so on.
Args:
string (str): like 1st, 2nd, 3rd,...
name (str): name of the string
Returns:
int
"""
try:
return int(string[:-2])
except ValueError as e:
raise ValueError(
f"Examples of {name} are 0th, 1st, 2nd..., but {string} was applied."
) from e
@classmethod
def _to_iso3(cls, name):
"""Convert country name(s) to ISO3 codes.
Args:
name (str or list[str] or None): country name(s)
Returns:
list[str]: ISO3 code(s)
Note:
"UK" will be converted to "GBR".
Note:
When the country was not found or None, it will not be converted.
Examples:
>>> Term._to_iso3("Japan")
['JPN']
>>> Term._to_iso3("UK")
['GBR']
>>> Term._to_iso3("Moon")
['Moon']
>>> Term._to_iso3(None)
['---']
>>> Term._to_iso3(["Japan", "UK", "Moon", None])
['JPN', 'GBR', 'Moon', '---']
"""
logging.basicConfig(level=logging.CRITICAL)
warnings.simplefilter("ignore", FutureWarning)
names = [name] if (isinstance(name, str) or name is None) else name
excepted_dict = {"UK": "GBR", None: cls.NA * 3}
code_dict = {
elem: excepted_dict[elem] if elem in excepted_dict else coco.convert(elem, to="ISO3", not_found=elem)
for elem in set(names)
}
return [code_dict[elem] for elem in names]
def _country_information(self):
"""Return the raw data of country_converter library raw data as a dataframe.
Returns:
pandas.DataFrame:
Index
reset index
Columns:
- name_short: standard or short names
- ISO2: ISO2 codes
- ISO3: ISO3 codes
- Continent: continent names
- the other columns listed in country_converter library homepage.
Note:
Refer to https://github.com/konstantinstadler/country_converter
"""
return coco.CountryConverter().data