Files
student_dbms/main.py
T
2026-09-25 08:14:04 -07:00

338 lines
8.4 KiB
Python

#!/usr/bin/env python3
"""
Student Management System
==========================
Terminal CRUD application for STUDENT / GUARDIAN / ATTENDANCE, backed by
MySQL on 10.0.1.40:3306 (student_db).
On startup this:
1. Connects to the MySQL server.
2. Verifies (or creates) the student_db database.
3. Verifies (or creates) the STUDENT, GUARDIAN and ATTENDANCE tables.
4. Launches an interactive terminal menu for CRUD operations.
Run:
python3 main.py
"""
import sys
import pymysql
import crud
import db
from ui_helpers import (
clear_hint,
pause,
print_table,
prompt_attendance_status,
prompt_date,
prompt_guid,
prompt_int,
prompt_phone,
prompt_str,
)
# ============================================================ GUARDIAN UI ==
def menu_guardians(conn):
while True:
clear_hint()
print("GUARDIAN MANAGEMENT")
print(" 1. List all guardians")
print(" 2. View a guardian")
print(" 3. Add a guardian")
print(" 4. Update a guardian")
print(" 5. Delete a guardian")
print(" 0. Back to main menu")
choice = input("\nChoice: ").strip()
try:
if choice == "1":
print()
print_table(crud.list_guardians(conn))
pause()
elif choice == "2":
guid = prompt_guid()
row = crud.get_guardian(conn, guid)
print()
print_table([row] if row else [])
pause()
elif choice == "3":
add_guardian(conn)
elif choice == "4":
update_guardian(conn)
elif choice == "5":
delete_guardian(conn)
elif choice == "0":
return
else:
print(" Invalid choice.")
except crud.CrudError as e:
print(f"\n [ERROR] {e}")
pause()
def add_guardian(conn):
print("\n-- Add Guardian --")
guid = prompt_guid()
gname = prompt_str("Guardian name", max_len=20)
gphone = prompt_phone()
gaddress = prompt_str("Guardian address", max_len=30)
crud.create_guardian(conn, guid, gname, gphone, gaddress)
print(f" [OK] Guardian {guid} added.")
pause()
def update_guardian(conn):
print("\n-- Update Guardian --")
guid = prompt_guid()
existing = crud.get_guardian(conn, guid)
if not existing:
print(" No guardian found with that GUID.")
pause()
return
print(f" Current: {existing}")
print(" (Press Enter to leave a field unchanged)")
gname = prompt_str("New name", max_len=20, allow_blank_skip=True)
gphone_raw = input("New phone (10 digits, blank = unchanged, 'clear' = remove): ").strip()
gphone = existing["GPhone"]
if gphone_raw.lower() == "clear":
gphone = None
elif gphone_raw:
gphone = prompt_phone_validate(gphone_raw)
if gphone is None:
print(" Invalid phone — update aborted for that field.")
gphone = existing["GPhone"]
gaddress = prompt_str("New address", max_len=30, allow_blank_skip=True)
crud.update_guardian(conn, guid, gname=gname, gphone=gphone, gaddress=gaddress)
print(" [OK] Guardian updated.")
pause()
def prompt_phone_validate(raw):
import re
return raw if re.match(r"^\d{10}$", raw) else None
def delete_guardian(conn):
print("\n-- Delete Guardian --")
guid = prompt_guid()
confirm = input(f" Type 'yes' to confirm deleting guardian {guid}: ").strip().lower()
if confirm != "yes":
print(" Cancelled.")
pause()
return
rows = crud.delete_guardian(conn, guid)
if rows:
print(" [OK] Guardian deleted.")
else:
print(" No guardian found with that GUID.")
pause()
# ============================================================= STUDENT UI ==
def menu_students(conn):
while True:
clear_hint()
print("STUDENT MANAGEMENT")
print(" 1. List all students")
print(" 2. View a student")
print(" 3. Add a student")
print(" 4. Update a student")
print(" 5. Delete a student")
print(" 0. Back to main menu")
choice = input("\nChoice: ").strip()
try:
if choice == "1":
print()
print_table(crud.list_students(conn))
pause()
elif choice == "2":
roll = prompt_int("Roll number", max_digits=3)
row = crud.get_student(conn, roll)
print()
print_table([row] if row else [])
pause()
elif choice == "3":
add_student(conn)
elif choice == "4":
update_student(conn)
elif choice == "5":
delete_student(conn)
elif choice == "0":
return
else:
print(" Invalid choice.")
except crud.CrudError as e:
print(f"\n [ERROR] {e}")
pause()
def add_student(conn):
print("\n-- Add Student --")
roll = prompt_int("Roll number (max 3 digits)", max_digits=3)
sname = prompt_str("Student name", max_len=20)
dob = prompt_date("Date of birth")
print(" (Guardian must already exist — add them first via Guardian Management if needed)")
guid = prompt_guid()
crud.create_student(conn, roll, sname, dob, guid)
print(f" [OK] Student {roll} added.")
pause()
def update_student(conn):
print("\n-- Update Student --")
roll = prompt_int("Roll number", max_digits=3)
existing = crud.get_student(conn, roll)
if not existing:
print(" No student found with that roll number.")
pause()
return
print(f" Current: {existing}")
print(" (Press Enter to leave a field unchanged)")
sname = prompt_str("New name", max_len=20, allow_blank_skip=True)
dob = prompt_date("New date of birth", allow_blank_skip=True)
guid = prompt_guid("New guardian GUID", allow_blank_skip=True)
crud.update_student(conn, roll, sname=sname, sdateofbirth=dob, guid=guid)
print(" [OK] Student updated.")
pause()
def delete_student(conn):
print("\n-- Delete Student --")
roll = prompt_int("Roll number", max_digits=3)
confirm = input(f" Type 'yes' to confirm deleting student {roll} "
f"(also deletes their attendance records): ").strip().lower()
if confirm != "yes":
print(" Cancelled.")
pause()
return
rows = crud.delete_student(conn, roll)
if rows:
print(" [OK] Student deleted.")
else:
print(" No student found with that roll number.")
pause()
# =========================================================== ATTENDANCE UI ==
def menu_attendance(conn):
while True:
clear_hint()
print("ATTENDANCE MANAGEMENT")
print(" 1. Mark / update attendance for a student")
print(" 2. View attendance by date")
print(" 3. View attendance history for a student")
print(" 4. Delete an attendance record")
print(" 0. Back to main menu")
choice = input("\nChoice: ").strip()
try:
if choice == "1":
mark_attendance(conn)
elif choice == "2":
d = prompt_date("Date")
print()
print_table(crud.list_attendance_by_date(conn, d))
pause()
elif choice == "3":
roll = prompt_int("Roll number", max_digits=3)
print()
print_table(crud.list_attendance_by_student(conn, roll))
pause()
elif choice == "4":
delete_attendance(conn)
elif choice == "0":
return
else:
print(" Invalid choice.")
except crud.CrudError as e:
print(f"\n [ERROR] {e}")
pause()
def mark_attendance(conn):
print("\n-- Mark Attendance --")
roll = prompt_int("Roll number", max_digits=3)
if not crud.get_student(conn, roll):
print(" No student found with that roll number.")
pause()
return
d = prompt_date("Date")
status = prompt_attendance_status()
result = crud.mark_attendance(conn, d, roll, status)
print(f" [OK] Attendance {result} for student {roll} on {d}: {status}")
pause()
def delete_attendance(conn):
print("\n-- Delete Attendance Record --")
roll = prompt_int("Roll number", max_digits=3)
d = prompt_date("Date")
confirm = input(" Type 'yes' to confirm: ").strip().lower()
if confirm != "yes":
print(" Cancelled.")
pause()
return
rows = crud.delete_attendance(conn, d, roll)
if rows:
print(" [OK] Attendance record deleted.")
else:
print(" No matching attendance record found.")
pause()
# ================================================================ MAIN ====
def main_menu(conn):
while True:
clear_hint()
print("STUDENT MANAGEMENT SYSTEM")
print(" 1. Guardian management")
print(" 2. Student management")
print(" 3. Attendance management")
print(" 0. Exit")
choice = input("\nChoice: ").strip()
if choice == "1":
menu_guardians(conn)
elif choice == "2":
menu_students(conn)
elif choice == "3":
menu_attendance(conn)
elif choice == "0":
print("\nGoodbye!")
return
else:
print(" Invalid choice.")
def main():
print("=" * 60)
print(" STUDENT MANAGEMENT SYSTEM - Startup")
print("=" * 60)
conn = db.get_connection()
print("\nAll checks passed. Starting application...\n")
try:
main_menu(conn)
except KeyboardInterrupt:
print("\n\nInterrupted. Exiting.")
except pymysql.err.MySQLError as e:
print(f"\n[ERROR] Lost database connection: {e}")
sys.exit(1)
finally:
conn.close()
if __name__ == "__main__":
main()