-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathsmart_fare (1).py
More file actions
235 lines (211 loc) · 11.1 KB
/
Copy pathsmart_fare (1).py
File metadata and controls
235 lines (211 loc) · 11.1 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
import os, hashlib, datetime, random
FOLDER = "smart_fare_data"
BASE_FARE, FARE_PER_KM = 5, 2
ROUTES = {
"R01": {"name": "City Centre to Airport", "distance_km": 25},
"R02": {"name": "Old Town to Tech Park", "distance_km": 18},
"R03": {"name": "University to Railway Station", "distance_km": 12},
"R04": {"name": "Suburbs to Shopping Mall", "distance_km": 10},
"R05": {"name": "Hospital to IT Corridor", "distance_km": 15},
}
# ── helpers ──────────────────────────────────────────────────────────────────
def clear(): os.system("cls" if os.name == "nt" else "clear")
def line(c="="): print(c * 50)
def header(t): line(); print(" " + t); line()
def today(): return datetime.date.today().strftime("%Y-%m-%d")
def now(): return datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")
def hash_pw(p): return hashlib.sha256(p.encode()).hexdigest()
def new_id(): return "SF-" + "".join(random.choices("ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789", k=8))
def calc_fare(km): return BASE_FARE + km * FARE_PER_KM
# ── file i/o ─────────────────────────────────────────────────────────────────
def _path(f): return FOLDER + "/" + f
def _read(f):
try:
with open(_path(f)) as fp: return [l.strip() for l in fp if l.strip()]
except FileNotFoundError: return []
def _write(f, lines):
with open(_path(f), "w") as fp: fp.write("\n".join(lines) + "\n")
def load_users():
u = {}
for l in _read("users.txt"):
k, pw, w, j = l.split("|")
u[k] = {"password": pw, "wallet": float(w), "joined_on": j}
return u
def save_users(u):
_write("users.txt", [f"{k}|{v['password']}|{v['wallet']}|{v['joined_on']}" for k, v in u.items()])
def load_tickets():
t = {}
for l in _read("tickets.txt"):
u, tid, route, fare, dt, st = l.split("|")
t.setdefault(u, []).append({"ticket_id": tid, "route": route, "fare": fare, "booked_on": dt, "status": st})
return t
def save_tickets(t):
_write("tickets.txt", [f"{u}|{x['ticket_id']}|{x['route']}|{x['fare']}|{x['booked_on']}|{x['status']}" for u, xs in t.items() for x in xs])
def load_passes():
p = {}
for l in _read("passes.txt"):
u, pid, label, price, s, e = l.split("|")
p.setdefault(u, []).append({"pass_id": pid, "label": label, "price": price, "start_date": s, "end_date": e})
return p
def save_passes(p):
_write("passes.txt", [f"{u}|{x['pass_id']}|{x['label']}|{x['price']}|{x['start_date']}|{x['end_date']}" for u, xs in p.items() for x in xs])
# ── auth ──────────────────────────────────────────────────────────────────────
def register():
header("CREATE NEW ACCOUNT")
users = load_users()
while True:
u = input("Choose a username: ").strip().lower()
if not u: print("Username cannot be empty.")
elif u in users: print("Username taken. Try another.")
else: break
while True:
pw = input("Choose a password (min 4 chars): ").strip()
if len(pw) < 4: print("Password too short."); continue
if input("Confirm password: ").strip() != pw: print("Passwords do not match.")
else: break
while True:
try:
bal = float(input("Add money to wallet (Rs.): "))
if bal >= 0: break
print("Amount cannot be negative.")
except ValueError: print("Enter a number like 500.")
users[u] = {"password": hash_pw(pw), "wallet": bal, "joined_on": today()}
save_users(users)
print(f"\nAccount created! Welcome, {u}")
return u
def login():
header("LOGIN")
users, attempts = load_users(), 3
while attempts > 0:
u = input("Username: ").strip().lower()
pw = input("Password: ").strip()
if u in users and users[u]["password"] == hash_pw(pw):
print(f"\nWelcome back, {u}!"); return u
attempts -= 1
print(f"Wrong credentials. {attempts} attempt(s) left.")
print("Too many failed attempts."); return None
# ── transport ─────────────────────────────────────────────────────────────────
def view_profile(u):
header("MY PROFILE")
usr = load_users().get(u, {})
print(f" Username : {u}\n Member Since : {usr.get('joined_on','N/A')}\n Wallet Bal. : Rs. {usr.get('wallet',0)}")
def top_up_wallet(u):
header("PAYMENT / TOP-UP WALLET")
users = load_users()
print("Current Balance: Rs.", users[u]["wallet"])
print("\n [1] UPI\n [2] Debit / Credit Card\n [3] Net Banking\n [0] Back")
ch = input("\nYour choice: ").strip()
methods = {"1": "UPI", "2": "Card", "3": "Net Banking"}
if ch == "0" or ch not in methods: return
while True:
try:
amt = float(input("Enter amount to add (Rs.): "))
if amt > 0: break
print("Amount must be more than 0.")
except ValueError: print("Enter a valid number.")
print(f"\nProcessing {methods[ch]} payment of Rs. {amt} ...\nPayment Successful!")
users[u]["wallet"] += amt
save_users(users)
print("New Balance: Rs.", users[u]["wallet"])
def _print_receipt(t, u, bal):
line("*"); print(" SMART FARE - TICKET RECEIPT"); line("*")
print(f" Ticket ID : {t['ticket_id']}\n Passenger : {u}\n Route : {t['route']}")
print(f" Fare Paid : Rs. {t['fare']}\n Date/Time : {t['booked_on']}\n Status : {t['status']}")
print(f" Balance : Rs. {bal}"); line("*")
print(" Thank you for travelling with Smart Fare!"); line("*")
def book_ticket(u):
header("BOOK A TICKET")
users = load_users()
print("Available Routes:\n")
for code, info in ROUTES.items():
print(f" [{code}] {info['name']} | Rs.{calc_fare(info['distance_km'])}")
rc = input("\nEnter Route Code (e.g. R01): ").strip().upper()
if rc not in ROUTES: print("Invalid route code."); return
route, fare, bal = ROUTES[rc], calc_fare(ROUTES[rc]["distance_km"]), users[u]["wallet"]
print(f"\n Route : {route['name']}\n Distance : {route['distance_km']} km\n Fare : Rs. {fare}\n Wallet : Rs. {bal}")
if bal < fare: print(f"Not enough balance! You need Rs. {fare - bal} more."); return
if input("\nConfirm booking? (y/n): ").strip().lower() != "y": print("Booking cancelled."); return
users[u]["wallet"] -= fare
save_users(users)
new = {"ticket_id": new_id(), "route": route["name"], "fare": fare, "booked_on": now(), "status": "Active"}
tickets = load_tickets()
tickets.setdefault(u, []).append(new)
save_tickets(tickets)
_print_receipt(new, u, users[u]["wallet"])
def ticket_history(u):
header("MY TICKET HISTORY")
my = load_tickets().get(u, [])
if not my: print("No tickets booked yet."); return
print(f"Total Tickets: {len(my)}\n")
for i, t in enumerate(my, 1):
print(f" [{i}] {t['ticket_id']} | {t['route']}\n Fare: Rs.{t['fare']} | {t['booked_on']}\n")
ch = input("Enter ticket number for receipt (or 0 to go back): ").strip()
try:
idx = int(ch) - 1
if 0 <= idx < len(my): _print_receipt(my[idx], u, load_users()[u]["wallet"])
except ValueError: pass
def buy_pass(u):
header("BUY A BUS PASS")
users = load_users()
print(f"Wallet Balance: Rs. {users[u]['wallet']}\n")
print(" [1] Weekly Pass - Rs.299 (20% off, 7 days)")
print(" [2] Monthly Pass - Rs.999 (40% off, 30 days)\n [0] Back")
ch = input("\nChoose: ").strip()
opts = {"1": {"label": "Weekly Pass", "price": 299, "days": 7}, "2": {"label": "Monthly Pass", "price": 999, "days": 30}}
if ch == "0" or ch not in opts: return
sel, bal = opts[ch], users[u]["wallet"]
print(f"\n Pass : {sel['label']}\n Price : Rs. {sel['price']}\n Wallet: Rs. {bal}")
if bal < sel["price"]: print("Not enough balance."); return
if input("Confirm purchase? (y/n): ").strip().lower() != "y": print("Cancelled."); return
users[u]["wallet"] -= sel["price"]
save_users(users)
start = datetime.date.today()
end = start + datetime.timedelta(days=sel["days"])
new = {"pass_id": new_id(), "label": sel["label"], "price": sel["price"], "start_date": str(start), "end_date": str(end)}
passes = load_passes()
passes.setdefault(u, []).append(new)
save_passes(passes)
line("*"); print(" SMART FARE - PASS RECEIPT"); line("*")
print(f" Pass ID : {new['pass_id']}\n Type : {new['label']}\n Valid : {new['start_date']} to {new['end_date']}")
print(f" Price : Rs. {new['price']}\n Balance : Rs. {users[u]['wallet']}"); line("*")
def view_passes(u):
header("MY BUS PASSES")
my = load_passes().get(u, [])
if not my: print("No passes bought yet."); return
td = datetime.date.today()
for p in my:
left = (datetime.date.fromisoformat(p["end_date"]) - td).days
status = f"Active - {left} days left" if left >= 0 else "Expired"
print(f" Pass ID : {p['pass_id']}\n Type : {p['label']}\n Valid : {p['start_date']} to {p['end_date']}\n Status : {status}\n")
# ── dashboard & main ──────────────────────────────────────────────────────────
def dashboard(u):
actions = {"1": book_ticket, "2": ticket_history, "3": buy_pass, "4": view_passes, "5": top_up_wallet, "6": view_profile}
while True:
clear(); line()
print(f" SMART FARE | Hello, {u.upper()}"); line()
print(" [1] Book a Ticket\n [2] My Ticket History\n [3] Buy a Bus Pass")
print(" [4] View My Passes\n [5] Payment / Top-Up Wallet\n [6] My Profile\n [0] Logout"); line()
ch = input(" Your choice: ").strip()
if ch == "0": print(f"\nGoodbye, {u}! Travel safe!"); break
elif ch in actions:
try: actions[ch](u)
except Exception as e: print("Something went wrong:", e)
else: print("Invalid choice.")
input("\nPress Enter to continue ...")
def main():
os.makedirs(FOLDER, exist_ok=True)
while True:
clear(); line()
print(" SMART FARE\n Bus Ticket Management System"); line()
print(" [1] Login\n [2] Create Account\n [0] Exit"); line()
ch = input(" Your choice: ").strip()
try:
if ch == "1": u = login(); u and dashboard(u)
elif ch == "2": u = register(); u and dashboard(u)
elif ch == "0": print("\nThank you for using Smart Fare! Goodbye!\n"); break
else: print("Invalid choice.")
except KeyboardInterrupt: print("\n\nApp closed. Goodbye!"); break
except Exception as e: print("Something went wrong:", e)
input("\nPress Enter to continue ...")
if __name__ == "__main__":
main()