Chapter 7: Complete Source Code
import
[Link]
import datetime
import
random
import sys
#
=============================================================
==== # CLASS XII CS PROJECT: RAILWAY MANAGEMENT SYSTEM -
PROCEDURAL LOGIC
# All database, session state, and UI logic in one file.
# =================================================================
# --- GLOBAL VARIABLES FOR DATABASE CONFIGURATION
--- DB_CONFIG = {
'host': 'localhost',
'user': 'root',
'password': 'root',
'database': 'railway_db'
}
dbconn =
None dbcur =
None user_id
= None
is_adm =
False
#
==============================================================
=== # DATABASE CONNECTION & UTILITY FUNCTIONS
# =================================================================
def create_tables_if_not_exists():
"""Defines and creates all necessary tables if they do not
exist.""" global dbcur, dbconn
print("[INFO] Checking database schema (tables)...")
# CREATE TABLE IF NOT EXISTS
tables =
[ """
CREATE TABLE IF NOT EXISTS PASSENGERS (
passenger_id INT AUTO_INCREMENT PRIMARY
KEY, username VARCHAR(50) UNIQUE NOT
NULL,
name VARCHAR(100) NOT NULL,
email VARCHAR(100) UNIQUE,
phone VARCHAR(15),
password_hash VARCHAR(255) NOT NULL
)
""",
"""
CREATE TABLE IF NOT EXISTS TRAINS
( train_no VARCHAR(10) PRIMARY
KEY,
train_name VARCHAR(100) NOT NULL,
source_st VARCHAR(50) NOT NULL,
destination_st VARCHAR(50) NOT
NULL,
total_seats INT NOT NULL,
fare DECIMAL(10, 2) NOT
NULL,
TIME running_status ENUM('ON TIME', 'DELAYED', 'CANCELLED') DEFAULT
' ) 'ON
"""
,
"""
CREATE TABLE IF NOT EXISTS SEAT_AVAILABILITY (
train_no VARCHAR(10),
journey_date DATE,
available_seats INT NOT
NULL,
PRIMARY KEY (train_no, journey_date),
FOREIGN KEY (train_no) REFERENCES TRAINS(train_no)
)
""",
"""
CREATE TABLE IF NOT EXISTS TICKETS (
pnr_no VARCHAR(20) PRIMARY KEY,
train_no VARCHAR(10) NOT NULL,
passenger_id INT NOT NULL,
booking_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
date_of_journey DATE NOT NULL,
seats_booked INT NOT NULL,
total_price DECIMAL(10, 2) NOT
NULL,
ticket_status ENUM('CONFIRMED', 'CANCELLED') DEFAULT 'CONFIRMED',
FOREIGN KEY (train_no) REFERENCES TRAINS(train_no),
FOREIGN KEY (passenger_id) REFERENCES PASSENGERS(passenger_id)
)
"""
]
try:
# Execute each CREATE TABLE
query for query in tables:
[Link](query)
[Link]()
print("[SUCCESS] All tables
checked/created.") return True
except [Link]:
print("[ERROR] Failed to create tables:" )
[Link]()
return False
def
connect_db(
): """
Establishes connection to MySQL. It first connects to the server to
ensure the 'railway_db' exists, and then connects directly to that
database.
"""
global dbconn, dbcur
database_name = DB_CONFIG['database']
# 1. First attempt: Connect to the MySQL Server (without
specifying the database)
try:
dbconn = [Link](
host=DB_CONFIG['host'],
user=DB_CONFIG['user'],
password=DB_CONFIG['password']
)
dbcur = [Link]()
# 2. Create the target database if it doesn't exist
[Link]("CREATE DATABASE IF NOT EXISTS " +
database_name) [Link]()
[Link]()
print(">>> Database '%s' checked/created." % database_name)
# 3. Reconnect specifying the database
# We use the full DB_CONFIG dictionary now that we know the database
exists
. dbconn =
[Link](**DB_CONFIG) dbcur
= [Link]()
print(">>> Database connection established successfully.")
# 4. Create all necessary tables
return
create_tables_if_not_exists()
except [Link]:
print("\n[ERROR] Database connection/creation failed:"
) return False
def close_db():
"""Closes the database connection
gracefully.""" global dbconn
if dbconn and
dbconn.is_connected():
[Link]()
[Link]()
print(">>> Database connection closed.")
def execute_query(query, params=None, fetch_one=False,
commit=False): """
A centralized method to execute SQL queries.
Uses global dbconn and dbcur. Returns results as
tuples. """
global dbconn, dbcur
try:
[Link](query, params)
if commit:
[Link]()
return [Link] # Return the ID of the last inserted row
if fetch_one:
return [Link]()
else:
return [Link]()
except [Link] as err:
print("\n[DB ERROR] Query execution failed: %s" %
err) [Link]() # Rollback any changes on
error return None if fetch_one else []
#
==============================================================
=== # AUTHENTICATION FUNCTIONS
# =================================================================
def register_user(username, name, email, phone, password):
"""Registers a new user/passenger."""
# Keeping the password handling simple as per original
project password_hash = password
query = ("INSERT INTO PASSENGERS (username, name, email, phone,
password_hash)
"
"VALUES (%s, %s, %s, %s, %s)")
params = (username, name, email, phone, password_hash)
try:
if execute_query(query, params, commit=True) is not None:
print("\n[SUCCESS] Registration complete. You can now log
in.") return True
else:
print("[FAILURE] Registration failed, possibly duplicate
email." username or
)
return False
except Exception:
print("[FAILURE] Registration failed due to an unexpected
error.") return False
def login_user(username, password):
"""Authenticates a user and sets the global session
variables.""" global user_id, is_adm
# Select passenger_id (index 0) and password_hash (index 1)
query = "SELECT passenger_id, password_hash FROM PASSENGERS WHERE
%s
" username = user = execute_query(query, (username,), fetch_one=True)
# Check if user exists and password matches (accessing tuple elements by
index) if user and user[1] == password:
user_id = user[0]
# Admin check based on a specific username
is_adm = ([Link]() == 'admin_user')
print("\n[SUCCESS] Logged in as: %s (ID: %d)" % (username,
user_id)) return True
else:
print("\n[FAILURE] Invalid username or
password.") return False
def logout_user():
"""Clears the current session
data.""" global user_id, is_adm
user_id = None
is_adm = False
print("\n[INFO] Logged out successfully.")
#
==============================================================
=== # TRAIN MANAGEMENT FUNCTIONS (ADMIN ONLY)
# =================================================================
def add_train(train_no, name, source, dest, total_seats, fare):
"""Adds a new train and initializes seat availability for the next 30
days.""" global is_adm, dbcur, dbconn
if not is_adm:
print("\n[ACCESS DENIED] Only administrators can add
trains.") return False
# 1. Insert into TRAINS table
train_query = ("INSERT INTO TRAINS (train_no, train_name, source_st,
destination_st, total_seats, fare) "
"VALUES (%s, %s, %s, %s, %s, %s)")
train_params = (train_no, name, source, dest, total_seats, fare)
if execute_query(train_query, train_params, commit=True) is None:
print("\n[FAILURE] Failed to add train details.")
return False
# 2. Initialize SEAT_AVAILABILITY for the new train for the next 30
days print("[INFO] Initializing seat availability...")
today =
[Link]()
dates_to_insert = []
for i in range(1, 31): # 30 days of advance booking
journey_date = today + [Link](days=i)
dates_to_insert.append((train_no, journey_date, total_seats))
availability_query = (
"INSERT INTO SEAT_AVAILABILITY (train_no, journey_date,
available_seats) " "VALUES (%s, %s, %s)"
)
# Using executemany for
efficiency try:
[Link](availability_query, dates_to_insert)
[Link]()
print("[SUCCESS] Train %s (%s) added and seats initialized for 30
days." % (train_no, name))
return True
except [Link] as err:
print("[ERROR] Failed to initialize seat availability: %s. Train
details might be added but availability is missing." % err)
[Link]()
return False
def update_train_status(train_no, status):
"""Updates the running status of a train (e.g., DELAYED,
CANCELLED).""" global is_adm
if not is_adm:
print("\n[ACCESS DENIED] Only administrators can update train
status.") return False
query = "UPDATE TRAINS SET running_status = %s WHERE train_no =
%s" params = ([Link](), train_no)
if execute_query(query, params, commit=True) is not None:
print("\n[SUCCESS] Train %s status updated to %s." %
(train_no,
[Link]()))
return
True else:
print("\n[FAILURE] Could not find or update train %s." %
train_no) return False
def view_all_trains():
"""Fetches and returns all train details as a list of tuples."""
query = "SELECT train_no, train_name, source_st, destination_st,
total_seats, fare, running_status FROM TRAINS ORDER BY train_no"
return execute_query(query)
#
==============================================================
=== # BOOKING AND CANCELLATION CORE LOGIC
# =================================================================
def search_trains(source, destination, journey_date_str):
"""Searches for available trains between source and destination on a
specific date."""
try:
# Validate and format date
journey_date =
[Link](journey_date_str, '%Y-%m-
%d').date()
if journey_date < [Link](): print("\
n[INFO] Cannot search for past dates.")
return []
except
ValueError:
print("\n[ERROR] Invalid date format. Please use YYYY-
MM-DD.") return []
query = """
SELECT
T.train_no, T.train_name, T.source_st, T.destination_st, [Link],
T.running_status, SA.available_seats
FROM TRAINS T
JOIN SEAT_AVAILABILITY SA ON T.train_no =
SA.train_no WHERE
T.source_st = %s AND T.destination_st = %s
AND SA.journey_date = %s AND SA.available_seats
> 0 AND T.running_status != 'CANCELLED'
ORDER BY T.train_no
"""
params = ([Link](), [Link](),
journey_date) return execute_query(query, params)
def _get_ticket_fare(train_no):
"""Private helper to get fare (index 0) and total_seats (index 1)
for booking."""
query = "SELECT fare, total_seats FROM TRAINS WHERE train_no
= %s" return execute_query(query, (train_no,),
fetch_one=True)
def _update_seat_count(train_no, journey_date, seats_change):
"""Private helper to update available seats in SEAT_AVAILABILITY
table.""" # seats_change is positive for booking, negative for
cancellation
query = (
"UPDATE SEAT_AVAILABILITY "
"SET available_seats = available_seats - %s "
"WHERE train_no = %s AND journey_date = %s AND available_seats >=
%s"
)
# Ensure we don't overbook seats during
booking if seats_change > 0:
# For booking: decrement seats, require available_seats >=
seats_change params = (seats_change, train_no, journey_date,
seats_change)
else:
# For cancellation: increment seats, require available_seats >= 0
# seats_change is already negative here, so we pass it as-is for the
decrement
params = (seats_change, train_no, journey_date, 0)
[Link](query,
params) return
[Link] > 0
def book_ticket(train_no, journey_date_str, seats_to_book):
"""Main function to handle ticket booking
transaction."""
global user_id, dbconn,
dbcur if not user_id:
print("\n[ALERT] Please log in to book tickets.")
return None
try:
journey_date = [Link](journey_date_str,
'%Y-%m-%d').date()
if journey_date < [Link]():
print("\n[INFO] Booking is not allowed for past
dates.") return None
except ValueError:
print("\n[ERROR] Invalid date format. Please use YYYY-
MM-DD.") return None
# Start Transaction
Block try:
[Link] = False # Disable autocommit
# 1. Get Fare (index 0) and Total Seats (index 1)
train_info = _get_ticket_fare(train_no)
if not train_info:
print("[FAILURE] Train %s not found." %
train_no) raise Exception("Train not found")
fare = train_info[0]
# Check actual available seats (index 0)
avail_query = "SELECT available_seats FROM SEAT_AVAILABILITY WHERE
train_no
= %s AND journey_date = %s"
availability = execute_query(avail_query, (train_no, journey_date),
fetch_one=True)
if not availability:
print("[FAILURE] Seat availability data missing for %s on %s." %
(train_no, journey_date_str))
raise Exception("Availability missing")
current_seats =
availability[0] if
current_seats <
seats_to_book:
print("[FAILURE] Only %d seats available. Cannot book %d seats."
% (current_seats, seats_to_book))
raise Exception("Insufficient seats")
# 2. Calculate Price and Generate PNR
total_price = fare * seats_to_book
pnr_no = "%s-%d" % (journey_date.strftime('%Y%m%d'),
99999) [Link](10000,
)
# 3. Insert into TICKETS table
ticket_query = (
"INSERT INTO TICKETS (pnr_no, train_no, passenger_id,
date_of_journey, seats_booked, total_price) "
"VALUES (%s, %s, %s, %s, %s, %s)"
)
[Link](ticket_query, (pnr_no, train_no, user_id,
journey_date, seats_to_book, total_price))
# 4. Update SEAT_AVAILABILITY
if not _update_seat_count(train_no, journey_date, seats_to_book):
print("[FAILURE] Seat availability update failed. Rolling back
booking.")
raise Exception("Seat update failed")
# 5. Commit Transaction
[Link]()
print("\
n==================================================")
print("[SUCCESS] TICKET BOOKED! PNR: %s" % pnr_no)
print("Train: %s | Seats: %d | Total Price: \u20B9%.2f" % (train_no,
seats_to_book, total_price))
print("Journey Date: %s" % journey_date_str)
print("=================================================="
)
return pnr_no
except Exception as e:
print("\n[TRANSACTION FAILED] Booking rolled back. Reason: %s" % e)
[Link]()
return
None finally:
[Link] = True # Re-enable autocommit
def view_my_bookings():
"""Retrieves all active and cancelled bookings for the current
user.""" global user_id
if not user_id:
print("\n[ALERT] Please log in to view
bookings.") return []
query = """
SELECT
T.pnr_no, T.train_no, TR.train_name, TR.source_st,
TR.destination_st, T.date_of_journey, T.seats_booked,
T.total_price, T.ticket_status
FROM TICKETS T
JOIN TRAINS TR ON T.train_no =
TR.train_no WHERE T.passenger_id = %s
ORDER BY T.date_of_journey DESC, T.booking_time DESC
"""
return execute_query(query,
(user_id,)) def cancel_ticket(pnr_no):
"""Handles ticket cancellation and seat recovery
transaction.""" global user_id, dbconn, dbcur
if not user_id:
print("\n[ALERT] Please log in to cancel
tickets.") return False
# Start Transaction
Block try:
[Link] = False
# 1. Fetch ticket details and check ownership/status
# Indices: 0:train_no, 1:date_of_journey, 2:seats_booked,
3:passenger_id, 4:ticket_status
fetch_query = (
"SELECT train_no, date_of_journey, seats_booked, passenger_id,
ticket_status "
"FROM TICKETS WHERE pnr_no = %s"
)
ticket = execute_query(fetch_query, (pnr_no,), fetch_one=True)
if not ticket:
print("[FAILURE] PNR %s not found." %
pnr_no) raise Exception("PNR not found")
# Accessing tuple elements
ticket_pid = ticket[3]
ticket_status = ticket[4]
if ticket_pid != user_id:
print("[FAILURE] This ticket does not belong to your
account.") raise Exception("Ownership failed")
if ticket_status == 'CANCELLED':
print("[INFO] Ticket %s is already cancelled." %
pnr_no) return True
# 2. Update ticket status to CANCELLED
cancel_query = "UPDATE TICKETS SET ticket_status = 'CANCELLED' WHERE
=
%s" pnr_no [Link](cancel_query, (pnr_no,))
# 3. Recover seats in SEAT_AVAILABILITY (seats_booked is negative
for recovery)
train_no = ticket[0]
journey_date = ticket[1]
seats_to_recover =
ticket[2]
# Pass negative value to add seats back
if not _update_seat_count(train_no, journey_date, -
seats_to_recover): print("[FAILURE] Failed to recover seats.
Rolling back cancellation.")
raise Exception("Seat recovery failed")
# 4. Commit Transaction
[Link]()
print("\n[SUCCESS] Ticket %s cancelled successfully. %d seats
recovered." % (pnr_no, seats_to_recover))
return True
except Exception as e:
print("\n[TRANSACTION FAILED] Cancellation rolled back. Reason: %s"
% e) [Link]()
return
False finally:
[Link] = True
#
==============================================================
=== # COMMAND LINE INTERFACE (CLI) FUNCTIONS
# =================================================================
def print_header(title):
"""Prints a formatted header for menu pages."""
print("\n" + "=" * 60)
print("%s%s" % (' ' * 20,
[Link]())) print("=" * 60)
def validate_date(prompt):
"""Helper function to get and validate date
input.""" while True:
date_str = input(prompt).strip()
if date_str.lower() == 'q': return
'Q' try:
# Check for correct format
date_obj = [Link](date_str, '%Y-%m-
%d').date() if date_obj < [Link]():
print("[!] Date cannot be in the past. Please enter a valid
future date (YYYY-MM-DD).")
continue
return
date_str
except ValueError:
print("[!] Invalid date format. Please use YYYY-MM-DD
(e.g., 2025-12-31).")
def validate_int(prompt, min_val=1):
"""Helper function to get and validate integer
input.""" while True:
try:
val = input(prompt).strip()
if [Link]() == 'q': return
'Q' num = int(val)
if num < min_val:
print("[!] Value must be a positive integer (min %d)." %
min_val) continue
return num
except
ValueError:
print("[!] Invalid input. Please enter a valid
number.") # --- HANDLER FUNCTIONS (ADMIN) ---
def handle_add_train():
"""Gathers input and calls the add_train logic."""
print_header("Add New Train")
print("Enter 'Q' at any time to return to the Admin Menu.")
train_no = input("Train Number (e.g., 12345):
").strip().upper() if train_no == 'Q': return
train_name = input("Train Name:
").strip() if train_name == 'Q': return
source = input("Source Station (City Name):
").strip().upper() if source == 'Q': return
dest = input("Destination Station (City Name):
").strip().upper() if dest == 'Q': return
total_seats = validate_int("Total Seats:
") if total_seats == 'Q': return
try:
fare = float(input("Fare per Seat (e.g., 1500.50): ").strip())
except ValueError:
print("[!] Invalid fare amount. Returning to
menu.") return
add_train(train_no, train_name, source, dest, total_seats,
fare) def handle_view_all_trains():
"""Displays a list of all trains in the system."""
print_header("All Registered
Trains") trains =
view_all_trains()
if not trains:
print("No trains found in the
system.") return
# Print a formatted table header
print("%-6s%-25s%-15s%-15s%-7s%-10s%-10s" % ('NO', 'TRAIN NAME',
'SOURCE', 'DESTINATION', 'SEATS', 'FARE', 'STATUS'))
print("-" * 88)
# Indices: 0:train_no, 1:name, 2:source, 3:dest, 4:seats, 5:fare,
6:status for t in trains:
print(
"%-6s%-25s%-15s%-15s%-7d\u20B9%-9.2f%-10s" % (
t[0], # train_no
t[1], # train_name
t[2], # source_st
t[3], #
destination_st
t[4], # total_seats
t[5], # fare
t[6] # running_status
)
)
print("-" * 88)
def handle_update_train_status():
"""Allows admin to change a train's running status."""
print_header("Update Train Running Status")
train_no = input("Enter Train Number to update: ").strip().upper()
if not train_no:
print("[!] Train number cannot be
empty.") return
print("Available Statuses: 1. ON TIME, 2. DELAYED, 3. CANCELLED")
status_choice = input("Enter new status (1/2/3): ").strip()
status_map = {'1': 'ON TIME', '2': 'DELAYED', '3': 'CANCELLED'}
new_status = status_map.get(status_choice)
if new_status:
update_train_status(train_no,
new_status) else:
print("[!] Invalid status choice.")
def admin_menu():
"""Admin-specific options
loop.""" global is_adm
while is_adm:
print_header("Admin Menu")
print("1. Add New Train")
print("2. View All Trains")
print("3. Update Train
Status") print("4. Logout")
choice = input("\nEnter choice: ").strip()
if choice == '1':
handle_add_train()
elif choice == '2':
handle_view_all_trains()
elif choice == '3':
handle_update_train_status()
elif choice == '4':
logout_user()
break
else:
print("[!] Invalid choice. Please try
again.") # --- HANDLER FUNCTIONS (PASSENGER) ---
def display_search_results(trains):
"""Prints formatted search results (list of
tuples).""" if not trains:
print("\n[INFO] No trains found matching your
criteria.") return False
print("\n" + "=" * 60)
print("Available Trains:")
print("=" * 60)
print("%-6s%-25s%-10s%-7s%-12s" % ('NO', 'TRAIN NAME', 'FARE', 'AVAIL',
'STATUS'))
print("-" * 60)
# Indices: 0:train_no, 1:name, 4:fare, 6:avail_seats, 5:status (note:
indices changed from select query in search_trains)
for t in trains:
train_no = t[0]
train_name =
t[1] fare =
t[4] status =
t[5]
available_seats = t[6]
print(
"%-6s%-25s\u20B9%-9.2f%-7d%-12s" % (
train_no,
train_name,
fare,
available_seats
, status
)
)
print("-" * 60)
return True
def handle_search_and_book():
"""Gathers search criteria, displays results, and initiates booking."""
print_header("Search & Book Train")
print("Enter 'Q' at any time to return to the Passenger
Menu.") source = input("Enter Source Station:
").strip().upper()
if source == 'Q': return
destination = input("Enter Destination Station:
").strip().upper() if destination == 'Q': return
journey_date_str = validate_date("Enter Date of Journey (YYYY-MM-
DD): ") if journey_date_str == 'Q': return
trains = search_trains(source, destination,
journey_date_str) if not
display_search_results(trains):
return
book_choice = input("Proceed to booking? (Y/N):
").strip().upper() if book_choice != 'Y':
return
# --- Booking Sub-flow ---
train_no = input("Enter Train Number to book:
").strip().upper() if train_no == 'Q': return
# Finding the selected train tuple in the list of results
valid_train = None
for t in trains:
if t[0] == train_no: # t[0] is train_no
valid_train = t
break
if not valid_train:
print("[!] Invalid train number
entered.") return
# valid_train[6] is available_seats
max_seats = valid_train[6]
seats_to_book = validate_int("Enter number of seats to book (Max %d): "
% max_seats)
if seats_to_book == 'Q': return
if seats_to_book > max_seats:
print("[!] Cannot book %d seats. Available: %d" %
(seats_to_book, max_seats))
return
# Call the booking logic
book_ticket(train_no, journey_date_str, seats_to_book)
def handle_view_my_bookings():
"""Displays the current user's booked tickets."""
print_header("My Bookings")
bookings = view_my_bookings()
if not bookings:
print("You have no current or past
bookings.") return
# Print a formatted table header
print("%-15s%-6s%-20s%-12s%-7s%-10s%-10s" % ('PNR', 'TRAIN', 'NAME',
'DATE', 'SEATS', 'PRICE', 'STATUS'))
print("-" * 80)
# Indices: 0:pnr_no, 1:train_no, 2:name, 3:source, 4:dest, 5:date,
6:seats, 7:price, 8:status
for b in
bookings:
pnr = b[0]
tno = b[1]
tname = b[2]
date_of_journey = b[5].strftime('%Y-%m-
%d') seats = b[6]
price = b[7]
status =
b[8]
status_display = "[CONFIRMED]" if status == 'CONFIRMED' else
"[CANCELLED]" print(
"%-15s%-6s%-20.20s%-12s%-7d\u20B9%-9.2f%-10s" % (
pnr,
tno,
tname
,
date_of_journey,
seats,
price,
status_display
)
)
print("-" * 80)
def handle_cancel_ticket():
"""Gathers PNR and calls the cancellation logic."""
print_header("Cancel Ticket")
pnr_no = input("Enter PNR Number of the ticket to cancel:
").strip().upper()
if pnr_no:
cancel_ticket(pnr_no
) else:
print("[!] PNR cannot be empty.")
def passenger_menu():
"""Passenger-specific options loop."""
global user_id, is_adm
while user_id and not is_adm:
print_header("Passenger Menu")
print("1. Search & Book Train")
print("2. View My Bookings")
print("3. Cancel Ticket (by
PNR)") print("4. Logout")
choice = input("\nEnter choice: ").strip()
if choice == '1':
handle_search_and_book()
elif choice == '2':
handle_view_my_bookings()
elif choice == '3':
handle_cancel_ticket(
)
elif choice == '4':
logout_user()
break
else:
print("[!] Invalid choice. Please try
again.") # --- MAIN APPLICATION FLOW ---
def handle_registration():
"""Gathers user input for new account registration."""
print_header("New User Registration")
username = input("Enter Username:
").strip() name = input("Enter Full
Name: ").strip() email = input("Enter
Email: ").strip()
phone = input("Enter Phone Number: ").strip()
password = input("Enter Password: ").strip()
if all([username, name, email, phone, password]):
register_user(username, name, email, phone, password)
else:
print("[FAILURE] All fields are mandatory for registration.")
def handle_login():
"""Gathers login credentials and attempts
authentication.""" print_header("User Login")
username = input("Enter Username:
").strip() password = input("Enter
Password: ").strip()
login_user(username,
password) def main_app_loop():
"""The main loop that directs flow based on user type."""
global is_adm,
user_id if is_adm:
admin_menu()
elif user_id:
passenger_menu()
def main_auth_menu():
"""The initial menu for registration or
login.""" global user_id
while user_id is None:
print_header("Welcome to RMS - Railway Management
System") print("1. Login")
print("2. Register")
print("3. Exit System")
choice = input("\nEnter choice: ").strip()
if choice == '1':
handle_login()
elif choice == '2':
handle_registration()
elif choice == '3':
print("Exiting Railway Management System.
Goodbye!") close_db()
[Link](0)
else:
print("[!] Invalid choice. Please try again.")
# Main entry point of the
application if name == " main
":
if not connect_db():
[Link](1)
try:
main_auth_menu() # First, handle login/registration
# Loop until the user exits or logs
out while True:
if user_id:
main_app_loop() # Go to admin/passenger
menu else:
# If they logged out, return to the auth menu
main_auth_menu()
except KeyboardInterrupt:
print("\n[INFO] Program interrupted by
user.") except Exception as e:
print("\n[CRITICAL ERROR] An unexpected error occurred: %s" %
e) finally:
close_db()
[Link](0)