diff --git a/mypy.ini b/mypy.ini new file mode 100644 index 0000000..5c141a2 --- /dev/null +++ b/mypy.ini @@ -0,0 +1,8 @@ +[mypy] +python_version = 3.13 +ignore_missing_imports = True +disallow_untyped_defs = False +strict_optional = True + +[mypy-ssb_konjunk.dash.components.__init__] +ignore_errors = True diff --git a/pyproject.toml b/pyproject.toml index 292ef60..aed6459 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [project] name = "ssb-konjunk" -version = "2.1.4" +version = "2.1.5" description = "SSB Konjunk 422" authors = [ {name = "Johanne Saxegaard", email = "jox@ssb.no"}, diff --git a/src/ssb_konjunk/dash/calculations/calc_data.py b/src/ssb_konjunk/dash/calculations/calc_data.py index 5081f68..f1b99ee 100644 --- a/src/ssb_konjunk/dash/calculations/calc_data.py +++ b/src/ssb_konjunk/dash/calculations/calc_data.py @@ -184,7 +184,7 @@ def get_nacer(self) -> list[str]: """ return self.data["nar"].unique().tolist() # pyright: ignore - def add_klass_codes(self, data: pd.DataFrame, on: str) -> pd.dataframe: + def add_klass_codes(self, data: pd.DataFrame, on: str) -> pd.DataFrame: """Legger til klassifikasjonsnavn til et datasett basert på en spesifisert kolonne. Slår opp koder fra `self.class_codes` og legger til fullstendige navn i en ny kolonne, @@ -235,11 +235,11 @@ def sort_aggregates(index: pd.Series) -> pd.Series: else: hierarchal_aggregates[key] - for key in sorted(map(int, hierarchal_aggregates.keys())): - main_aggregate.append(f"{key}") + for key_int in sorted(map(int, hierarchal_aggregates.keys())): + main_aggregate.append(f"{key_int}") main_aggregate.extend( - f"{key}.{sub}" - for sub in sorted(map(int, hierarchal_aggregates[str(key)])) + f"{key_int}.{sub}" + for sub in sorted(map(int, hierarchal_aggregates[str(key_int)])) ) mapper = {item: idx for idx, item in enumerate(main_aggregate)} @@ -256,7 +256,7 @@ def get_all_periods(self) -> list[str]: """ return [item.as_period() for item in self.periods.create_period_range(12)] - def format_aggregates(self, data: pd.Series) -> pd.series: + def format_aggregates(self, data: pd.Series) -> pd.Series: """Formaterer hierarkiske aggregeringskoder med innrykk. Bruker `pad_single` for å legge til visuelt innrykk basert på hierarkinivå diff --git a/src/ssb_konjunk/dash/calculations/helper_functions.py b/src/ssb_konjunk/dash/calculations/helper_functions.py index 56041f5..57ee2a6 100644 --- a/src/ssb_konjunk/dash/calculations/helper_functions.py +++ b/src/ssb_konjunk/dash/calculations/helper_functions.py @@ -395,7 +395,7 @@ def rounded_average(df: pd.DataFrame, ordered_columns: list[str]) -> pd.Series: def calc_change_rate( df: pd.DataFrame, ordered_columns: list[str], n: int = 1 -) -> pd.dateframe: +) -> pd.DataFrame: """Beregner prosentvis endring mellom kolonner over n perioder. Args: @@ -416,7 +416,7 @@ def calc_change_rate( return pd.concat(results, axis="columns", keys=ordered_columns[n:]) -def rolling_change_rate(df: pd.DataFrame, step: int = 1) -> pd.dateframe: +def rolling_change_rate(df: pd.DataFrame, step: int = 1) -> pd.DataFrame: """Beregner rullende prosentvis endring mellom kolonner med gitt steg. Args: diff --git a/src/ssb_konjunk/dash/calculations/period_utils.py b/src/ssb_konjunk/dash/calculations/period_utils.py index cc6e2a5..0ab19ea 100644 --- a/src/ssb_konjunk/dash/calculations/period_utils.py +++ b/src/ssb_konjunk/dash/calculations/period_utils.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from functools import total_ordering from typing import Self @@ -69,7 +71,7 @@ def as_string(self) -> str: return f"{month} {year}" def set_period( - self, + self: Self, year: int | None = None, month: int | None = None, day: int | None = None, @@ -99,40 +101,57 @@ def as_datetime(self) -> pendulum.DateTime: """ return self.period - def _is_valid_operand(self: "Period", other: "Period"): - return hasattr(other, "period") - - def subtract( - self: "Period", - years: int = 0, - months: int = 0, - weeks: int = 0, - days: int = 0, - hours: int = 0, - minutes: int = 0, - seconds: float = 0, - microseconds: int = 0, - ): - return Period.from_dt( - self.period.subtract( - years, months, weeks, days, hours, minutes, seconds, microseconds - ) + def subtract( + self: Self, + years: int = 0, + months: int = 0, + weeks: int = 0, + days: int = 0, + hours: int = 0, + minutes: int = 0, + seconds: float = 0, + microseconds: int = 0, + ) -> Period: + """Trekker fra angitte tidskomponenter fra denne perioden og returnerer en ny `Period`. + + Parametere: + years (int): Antall år å trekke fra. Standard 0. + months (int): Antall måneder å trekke fra. Standard 0. + weeks (int): Antall uker å trekke fra. Standard 0. + days (int): Antall dager å trekke fra. Standard 0. + hours (int): Antall timer å trekke fra. Standard 0. + minutes (int): Antall minutter å trekke fra. Standard 0. + seconds (float): Antall sekunder å trekke fra (kan være flyttall). Standard 0. + microseconds (int): Antall mikrosekunder å trekke fra. Standard 0. + + Returnerer: + Period: En ny periode der de oppgitte komponentene er trukket fra. + + Merknader: + - Alle parametere er valgfrie; 0 betyr ingen endring for komponenten. + - Negativt tall vil i praksis legge til tilsvarende tid. + """ + return Period.from_dt( + self.period.subtract( + years, months, weeks, days, hours, minutes, seconds, microseconds ) + ) def __hash__(self) -> int: """Returnerer has verdien til objectet.""" return hash(str(self)) - def __eq__(self, other: "Period") -> bool: + def __eq__(self, other: object) -> bool: """Sjekker om dette objektet er likt et annet basert på perioden.""" - if not self._is_valid_operand(other): + if not isinstance(other, type(self)): return NotImplemented + return self.period == other.period return self.period == other.period - def __lt__(self, other: "Period") -> bool: + def __lt__(self, other: object) -> bool: """Sjekker om dette objektets periode er mindre enn et annet objekt sin periode.""" - if not self._is_valid_operand(other): + if not isinstance(other, type(self)): return NotImplemented return self.period < other.period @@ -248,19 +267,6 @@ def __str__(self) -> str: return f"AllPeriods<{[str(item) for item in self.periods]}>" -def _pad_month(month: int) -> str: - """Funksjonen gjør om ett- og tosifrete ints til str med en null foran hvis input bare er ett siffer. - - Args: - month: int, ett eller to siffer. - - Returns: - str - - """ - return f"{month:02d}" - - def period_parser(year: int, month: int) -> str: """Lager en periodestreng i formatet 'YYYYMmm' fra år og måned. @@ -271,8 +277,7 @@ def period_parser(year: int, month: int) -> str: Returns: str: Periodestreng, f.eks. '2026M03'. """ - month = _pad_month(month) - return f"{year}M{month}" + return f"{year}M{month:02d}" def create_period_range_list(year: int, month: int, n_months: int) -> list[str]: diff --git a/src/ssb_konjunk/dash/components/__init__.py b/src/ssb_konjunk/dash/components/__init__.py index 88868d7..95c1108 100644 --- a/src/ssb_konjunk/dash/components/__init__.py +++ b/src/ssb_konjunk/dash/components/__init__.py @@ -1,3 +1,4 @@ +# mypy: ignore-errors """Components to use in the dash app.""" from typing import Any diff --git a/src/ssb_konjunk/dash/components/page_aio.py b/src/ssb_konjunk/dash/components/page_aio.py index e7024e2..2db27e8 100644 --- a/src/ssb_konjunk/dash/components/page_aio.py +++ b/src/ssb_konjunk/dash/components/page_aio.py @@ -37,7 +37,7 @@ class ReturnData: class Tables: """Dataclass to define how a table and graph should be constructed.""" - getter_function: Callable[[str | None, int | None], ReturnData] + getter_function: Callable[[str | None, str | None], ReturnData] table_header: str figure_header: str diff --git a/src/ssb_konjunk/dash/utils.py b/src/ssb_konjunk/dash/utils.py index c23f504..0935fc9 100644 --- a/src/ssb_konjunk/dash/utils.py +++ b/src/ssb_konjunk/dash/utils.py @@ -1,19 +1,22 @@ +import shutil +import tempfile from functools import cache +from pathlib import Path from typing import Any +import ssb_konjunk from ssb_konjunk.dash.calculations.calc_data import DataManager from ssb_konjunk.dash.calculations.calc_data import get_data_manager _config = None + def setup(config: type[Any]) -> None: """Setter global konfigurasjon for modulen. Args: config (type[Config]): Klassen som inneholder konfigurasjonsinnstillinger. """ -def setup(config) -> None: - global _config _config = config @@ -64,11 +67,10 @@ def dropdown_getter(file: str | None = None) -> list[dict[str, str]]: ] return dropdown_data - + @cache def get_assets_folder() -> str: - """ - Lager en temp mappe som har assets fra pakken og assets lokalt. + """Lager en temp mappe som har assets fra pakken og assets lokalt. lokale assets overskriver pakke assets. @@ -77,7 +79,7 @@ def get_assets_folder() -> str: """ package_assets = Path(ssb_konjunk.__file__).parent / "dash" / "assets" local_assets = Path("dash/assets") - + combined = Path(tempfile.mkdtemp(prefix="dash_assets_")) if package_assets.exists(): @@ -85,5 +87,5 @@ def get_assets_folder() -> str: if local_assets.exists(): shutil.copytree(local_assets, combined, dirs_exist_ok=True) - - return str(combined) \ No newline at end of file + + return str(combined)