#!/usr/bin/env python3 # -*- coding: utf-8 -*- from __future__ import annotations from typing import Union import math class Gradation: mg_per_liter: int def __init__(self, grams_per_liter: Union[float, int]): self.mg_per_liter = round(grams_per_liter * 1000) @property def grams_per_liter(self) -> float: return self.mg_per_liter / 1000 def get_nm(self) -> float: return self.grams_per_liter / 10 def get_kmw(self) -> float: return 0.732 * self.get_nm() + 3.2 def get_oe(self) -> float: return self.get_kmw() * (4.54 + 0.022 * self.get_kmw()) def get_be(self) -> float: return self.get_kmw() / 1.53 def get_bx(self) -> float: return self.get_be() / 0.55 @staticmethod def from_nm(nm: float) -> Gradation: return Gradation(nm * 10) @staticmethod def from_kmw(kmw: float) -> Gradation: return Gradation.from_nm((kmw - 3.2) / 0.732) @staticmethod def from_oe(oe: float) -> Gradation: return Gradation.from_kmw((-4.54 + math.sqrt(4.54 * 4.54 - 4 * 0.022 * -oe)) / (2 * 0.022)) def test(): g1 = Gradation.from_kmw(15) assert round(g1.get_kmw(), 1) == 15 assert round(g1.get_oe(), 0) == 73 for i in range(14 * 10, 22 * 10): kmw = i / 10 g2 = Gradation.from_kmw(kmw) assert kmw == round(g2.get_kmw(), 1), f"{kmw} != {g2.get_kmw():.1f}" def print_all(): for i in range(14 * 2, 22 * 2): kmw = i / 2 g = Gradation.from_kmw(kmw) print(f"{kmw} -> {g.get_kmw():.1f} °KMW, {g.get_oe():3.0f} °Oe, {g.get_nm():.1f} °NM, {g.grams_per_liter:.1f}") print("================================") for oe in range(65, 110): g = Gradation.from_oe(oe) print(f"{oe:3} -> {g.get_kmw():.1f} °KMW, {g.get_oe():3.0f} °Oe, {g.get_nm():.1f} °NM, {g.grams_per_liter:.1f}") if __name__ == '__main__': print_all() test()