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