Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- import random
- import json
- import os
- import re
- from collections import defaultdict
- import logging
- from kivy.app import App
- from kivy.uix.label import Label
- from kivy.uix.button import Button
- from kivy.uix.boxlayout import BoxLayout
- from kivy.uix.scrollview import ScrollView
- from kivy.uix.textinput import TextInput
- from kivy.uix.popup import Popup
- from kivy.uix.image import Image
- from kivy.uix.floatlayout import FloatLayout
- # Configure logging
- logging.basicConfig(filename='app.log', level=logging.DEBUG, format='%(asctime)s - %(levelname)s - %(message)s')
- class RecipeApp(App):
- def build(self):
- try:
- self.recipes = self.load_recipes()
- self.layout = FloatLayout()
- self.background = Image(source='background.jpg', allow_stretch=True, keep_ratio=False)
- self.layout.add_widget(self.background)
- self.main_layout = BoxLayout(orientation='vertical', padding=10, spacing=10, size_hint=(0.8, 0.8))
- self.main_layout.pos_hint = {'center_x': 0.5, 'center_y': 0.5}
- button_layout = BoxLayout(orientation='horizontal', size_hint_y=None, height=50, spacing=10)
- self.add_recipe_button = Button(text="Add Recipe", size_hint=(0.3, 1), background_color=(0, 0.5, 0.5, 1))
- self.add_recipe_button.bind(on_press=self.show_add_recipe_form)
- button_layout.add_widget(self.add_recipe_button)
- self.remove_recipe_button = Button(text="Remove Recipe", size_hint=(0.3, 1), background_color=(0.5, 0, 0, 1))
- self.remove_recipe_button.bind(on_press=self.show_remove_recipe_list)
- button_layout.add_widget(self.remove_recipe_button)
- self.generate_list_button = Button(text="Generate Shopping List", size_hint=(0.4, 1), background_color=(0.5, 0.5, 0, 1))
- self.generate_list_button.bind(on_press=self.generate_shopping_list)
- button_layout.add_widget(self.generate_list_button)
- self.main_layout.add_widget(button_layout)
- self.recipe_display = ScrollView(size_hint=(1, 1))
- self.recipe_label = Label(size_hint_y=None, text='', text_size=(None, None), valign='top', halign='left', color=(1, 1, 1, 1))
- self.recipe_label.bind(texture_size=self._update_label_height)
- self.recipe_display.add_widget(self.recipe_label)
- self.main_layout.add_widget(self.recipe_display)
- self.layout.add_widget(self.main_layout)
- self.update_recipe_display()
- return self.layout
- except Exception as e:
- logging.exception("Error during build")
- def _update_label_height(self, instance, value):
- instance.height = instance.texture_size[1]
- instance.width = instance.texture_size[0]
- def load_recipes(self):
- try:
- if os.path.exists('recipes.json'):
- with open('recipes.json', 'r') as f:
- return json.load(f)
- else:
- return {} # Start with an empty dictionary if no recipes.json file exists
- except Exception as e:
- logging.exception("Error loading recipes")
- return {}
- def save_recipes(self):
- try:
- with open('recipes.json', 'w') as f:
- json.dump(self.recipes, f)
- except Exception as e:
- logging.exception("Error saving recipes")
- def show_add_recipe_form(self, instance):
- try:
- layout = BoxLayout(orientation='vertical', padding=10, spacing=10)
- self.recipe_name_input = TextInput(hint_text='Recipe Name', size_hint_y=None, height=30)
- self.recipe_ingredients_input = TextInput(hint_text='Ingredients (comma separated)', size_hint_y=None, height=100)
- layout.add_widget(self.recipe_name_input)
- layout.add_widget(self.recipe_ingredients_input)
- submit_button = Button(text='Submit', size_hint_y=None, height=40, background_color=(0, 0.5, 0, 1))
- submit_button.bind(on_press=self.add_recipe)
- layout.add_widget(submit_button)
- self.popup = Popup(title='Add Recipe', content=layout, size_hint=(0.8, 0.8))
- self.popup.open()
- except Exception as e:
- logging.exception("Error showing add recipe form")
- def add_recipe(self, instance):
- try:
- recipe_name = self.recipe_name_input.text
- ingredients_text = self.recipe_ingredients_input.text
- ingredients = [ingredient.strip() for ingredient in ingredients_text.split(',')]
- self.recipes[recipe_name] = ingredients
- self.save_recipes()
- self.popup.dismiss()
- self.update_recipe_display()
- except Exception as e:
- logging.exception("Error adding recipe")
- def show_remove_recipe_list(self, instance):
- try:
- layout = BoxLayout(orientation='vertical', padding=10, spacing=10)
- for recipe in self.recipes.keys():
- recipe_layout = BoxLayout(orientation='horizontal', size_hint_y=None, height=40)
- recipe_label = Label(text=recipe, size_hint_x=0.8, color=(1, 1, 1, 1)) # Text color set to white
- remove_button = Button(text='Remove', size_hint_x=0.2, background_color=(0.5, 0, 0, 1))
- remove_button.bind(on_press=lambda btn, r=recipe: self.remove_recipe(r))
- recipe_layout.add_widget(recipe_label)
- recipe_layout.add_widget(remove_button)
- layout.add_widget(recipe_layout)
- self.popup = Popup(title='Remove Recipe', content=layout, size_hint=(0.8, 0.8))
- self.popup.open()
- except Exception as e:
- logging.exception("Error showing remove recipe list")
- def remove_recipe(self, recipe_name):
- try:
- if recipe_name in self.recipes:
- del self.recipes[recipe_name]
- self.save_recipes()
- self.popup.dismiss()
- self.update_recipe_display()
- except Exception as e:
- logging.exception("Error removing recipe")
- def update_recipe_display(self):
- try:
- display_text = "Recipes:\n"
- for recipe, ingredients in self.recipes.items():
- display_text += f"\n{recipe}:\n"
- for ingredient in ingredients:
- display_text += f"{ingredient}\n"
- self.recipe_label.text = display_text
- except Exception as e:
- logging.exception("Error updating recipe display")
- def generate_shopping_list(self, instance):
- try:
- if len(self.recipes) < 2:
- logging.warning("Not enough recipes to generate a shopping list.")
- return
- selected_recipes = random.sample(list(self.recipes.items()), 2)
- display_text = "Selected Recipes:\n"
- for recipe, ingredients in selected_recipes:
- display_text += f"\n{recipe}:\n"
- for ingredient in ingredients:
- display_text += f"{ingredient}\n"
- all_ingredients = defaultdict(float)
- for recipe, ingredients in selected_recipes:
- for ingredient in ingredients:
- quantity, item = self.parse_ingredient(ingredient)
- all_ingredients[item] += quantity
- # Debugging: print all ingredients and quantities
- logging.debug(f"All ingredients combined: {dict(all_ingredients)}")
- shopping_list_text = "Shopping List:\n\n"
- for item, quantity in all_ingredients.items():
- shopping_list_text += f"{quantity} {item}\n"
- self.show_shopping_list_popup(display_text + "\n\n" + shopping_list_text)
- except Exception as e:
- logging.exception("Error generating shopping list")
- def parse_ingredient(self, ingredient):
- try:
- logging.debug(f"Parsing ingredient: {ingredient}")
- # Check if the ingredient starts with a number
- match = re.match(r'(\d*\.?\d*)\s*(.*)', ingredient)
- if match:
- quantity_str, item = match.groups()
- quantity = float(quantity_str) if quantity_str else 1 # Default quantity to 1 if not specified
- item = item.strip()
- logging.debug(f"Parsed quantity: {quantity}, item: {item}")
- return quantity, item
- else:
- logging.debug(f"No quantity found, default to 1 for item: {ingredient.strip()}")
- return 1, ingredient.strip() # Default quantity is 1 if no number is found
- except Exception as e:
- logging.exception("Error parsing ingredient")
- return 1, ingredient.strip() # Default quantity is 1 in case of error
- def show_shopping_list_popup(self, text):
- try:
- layout = BoxLayout(orientation='vertical', padding=10, spacing=10)
- shopping_list_label = Label(text=text, size_hint_y=None, height=400, text_size=(None, None), valign='top', halign='left', color=(1, 1, 1, 1))
- shopping_list_label.bind(texture_size=self._update_label_height)
- scroll_view = ScrollView()
- scroll_view.add_widget(shopping_list_label)
- layout.add_widget(scroll_view)
- close_button = Button(text='Close', size_hint_y=None, height=40, background_color=(0.5, 0, 0, 1))
- close_button.bind(on_press=self.close_popup)
- layout.add_widget(close_button)
- self.popup = Popup(title='Shopping List', content=layout, size_hint=(0.8, 0.8))
- self.popup.open()
- except Exception as e:
- logging.exception("Error showing shopping list popup")
- def close_popup(self, instance):
- try:
- self.popup.dismiss()
- except Exception as e:
- logging.exception("Error closing popup")
- if __name__ == '__main__':
- RecipeApp().run()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement