-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathentry.py
More file actions
128 lines (107 loc) · 4.6 KB
/
entry.py
File metadata and controls
128 lines (107 loc) · 4.6 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
'''
The data model for a daily entry into the journal.
Example:
Entry:
├── Date of meal: 07-19-2024
└── Meals:
├── Time: 04-01 PM
├── Original prompt: grilled chicken
├── Calories: 500
└── Macros: {'protein': 14.0, 'carbs': 0.0, 'sat_fat': 0.0, 'unsat_fat': 0.0, 'trans_fat': 0.0, 'fiber': 0.0, 'sugar': 0.0, 'sodium': 0.0, 'cholesterol': 0.0, 'other': 'n/a'}
│
├── Time: 04-01 PM
├── Original prompt: rice and beans
├── Calories: 700
└── Macros: {'protein': 0.0, 'carbs': 0.0, 'sat_fat': 0.0, 'unsat_fat': 0.0, 'trans_fat': 0.0, 'fiber': 0.0, 'sugar': 0.0, 'sodium': 0.0, 'cholesterol': 0.0, 'other': 'n/a'}
'''
import json
import os
from datetime import datetime
from typing import List, Dict, Optional, TypedDict
from pathlib import Path
class Macros(TypedDict):
protein: float
carbs: float
sat_fat: float
unsat_fat: float
trans_fat: float
fiber: float
sugar: float
sodium: float
cholesterol: float
other: str
def default_macros() -> Macros:
return {"protein": 0.0, "carbs": 0.0, "sat_fat": 0.0, "unsat_fat": 0.0, "trans_fat": 0.0, "fiber": 0.0, "sugar": 0.0, "sodium": 0.0, "cholesterol": 0.0, "other": "n/a"}
class Meal:
def __init__(self, time_of_meal: datetime, user_prompt: str, meal_name:Optional[str], calories: Optional[float] = 0, macros: Optional[Macros] = None) -> None:
self.time_of_meal: datetime = time_of_meal
self.user_prompt: str = user_prompt
self.calories: float = calories
self.meal_name: str = meal_name
# init macros
default_macro_values = default_macros()
if macros is None:
# default macros
self.macros = default_macro_values
else:
# overwrite default macros with partial/all provided macros
self.macros = Macros(**{**default_macro_values, **macros})
def to_dict(self) -> Dict:
return {
"time_of_meal": self.time_of_meal.isoformat(),
"user_prompt": self.user_prompt,
"meal_name": self.meal_name,
"calories": self.calories,
"macros": self.macros
}
@classmethod
def from_dict(cls, json_data: Dict) -> 'Meal':
return cls(
time_of_meal=json_data["time_of_meal"],
user_prompt=json_data["user_prompt"],
meal_name=json_data["meal_name"],
calories=json_data.get("calories", 0),
macros=json_data.get("macros", default_macros())
)
def __repr__(self) -> str:
return (f"\t├── Time: {self.time_of_meal.strftime('%I-%M %p')}\n\t├── Original prompt: {self.user_prompt}\n\t├── Meal Name: {self.meal_name}\n\t├── Calories: {self.calories}\n\t└── Macros: {self.macros}\n")
class Entry:
def __init__(self, date: datetime, meals: Optional[List[Meal]] = list()) -> None:
self.date: datetime = date
self.meals: List[Meal] = meals
def to_dict(self) -> Dict:
return {
"date": self.date.isoformat(),
"meals": [meal.to_dict() for meal in self.meals]
}
def save_json(self) -> None:
entry_dict = self.to_dict()
filename = f"entry_{self.date.strftime('%Y%m%d_%H%M%S')}.json"
with Path(os.path.join("./static/", filename)).open('w', encoding='utf-8') as f:
json.dump(entry_dict, f, indent=2, ensure_ascii=False)
@classmethod
def from_dict(cls, json_data: Dict) -> 'Entry':
return cls(
date=json_data["date"],
meals=[Meal.from_dict(meal) for meal in json_data.get("meals", [])]
)
def __repr__(self) -> str:
meals = "\t│\n".join(repr(meal) for meal in self.meals)
return (f"Entry:\n├── Date of meal: {self.date.strftime('%m-%d-%Y')}\n└── Meals:\n{meals}\n")
if __name__ == "__main__":
# Example
# Serializing and deserializing data to and from JSON
# Create a new entry consisting of two meals
entry = Entry(date=datetime.now(), meals=[
Meal(time_of_meal=datetime.now(), user_prompt="grilled chicken", calories=500, macros=Macros(protein=14.0)),
Meal(time_of_meal=datetime.now(), user_prompt="rice and beans", calories=700)
])
# Save json locally
entry.save_json()
# Serialize Entry object into JSON string
entry_json = json.dumps(entry.to_dict(), indent=4)
print(entry_json)
# Deserialize JSON string into Entry object
entry_dict = json.loads(entry_json)
new_entry = Entry.from_dict(entry_dict)
print(new_entry)