[docs]classSweden(CountryTestBase):location="Sweden"units="tests performed"source_label="Swedish Public Health Agency"notes=""source_url="https://www.folkhalsomyndigheten.se/smittskydd-beredskap/utbrott/aktuella-utbrott/covid-19/statistik-och-analyser/antalet-testade-for-covid-19/"regex={"title":r"Antalet testade individer och genomförda test per","week":r"[vV]ecka (\d+)",}
[docs]defread(self)->pd.DataFrame:"""Reads data from source."""soup=get_soup(self.source_url)data=self._parse_data(soup)df=self._build_df(data)returndf
[docs]def_build_df(self,data:dict)->pd.DataFrame:"""Builds dataframe from data."""# Create dataframedf=pd.DataFrame([data])# Create date range (check week distance)dt_min=self._load_last_date()+timedelta(days=1)dt=clean_date(df.Date.max(),"%Y-%m-%d",as_datetime=True)if((days_diff:=(dt-dt_min).days)!=6)&(days_diff!=-1):raiseValueError(f"Date distance is no longer a week ({days_diff})! Please check.")ds=pd.Series(pd.date_range(dt-timedelta(days=6),dt).astype(str),name="Date")# Distribute week value over 7 daysdf=df.merge(ds,how="right")df=df.assign(**{"Source URL":self.source_url,"Daily change in cumulative total":round(df["Daily change in cumulative total"].bfill()),})returndf
[docs]def_parse_data(self,soup:BeautifulSoup)->list:"""Gets data from the source page."""# Extract the relevant elementelem=self._get_relevant_element(soup)# Get the week numberweek_num=self._get_week_num_from_element(elem)# Extract the text from the elementtext=self._get_text_from_element(elem)# Extract the metricsweekly_change=self._parse_metrics(text,week_num)# Parse datedate=self._parse_date(week_num)record={"Date":date,"Daily change in cumulative total":round(weekly_change/7),}returnrecord
[docs]def_get_relevant_element(self,soup:BeautifulSoup)->element.Tag:"""Gets element from the soup."""elem_list=soup.find_all("h2")elem=[titlefortitleinelem_listifself.regex["title"]intitle.text]elem=elem[0]ifnotelem:raiseTypeError("Website Structure Changed, please update the script")returnelem
[docs]def_get_week_num_from_element(self,elem:element.Tag)->int:"""Gets week number from element."""week_num=int(re.search(self.regex["week"],elem.text).group(1))ifweek_num==1:raiseValueError("Week 1: New Year, please update date in the script")returnweek_num
[docs]def_get_text_from_element(self,elem:element.Tag)->str:"""Gets text from element."""elem=elem.find_next_sibling("table").text.replace(" ","").replace("\n"," ")returnelem
[docs]def_parse_metrics(self,text:str,week_num)->int:"""Gets metrics from the text."""count=re.search(fr"[vV]ecka{week_num} \d+ (\d+)",text).group(1)returnclean_count(count)
[docs]def_parse_date(self,week_num)->Iterator:"""parses the date from the week number."""date=Week(2022,week_num,system="iso").enddate()returnclean_date(date)
[docs]def_load_last_date(self)->str:"""Loads the last date from the datafile."""df_current=self.load_datafile()date=df_current.Date.max()returnclean_date(date,"%Y-%m-%d",as_datetime=True)
[docs]defexport(self):"""Exports data to csv."""df=self.read().pipe(self.pipe_metadata)self.export_datafile(df,attach=True)