import sqlite3
from abc import ABC, abstractmethod
import customtkinter as ctk
from tkinter import messagebox
ctk.set_appearance_mode("Dark")
ctk.set_default_color_theme("blue")
def is_valid_name(name: str) -> bool:
return [Link]()
def average(values: list) -> float:
return sum(values) / len(values) if values else 0.0
customers_list = [] # List of customer names
employees_set = set() # Set of employee names (unique)
orders_dict = {} # Dict of {order_id: (item, qty, price)}
restaurant_info = ("MyRestaurant", "Sanaa") # Tuple (immutable info)
class DatabaseManager:
def __init__(self, db_name="[Link]"):
[Link] = [Link](db_name)
[Link] = [Link]()
self.create_tables()
def create_tables(self):
[Link]("""
CREATE TABLE IF NOT EXISTS customers (
id INTEGER PRIMARY KEY AUTOINCREMENT,
name TEXT,
phone TEXT
)""")
[Link]("""
CREATE TABLE IF NOT EXISTS employees (
id INTEGER PRIMARY KEY AUTOINCREMENT,
name TEXT,
role TEXT
)""")
[Link]("""
CREATE TABLE IF NOT EXISTS orders (
id INTEGER PRIMARY KEY AUTOINCREMENT,
customer_name TEXT,
item TEXT,
quantity INTEGER,
price INTEGER
)""")
[Link]()
def insert_customer(self, name, phone):
[Link]("INSERT INTO customers (name, phone) VALUES (?,?)",
(name, phone))
[Link]()
def insert_employee(self, name, role):
[Link]("INSERT INTO employees (name, role) VALUES (?,?)",
(name, role))
[Link]()
def insert_order(self, customer_name, item, quantity, price):
[Link](
"INSERT INTO orders (customer_name, item, quantity, price) VALUES
(?,?,?,?)",
(customer_name, item, quantity, price)
)
[Link]()
def delete_customer(self, cid):
[Link]("DELETE FROM customers WHERE id=?", (cid,))
[Link]()
def delete_employee(self, eid):
[Link]("DELETE FROM employees WHERE id=?", (eid,))
[Link]()
def delete_order(self, oid):
[Link]("DELETE FROM orders WHERE id=?", (oid,))
[Link]()
def fetch_all(self, table):
[Link](f"SELECT * FROM {table}")
return [Link]()
# Abstract Person
class Person(ABC):
def __init__(self, name):
self.__name = name # private attribute
@property
def name(self):
return self.__name
@[Link]
def name(self, value):
if value :
self.__name = value
else:
raise ValueError("Name cannot be empty.")
@abstractmethod
def info(self):
pass
# Customer
class Customer(Person):
total_customers = 0 # class attribute
def __init__(self, name, phone):
super().__init__(name)
self.__phone = phone # private attribute
Customer.total_customers += 1
@property
def phone(self):
return self.__phone
@[Link]
def phone(self, value):
if value:
self.__phone = value
else:
raise ValueError("Phone cannot be empty.")
def info(self):
return f"Customer: {[Link]}, Phone: {[Link]}"
@staticmethod
def greet():
return "Welcome, dear customer!"
@classmethod
def get_total_customers(cls):
return cls.total_customers
# Employee
class Employee(Person):
def __init__(self, name, role):
super().__init__(name)
self.__role = role # private attribute
@property
def role(self):
return self.__role
@[Link]
def role(self, value):
if value:
self.__role = value
else:
raise ValueError("Role cannot be empty.")
def info(self):
return f"Employee: {[Link]}, Role: {[Link]}"
# Restaurant
class Restaurant:
def __init__(self, db: DatabaseManager):
[Link] = db # composition
def add_customer(self, customer: Customer):
[Link].insert_customer([Link], [Link])
customers_list.append([Link])
def add_employee(self, employee: Employee):
[Link].insert_employee([Link], [Link])
employees_set.add([Link])
def add_order(self, customer_name, item, quantity, price):
[Link].insert_order(customer_name, item, quantity, price)
self._rebuild_orders_dict()
def delete_customer(self, cid):
[Link].delete_customer(cid)
self._rebuild_structures()
def delete_employee(self, eid):
[Link].delete_employee(eid)
self._rebuild_structures()
def delete_order(self, oid):
[Link].delete_order(oid)
self._rebuild_orders_dict()
def show_customers(self):
return [Link].fetch_all("customers")
def show_employees(self):
return [Link].fetch_all("employees")
def show_orders(self):
return [Link].fetch_all("orders")
def _rebuild_structures(self):
customers_list.clear()
employees_set.clear()
for c in self.show_customers():
# (id, name, phone)
customers_list.append(c[1])
for e in self.show_employees():
employees_set.add(e[1])
self._rebuild_orders_dict()
def _rebuild_orders_dict(self):
orders_dict.clear()
for o in self.show_orders():
# o = (id, customer_name, item, quantity, price)
oid = o[0]
orders_dict[oid] = (o[2], o[3], o[4]) # (item, qty, price)
def run_gui():
db = DatabaseManager()
restaurant = Restaurant(db)
app = [Link]()
[Link]("Restaurant Management System")
[Link]("700x560")
title_label = [Link](
master=app,
text="Restaurant Database Management 📊 ",
text_color="#4FC3F7",
font=("Arial", 22, "bold")
)
title_label.pack(pady=(8, 5))
tabview = [Link](app)
[Link](expand=True, fill="both", padx=12, pady=(0, 6))
footer_label = [Link](
master=app,
text="© All rights reserved - Eng Hesham Alsaadi - 2025",
text_color="white",
font=("Arial", 10)
)
footer_label.pack(pady=(0, 8))
# Tabs
tab_customers = [Link]("Customers")
tab_employees = [Link]("Employees")
tab_orders = [Link]("Orders")
tab_show = [Link]("Show Data")
# Customers Tab
[Link](tab_customers, text="Name").pack(pady=(8, 2))
entry_cust_name = [Link](tab_customers)
entry_cust_name.pack(padx=10)
[Link](tab_customers, text="Phone").pack(pady=(8, 2))
entry_cust_phone = [Link](tab_customers)
entry_cust_phone.pack(padx=10)
def add_customer_ui():
name = entry_cust_name.get().strip()
phone = entry_cust_phone.get().strip()
if not (name and phone):
[Link]("Error", "Fill all fields!")
return
if not is_valid_name(name):
[Link]("Error", "Name must be Alphabet.")
return
if not [Link]():
[Link]("Error", "Phone must contain only digits.")
return
c = Customer(name, phone)
restaurant.add_customer(c)
[Link]("Success", f"{[Link]()}\nCustomer added! Total:
{Customer.get_total_customers()}")
entry_cust_name.delete(0, "end")
entry_cust_phone.delete(0, "end")
[Link](tab_customers, text="Add Customer", command=add_customer_ui,
fg_color="#3498db", hover_color="green",
corner_radius=10).pack(pady=8)
# Delete customer
[Link](tab_customers, text="Delete Customer by ID").pack(pady=(8, 2))
entry_del_cust = [Link](tab_customers)
entry_del_cust.pack(padx=10)
def delete_customer_ui():
cid = entry_del_cust.get().strip()
if [Link]():
restaurant.delete_customer(int(cid))
[Link]("Deleted", f"Customer {cid} deleted!")
entry_del_cust.delete(0, "end")
else:
[Link]("Error", "Enter valid ID!")
[Link](tab_customers, text="Delete Customer",
command=delete_customer_ui,
fg_color="#3498db", hover_color="red",
corner_radius=10).pack(pady=8)
# Employees Tab
[Link](tab_employees, text="Name").pack(pady=(8, 2))
entry_emp_name = [Link](tab_employees)
entry_emp_name.pack(padx=10)
[Link](tab_employees, text="Role").pack(pady=(8, 2))
entry_emp_role = [Link](tab_employees)
entry_emp_role.pack(padx=10)
def add_employee_ui():
name = entry_emp_name.get().strip()
role = entry_emp_role.get().strip()
if not (name and role):
[Link]("Error", "Fill all fields!")
return
if not is_valid_name(name):
[Link]("Error", "Name must Alphabet.")
return
e = Employee(name, role)
restaurant.add_employee(e)
[Link]("Success", "Employee added!")
entry_emp_name.delete(0, "end")
entry_emp_role.delete(0, "end")
[Link](tab_employees, text="Add Employee", command=add_employee_ui,
fg_color="#3498db", hover_color="green",
corner_radius=10).pack(pady=8)
# Delete employee
[Link](tab_employees, text="Delete Employee by ID").pack(pady=(8, 2))
entry_del_emp = [Link](tab_employees)
entry_del_emp.pack(padx=10)
def delete_employee_ui():
eid = entry_del_emp.get().strip()
if [Link]():
restaurant.delete_employee(int(eid))
[Link]("Deleted", f"Employee {eid} deleted!")
entry_del_emp.delete(0, "end")
else:
[Link]("Error", "Enter valid ID!")
[Link](tab_employees, text="Delete Employee",
command=delete_employee_ui,
fg_color="#3498db", hover_color="red",
corner_radius=10).pack(pady=8)
# Orders Tab
[Link](tab_orders, text="Customer Name").pack(pady=(8, 2))
entry_order_cust = [Link](tab_orders)
entry_order_cust.pack(padx=10)
[Link](tab_orders, text="Choose Item").pack(pady=(8, 2))
entry_order_item = [Link](tab_orders, values=['meat', 'rice',
'chicken', 'sandwich', 'salad', 'juice'])
entry_order_item.pack(padx=10)
[Link](tab_orders, text="Quantity").pack(pady=(8, 2))
entry_order_qty = [Link](tab_orders)
entry_order_qty.pack(padx=10)
[Link](tab_orders, text="Price").pack(pady=(8, 2))
entry_order_price = [Link](tab_orders)
entry_order_price.pack(padx=10)
def add_order_ui():
cust = entry_order_cust.get().strip()
item = entry_order_item.get().strip()
qty = entry_order_qty.get().strip()
price = entry_order_price.get().strip()
if not (cust and item and qty and price):
[Link]("Error", "Fill all fields!")
return
if not ([Link]() and [Link]()):
[Link]("Error", "Quantity and Price must be numbers!")
return
if not is_valid_name(cust):
[Link]("Error", "Name must be Alphabet.")
return
restaurant.add_order(cust, item, int(qty), int(price))
[Link]("Success", "Order added!")
entry_order_cust.delete(0, "end")
entry_order_item.set("") # clear combobox
entry_order_qty.delete(0, "end")
entry_order_price.delete(0, "end")
[Link](tab_orders, text="Add Order", command=add_order_ui,
fg_color="#3498db", hover_color="green",
corner_radius=10).pack(pady=8)
# Delete order
[Link](tab_orders, text="Delete Order by ID").pack(pady=(8, 2))
entry_del_order = [Link](tab_orders)
entry_del_order.pack(padx=10)
def delete_order_ui():
oid = entry_del_order.get().strip()
if [Link]():
restaurant.delete_order(int(oid))
[Link]("Deleted", f"Order {oid} deleted!")
entry_del_order.delete(0, "end")
else:
[Link]("Error", "Enter valid ID!")
[Link](tab_orders, text="Delete Order", command=delete_order_ui,
fg_color="#3498db", hover_color="red",
corner_radius=10).pack(pady=8)
# Show Data Tab
text_box = [Link](tab_show, width=640, height=300)
text_box.pack(pady=10)
def show_data_ui():
restaurant._rebuild_structures()
text_box.delete("1.0", "end")
text_box.insert("end", "=== Customers ===\n")
for c in restaurant.show_customers():
text_box.insert("end", f"ID: {c[0]} | Name: {c[1]} | Phone: {c[2]}\n")
text_box.insert("end", "\n=== Employees ===\n")
for e in restaurant.show_employees():
text_box.insert("end", f"ID: {e[0]} | Name: {e[1]} | Role: {e[2]}\n")
text_box.insert("end", "\n=== Orders ===\n")
prices = []
for o in restaurant.show_orders():
# o = (id, customer_name, item, quantity, price)
text_box.insert("end", f"ID: {o[0]} | Customer: {o[1]} | Item: {o[2]} |
Qty: {o[3]} | Price: {o[4]}\n")
[Link](o[4])
avg_price = average(prices)
text_box.insert("end", "\n============================\n")
text_box.insert("end", f" Total Customers:
{len(restaurant.show_customers())}\n")
text_box.insert("end", f" Total Employees:
{len(restaurant.show_employees())}\n")
text_box.insert("end", f" Total Orders: {len(restaurant.show_orders())}\n")
text_box.insert("end", f" Average Order Price: {avg_price:.2f}\n")
[Link](tab_show, text="Refresh Data", command=show_data_ui,
fg_color="#3498db", hover_color="purple",
corner_radius=10).pack(pady=(4, 6))
def show_structures_ui():
# Rebuild to be safe
restaurant._rebuild_structures()
text = "=== Data Structures ===\n"
text += f"Customers List (len={len(customers_list)}): {customers_list}\n\n"
text += f"Employees Set (len={len(employees_set)}): {employees_set}\n\n"
# orders_dict sample (show up to 10 items)
text += f"Orders Dict (len={len(orders_dict)}):\n"
for k, v in list(orders_dict.items())[:10]:
text += f" {k} -> item:{v[0]}, qty:{v[1]}, price:{v[2]}\n"
text += f"\nRestaurant Info (Tuple): {restaurant_info}\n\n"
[Link]("Structures", text)
[Link](tab_show, text="Show Structures (List/Set/Dict/Tuple)",
command=show_structures_ui,
fg_color="#2ecc71", hover_color="brown",
corner_radius=10).pack(pady=(0, 8))
[Link]()
if __name__ == "__main__":
run_gui()