Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added recipe finder and red black tree #911

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,180 @@
import time
import matplotlib.pyplot as plt
import networkx as nx

# RBNode class with Red-Black Tree node properties
class RBNode:
def __init__(self, value, color='red', parent=None):
self.value = value
self.color = color
self.parent = parent
self.left = None
self.right = None

def sibling(self):
if self.parent:
if self == self.parent.left:
return self.parent.right
return self.parent.left
return None

class RedBlackTree:
def __init__(self):
self.root = None

def measure_operation_time(self, func, *args):
start_time = time.time()
func(*args)
end_time = time.time()
elapsed_time = end_time - start_time
print(f"Time taken for operation: {elapsed_time:.6f} seconds")

# BST insert helper
def _bst_insert(self, root, node):
if node.value < root.value:
if root.left:
self._bst_insert(root.left, node)
else:
root.left = node
node.parent = root
else:
if root.right:
self._bst_insert(root.right, node)
else:
root.right = node
node.parent = root

# Insert node and fix violations
def insert(self, value):
new_node = RBNode(value)
if not self.root:
self.root = new_node
self.root.color = 'black'
else:
self._bst_insert(self.root, new_node)
self.insert_fix(new_node)
print(f"Inserted {value} into the tree.")

def insert_fix(self, node):
# Placeholder for balancing the tree after insertion
pass

def delete(self, value):
node_to_remove = self.search(value)
if not node_to_remove:
print(f"Value {value} not found in the tree.")
return
# Deletion and balancing logic here
print(f"Deleted {value} from the tree.")
self.delete_fix(node_to_remove)

def delete_fix(self, node):
# Placeholder for balancing the tree after deletion
pass

def search(self, value):
current = self.root
while current:
if current.value == value:
print(f"Found {value} in the tree.")
return current
elif value < current.value:
current = current.left
else:
current = current.right
print(f"Value {value} not found in the tree.")
return None

# Traversal methods
def inorder_traversal(self, node):
if node:
self.inorder_traversal(node.left)
print(f"{node.value}({node.color})", end=" ")
self.inorder_traversal(node.right)

def preorder_traversal(self, node):
if node:
print(f"{node.value}({node.color})", end=" ")
self.preorder_traversal(node.left)
self.preorder_traversal(node.right)

def postorder_traversal(self, node):
if node:
self.postorder_traversal(node.left)
self.postorder_traversal(node.right)
print(f"{node.value}({node.color})", end=" ")

# Calculate tree height
def tree_height(self, node):
if not node:
return 0
return 1 + max(self.tree_height(node.left), self.tree_height(node.right))

# Display function using matplotlib
def display_tree(self):
G = nx.DiGraph()
def add_edges(node):
if node:
G.add_node(node.value, color=node.color)
if node.left:
G.add_edge(node.value, node.left.value)
add_edges(node.left)
if node.right:
G.add_edge(node.value, node.right.value)
add_edges(node.right)

add_edges(self.root)
pos = nx.spring_layout(G)
color_map = ['red' if G.nodes[node]['color'] == 'red' else 'black' for node in G.nodes]
nx.draw(G, pos, node_color=color_map, with_labels=True)
plt.show()

# Main function for user interaction
def main():
rb_tree = RedBlackTree()
while True:
print("\nChoose an operation:")
print("1. Insert")
print("2. Delete")
print("3. Search")
print("4. Display Tree")
print("5. Inorder Traversal")
print("6. Preorder Traversal")
print("7. Postorder Traversal")
print("8. Tree Height")
print("9. Exit")

choice = input("Enter choice: ")
if choice == '1':
value = int(input("Enter value to insert: "))
rb_tree.measure_operation_time(rb_tree.insert, value)
elif choice == '2':
value = int(input("Enter value to delete: "))
rb_tree.measure_operation_time(rb_tree.delete, value)
elif choice == '3':
value = int(input("Enter value to search: "))
rb_tree.measure_operation_time(rb_tree.search, value)
elif choice == '4':
rb_tree.display_tree()
elif choice == '5':
print("Inorder Traversal:")
rb_tree.inorder_traversal(rb_tree.root)
print()
elif choice == '6':
print("Preorder Traversal:")
rb_tree.preorder_traversal(rb_tree.root)
print()
elif choice == '7':
print("Postorder Traversal:")
rb_tree.postorder_traversal(rb_tree.root)
print()
elif choice == '8':
height = rb_tree.tree_height(rb_tree.root)
print(f"Tree Height: {height}")
elif choice == '9':
break
else:
print("Invalid choice. Please select again.")

if __name__ == "__main__":
main()
1 change: 1 addition & 0 deletions Algorithms_and_Data_Structures/Trees/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ Algorithms_and_Data_Structures/
│ ├── Menu_Driven_Code_for_Tree_Traversals.py
│ ├── Menu_Driven_Code_for_DFS.py
│ ├── Menu_Driven_Code_for_Prefix_Tree.py
| ├── Menu_Driven_Code_For_RedBlack_Tree.py
│ ├── README.md


Expand Down
50 changes: 50 additions & 0 deletions Beginner_Projects/Recipe_Finder/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
# Recipe Finder Using Tkinter

## Overview

This project is a simple **Recipe Finder** built using **Tkinter**, a GUI library in Python. The application allows users to input ingredients they have at home and find suitable recipes. It uses the Spoonacular API to fetch and display recipes based on the provided ingredients.

## Features

- **Graphical User Interface (GUI):** The interface allows users to easily input ingredients and view corresponding recipe suggestions.
- **Recipe Search:** Users can enter a list of ingredients, and the application retrieves recipes that can be made with those ingredients.
- **Clickable Recipe Links:** The application provides links to actual recipes on the Spoonacular website, allowing users to view detailed instructions and ingredients.

## How It Works

1. **Spoonacular API:**
- The application utilizes the Spoonacular API to access a large database of recipes. The API requires an API key for access, which must be included in the code.

2. **Tkinter GUI:**
- The GUI is built using `Tkinter`, featuring an input field for entering ingredients and a button to initiate the recipe search.
- Upon clicking the "Find Recipes" button, the application sends a request to the Spoonacular API with the specified ingredients.

3. **Displaying Recipes:**
- The results are displayed in a new window, showing the titles of the recipes. Each recipe title is a clickable link that opens the corresponding recipe in a web browser.

## How to Run the Project

1. Clone the repository or download the project files.
2. Ensure you have Python 3.x installed on your machine.
3. Install the required libraries using pip:
```bash
pip install requests
```
4. Replace the placeholder API key in the script with your Spoonacular API key.
5. Run the `recipe_finder.py` script using Python:
```bash
python recipe_finder.py
```
6. Enter ingredients separated by commas in the input box and click "Find Recipes." The application will display recipe suggestions.

## Requirements

- Python 3.x
- Tkinter library (included with Python)
- `requests` library (install via pip)

## Future Enhancements

- **Save Favorite Recipes:** Allow users to save their favorite recipes for quick access.
- **Ingredient Suggestions:** Provide suggestions for recipes based on partial ingredients or commonly available items.
- **User Accounts:** Implement user accounts to save preferences and custom ingredient lists.
60 changes: 60 additions & 0 deletions Beginner_Projects/Recipe_Finder/recipe_finder.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
import requests
import tkinter as tk
from tkinter import messagebox
import webbrowser

def find_recipes(ingredients):
SPOONACULAR_API_KEY = 'feb01116afe3415cb6cca75636a799d8'
url = f'https://api.spoonacular.com/recipes/findByIngredients?ingredients={ingredients}&apiKey={SPOONACULAR_API_KEY}'

response = requests.get(url)

if response.status_code == 200:
return response.json()
else:
messagebox.showerror("Error", "Failed to retrieve recipes.")
return []

def open_recipe(url):
webbrowser.open(url)

def display_recipes(recipes):
# Create a popup window with a specified size
recipe_window = tk.Toplevel()
recipe_window.title("Recipe Results")
recipe_window.geometry("500x400") # Set the size of the popup window (width x height)

for recipe in recipes:
recipe_name = recipe['title']
recipe_url = f"https://spoonacular.com/recipes/{recipe['id']}-{recipe_name.replace(' ', '-')}"

recipe_link = tk.Label(recipe_window, text=recipe_name, fg="blue", cursor="hand2")
recipe_link.pack(pady=10)

# Bind click event to open the recipe URL
recipe_link.bind("<Button-1>", lambda e, url=recipe_url: open_recipe(url))

def search_recipes():
ingredients = ingredients_entry.get() # Get ingredients from the entry field
if ingredients:
recipes = find_recipes(ingredients)
display_recipes(recipes)

# Create the main window
root = tk.Tk()
root.title("Recipe Finder")
root.geometry("500x300") # Increase the size of the main window

# Set a colorful background
root.configure(bg="#6A5ACD")

# Ingredients input
tk.Label(root, text="Enter ingredients (comma-separated):", bg="#ffffff", font=("Helvetica", 14)).pack(pady=10)
ingredients_entry = tk.Entry(root, width=40, font=("Helvetica", 14), bg="#FFE4B5") # Light lemon chiffon color
ingredients_entry.pack(pady=50)

# Search button
search_button = tk.Button(root, text="Find Recipes", command=search_recipes, bg="#90EE90", font=("Helvetica", 14)) # Light green color
search_button.pack(pady=20)

root.mainloop()
Loading