Why do my dictionaries not update after I close the program? - python

I'm trying to create a program that will assign a hotel room number to the guests. After it is assigned, inside the dictionary, the value for the key should be updated into either 'Unavailable' or 'Reserved'. But, the thing is, after I close the program. Those room numbers that were updated becomes back into 'Available'.
Is there a way to change the value, so that it stays updated even after I close the program?
import math
f = open('room.txt', 'r+')
#Hotel Rooms
for i in range(1, 7):
locals()['Level{}'.format(i)] = {} # Creating Dictionary
start = 101
for x in range(1, 7):
for i in range(start, start + 10):
eval("Level" + str(x))[i] = 'Available' # Adding Values into Dictionary
start += 100
# heading function
def heading(number, header):
for i in range(60):
print('-', end = '')
print()
for i in range(number):
print('*', end = ' ')
print('\n' + header)
for i in range(number):
print('*', end = ' ')
print()
# customer details function
def customer():
print('''Room Types:
1 --> Single (Level 1)
2 --> Double (Level 2)
3 --> Triple (Level 3)
4 --> Quad (Level 4)
5 --> Queen (Level 5)
6 --> King (Level 6)
''')
room = input('Room Type: ')
name = input('Name: ')
hp = input('Mobile Number: ')
guests = input('Number of Guests: ')
arrival = input('Arrival Date(dd/mm/yyyy): ')
departure = input('Departure Date(dd/mm/yyyy): ')
confirm = input('Confirmation(Y/N): ')
conf(confirm, room, option)
# confirmation function + room for guest
def conf(con, num, opt):
if con == 'Y':
try:
for level, availability in eval('Level' + str(num)).items():
if availability == 'Available':
print('Guest Room Number:', level)
if option == '1':
eval('Level' + str(num))[level] = 'Reserved'
elif option == '2':
eval('Level' + str(num))[level] = 'Unavailable'
print('\nRoom Recorded!')
break
for i in range(1, 7):
f.write('Level ' + str(i) + '\n')
for key in eval('Level' + str(i)):
f.write(str(key) + ": " + eval('Level' + str(i))[key] + '\n')
f.write('\n')
f.close()
except NameError:
print('\nInvalid Room Type.')
elif con == 'N':
print('\nRecord Not Recorded.')
else:
print('\nInvalid Confirmation.')
# sub-headings (options)
def options():
print('''
Choose one of the following options (0-3):
0 <-- Back to Main Menu.
1 --> Booking Engine
2 --> Check In
3 --> Check Out''')
while True:
cus = '* Customer Registration *'
num = math.ceil(len(cus)/2)
heading(num, cus)
options()
option = input('Enter your option: ')
# Booking Engine
if option == '1':
boo = '* Booking Engine *'
num = math.ceil(len(boo)/2)
heading(num, boo)
customer()
#Check In
elif option == '2':
chein = '* Check In *'
num = math.ceil(len(chein)/2)
heading(num, chein)
customer()
else:
print("\nInvalid Option.")
continue

I haven't executed your code, but from what I see :
These are the first lines of your code :
f = open('room.txt', 'r+')
#Hotel Rooms
for i in range(1, 7):
locals()['Level{}'.format(i)] = {} # Creating Dictionary
start = 101
for x in range(1, 7):
for i in range(start, start + 10):
eval("Level" + str(x))[i] = 'Available' # Adding Values into Dictionary
start += 100
Here, you create a dictionary of all rooms, marking ALL of them as Available. It means that whatever the current value of a room, it will be marked as Available again.
Then in the conf function, you re-write the whole file, so the previously Reserved or Unavailable rooms are tagged as Available again.
Here is an example to be clear:
you start the program
You book a room, (e.g room 101), it is marked as Reserved
The rooms.txt file is saved with the correct value.
You stop your program
Then, when starting the program again:
A dict with ALL values set to Available is created. It means that even the room 101 is back to Available
You book any other room (e.g 201)
The dict is saved in your file. BUT remember that as you initialised your dict, all rooms where marked as Available again.
The problem, in fine is that you don't read your rooms.txt file when starting your program to actually load the state of each room in your dictionary.
I also recommend you to drop the custom data structure with which you save the file and go for a JSON file. It will simplify your code.

Related

Budget tracker program not working in Linux

I am trying to improve this program. I am working with Linux. I want to add a menu function where the user can pick an option and based on the option call the respective function, but the program is not working, when I run it in the Terminal it doesn't do anything and doesn't show any errors. Please, I need help to solve the problem and make the program works. Thanks!
Here's what I have so far, still there are some functions that need to develop:
#! /usr/bin/python3
import sys
def menu(self):
print ("""
1. Add an Expense
2. Remove an Expense
3. Add revenue
4. Remove Revenue
5. Exit
""")
option = input ("What would you like to do [Number Only]?")
if option == "1":
self.add_expense()
elif option == "2":
self.remove_expense()
elif option == "3":
self.add_revenue()
elif option == "4":
self.remove_revenue()
else:
self.reset_program()
self.close_program()
return option
def add_expense(self):
def __init__(self):
self.month_balance = 0
self.expenses = 0
self.expense_list = []
self.expense_name = []
self.month_balance_name = []
self.month_balance_list = []
self.prompt_income()
def month_balance_ask(self):
add_month_balance = input('Add monthly balance? [y/n]: ')
return add_month_balance
def month_balance_sum(self):
self.month_balance = sum(self.month_balance_list)
def expense_ask(self):
add_expense = input('Add expense? [y/n]: ')
return add_expense
def expense_sum(self):
self.expenses = sum(self.expense_list)
def month_balance_check(self):
if not self.month_balance_list:
print('Please enter at least one monthly balance. ')
self.prompt_month_balance()
def expense_check(self):
if not self.expense_list:
print('Please enter at least one expense. ')
self.prompt_expense()
def prompt_month_balance(self):
x = False
while not x:
result = self.month_balance_ask()
if result == 'y':
month_balance_input = int(input('Enter monthly balance. [Numbers Only]: '))
self.month_balance_list.append(month_balance_input)
month_balance_name = input('Enter monthly balance name. [Name Only]: ')
self.month_balance_name.append(month_balance_name)
else:
self.month_balance_check()
x = True
self.month_balance_sum()
name = [name for name in self.month_balance_name]
month_balance = [month_balance for month_balance in self.month_balance_list]
month_balancedict = dict(zip(name, month_balance))
for k in incomedict:
print(k + ': ', '$' + str(month_balancedict[k]))
print('Total user monthly balance: ', '$' + str(self.month_balance))
self.prompt_expense()
def prompt_expense(self):
x = False
while not x:
result = self.expense_ask()
if result == 'y':
expense_input = int(input('Enter expense amount. [Numbers Only]: '))
self.expense_list.append(expense_input)
expense_name = input('Enter expense name. [Name Only]: ')
self.expense_name.append(expense_name)
else:
self.expense_check()
x = True
self.expense_sum()
name = [name for name in self.expense_name]
expense = [income for income in self.expense_list]
expensedict = dict(zip(name, expense))
for k in expensedict:
print(k + ': ', '$' + str(expensedict[k]))
print('Total user expenses: ', '$' + str(self.expenses))
self.added_expense()
def added_expense(self):
expenseadded = self.month_balance - self.expenses
if expenseadded < 0:
print('You are in the negative, you have a deficit of ' + '$' + str(expenseadded))
if expenseadded == 0:
print('You have broken even, you are spending exactly as much as you make.')
if expenseadded > 0:
print('You are in the positive, you have a surplus of ' + '$' + str(expenseadded))
another = input('Would you like to run another analysis? [y/n]: ')
if another == 'y':
self.menu()
else:
self.reset_program()
self.close_program()
def remove_expense(self):
print("code goes here")
def add_revenue(self):
print("code goes here")
def remove_revenue(self):
print("code goes here")
def reset_program(self):
self.month_balance = 0
self.expenses = 0
del self.expense_list[0:]
del self.expense_name[0:]
del self.month_balance_name[0:]
del self.month_balance_list[0:]
self.prompt_month_balance()
def close_program(self):
print('Exiting Program.')
sys.exit(0)

Restricting the domain of integer values accepted as input in python

I'm building a command line game using python.A main feature of this game is to get the user's input of either 1 or 2 as integer values.Any other character must be rejected.I used try-except & if-else condition to do this like shown below.I want to know whether there is any better method to get this done in one line or some other way without having to indent a whole bunch of code.
if __name__ == '__main__':
# INITIALIZE THE TOTAL STICKS , DEPTH OF THE TREE AND THE STARTINGG PLAYER
i_stickTotal = 11 # TOTAL NO OF STICKS IN THIS GAME
i_depth = 5 # THE DEPTH OF THE GOAL TREEE THE COMPUTER WILL BUILD
i_curPlayer = 1 # THIS WILL BE +1 FOR THE HUMAN AND -1 FOR THE COMPUTER
print("""There are 11 sticks in total.\nYou can choose 1 or 2 sticks in each turn.\n\tGood Luck!!""")
# GAME LOOP
while i_stickTotal > 0:
print("\n{} sticks remain. How many would you pick?".format(i_stickTotal))
try:
i_choice = int(input("\n1 or 2: "))
if i_choice - 1 == 0 or i_choice - 2 == 0:
i_stickTotal -= int(i_choice)
if WinCheck(i_stickTotal, i_curPlayer):
i_curPlayer *= -1
node = Node(i_depth, i_curPlayer, i_stickTotal)
bestChoice = -100
i_bestValue = -i_curPlayer * maxsize
# Determine No of Sticks to Remove
for i in range(len(node.children)):
n_child = node.children[i]
#print("heres what it look like ", n_child.i_depth, "and",i_depth)
i_val = MinMax(n_child, i_depth-1, i_curPlayer)
if abs(i_curPlayer * maxsize - i_val) <= abs(i_curPlayer*maxsize-i_bestValue):
i_bestValue = i_val
bestChoice = i
#print("Best value was changed # ", i_depth, " by " , -i_curPlayer, " branch ", i, " to ", i_bestValue)
bestChoice += 1
print("Computer chooses: " + str(bestChoice) + "\tbased on value: " + str(i_bestValue))
i_stickTotal -= bestChoice
WinCheck(i_stickTotal, i_curPlayer)
i_curPlayer *= -1
else:
print("You can take only a maximum of two sticks.")
except:
print("Invalid input.Only Numeric Values are accepted")
You can create a function to check user input and use below code.
while True:
var = int(input('Enter value (1 or 2) - '))
if var not in range(1, 3):
print('Invalid entry, please try again...')
continue
else:
break
Write a function that loops, calling input, until the value satisfies your constraint. Perhaps call it get_user_input. Then call that in your main function instead of input. For added value, pass a lambda into that function as a predicate to test the user input value - that'll make get_user_input more general.

An error has occured with str on address book

Im making an address book and i got a problem. It's telling me that I have a problem with str and lists. I'm new to python so i dont really know what to do.
Here is the full program:
print("\n This is your address book.")
import os
import time
saveFile = open("ContactList.txt", "r")
ContactsString = saveFile.read()
saveFile.close()
Contacts = ContactsString.split('\n')
while '' in Contacts:
Contacts.remove('')
def printContacts():
index = 1
for contact in Contacts:
print("{}: {}".format(index, contact))
index = index + 1
def addContact():
print("You have chosen to add a new contact into your address book.")
name = input("What's the contacts name? ")
counter = Contacts.count(name)
if counter == 0:
address = input("Enter the address of " + name + ': ')
email = input("Enter the email of " + name + ': ')
Contacts.append([ name, address, email ])
else:
print("The contact already exists in the address book.")
print("If you desire to change the contacts current information, enter nr 3 in the menu.")
def browseContacts():
print("You have chosen to view all your contacts with their name, address and email." "\n")
for i in range(0, len(Contacts), 3):
print(Contacts[i], Contacts[i + 1], Contacts[i + 2], '\n')
def searchContacts():
print("\n You have chosen to search up a specific contact.")
searchName = input("Enter the name of the contact that you want to search up: ")
searchFound = False
for i in range(0, len(Contacts), 3):
if searchName == Contacts[i]:
searchName = True
break
if searchFound == True:
print(Contacts[i], Contacts[i + 1], Contacts[i + 2], "\n")
else:
print("We couldn't find " + searchName + " in the address book.")
print("Check whether your spelling was correct or not.")
time.sleep(4)
def deleteContact():
print('\n You have chosen option 4, to delete a specific contact from your address book')
printContacts()
deletename = input(' Enter the name of the contact you wish to delete from your address book: ').title()
deletefound = False
for i in range(0, len(Contacts), 3): #finds the contact the user wants to delete. It only iterates through each third post so that it only goes through the names of the contact.
if deletename == Contacts[i]:
deletefound = True
break
if deletefound == True:
Contacts.pop(i) # deletes the contact information from the list
Contacts.pop(i)
Contacts.pop(i)
print('\n ' + deletename + 'has been removed from your address book')
else:
print('\n ' + deletename + "doesn't exist in the address book")
def modifyContacts():
print("You have chosen option 5, to update a specific contact in your address book.")
printContacts()
newName = input("Enter the name of the contact you wish to update: ")
modifyFound = False
for i in range(0, len(Contacts), 3):
if newName == Contacts[i]:
modifyFound = True
break
if modifyFound == True:
Contacts[i] = input(' Enter the new name of ' + newName + ': ')
Contacts[i + 1] = input(' Enter the new address of ' + Contacts[i] + ': ')
Contacts[i + 2] = input(' Enter the new e-mail of ' + Contacts[i] + ': ')
print('\n The contact has now been updated')
else:
print("\n " + newName + " doesn't exist in the address book")
print(" You can add " + newName + "to your address book by pressing 1 in the menu below")
time.sleep(4)
running = True
while running == True:
print('''
===================================================================
Menu:
1: Add new contact (press 1)
2: Show all contacts (press 2)
3: Show a specific contact (press 3)
4: Delete contact (press 4)
5: Update contact (press 5)
6: Quit program (press 6)
===================================================================''')
actionchoice = input('\n Please enter your choice of action: ')
if actionchoice == '1':
addContact()
elif actionchoice == '2':
browseContacts()
elif actionchoice == '3':
searchContacts()
elif actionchoice == '4':
deleteContact()
elif actionchoice == '5':
modifyContacts()
elif actionchoice == '6':
print('\n Shutting down. Thank you for using the adressbook! \n')
running = False
else:
print('\n The entered command does not exist within this program')
print(' Please enter one of the actions shown in the menu: \n')
time.sleep(4)
saveFile = open("ContactList.txt", "w")
for x in range(0, len(Contacts), 3):
saveFile.write("\n" + Contacts[x] + "\n")
saveFile.write( Contacts[x + 1] + "\n")
saveFile.write( Contacts[x + 2] + "\n")
saveFile.close()
The problem is in the end and the problem says:
Exception has occurred: TypeError
**can only concatenate str (not "list") to str**
File "C:\Users\Anvandare\Documents\Programmering1\Arbetet\addressbook.py", line 162, in <module>
saveFile.write("\n" + Contacts[x] + "\n")
In other words, this is the problem:
saveFile.write("\n" + Contacts[x] + "\n")
What am i supposed to do for it to work?
This line is wrong:
Contacts.append([ name, address, email ])
This is not appending each variable as a separate element of the list, it's creating a nested list in Contacts. It should be:
Contacts.append(name)
Contacts.append(address)
Contacts.append(email)
or:
Concacts += [ name, address, email ]
You also need to fix printContacts() to process Contacts in groups of 3, like the rest of the code.
def printContacts():
index = 1
for i in range(0, len(Contacts), 3):
print("{}: {} {} {}".format(index, *Contacts[i:i+3]))
index = index + 1
IMHO it would be better for Contacts to be a list of dictionaries, but doing this would require a rewrite to 90% of your code and I'm not going to do that here.

Why is my code getting this ValueError when it's automarked?

So, my code is based of a module in a learning site which I use called Grok, these are the requirements which I had to create in order to pass to the next stage
The Requirements (left-hand-side of photo) and Auto Marker Error (bottom right handside)
The error in question is;
Testing a longer case with many letters. Your submission raised an exception of type ValueError. This occurred on line 4 of program.py.
I can't seem to figure out how to fix this to get it marked correctly, yet my code works pretty much perfectly.
My code
import collections
collect = collections.defaultdict(list)
order = input('Name: ')
name, surname = order.split(' ', 1)
collect[surname].append(name)
mail = open('mail.txt', encoding="UTF-8").read()
mail = mail.split('\n')
letter = 0
package = 0
count = mail.count(' '.join(collect[surname]) + ' ' + surname + ',Letter')
count2 = mail.count(' '.join(collect[surname]) + ' ' + surname + ',Package')
for i in collect:
if (' '.join(collect[surname]) + ' ' + surname + ',Letter') in mail:
letter += 1 * count
if (' '.join(collect[surname]) + ' ' + surname + ',Package') in mail:
package += 1 * count2
if package == 0 and letter == 0:
print("No mail")
if letter > 1:
print(count, "Letters")
if letter == 1:
print(count, "Letter")
if letter == 0 and package != 0:
print("No Letters")
if package > 1:
print(count2, "Packages")
if package == 1:
print(package, "Package")
if package == 0 and letter != 0:
print("No Packages")
There is only one space in the second line of the example for the third input in the screenshot.
For line 4 (name, surname = order.split(' ', 1)), the tuple unpacking will raise a ValueError if there's no space in order.
EDIT:
order = input('Name: ')
# was name, surname = order.split(' ', 1)
try:
name, surname = order.split(' ', 1)
except ValueError:
name, surname = order, ""
collect[surname].append(name)

Adding score + name in each cell in excel file

I'm trying to get this problem fixed. I'm creating a program which stores the score in a spreadsheet but when it does, it does not write the score and name in different cell. I have tried adding the column string/row string but always getting error, some guide and help will be appreciated.
So far this is what I have done:
!(http://postimg.org/image/6zn9l43bj/)!
I tried to get a heading saying name and the users name below in each cell and same with score and need some starting point/help
ClassA = open('classa.csv', 'w')
ClassB = open('classb.csv', 'w')
ClassC = open('classc.csv', 'w')
start = True
while start:
user =(input("What is your name?"))
form =(input("Which Group are you in A/B or C ")).lower()
import re
import random
from random import randint
score = 0
for i in range(3):
first_num = random.randint(1,10)
second_num = random.randint(1,10)
choice = (first_num+second_num)
if choice == first_num+second_num:
print ("Question (%d)" % (i+1))
print (first_num)
print("Add (+)")
print(second_num)
check = True
while check:
answer = (input('enter the answer: '))
if not (re.match('-?[0-9]\d*(\.\d+)?$', answer)):
print("Only input numbers")
else:
check = False
answer = int(answer)
if answer == (choice):
print("It's correct!")
score +=1
else:
print("It's wrong!")
print ("The correct answer is: ", choice)
print('')
print(user)
if form == 'a':
ClassA.write("Name: "+str(user) + ' ' + "Score: "+str(score)+"/10" + '\n')
elif form == 'b':
ClassB.write("Name: "+str(user) + ' ' + "Score: "+str(score)+"/10" + '\n')
elif form == 'c':
ClassC.write("Name: "+str(user) + ' ' + "Score: "+str(score)+"/10" + '\n')
yesorno = input("Restart?, Y or N ").lower()
if yesorno == 'y':
start = True
elif yesorno == 'n':
start = False
ClassA.close()
ClassB.close()
ClassC.close()
Thanks
A bit of background: CSV stands for Comma Separated Values, oddly enough Values are quite often separated by semicolons in CSV files and, in fact, (I think) Excel won't recognise columns if you use commas, but it will if you use semicolons. Edit: As pointed out in the comments, this probably depends on regional settings, if in your country the decimal point is usually a comma (e.g. most of Europe) use ;, if it's usually a point use , as separator.
So, back to your question: you are not separating your values, use this instead (notice the semicolon):
ClassA.write("Name: "+str(user) + '; ' + "Score: "+str(score)+"/10" + '\n')
I wouldn't recommend writing the Name: and Score: prefixes either, I would go with a header row (Name; Score; Max Score) and something like this:
ClassA.write("{0}; {1}; {2}\n".format(user, score, max_score))
See also: str.format

Categories

Resources