-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathapp.py
More file actions
137 lines (119 loc) · 4.47 KB
/
app.py
File metadata and controls
137 lines (119 loc) · 4.47 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
129
130
131
132
133
134
135
136
137
"""A simple recipe app CLI with persistent storage.
Features:
- Add, delete, and display recipes
- Persist recipes to `recipes.json`
"""
import json
import os
from typing import List
class Recipe:
def __init__(self, name: str, ingredients: List[str], instructions: List[str]):
self.name = name
self.ingredients = ingredients
self.instructions = instructions
def to_dict(self):
return {
"name": self.name,
"ingredients": self.ingredients,
"instructions": self.instructions,
}
class RecipeApp:
def __init__(self, data_file: str = "recipes.json"):
self.recipes: List[Recipe] = []
self.data_file = data_file
self.load_recipes()
def load_recipes(self):
if not os.path.exists(self.data_file):
return
try:
with open(self.data_file, "r", encoding="utf-8") as f:
data = json.load(f)
for item in data:
r = Recipe(
name=item.get("name", ""),
ingredients=item.get("ingredients", []),
instructions=item.get("instructions", []),
)
self.recipes.append(r)
except Exception:
# If loading fails, start with empty list (avoid crash on corrupt file)
self.recipes = []
def save_recipes(self):
data = [r.to_dict() for r in self.recipes]
try:
with open(self.data_file, "w", encoding="utf-8") as f:
json.dump(data, f, indent=2, ensure_ascii=False)
except Exception as e:
print(f"Error saving recipes: {e}")
def add_recipe(self, name: str, ingredients: List[str], instructions: List[str]):
if not name:
print("Recipe must have a name.")
return
# prevent duplicate names
if any(r.name.lower() == name.lower() for r in self.recipes):
print("A recipe with that name already exists.")
return
r = Recipe(name=name, ingredients=ingredients, instructions=instructions)
self.recipes.append(r)
self.save_recipes()
print(f"Added recipe '{name}'.")
def delete_recipe(self, name: str):
before = len(self.recipes)
self.recipes = [r for r in self.recipes if r.name.lower() != name.lower()]
if len(self.recipes) < before:
self.save_recipes()
print(f"Deleted recipe '{name}'.")
else:
print(f"No recipe named '{name}' was found.")
def display_recipes(self):
if not self.recipes:
print("No recipes available.")
return
for idx, r in enumerate(self.recipes, start=1):
print(f"{idx}. {r.name}")
print(" Ingredients:")
for ing in r.ingredients:
print(f" - {ing}")
print(" Instructions:")
for step_no, step in enumerate(r.instructions, start=1):
print(f" {step_no}. {step}")
print()
def _read_multiline(prompt: str) -> List[str]:
print(prompt)
lines: List[str] = []
while True:
line = input()
if line.strip().lower() == "done":
break
lines.append(line.strip())
return [l for l in lines if l]
def main():
app = RecipeApp()
try:
while True:
print("\nRecipe App")
print("1. Add Recipe")
print("2. Delete Recipe")
print("3. Display Recipes")
print("4. Quit")
choice = input("Enter your choice (1-4): ").strip()
if choice == "1":
name = input("Enter recipe name: ").strip()
raw_ings = input("Enter ingredients (comma-separated): ").strip()
ingredients = [i.strip() for i in raw_ings.split(",") if i.strip()]
instructions = _read_multiline("Enter instructions, one per line. Type 'done' on its own line when finished:")
app.add_recipe(name, ingredients, instructions)
elif choice == "2":
name = input("Enter recipe name to delete: ").strip()
app.delete_recipe(name)
elif choice == "3":
app.display_recipes()
elif choice == "4":
print("Goodbye.")
break
else:
print("Invalid choice. Please try again.")
except KeyboardInterrupt:
print("\nInterrupted. Exiting.")
if __name__ == "__main__":
main()