treker/core

103 lines
3.9 KiB
Plaintext
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

from datetime import date, datetime
class HarmCalculator:
harms = {
"Никотин": {"сигарета": 11, "стик": 5, "тяжка": 3},
"Алкоголь": {"бутылка (500мл)": 15, "банка (500мл)": 12, "бокал (150мл)": 8, "рюмка (50мл)": 28, "глоток (30мл)": 4, "порция (250мл)": 18},
"Кофе": {"чашка (200мл)": 1, "стакан (350мл)": 1.5, "глоток (30мл)": 0.2, "порция (200мл)": 1},
"Энергетики": {"банка (250мл)": 2, "банка (330мл)": 3, "банка (500мл)": 5},
}
icons = {"Никотин": "🚬", "Алкоголь": "🍷", "Кофе": "☕", "Энергетики": "⚡"}
colors = {"Никотин": "#8fb0d9", "Алкоголь": "#f0a2bc", "Кофе": "#c8a07a", "Энергетики": "#7ea8ff"}
gender_mult = {"Мужской": 1.0, "Женский": 1.2, "М": 1.0, "Ж": 1.2}
def __init__(self, gender="Мужской", age=20):
self.gender = gender
self.age = age
def set_profile(self, gender, age):
self.gender = gender
self.age = age
def age_mult(self, age):
if age < 18: return 0.9
if age < 25: return 0.95
if age < 40: return 1.0
if age < 60: return 1.2
return 1.5
def calc_one(self, kind, unit, qty):
base = self.harms[kind][unit]
g = self.gender_mult.get(self.gender, 1.0)
a = self.age_mult(self.age)
return base * qty * g * a
def calc_total(self, hist):
total = 0
for e in hist:
total += self.calc_one(e["kind"], e["unit"], e["qty"])
return total
def fmt_time(self, mins):
if mins < 60: return f"{int(mins)} мин"
if mins < 1440: return f"{mins/60:.1f} ч"
if mins < 43200: return f"{mins/1440:.2f} дн"
return f"{mins/43200:.2f} мес"
def fmt_timer(self, mins):
h = int(mins // 60)
m = int(mins % 60)
s = int((mins * 60) % 60)
return f"{h:02d}:{m:02d}:{s:02d}"
def get_units(self, kind):
return list(self.harms.get(kind, {}).keys())
def get_config(self, kind):
return {
"icon": self.icons.get(kind, "📌"),
"color": self.colors.get(kind, "#cccccc"),
"units": self.get_units(kind),
}
def period_harm(self, hist, period="day"):
today = date.today()
filt = []
for e in hist:
d = datetime.fromisoformat(e["date"]).date()
if period == "day" and d == today:
filt.append(e)
elif period == "month" and d.year == today.year and d.month == today.month:
filt.append(e)
elif period == "year" and d.year == today.year:
filt.append(e)
elif period == "all":
filt.append(e)
return self.calc_total(filt), len(filt)
def days_with_harms(self, hist, year, month):
days = {}
for e in hist:
d = datetime.fromisoformat(e["date"]).date()
if d.year == year and d.month == month:
h = self.calc_one(e["kind"], e["unit"], e["qty"])
days[d.day] = days.get(d.day, 0) + h
return days
def summary(self, hist):
day = self.period_harm(hist, "day")
month = self.period_harm(hist, "month")
year = self.period_harm(hist, "year")
allt = self.period_harm(hist, "all")
return {
"day": {"mins": day[0], "fmt": self.fmt_time(day[0]), "cnt": day[1]},
"month": {"mins": month[0], "fmt": self.fmt_time(month[0]), "cnt": month[1]},
"year": {"mins": year[0], "fmt": self.fmt_time(year[0]), "cnt": year[1]},
"all": {"mins": allt[0], "fmt": self.fmt_time(allt[0]), "cnt": allt[1]},
}
def to_days(self, mins):
return mins / 1440