Skip to content
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
107 changes: 78 additions & 29 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,29 +1,78 @@
# Shopping List Application (Tkinter)

A simple **Shopping List** application built with Python's Tkinter library. This app allows users to manage a shopping list by adding or removing items and calculating the total number of items.

## Maintainers
[Mehnaz Ali](https://github.com/Mehnaz2004)

## Features
- **Add Items:** Input items with amount, price, and assign them to a specific category.
- **Edit Items:** Update the quantity of an existing item.
- **Remove Items:** Delete items from the shopping list.
- **Display List:** View all items.
- **Category Assignment:** Save items under specific categories like Grocery, Electronics, etc.
- **Category Filter:** Filter items by category to view only items within a specific category.
- **Search Items:** Find items by name.
- **Calculate Total:** Display the total cost of all items.
- **Clear List:** Remove all items from the list.
- **Save/Load List:** Automatically save and load your shopping list from a JSON file.


## Technologies
- **Python**
- **Tkinter:** For the GUI.

## How to Run
1. Ensure Python is installed.
2. Run the script:
```bash
python shopping_list.py

<h1>Shopping List Application (Tkinter)</h1>
<p>A simple and intuitive <strong>Shopping List</strong> application built using Python's Tkinter library. This application allows users to add, edit, remove, and manage their shopping list while keeping track of categories, total costs, and much more.</p>

<h2>Features</h2>
<ul>
<li><strong>Add Items:</strong> Easily add items with quantity, price, and assign them to specific categories.</li>
<li><strong>Edit Items:</strong> Modify the quantity of items already present in the list.</li>
<li><strong>Remove Items:</strong> Delete unwanted items from the shopping list.</li>
<li><strong>Display List:</strong> View all items in your shopping list, with their respective quantities, prices, and categories.</li>
<li><strong>Category Assignment:</strong> Organize items by categories such as Grocery, Electronics, Household, etc.</li>
<li><strong>Category Filter:</strong> Filter items by categories to view only specific types of items.</li>
<li><strong>Search Items:</strong> Quickly find specific items using the search function.</li>
<li><strong>Calculate Total:</strong> Calculate the total cost of all the items in the shopping list.</li>
<li><strong>Clear List:</strong> Remove all items from the list with a single click.</li>
<li><strong>Save/Load List:</strong> Automatically save your shopping list to a JSON file and load it on startup.</li>
</ul>

<h2>Screenshots</h2>
<p><strong>Main Application UI:</strong></p>
<img src="link_to_screenshot.png" alt="App UI">
<p><strong>Filtered List:</strong></p>
<img src="link_to_screenshot_filtered.png" alt="Filtered List">

<h2>Technologies Used</h2>
<ul>
<li><strong>Python:</strong> Core programming language for the logic.</li>
<li><strong>Tkinter:</strong> For the Graphical User Interface (GUI).</li>
<li><strong>JSON:</strong> To save and load the shopping list data.</li>
</ul>

<h2>How to Run</h2>
<ol>
<li><strong>Ensure Python 3.x is installed</strong> on your system.</li>
<li><strong>Clone this repository:</strong>
<pre><code>git clone https://github.com/kamal126/shopping-list-app.git</code></pre>
</li>
<li><strong>Navigate to the project directory:</strong>
<pre><code>cd shopping-list-app</code></pre>
</li>
<li><strong>Install dependencies (optional):</strong>
<pre><code>pip install -r requirements.txt</code></pre>
<p>(Note: Tkinter usually comes pre-installed with Python, so you may not need additional dependencies.)</p>
</li>
<li><strong>Run the application:</strong>
<pre><code>python shopping_list.py</code></pre>
</li>
</ol>

<h2>How to Use</h2>
<ul>
<li><strong>Add Items:</strong> Enter the item name, quantity, and price, then select a category and click "Add Item".</li>
<li><strong>Edit Items:</strong> Select an item, change its quantity, and click "Edit Item" to update.</li>
<li><strong>Remove Items:</strong> Select an item and click "Remove Item" to delete it.</li>
<li><strong>Filter Items:</strong> Use the dropdown menu to filter by category.</li>
<li><strong>Search Items:</strong> Enter the name of the item in the search bar to find it in the list.</li>
<li><strong>Calculate Total:</strong> Click on the "Calculate Total" button to see the total cost of your items.</li>
<li><strong>Clear List:</strong> Click "Clear List" to remove all items.</li>
</ul>

<h2>File Structure</h2>
<pre><code>shopping-list-app/
├── shopping_list.py # Main Python script
├── shopping_list.json # JSON file that stores the shopping list data
├── README.md # Project documentation
├── requirements.txt # List of dependencies (if needed)
</code></pre>

<h2>Contributing</h2>
<p>Contributions are welcome! If you'd like to improve the project or fix any issues, feel free to fork the repository and submit a pull request.</p>

<h2>License</h2>
<p>This project is licensed under the <strong>MIT License</strong>. See the <a href="LICENSE">LICENSE</a> file for details.</p>

<h2>Maintainer</h2>
<p>Kamal Chandra</p>

161 changes: 78 additions & 83 deletions Shopping-list.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import tkinter as tk
from tkinter import messagebox, ttk
from tkinter import messagebox, ttk, filedialog
import json
import os
import csv

# Global variables
shopping_list = {}
Expand All @@ -12,7 +13,9 @@
combobox_category = None
combobox_filter = None
filename = "shopping_list.json"
undo_stack = []
categories = ["Grocery", "Stationery", "Electronics", "Household", "Clothing", "Other", "All"]
is_dark_mode = False

# Function to load shopping list from a JSON file
def load_list():
Expand Down Expand Up @@ -52,6 +55,7 @@ def add_item():
shopping_list[item][0] += amount # Update amount
else:
shopping_list[item] = [amount, price, category] # Store amount, price, and category
undo_stack.append(('add', item, amount)) # Add action to undo stack
clear_entries()
display_list(combobox_filter.get()) # Refresh the list with the current filter
save_list() # Save the list after adding
Expand All @@ -73,7 +77,9 @@ def edit_item():
if new_amount < 0:
raise ValueError("Negative values are not allowed.")
if item in shopping_list:
old_amount = shopping_list[item][0]
shopping_list[item][0] = new_amount # Update the item's amount
undo_stack.append(('edit', item, old_amount)) # Add action to undo stack
clear_entries()
display_list(combobox_filter.get()) # Refresh the list with the current filter
save_list() # Save the list after editing
Expand All @@ -90,6 +96,7 @@ def remove_item():
global entry_item
item = entry_item.get().strip()
if item in shopping_list:
undo_stack.append(('remove', item, shopping_list[item])) # Add action to undo stack
del shopping_list[item]
clear_entries()
display_list(combobox_filter.get()) # Refresh the list with the current filter
Expand All @@ -98,63 +105,61 @@ def remove_item():
else:
messagebox.showerror("Error", f"{item} is not in your shopping list.")

# Function to clear the entire shopping list
def clear_list():
global shopping_list
shopping_list.clear()
display_list() # Clear display
save_list() # Save the cleared list
messagebox.showinfo("Success", "All items have been cleared from your shopping list.")

# Function to calculate the total cost of all items
def calculate_total():
total = sum(amount * price for amount, price, _ in shopping_list.values())
messagebox.showinfo("Total Cost", f"Total cost of items in the shopping list: ${total:.2f}")

# Function to search for an item in the shopping list
def search_item():
global entry_item
search_term = entry_item.get().strip().lower()
listbox.delete(0, tk.END)
found = False
for item, details in shopping_list.items():
if search_term in item.lower():
amount, price, category = details
listbox.insert(tk.END, f"- {item} (Amount: {amount}, Price: ${price:.2f}, Category: {category})")
found = True
if not found:
messagebox.showinfo("Search Result", "No matching items found.")

# Function to filter items by category
def filter_items():
display_list(combobox_filter.get())
# Function to undo the last action
def undo_action():
if undo_stack:
action, item, data = undo_stack.pop()
if action == 'add':
del shopping_list[item]
elif action == 'edit':
shopping_list[item][0] = data
elif action == 'remove':
shopping_list[item] = data
display_list(combobox_filter.get())
save_list()
messagebox.showinfo("Undo", "Last action has been undone.")
else:
messagebox.showerror("Error", "No actions to undo.")

# Function to toggle dark mode
def toggle_dark_mode():
global is_dark_mode
is_dark_mode = not is_dark_mode
if is_dark_mode:
root.configure(bg="#1c1c1c")
frame.configure(bg="#1c1c1c")
listbox.configure(bg="#333333", fg="white")
else:
root.configure(bg="#2d3250")
frame.configure(bg="#2d3250")
listbox.configure(bg="#A0A3B2", fg="black")

# Function to export shopping list as CSV
def export_to_csv():
file_path = filedialog.asksaveasfilename(defaultextension=".csv", filetypes=[("CSV Files", "*.csv")])
if file_path:
with open(file_path, mode='w', newline='') as file:
writer = csv.writer(file)
writer.writerow(["Item", "Amount", "Price", "Category"])
for item, details in shopping_list.items():
writer.writerow([item] + details)
messagebox.showinfo("Export", "Shopping list has been exported as CSV.")

# Function to clear entry fields
def clear_entries():
entry_item.delete(0, tk.END)
entry_amount.delete(0, tk.END)
entry_price.delete(0, tk.END)
combobox_category.set('') # Clear category selection
combobox_category.set('')

# Main function to set up the UI
import tkinter as tk
from tkinter import messagebox, ttk

def main():
global entry_item, entry_amount, entry_price, listbox, combobox_category, combobox_filter
global entry_item, entry_amount, entry_price, listbox, combobox_category, combobox_filter, frame, root
load_list() # Load the shopping list at startup
root = tk.Tk()
root.title("Shopping List")
root.configure(bg="#2d3250")

frame_logo = tk.Frame(root, bg="#2d3250")
frame_logo.pack(padx=10, pady=0, fill='x')

label_logo = tk.Label(frame_logo, text="SHOPPING LIST", font=("Helvetica", 24, "bold"), fg="white", bg="#2d3250")
label_logo.grid(row=0, column=0, columnspan=2, pady=10, sticky="nsew")
label_logo.pack()

# Main Input Frame
frame = tk.Frame(root, bg="#2d3250")
frame.pack(padx=10, pady=10, fill="both", expand=True)

Expand All @@ -180,58 +185,48 @@ def main():
label_category = tk.Label(frame, text="Category:", fg="white", bg="#2d3250", font=("Arial", 12))
label_category.grid(row=3, column=0, padx=5, pady=5, sticky="e")

combobox_category = ttk.Combobox(frame, values=categories[:-1], font=("Arial", 12), state="readonly") # Exclude "All"
combobox_category.grid(row=3, column=1, padx=5, pady=5)

# Filter dropdown
label_filter = tk.Label(frame, text="Filter By:", fg="white", bg="#2d3250", font=("Arial", 12))
label_filter.grid(row=4, column=0, padx=5, pady=5, sticky="e")

combobox_filter = ttk.Combobox(frame, values=categories, font=("Arial", 12), state="readonly")
combobox_filter.grid(row=4, column=1, padx=5, pady=5)
combobox_filter.set("All") # Default filter is "All"
combobox_filter.bind("<<ComboboxSelected>>", lambda e: filter_items())
combobox_category = ttk.Combobox(frame, values=categories[:-1], font=("Arial", 12))
combobox_category.grid(row=3, column=1, padx=5, pady=5, sticky="nsew")

# Buttons with styles
button_add = tk.Button(frame, text="Add Item", font=("Arial", 12), bg="#FF7F50", fg="black", command=add_item)
button_add.grid(row=5, column=0, padx=5, pady=5, sticky="we")
# Buttons
button_add = tk.Button(frame, text="Add", command=add_item, bg="#14a769", fg="white", font=("Arial", 12, "bold"))
button_add.grid(row=4, column=0, padx=5, pady=10)

button_edit = tk.Button(frame, text="Edit Item", font=("Arial", 12), bg="#FF7F50", fg="black", command=edit_item)
button_edit.grid(row=5, column=1, padx=5, pady=5, sticky="we")
button_edit = tk.Button(frame, text="Edit", command=edit_item, bg="#f39c12", fg="white", font=("Arial", 12, "bold"))
button_edit.grid(row=4, column=1, padx=5, pady=10)

button_remove = tk.Button(frame, text="Remove Item", font=("Arial", 12), bg="#FF7F50", fg="black", command=remove_item)
button_remove.grid(row=6, column=0, padx=5, pady=5, sticky="we")
button_remove = tk.Button(frame, text="Remove", command=remove_item, bg="#e74c3c", fg="white", font=("Arial", 12, "bold"))
button_remove.grid(row=5, column=0, padx=5, pady=10)

button_display = tk.Button(frame, text="Display List", font=("Arial", 12), bg="#FF7F50", fg="black", command=display_list)
button_display.grid(row=6, column=1, padx=5, pady=5, sticky="we")
button_undo = tk.Button(frame, text="Undo", command=undo_action, bg="#3498db", fg="white", font=("Arial", 12, "bold"))
button_undo.grid(row=5, column=1, padx=5, pady=10)

button_search = tk.Button(frame, text="Search Item", font=("Arial", 12), bg="#FF7F50", fg="black", command=search_item)
button_search.grid(row=7, column=0, padx=5, pady=5, sticky="we")

button_calculate = tk.Button(frame, text="Calculate Total Cost", font=("Arial", 12), bg="#FF7F50", fg="black", command=calculate_total)
button_calculate.grid(row=7, column=1, padx=5, pady=5, sticky="we")
button_csv = tk.Button(frame, text="Export CSV", command=export_to_csv, bg="#8e44ad", fg="white", font=("Arial", 12, "bold"))
button_csv.grid(row=6, column=0, padx=5, pady=10)

button_clear = tk.Button(frame, text="Clear List", font=("Arial", 12), bg="#FF7F50", fg="black", command=clear_list)
button_clear.grid(row=8, column=0, padx=5, pady=5, columnspan=2, sticky="we")
button_dark_mode = tk.Button(frame, text="Toggle Dark Mode", command=toggle_dark_mode, bg="#34495e", fg="white", font=("Arial", 12, "bold"))
button_dark_mode.grid(row=6, column=1, padx=5, pady=10)

# Listbox to display the items
listbox_frame = tk.Frame(root)
listbox_frame.pack(padx=10, pady=10, fill='both', expand=True)
# Listbox to display the shopping list
listbox = tk.Listbox(frame, font=("Arial", 12), bg="#A0A3B2", fg="black")
listbox.grid(row=0, column=2, rowspan=7, padx=10, pady=5, sticky="nsew")

listbox = tk.Listbox(listbox_frame, font=("Arial", 12), width=50, height=10, bg="#A0A3B2", fg="black")
listbox.pack(side=tk.LEFT, fill=tk.BOTH, expand=True)
# Category filter dropdown
label_filter = tk.Label(frame, text="Filter by Category:", fg="white", bg="#2d3250", font=("Arial", 12))
label_filter.grid(row=7, column=0, padx=5, pady=5, sticky="e")

scrollbar = tk.Scrollbar(listbox_frame)
scrollbar.pack(side=tk.RIGHT, fill=tk.Y)
combobox_filter = ttk.Combobox(frame, values=categories, font=("Arial", 12))
combobox_filter.grid(row=7, column=1, padx=5, pady=5, sticky="nsew")
combobox_filter.set("All")
combobox_filter.bind("<<ComboboxSelected>>", lambda event: display_list(combobox_filter.get()))

listbox.config(yscrollcommand=scrollbar.set)
scrollbar.config(command=listbox.yview)
display_list() # Display the shopping list at startup

# Display the list on startup
display_list()
# Set up grid row and column configurations for responsive resizing
frame.grid_columnconfigure(1, weight=1)
frame.grid_rowconfigure(0, weight=1)

root.mainloop()

# Run the main function
if __name__ == "__main__":
main()