-
Notifications
You must be signed in to change notification settings - Fork 20
/
Copy pathBustle.py
1440 lines (1402 loc) · 62.7 KB
/
Bustle.py
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
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
#For displaying images in the terminal itself
from PIL import Image
#For generating QR code's in python
import pyqrcode
#QR code module
from pyqrcode import QRCode
#To write in dictionary
import pickle
#Using to clear screen using defined clear() function
import os
from random import sample
#Slow down execution using sleep()
import time
#used to accept password without showing characters
import stdiomask
#Used to display a table
from tabulate import tabulate
#Used to create new voucher values with different references
from copy import deepcopy
#Used to evaluate regex
import re
#used to generate qr codes
import pyqrcode
clear = lambda: os.system('cls|clear')#Lambda function to clear the screen
user = ''#Global variable to record currently logged in user
def fileWrite(filename,data):#Universal function to write to any mentioned file
with open(filename,'wb') as file:
pickle.dump(data,file) #uses pickle module to write data into specified file
def fileRead(filename):#Universal function to read any mentioned file
with open(filename,'rb') as file:
data=pickle.load(file)
return data
def logout():#Function to display logout screen
clear()
print("Logging out");time.sleep(0.5);clear()
print("Logging out.");time.sleep(0.5);clear()
print("Logging out..");time.sleep(0.5);clear()
print("Logging out...");time.sleep(0.5);clear() #prints Logging out... with one . added every 0.5s and the screen cleared before adding each
login()
def setpass(usnID,score):#Function to set the password and security question
accounts = fileRead("bustle_files/UserAcc") #Reads existing user accounts as a dictionary
pass1 = input("Enter a password:\n")
pass1 = pass1.strip() #strips the password of any spaces on either side
while True:
pass2 = input("Confirm password:\n")
if pass2 == pass1:
while True:
sq = input("Enter your Security Question(Minimum of 5 characters ending with a '?'):\n")
if len(sq) >= 6 and sq.endswith('?'):
sa = input("Enter the answer for your Security Question:\nWARNING: Give an answer you can remember. You will need these in case you have to reset your account password!\n")
accounts.update({usnID:[pass1,score,sq,sa]}) #updates the details for user with given user id
fileWrite('bustle_files/UserAcc',accounts) #writes the updated list of users to the file that stores users and their details
return
else:
print("Enter a valid security question!(Min 5 characters ending with a '?')")
time.sleep(3) #waits for 3 seconds before clearing screen
clear()
continue
else:
print("Oops password doesn't match! Try again:")
def register(): #Function to add new user account
while True:
usn=input("Enter a username(Minimum of 5 characters without special characters):\n")
usn=usn.strip()
if len(usn) >= 5 and usn.isalnum(): #ensures that the username is a minimum of 5 characters and contains only alphabets and numbers
usn=usn+'e' #appends e to the username
break
else:
print("Enter a valid username!(Min 5 characters without special characters)")
time.sleep(3) #waits for 3 seconds before clearing
clear()
accounts=fileRead("bustle_files/UserAcc")
if usn in accounts: #if the given username is found in the list of registered users, a new account is not created and the user is notified that their account already exists
print("Account already exists!")
else:
setpass(usn,1000)
vdata=fileRead("bustle_files/vouchers")
vdatacopy=deepcopy(vdata["admine"])
del vdatacopy[4]
vdata.update({usn:vdatacopy}) #updates voucher data
fileWrite("bustle_files/vouchers",vdata) #writes updated voucher data to the file storing voucher details
print('User account successfully created! You will now be redirected to the login page')
def voucher():#Function to display and purchase vouchers
vfile=fileRead("bustle_files/vouchers")
accounts=fileRead("bustle_files/UserAcc") #reads the contents of file storing user details and the file storing voucher details
global user #global declaration allows us to access the user variable defined in the global scope
clear()
print("\t\t\t\tVouchers!")
print(f"\nUser:{user}\n")
print(f"Score:{accounts[user+'e'][1]}\n")
data =list(zip(vfile[user+'e'][0],vfile[user+'e'][1],vfile[user+'e'][2],vfile[user+'e'][3]))
print(tabulate(data, headers=["V.Code","Description","Bustle Points","Purchased"], tablefmt = "fancy_grid")) #prints the voucher details for every user in a formatted manner
vchoice=input("Which voucher would you like to purchase?\n")
if vchoice in vfile[user+'e'][0]:
vquantity=int(input("How many would you like to buy?\n"))
i=vfile["admine"][0].index(vchoice)
if int(accounts[user+'e'][1])>=(int(vfile[user+'e'][2][i])*vquantity): #makes sure the user has enough currency to purchase the specified type and amount of vouchers
print(f"{vquantity} Vouchers Added!")
vfile[user+'e'][3][i]=int(vfile[user+'e'][3][i])+vquantity
accounts[user+'e'][1]=int(accounts[user+'e'][1])-(int(vfile[user+'e'][2][i])*vquantity) #updates the vouchers possessed and the currency possessed
fileWrite("bustle_files/vouchers",vfile)
fileWrite("bustle_files/UserAcc",accounts) #writes the changes to the respective files
time.sleep(2)
elif int(accounts[user+'e'][1])<(int(vfile[user+'e'][2][i])*vquantity):
ynchoice=input("Insufficient Bustle Points!\nWould you like to play some games to get more Bustle Points?(y/n)\n")
#if the user has insufficient currency, they are encouraged to earn more by playing games
if ynchoice=='y':
clear()
games() #loads games if the user wishes to play
else:
clear()
home() #else it navigates back to the home screen
elif vchoice=='c':
clear()
home()
else:
print("Invalid input. Reinitializing page...")
time.sleep(2)
clear()
voucher()
home()
def vouchdisc(price): #function to view and utilise vouchers
global user
price=int(price)
ynchoice=input("Would you like to see the list of available vouchers?(y/n)\n")
if ynchoice=='y' and price>100:
vfile=fileRead("bustle_files/vouchers")
vcodes=[]
vdesc=[]
vnum=[]
for n in vfile[user+'e'][3]:
if n>0:
i=vfile[user+'e'][3].index(n)
vcodes.append(vfile[user+'e'][0][i])
vdesc.append(vfile[user+'e'][1][i])
vnum.append(vfile[user+'e'][3][i])
while True:
print(f"Bill Amount:{price}")
data =list(zip(vcodes,vdesc,vnum))
print(tabulate(data, headers=["V.Code","Description","Available"], tablefmt = "fancy_grid"))
vchoice=input("Which Voucher would you like to apply?\n")
if vchoice in vcodes:
i=vfile[user+'e'][0].index(vchoice)
vfile[user+'e'][3][i]=int(vfile[user+'e'][3][i])-1
discexp=vfile["admine"][4][i]
if eval(discexp)>=100:
price=eval(discexp)
return price #updates price based on the discount obtained by using a voucher
else:
print("This voucher cannot be applied on the current transaction!")
time.sleep(2)
clear()
return 0
elif vchoice=='c':
return 0
else:
print("Invalid Input, Reinitializing page...")
time.sleep(2)
clear()
elif ynchoice=='y' and price<=100:
print("Voucher cannot be applied on the current transaction!") #does not allow the application of vouchers on products under 100 rupees
return -1
elif ynchoice=='n':
return -1
else:
print("Invalid input, reinitializing...")
time.sleep(2)
clear()
return 0
def load():#Function to display loading screen
print("Loading");time.sleep(0.5);clear()
print("Loading.");time.sleep(0.5);clear()
print("Loading..");time.sleep(0.5);clear()
print("Loading...");time.sleep(0.5);clear()
def CardVerify(cnumber,ctype,ccomp):#Funcion to verfiy Card Number
if ctype=='1':
if ccomp=='1':
pattern="^5[1-5][0-9]{14}|^(222[1-9]|22[3-9]\\d|2[3-6]\\d{2}|27[0-1]\\d|2720)[0-9]{12}$" #all pattern variables are regexs defining the accepted format of credit card number for the specified type of credit card
elif ccomp=='2':
pattern="^4[0-9]{12}(?:[0-9]{3})?$"
elif ctype=='2':
if ccomp=='1':
pattern="^5[1-5][0-9]{14}|^(222[1-9]|22[3-9]\\d|2[3-6]\\d{2}|27[0-1]\\d|2720)[0-9]{12}$"
elif ccomp=='2':
pattern="^4[0-9]{12}(?:[0-9]{3})?$"
elif ctype == 'c':
clear()
load()
Booking()
p=re.compile(pattern)
if(re.search(p,cnumber)): #search is used to search for the presence of a substring. if the presence is detected, a Match object is returned which will evaluate to True if converted to boolean values. Here, if the given card number matches the corresponding regex for the card type it is accepted
return True
else:
return False
def settings():#Funtion for settings page
clear()
global user
accounts=fileRead("bustle_files/UserAcc")
book= fileRead("bustle_files/bookings") #opens and reads from file storing booking details
vouch=fileRead("bustle_files/vouchers")
setchoice=input("Settings:\n1)Clear Booking History\n2)Change Username\n3)Change Password\n4)Delete Profile\n5)About us\n6)Back\n")
if setchoice=='1': #option to clear booking history
while True:
ynchoice=input("Do you want to clear your Booking History?(y/n)\n")
if ynchoice=='y':
clear()
print("Booking History Cleared!")
del book[user] #deletes bookings for specified user
book.update({user:([],[],[],[])}) #after deleting, adds empty details for user
fileWrite("bustle_files/bookings",book) #writes updates to file
time.sleep(2)
settings() #opens the settings menu
elif ynchoice=='n':
print("Operation cancelled. Redirecting...")
time.sleep(2)
settings()
else:
print("Invalid Input, Reinitializing page...")
time.sleep(2)
clear()
elif setchoice=='2': #option to change username
ynchoice=input("Do you want to change your Username?(y/n)\n")
if ynchoice=='y':
clear()
newUSN=input("Enter the new username\n")
accounts[newUSN+'e']=accounts[user+'e'] #creates an account with the same details as the one with previous username but key as the new username
book[newUSN]=book[user] #updates bookings for user with the same details as the one with previous username but key as the new username
vouch[newUSN+'e']=vouch[user+"e"] #updates vouchers for user with the same details as the one with previous username but key as the new username
del accounts[user+'e']
del vouch[user+'e']
del book[user] #deletes records with key os old username
fileWrite("bustle_files/UserAcc",accounts)
fileWrite("bustle_files/vouchers",vouch)
fileWrite("bustle_files/bookings",book) #writes the changes to the files
print("Username changed! You will now be taken back to the settings page...")
user=newUSN
time.sleep(2)
settings() #takes user back to settings page
elif ynchoice=='n':
print("Operation cancelled. Redirecting...")
time.sleep(2)
settings()
else:
print("Invalid Input, Reinitializing page...")
time.sleep(2)
clear()
elif setchoice=='3': #option to change password
ynchoice=input("Do you want to change your Password?(y/n)\n")
if ynchoice=='y':
clear()
while True:
newPass=input("Confirm Current Password\n")
if newPass==accounts[user+'e'][0]: #only allows password to be changed if the entered current password is correct
newPass=input("Enter the new password:\n")
if newPass==input("Confirm the password:\n"):
accounts[user+'e'][0]=newPass
fileWrite("bustle_files/UserAcc",accounts) #updates password and writes to file
print("Password changed successfully! You will be redirected to the settings page\n")
time.sleep(2)
clear()
settings()
else:
print("The passwords do not match! Try setting the password again.") #displayed if the initial new password and the confirmation new password are different
time.sleep(2)
clear()
elif newPass=='c':
clear()
settings()
else:
print("Incorrect Password! Try Again")
time.sleep(3)
clear()
elif ynchoice=='n':
print("Operation cancelled. Redirecting...")
time.sleep(2)
settings()
else:
print("Invalid Input. Reinitializing page...")
time.sleep(2)
settings()
elif setchoice=='4': #option to delete user profile
ynchoice=input("Are you sure you want to delete your profile?(y/n)\n")
if ynchoice=='y':
del accounts[user+'e']
del book[user]
del vouch[user+'e'] #deletes all entries related to the user
fileWrite("bustle_files/UserAcc",accounts)
fileWrite("bustle_files/bookings",book)
fileWrite("bustle_files/vouchers",vouch) #updates all files
print("User Deleted! Hope to see you again!\n")
time.sleep(2)
clear()
menu() #redirects to menu
elif setchoice=='5': #option to display about us section
clear()
print("Team bustle is a group of persistant, hard working and perfectionist coders.")
print("Project Bustle, our very first project, is an intuitive slot booking and management software that ensures your time and efforts saved")
print("Members: Harsh Somvanshi, Harini Anand and Bhaskarla Sri Saahith")
time.sleep(4)
settings()
elif setchoice=='6':
clear()
home() #redirects to home page
else:
print("Invalid Input. Reinitializing page...")
time.sleep(2)
settings()
def admin():#Function to allow admin to manage the program
adminpass = fileRead("bustle_files/UserAcc")
adminpass = adminpass["admine"]
clear()
mastchoice1=input("What would you like to do?\n1)Add provider\n2)Delete provider\n3)Manage Vouchers\n4)Manage User Accounts\n5)Logout\n")
if mastchoice1=='1': #option to add
mastchoice2=input("Choose a category to add to: \n1)Restaurant\n2)Hotel\n3)Spa\n4)Bicycle Repair\n5)Back\n")#Add other services here
if mastchoice2=='1' or mastchoice2=='2':
if mastchoice2=='1':
tempname="restaurant"
try:
service=fileRead(f"bustle_files/restaurants/{tempname}")
except:
fileWrite(f"bustle_files/restaurants/{tempname}",{})
service=fileRead(f"bustle_files/restaurants/{tempname}")
elif mastchoice2=='2':
tempname="hotel"
try:
service=fileRead(f"bustle_files/hotels/{tempname}")
except:
fileWrite(f"bustle_files/hotels/{tempname}",{})
service=fileRead(f"bustle_files/hotels/{tempname}")
'''elif mastchoice2=='3':
tempname="bus"
try:
service=fileRead(f"bustle_files/buss/{tempname}")
except:
fileWrite(f"bustle_files/buss/{tempname}",{})
service=fileRead(f"bustle_files/buss/{tempname}")'''
while True:
try:
npname,npseat,npprice=input("Enter Name/Available Slots/Price\n").split('/')
except:
print("Incorrect number of inputs received")
time.sleep(3)
clear()
admin() #navigates to admin page
if npname in service:
print("Entry already exists!")
time.sleep(3)
else:
service.update({npname:[npseat,npprice]}) #updates service if it doesnt exist
break
fileWrite(f"bustle_files/{tempname+'s'}/{tempname}",service)
clear()
print("Provider successfully added!")
time.sleep(3)
admin()
elif mastchoice2=='3' or mastchoice2=='4':
if mastchoice2=='3':
tempname="spa"
try:
service=fileRead(f"bustle_files/spas/{tempname}")
except:
fileWrite(f"bustle_files/spas/{tempname}",{})
service=fileRead(f"bustle_files/spas/{tempname}")
elif mastchoice2=='4':
tempname="cycle"
try:
service=fileRead(f"bustle_files/cycles/{tempname}")
except:
fileWrite(f"bustle_files/cycles/{tempname}",{})
service=fileRead(f"bustle_files/cycles/{tempname}")
while True:
try:
if mastchoice2=='4':
nptype='cycle'
npname,npexp,npprice=input("Enter Name/Experience/Price\n").split('/')
else:
npname,nptype,npexp,npprice=input("Enter Name/Expertise/Experience/Price\n").split('/')
except:
print("Incorrect number of inputs received")
time.sleep(3)
clear()
admin()
if npname in service:
ynchoice=input("Entry already exists! Do you want to add another provider?(y/n)\n")
if ynchoice=='n':
admin()
else:
service.update({npname:[npexp,nptype,npprice]})
break
fileWrite(f"bustle_files/{tempname+'s'}/{tempname}",service)
clear()
print("Provider successfully added!")
time.sleep(3)
admin()
elif mastchoice2=='5':
clear()
admin()
else:
print("Invalid input! Reinitializing page...")
time.sleep(3)
clear()
admin()
elif mastchoice1=='2': #option to delete
while True:
mastchoice2=input("Choose a category to delete from:\n1)Restaurant\n2)Hotel\n3)Spa\n4)Bicycle Repair\n5)Back\n")#Add other services here
if mastchoice2=='1':
tempname="restaurant"
elif mastchoice2=='2':
tempname="hotel"
#elif mastchoice2=='3':
#tempname="bus"
elif mastchoice2=='3':
tempname="spa"
elif mastchoice2=='4':
tempname="cycle"
elif mastchoice2=='5':
admin()
else:
print("Invalid input! Reinitializing page..")
time.sleep(2)
clear()
continue
try:
service=fileRead(f"bustle_files/{tempname+'s'}/{tempname}")
if service:
for key in service:
print(key)
else:
ynchoice=input("No providers available for this category yet. Would you like to add a provider instead?(y/n)\n")
if ynchoice=='y':
clear()
admin()
elif ynchoice=='n':
continue
except:
ynchoice=input("No entries in this category available! Do you want to browse another category instead?(y/n)\n")
if ynchoice=='n':
admin()
elif ynchoice=='y':#check if really necessary
continue
dpname=input("Which provider would you like to delete?\n")
if dpname in service:
loginpass=stdiomask.getpass("Enter admin password to confirm:\n")
if loginpass==adminpass:
del service[dpname]
fileWrite(f"bustle_files/{tempname+'s'}/{tempname}",service)
print("Provider Deleted!\n")
else:
print("Incorrect password. Provider deleletion failed")
time.sleep(3)
clear()
else:
print("Provider doesn't exist! Provider deleletion failed")
time.sleep(3)
clear()
elif mastchoice1=='3': #option to manage vouchers
vfile=fileRead("bustle_files/vouchers")
vchoice=input("What would you like to do?\n1)Add Voucher\n2)Delete voucher\n")
if vchoice=='1':
while True:
try:
vcode,vdesc,vscore=input("Enter Voucher Code/Voucher Description/Cost\n").split('/')
vcalc=input("Enter the mathematical expression on \"price\"\n")
break
except:
print("Invalid Input! Reinitializing page")
time.sleep(3)
clear()
for user in fileRead("bustle_files/UserAcc"):
if user in vfile: #appends voucher information for the selected user
vfile[user][0].append(vcode)#list of all voucher codes
vfile[user][1].append(vdesc)#list of all voucher descriptions
vfile[user][2].append(vscore)#list of all costs
vfile[user][3].append(0)#quantity of vouchers present
vfile.update({user:vfile[user]}) #updates voucher file with user voucher data
vfile["admine"][4].append(vcalc)#list of all the mathematical operations for vouchers
fileWrite("bustle_files/vouchers",vfile) #writes all updates into the voucher file
clear()
print("Voucher Added!")
time.sleep(3)
admin() #navigates to admin after running successfully
elif vchoice=='2':
vfile=fileRead("bustle_files/vouchers")
while True:
if len(vfile["admine"][0])!=0:
print("Which voucher would you like to delete?")
print(vfile["admine"][0]) #prints voucher codes
vcode=input()
if vcode in vfile["admine"][0]:
i=vfile["admine"][0].index(vcode)
for user in vfile: #deletes all voucher related information for a given voucher code
del vfile[user][0][i]
del vfile[user][1][i]
del vfile[user][2][i]
del vfile[user][3][i]
vfile.update({user:vfile[user]})
fileWrite("bustle_files/vouchers",vfile)
clear()
print("Voucher Deleted!")
time.sleep(3)
admin()
else:
print("Invalid input! Reinitializing page...")
time.sleep(2)
clear()
continue
else:
print("No vouchers found!")
time.sleep(3)
clear()
admin()
elif vchoice=='c':
clear()
admin()
else:
print("Invalid Input!")
time.sleep(3)
clear()
admin()
elif mastchoice1=='4':
mchoice=input("What would you like to do?\n1)Enable/Disable user\n2)Delete a user\n")
accounts = fileRead("bustle_files/UserAcc")
if mchoice=='1':
print("Which account do you wish to manage?")
for key in accounts: #As accounts is stored as a dictionary we must refer to its keys, where keys are user id
if key != "admine":
print(key)
edchoice = input()
if edchoice in accounts and edchoice[-1] == 'e': #checks if a user exists and is enabled before disabling their account
print(f"Do you wish to disable {edchoice}(y/n)?")
yncheck = input()
if yncheck == 'y':
accounts[edchoice[0:-1]+'d'] = accounts[edchoice]
del accounts[edchoice]
elif edchoice in accounts and edchoice[-1] == 'd': #checks if a user exists and is disabled before enabling their account
print(f"Do you wish to enable {edchoice}?(y/n)")
yncheck = input()
if yncheck == 'y':
accounts[edchoice[0:-1]+'e'] = accounts[edchoice]
del accounts[edchoice]
else:
print("Account doesnt exist! Try again!") #notifies the user if the selected account to disable does not exist
time.sleep(3)
admin()
fileWrite("bustle_files/UserAcc",accounts)
elif mchoice=='2':
for key in accounts:
if key != "admine":
print(key)
usnchoice=input("Which user would you like to delete\n")
while True:
if usnchoice in accounts: #As user id is key and usnchoice is a user id, this expression is valid
del accounts[usnchoice]
vfile=fileRead("bustle_files/vouchers")
del vfile[usnchoice]
fileWrite("bustle_files/UserAcc",accounts)
fileWrite("bustle_files/vouchers",vfile) #deletes user and writes the changes to the files
print("User deleted!")
time.sleep(2)
clear()
admin()
elif usnchoice=='c':
clear()
break
else:
print("Invalid Input! Reinitializing...")
clear()
elif mchoice=='c':
clear()
admin()
else:
print("Invalid Input! Reinitializing...")
clear()
admin()
elif mastchoice1=='5':
logout()
else:
print("Invalid Input! Reinitializing page...")
time.sleep(3)
admin()
def games():#Function to display and launch games
global user
accounts=fileRead("bustle_files/UserAcc")
print("Which game would you like to play?\n")
gchoice=input("1)Snake!\n2)Bustle Tetris\n3)Impossible Tic-Tac-Toe!\n4)Sudoku\n5)Trivia!\n6)Guess the number\n7)Points Distribution\n8)Rock Paper Scissor\n9)Back\n")
if gchoice =='1':
exec(open("game_files/snake.py").read()) #exec() function is used for dynamically executing Python programs read as strings or object code
with open("tempscore","r") as file:
score=int(file.read()) #score for game is stored in the store variable which allows to delete the temporary file used to store the score
os.remove("tempscore")
if score>10:
accounts[user+'e'][1]+=int((score-10)/2)
fileWrite("bustle_files/UserAcc",accounts)
time.sleep(2)
elif gchoice =='2':
exec(open("game_files/TETRIS_FINAL.py").read())
clear()
with open("tempscore","r") as file:
score=int(file.read())
os.remove("tempscore")
score=score/10
accounts[user+'e'][1]+=int(score)
fileWrite("bustle_files/UserAcc",accounts)
print(f"Your Final Score was: {score}")
time.sleep(2)
elif gchoice =='3':
exec(open("game_files/tictactoe/TictacToe.py").read())
elif gchoice=='4':
exec(open("game_files/sudoku/GUI.py").read())
with open("tempscore","r") as file:
if not file.read() == "None":
score=int(file.read())
else:
score=0
os.remove("tempscore")
accounts[user+'e'][1]+=int(score) #increments the users total score
fileWrite("bustle_files/UserAcc",accounts) #writes the score to the users file
print(f"Your Final Score was: {score}") #prints final score using format string
time.sleep(2)
elif gchoice=='5':
exec(open("game_files/trivia/BUSTLEQUIZ.py").read())
clear()
with open("tempscore","r") as file:
score=int(file.read())
os.remove("tempscore")
accounts[user+'e'][1]+=int(score)
fileWrite("bustle_files/UserAcc",accounts)
print(f"Your Final Score was: {score}")
time.sleep(2)
elif gchoice=='6':
exec(open('game_files/Guess_The_Number.py').read())
time.sleep(2)
elif gchoice=='7':
clear()
data =list(zip(["Snake!","Bustle Tetris","Impossible Tic-Tac-Toe!","Sudoku","Trivia!"],["0.5 Bustle Points for every Game point after 10","1 Bustle point for every row cleared","100 Bustle points for winning against computer","10 Bustle points for clearing boaard","1 Bustle point for every correct answer"]))
print(tabulate(data, headers=["Game","Points Awarded"], tablefmt = "fancy_grid"))
input("\nPress any key to go back")
elif gchoice =='8':
exec(open("game_files/rps.py").read())
with open("tempscore","r") as file:
score=int(file.read())
os.remove("tempscore")
if score>10:
accounts[user+'e'][1]+=int((score-10)/2)
fileWrite("bustle_files/UserAcc",accounts)
time.sleep(2)
elif gchoice=='9':
home()
else:
print("Invalid Input. Reinitializing page...")
time.sleep(2)
clear()
games()
home()
def login(): #Checks and logs in user
clear()
n=5
accounts=fileRead("bustle_files/UserAcc")
bool=True
for key in accounts:
if key[-1]=='e':
print(key[0:-1])
elif key[-1]=='d':
print(key[0:-1],"(disabled)") #notifies a user if the accoutn they are trying to log into is disabled. disabled accoutns are denoted with a 'd' at the end and enabled accounts are denoted with 'e'
usnchoice=input("Select an account (Enter 'c' to go back)\n")
for key in accounts:
if key.startswith(usnchoice) and key[-1]=='e':
usnchoice = usnchoice + key[-1]
bool=True
elif key.startswith(usnchoice) and key[-1]=='d':
usnchoice = usnchoice + key[-1]
bool=False
if usnchoice=="admine":
loginpass=stdiomask.getpass("Enter your password\n")
if loginpass==accounts[usnchoice]:
admin()
else:
if n!=0:
print("Incorrect Password.\nTry again!\nYou have ",n," tries remaining:\n")
else:
print("Too many failed attempts. You will now be redirected to the login page")
accounts[usnchoice[0:-1]+'d']=accounts[usnchoice]
del accounts[usnchoice]
fileWrite('bustle_files/UserAcc',accounts)
return False #if login ttempt fails, the user is disabled
elif usnchoice in accounts and bool==True:
while n>=0:
loginpass=stdiomask.getpass("Enter your password\n") #stdiomask gets password input from the stdin and masks each character with *
if loginpass==accounts[usnchoice][0]:
clear()
global user
print("Welcome ",usnchoice[0:-1],"!\nLoading");time.sleep(0.5);clear()
print("Welcome ",usnchoice[0:-1],"!\nLoading.");time.sleep(0.5);clear()
print("Welcome ",usnchoice[0:-1],"!\nLoading..");time.sleep(0.5);clear()
print("Welcome ",usnchoice[0:-1],"!\nLoading...");time.sleep(0.5);clear() #Creates a loading screen
user = usnchoice[0:-1]
home()
elif loginpass=='F': #Forgot password option
fpans=input(accounts[usnchoice][2]) #The answer to the security question needs to be submitted here
if fpans== accounts[usnchoice][3]:
print("Enter New Password(Make sure to remember this one!)\nNote:You will be required to enter new Security credentials\n")
score=accounts[usnchoice][1]
setpass(usnchoice,score)
login()
else:
n=n-1
if n!=0:
print("Incorrect Password.\nForgot Password? Press F (to pay respects)\nTry again!\nYou have ",n," tries remaining:")
else:
print("Too many failed attempts. You will now be redirected to the login page")
accounts[usnchoice[0:-1]+'d']=accounts[usnchoice]
del accounts[usnchoice]
fileWrite('bustle_files/UserAcc',accounts)
return False #if all login attempts are exhausted then, the account is disabled
elif usnchoice in accounts and bool==False:
print("This account is disabled. Kindly contact the admin to re-enable your account") #if there is an attempt to access a disabled account, it will print this
return False
elif usnchoice=='c':
clear()
menu()
else:
clear()
print("This user doesn't exist!")
time.sleep(3)
login()
def home():#Home page
clear()
homechoice=input("What would you like to do today?\n1)Make a Booking\n2)Booking History\n3)Vouchers\n4)Games\n5)Settings\n6)Logout\n")
if homechoice=='1':
clear()
load()
Booking() #opens bookings page
elif homechoice=='2':
clear()
load()
BookingHist(None,None,None,None)
elif homechoice=='3':
clear()
voucher() #opens voucher page
elif homechoice=='4':
clear()
games() #opens games page
elif homechoice=='5':
clear()
settings() #opens settings page
elif homechoice=='6':
logout() #logs out a user
else:
print("Invalid Input")
time.sleep(2)
home() #if the input is invalid, the user will be returned to the home screen
def menu():#Starting page of the program
try:
fileRead("bustle_files/UserAcc")
fileRead("bustle_files/vouchers")
except:
fileWrite("bustle_files/UserAcc",{'admine':'mpass'})
fileWrite("bustle_files/vouchers",{"admine":[[],[],[],[],[]]})
while True:
loginno=input("Welcome to Bustle!\n1.Login\n2.Register\n")
if loginno=='1':
login()
elif loginno=='2':
register()
time.sleep(3)
clear()
elif loginno=='disp': #Dev Command
accounts=fileRead('bustle_files/UserAcc')
print(accounts) #displays all the accounts that are registered
elif loginno=='fclr': #Dev Command
os.remove("bustle_files/UserAcc")
fileWrite("bustle_files/UserAcc",{'admine':'mpass'}) #clears all accounts apart from the admin account
elif loginno=='m':#TEMPORARY
admin()
elif loginno=='vdisp':
print(fileRead("bustle_files/vouchers")) #prints the contents of the vouchers file
else:
print("Invalid Input")
time.sleep(3)
clear()
def Booking(): #Bookings page
bchoice = input("Which service would you like to book?\n1)Restaurant\n2)Hotel\n3)Cycle Repair\n4)Spa\n5)Back\n")
if bchoice == '1':
Restaurant()
elif bchoice == '2':
Hotel()
elif bchoice == '3':
Cycle_Repair()
elif bchoice == '4':
SPA()
elif bchoice == '5':
clear()
home()
else:
print("Invalid Input!")
time.sleep(3)
clear()
Booking()
def Restaurant(): #Choosing Restaurants
from datetime import datetime
try:
fileRead("bustle_files/restaurants/restaurant")
except:
clear()
print("Error 404: Page not found")
time.sleep(3)
Booking()
name = "Restaurant"
clear()
slots = fileRead("bustle_files/restaurants/restaurant") #opens file with list of restaurants
print("Which restaurant would you like to book a table in?")
for key in slots:
print(key) #prints list of all the restaurants
print("(Press 'c' to go back)")
rchoice = input()
if rchoice in slots: #checks if the chosen restaurant is in the list of existing ones.
try: #try except block to handle any errors that may arise
fileRead(f"bustle_files/restaurants/{rchoice}")
except:
fileWrite(f"bustle_files/restaurants/{rchoice}", {"10:00-12:00":[slots[rchoice][0],slots[rchoice][1]],"12:00-2:00":[slots[rchoice][0],slots[rchoice][1]],"2:00-4:00":[slots[rchoice][0],slots[rchoice][1]],"4:00-6:00":[slots[rchoice][0],slots[rchoice][1]],"6:00-8:00":[slots[rchoice][0],slots[rchoice][1]],"8:00-10:00":[slots[rchoice][0],slots[rchoice][1]]})
booking = fileRead(f"bustle_files/restaurants/{rchoice}") #list of restaurants that a user has a booking in
print("\nNo. of seats per table: 4")
print(f"Price per table: {slots[rchoice][1]}")
while True:
print("\nWhich Time slot would you like to book?")
i = 1
for key in booking:
print(f"{i}) {key}")
i += 1
print("(Press 'c' to go back)")
tchoice = input()
if tchoice == '1':
tname = "10:00-12:00"
elif tchoice == '2':
tname = "12:00-2:00"
elif tchoice == '3':
tname = "2:00-4:00"
elif tchoice == '4':
tname = "4:00-6:00"
elif tchoice == '5':
tname = "6:00-8:00"
elif tchoice == '6':
tname = "8:00-10:00"
elif tchoice == 'c':
clear()
Restaurant()
else:
print("Invalid Input!")
tname = ""
if tname in booking:
avail = int(booking[tname][0])
clear()
print(f"No. of tables available in time slot {tname}: {avail}")
nchoice = input("\nHow many persons would you like to book for?\n")
if nchoice.isdigit():
if int(nchoice) > 4 and int(nchoice)%4 != 0:
no = 1 + (int(nchoice)//4)
elif int(nchoice)%4 == 0:
no = int(nchoice)//4
else:
no = 1
if (avail - no) >= 0:
price = int(booking[tname][1])*no
print("No. of tables:",no)
print("Total price:",price)
ychoice = input("Would you like to proceed to checkout(y/n)?\n")
if ychoice == 'y':
clear()
load()
n=0
while True:
print("Restaurant name:",rchoice)
print("Time slot:",tname)
print("No of persons:",nchoice)
print("Total price:",price)
print(f"{n} vouchers applied!")
check=vouchdisc(price)
if check==-1:
break
elif check==0:
continue
else:
price=check
n+=1
pchoice = input("\nDo you wish to continue?(y/n)\n")
if pchoice == 'y':
if checkout():
print("Payment successful")
avail = avail - no
booking.update({tname:[avail,booking[tname][1]]})
fileWrite(f"bustle_files/restaurants/{rchoice}",booking)
now = datetime.now()
time.sleep(3)
clear()
BookingHist(rchoice,name,price,now)
else:
print("Payment Failed!")
Restaurant()
elif pchoice == 'n':
clear()
break
elif ychoice == 'n':
clear()
else:
print(f"\nSorry! {no} table(s) unavailable in time slot {tname}")
time.sleep(3)
clear()
elif nchoice == 'c':
clear()
else:
print("invalid input!")
time.sleep(3)
clear()
else:
print("Invalid time slot!")
time.sleep(3)
clear()
elif rchoice == 'c':
clear()
Booking()
else:
print("Please give a valid restaurant name")
time.sleep(3)
clear()
Restaurant()
def Hotel():#Funtion to book hotels
from datetime import datetime
try:
fileRead("bustle_files/hotels/hotel")
except:
clear()
print("Error 404: Page not found")
time.sleep(3)
Booking()
name = 'Hotel'
clear()
slots = fileRead("bustle_files/hotels/hotel")
print("Which hotel would you like to book a room in?")
for key in slots:
print(key)
print("(Press 'c' to go back)")
hchoice = input()
if hchoice in slots:
clear()
try:
fileRead(f"bustle_files/hotels/{hchoice}")
except:
fileWrite(f"bustle_files/hotels/{hchoice}",[slots[hchoice][0],slots[hchoice][1]])
booking = fileRead(f"bustle_files/hotels/{hchoice}")
while True:
print("(Note: Check-in time: 10:00 am and Check-out time: 12:00 pm for all bookings)")
print(f"Number of rooms available: {booking[0]}")
print(f"Price per room: {booking[1]}")
bchoice = input(f"Would you like to book in {hchoice}?(y/n): ")
avail = int(booking[0])
if bchoice == 'y':
while True:
nchoice = input("How many rooms would you like to book?\n(Press 'c' to go back)\n")
if nchoice.isdigit():
if (avail-int(nchoice)) >= 0:
price = int(booking[1])*int(nchoice)
clear()
print(f"No. of rooms to be booked: {nchoice}")
print(f"Total price: {price}")
cchoice = input("\nDo you wish to proceed to checkout?(y/n)\n")
if cchoice == 'y':
clear()