Source code for lories.simulation.durations

# -*- coding: utf-8 -*-
"""
lories.simulation.durations
~~~~~~~~~~~~~~~~~~~~~~~~~~~


"""

from __future__ import annotations

import datetime as dt
import json
import os
from collections.abc import Mapping
from typing import Iterator

from lories import Directory


[docs] class Durations(Mapping): # noinspection PyShadowingBuiltins def __init__(self, dir: Directory) -> None: self._durations = {} self._file = os.path.join(dir, "durations.json") if os.path.isfile(self._file): with open(self._file, "r", encoding="utf-8") as f: self._durations = json.load(f) for duration in self._durations.values(): def get_duration(key): return dt.datetime.strptime(duration[key], "%Y-%m-%d %H:%M:%S.%f") if "start" in duration: duration["start"] = get_duration("start") if "end" in duration: duration["end"] = get_duration("end") def __repr__(self) -> str: return str(self._durations) def __iter__(self) -> Iterator: return iter(self._durations) def __len__(self) -> int: return len(self._durations) def __getitem__(self, key: str) -> float: return self._durations[key]["minutes"] def start(self, key: str) -> None: if key not in self._durations: self._durations[key] = {} if "minutes" not in self._durations[key]: self._durations[key]["minutes"] = 0 if "complete" not in self._durations[key]: self._durations[key]["complete"] = False if not self._durations[key]["complete"]: if "end" in self._durations[key]: del self._durations[key]["end"] self._durations[key]["start"] = dt.datetime.now() def stop(self, key: str = None) -> None: for k in self.keys() if key is None else [key]: self._stop(k) self._write() def _stop(self, key: str = None) -> None: if key not in self._durations: raise ValueError('No duration found for key: "{}"'.format(key)) if "start" not in self._durations[key]: raise ValueError('Timer for key "{}" not started yet'.format(key)) self._durations[key]["end"] = dt.datetime.now() minutes = self._durations[key]["minutes"] if "minutes" in self._durations[key] else 0 minutes += round((self._durations[key]["end"] - self._durations[key]["start"]).total_seconds() / 60.0, 6) self._durations[key]["minutes"] = minutes # noinspection PyTypeChecker def _write(self) -> None: with open(self._file, "w", encoding="utf-8") as file: json.encoder.FLOAT_REPR = lambda o: format(o, ".3f") json.dump(self._durations, file, indent=4, default=str, ensure_ascii=False) def complete(self) -> None: for key in self.keys(): self._durations[key]["complete"] = True self.stop(key) def is_complete(self) -> bool: return all(d["complete"] for d in self._durations.values())