UnboundLocalError after user inputs last piece of data - python

Finishing up a database project and I'm having issues w/ it all coming together. I keep getting the below error after the user inputs the final data request.
Traceback (most recent call last):
File "c:/Users/j/Documents/Ashford U/CPT 200/Python Code/CPT 200 - Wk 5 Final Project JC.py", line 72, in <module>
main()
File "c:/Users/j/Documents/Ashford U/CPT 200/Python Code/CPT 200 - Wk 5 Final Project JC.py", line 42, in main
if employee_found is None:
UnboundLocalError: local variable 'employee_found' referenced before assignment
The user is to be able to input the requested data and it loop to the main question of adding, viewing, querying, or editing. So far its not looping back and I'm not sure where I've gotten off the wrong track at. Any help is much appreciated as I still have to add in the ability to write this to a file. Code below.
class Employee:
def __init__(self, name, ssn, phone, email, salary):
self.name = name
self.ssn = ssn
self.phone = phone
self.email = email
self.salary = salary
def add():
name = input("Please enter the employee's name: ")
ssn = input("Please enter the employee's ssn: ")
phone = str(input("Please enter the employee's phone number xxx-xxx-xxxx: "))
email = input("Please enter the employee's email: ")
salary = str(input("Please enter the employee's salary: "))
return Employee(name, ssn, phone, email, salary)
def formatEmployee(employee, name, ssn, phone, email, salary):
print(f'---------------------------- {name} -----------------------------')
print(f'SSN: {ssn}')
print(f'Phone: {phone}')
print(f'Email: {email}')
print(f'Salary: {salary}')
print('------------------------------------------------------------------------')
def main():
employee_list = []
#Loop of questions to add, search, edit, ect.
while True:
user_input = input('Please enter a command (add, view, query, edit): ')
if user_input == 'add':
new_employee = add()
employee_list.append(new_employee)
print(f'There are now ({(len(employee_list))}) employees in the database.')
if user_input == 'view':
for employee in employee_list:
#prints(employee_list)
formatEmployee(employee)
if user_input == 'find':
ssn = input('Enter employee SSN:')
employee_found = find(ssn, employee_list)
if employee_found is None:
print('Employee not found')
else:
formatEmployee(employee_found)
if user_input == 'edit':
ssn = input('Enter SSN of employee to edit their info: ')
employee_found = find(ssn, employee_list)
edit_field = input('Please enter the employee information that you want to edit: ')
new_info = input(f'Please enter the new: {edit_field}')
print('edit complete!')
# Employee edit branches
def edit(info, newinfo, employee):
if info == 'name':
employee.name = newinfo
if info == 'ssn':
employee.ssn = newinfo
if info == 'phone':
employee.phone = newinfo
if info == 'email':
employee.email = newinfo
if info == 'salary':
employee.salary = newinfo
#Query by SSN of employee
def find(ssn, employee_list):
for employee in employee_list:
if ssn == employee.ssn:
return employee
return None
main()

The problem is in your indentation... your main function should look like this:
def main():
employee_list = []
#Loop of questions to add, search, edit, ect.
while True:
user_input = input('Please enter a command (add, view, query, edit): ')
if user_input == 'add':
new_employee = add()
employee_list.append(new_employee)
print(f'There are now ({(len(employee_list))}) employees in the database.')
if user_input == 'view':
for employee in employee_list:
#prints(employee_list)
formatEmployee(employee)
if user_input == 'find':
ssn = input('Enter employee SSN:')
employee_found = find(ssn, employee_list)
if employee_found is None:
print('Employee not found')
else:
formatEmployee(employee_found)
if user_input == 'edit':
ssn = input('Enter SSN of employee to edit their info: ')
employee_found = find(ssn, employee_list)
edit_field = input('Please enter the employee information that you want to edit: ')
new_info = input(f'Please enter the new: {edit_field}')
print('edit complete!')

Related

How can we check and re ask the user to enter username if it is already taken from csv file

def datafirstrow():
with open("data.csv", "w") as obj:
fileobj = csv.writer(obj)
fileobj.writerow(["Username", "Password", "First Name","Last Name","UserID","UPI ID","Bank Details","Mobile Info"])
datafirstrow()
Above are the columns of my csv file.
def newUser(userid):
with open("data.csv", "a") as obj:
fileobj = csv.writer(obj)
while(True):
username = check(input("Enter username: "))
password = input("Enter password: ")
pwd = (hashlib.sha256(password.encode('utf-8')).hexdigest())
First = input("Enter First Name: ")
Last = input("Enter Last Name: ")
Upi = input("Enter UPI ID: ")
print("Enter Bank Details: \n")
bankDetails = ""
BankNumber = str(input("Please enter Account Number \n"))
bankDetails += ('Bank Account Number: {}\n'.format(BankNumber))
BankName = str(input("Enter the Bank Name: \n"))
bankDetails += ('Bank Name: {}\n'.format(BankName))
BankHolderName = str(input("Enter Account Holder Name \n"))
bankDetails += ('Account Holder Name: {}\n'.format(BankHolderName))
IFSC = str(input("Enter IFSC Code"))
bankDetails += ('Branch IFSC Code: {}\n'.format(IFSC))
mobile = input("Enter your Contact Number: ")
record = [username, pwd,First,Last,userid,Upi,bankDetails,mobile]
fileobj.writerow(record)
break
obj.close()
Above is the function I am using to add new data to the table
def check(username):
with open("data.csv", "r") as obj:
fileobj2 = csv.reader(obj)
for i in fileobj2:
next(fileobj2)
if i[0] == username:
print("Username is taken \n Please input a unique username \n")
username = input("Enter Username: ")
checkusername(username)
elif i[0] != username:
break
obj.close()
return username
check(input("enter username"))
This function checks if the username is taken or not
But it checks the username once and then if I enter the same username again it returns me the same username
What I want is it to check the username everytime
I changed your code a bit (I have a comment where I change the code) I hope this will work. If not let me know in the comment.
import csv
import hashlib
def datafirstrow():
with open("data.csv", "w") as obj:
fileobj = csv.writer(obj)
fileobj.writerow(["Username", "Password", "First Name","Last Name","UserID","UPI ID","Bank Details","Mobile Info"])
datafirstrow()
def newUser(userid):
with open("data.csv", "a") as obj:
fileobj = csv.writer(obj)
username = None #changed
while username is None: #changed
username = check(input("Enter username: ")) #changed
password = input("Enter password: ")
pwd = (hashlib.sha256(password.encode('utf-8')).hexdigest())
First = input("Enter First Name: ")
Last = input("Enter Last Name: ")
Upi = input("Enter UPI ID: ")
print("Enter Bank Details: \n")
bankDetails = ""
BankNumber = str(input("Please enter Account Number \n"))
bankDetails += ('Bank Account Number: {}\n'.format(BankNumber))
BankName = str(input("Enter the Bank Name: \n"))
bankDetails += ('Bank Name: {}\n'.format(BankName))
BankHolderName = str(input("Enter Account Holder Name \n"))
bankDetails += ('Account Holder Name: {}\n'.format(BankHolderName))
IFSC = str(input("Enter IFSC Code"))
bankDetails += ('Branch IFSC Code: {}\n'.format(IFSC))
mobile = input("Enter your Contact Number: ")
record = [username, pwd,First,Last,userid,Upi,bankDetails,mobile]
fileobj.writerow(record)
obj.close()
def check(username): #changed
with open("data.csv", "r") as obj:
fileobj2 = csv.reader(obj)
if username in map(lambda e:e[0],list(fileobj2)[1:]):
print("Username already exists.")
return None
obj.close()
return username
result = None
while result is None:
result = check(input("enter username"))
print(result)
Thank you everyone for helping
I got the solution-
I changed my check(username) function to read every username column of the data file and make a list and then check if the username is in the list or not
Heres the code-
def check(username): #changed
with open("data.csv", "r") as obj:
fileobj2 = csv.DictReader(obj)
usernames = []
for col in fileobj2:
usernames.append(col['Username'])
if username not in usernames:
return username
print("Username already exists.")
username = input("Enter username")
return check(username)
obj.close()

Trouble with saving and loading dictionary with class instances using pickle

New to programming and trying to learn how to store data using pickle. Essentially, what I'm trying to do is create an address book using classes stored in a dictionary. I define the class (Contact). It all worked, but when I tried to introduce pickling to store data from a previous session, I've created 2 errors that I've found so far.
1: If I select to load a previous address book, I cant update or view the class variables. It's almost like there are two different dictionaries.
2: I select not to load a previous address book and add a contact. When I add the contact and try to view the contacts, I'll get an "Unbound Error: local variable 'address book' referenced before assignment"
What am I doing wrong with pickling?
address_book= {}
class Contact:
def __init__(self,first_name,last_name, phone,company):
self.first_name = first_name
self.last_name = last_name
self.phone = phone
self.company = company
def __call__(self):
print("Contact: %s \nPhone #: %s \nCompany: %s" %(self.name,self.phone,self.company))
def erase(entry):
del address_book[entry] # delete address book entry
del entry #delete class instance
def save():
new_file = open("addressBook.pkl", "wb")
saved_address = pickle.dump(address_book, new_file)
new_file.close()
def load():
open_file = open("addressBook.pkl", "rb")
address_book = pickle.load(open_file)
open_file.close()
print(address_book)
return address_book
def add_contact():
first_name = input("Please type the first name of the contact. ")
last_name = input("Please type in the last name of the contact. ")
if " " in first_name or " " in last_name:
print("Please do not add spaces to your first or last name.")
else:
phone = input("Please type the user phone number without hyphens. ")
if not phone.isnumeric():
print("That isn't a valid phone number.")
else:
company = input("Please type the company they work for. ")
contact = Contact(first_name,last_name,phone,company)
address_book[first_name + " " +last_name] = contact #assign key[first and last name] to value[the class instance] in dictionary
def view_contact(entry):
if entry in address_book:
print("First Name: %s" %(address_book[entry].first_name)) #get class variables
print("Last Name: %s" %(address_book[entry].last_name))
print("Phone Number: %s" %(address_book[entry].phone))
print("Company: %s" %(address_book[entry].company))
else:
print("That person isn't in your address book")
def update(entry):
if entry in address_book:
update_choice = input("Would you like to update the first name (f), last name (l), phone (p), or company (c)? ").lower()
if update_choice == "f":
address_book[entry].first_name = input("Please type the updated first name of this contact. ")
updated_key = address_book[entry].first_name + " " + address_book[entry].last_name
address_book[updated_key] = address_book[entry]
del address_book[entry] #delete old key
elif update_choice == "l": #update last name
address_book[entry].last_name = input("Please type the updated last name of this contact. ")
updated_key = address_book[entry].first_name + " " + address_book[entry].last_name
address_book[updated_key] = address_book[entry]
del address_book[entry]
elif update_choice == "p":
address_book[entry].phone = input("Please type the updated phone number of this contact. ")
elif update_choice == "c":
address_book[entry].company = input("Please type the updated company of this contact. ")
else:
print("That was not valid. Please try again.")
def main():
print("Welcome to your address book!!")
returning_user = input("Would you like to load a previous address book? Y or N ").lower()
if returning_user == "y":
address_book = load()
while True:
choice = input("Please type A:Add, B:View All Contacts, V:View a Contact, D:Delete, U:Update, or X:Exit ").lower()
if choice == "x":
break
elif choice == "a":
add_contact()
elif choice == "b":
if len(address_book) == 0: #error check if no contacts
print("You don't have any friends. PLease go make some and try again later. :(")
else:
for i in address_book:
print(i)
elif choice == "v":
if len(address_book) == 0:
print("You don't have any friends. PLease go make some and try again later. :(")
else:
view = input("Who do you want to view? Please type in their first and last name. ")
view_contact(view)
elif choice == "d":
if len(address_book) == 0:
print("You don't have any friends. PLease go make some and try again later. :(")
else:
contact = input("Please type the first and last name of the person you want to delete ")
if contact in address_book:
erase(contact)
elif choice == "u":
if len(address_book) == 0:
print ("C'mon, you don't know anyone yet. How about you make some friends first?")
else:
choice = input("What is the first and last name of the person you'd like to update? ")
update(choice)
else:
print("That was not valid. Please try again.")
print()
save_book = input("Would you like to save your book? Y or N ").lower()
if save_book == "y":
save()
print("Thanks for using the address book!")
main()

Trying to call an object from a different file but the output is only displaying blanks

For a homework, I made an employee class file. Then I made a separate program that has a menu, from which a user can add, edit, display the content of the employee file. however, when i am trying to display, the only output coming is blank.
employee.py:
class Employee:
def __init__(self, name, emplpoyeeid, department, job_title):
self.__name = ""
self.__employeeid = ""
self.__department = ""
self.__job_title = ""
def set_name(self, name):
self.__name = name
def set_id(self, employeeid):
self.__employeeid = employeeid
def set_department(self, department):
self.__department = department
def set_job_title(self, job_title):
self.__job_title = job_title
def get_name(self):
return self.__name
def get_employeeid(self):
return self.__employeeid
def get_department(self):
return self.__department
def get_job_title(self):
return self.__job_title
The actual program file:
import pickle
from Employee import Employee
try:
filename=open('Employee.dat','rb')
dictionary=pickle.load(filename)
except:
dictionary={}
while True:
print('\n1. Look up an employee in the dictionary')
print('2. Add a new employee in the dictionary')
print("3. Change an existing employee's name,department and job title in the dictionary")
print('4. Delete an employee from the dicionary')
print('5. Quit the program\n')
choice=input('\nEnter a choice: ')
if choice == '1':
while True:
employeeid=input('\nEnter the ID of the employee: ')
if employeeid in dictionary:
ob=dictionary[employeeid]
print('Employee Name: ',ob.get_name())
print('Employee ID: ',ob.get_employeeid())
print('Employee department: ',ob.get_department())
print('Employee job title: ',ob.get_job_title())
break
else:
print('\nEmployee not found \n')
break
elif choice== '2':
while True:
name=input('\nEnter the name of the employee: ')
employeeid=input('\nEnter the employee id: ')
dept=input('\nEnter the employee department: ')
title=input('\nEnter the employee job title: ')
ob=Employee(name,employeeid,dept,title)
dictionary[employeeid]=ob
print("employee has been added")
break
elif choice== '3':
while True:
employeeid=input('\nEnter the employee ID to change the details: ')
if employeeid in dictionary:
ob=dictionary[employeeid]
while True:
name=input('\nEnter the new name of the employee: ')
ob.set_name(name)
dept=input('\nEnter the new department of the employee: ')
ob.set_department(dept)
title=input('\nEnter the new job title of the employee: ')
ob.set_job_title(title)
break
else:
print('\nID not found \n')
elif choice == '4':
while True:
employeeid=input('\nEnter the ID of the employee to delete: ')
if employeeid in dictionary:
del dictionary[employeeid]
print('\nEmployee data removed \n ')
else:
print("Employee data not found")
elif choice == '5':
filename=open('Employee.dat','wb')
pickle.dump(dictionary,filename)
filename.close()
else:
print('\nPlease enter a valid choice ')
Look up an employee in the dictionary
Add a new employee in the dictionary
Change an existing employee's name,department and job title in the dictionary
Delete an employee from the dicionary
Quit the program
Enter a choice: 2
Enter the name of the employee: sam
Enter the employee id: 1
Enter the employee department: 2
Enter the employee job title: 3 employee has been added
Look up an employee in the dictionary
Add a new employee in the dictionary
Change an existing employee's name,department and job title in the dictionary
Delete an employee from the dicionary
Quit the program 4
Enter a choice: 1
Enter the ID of the employee: 1 Employee Name: Employee ID:
Employee department: Employee job title:
Look up an employee in the dictionary
Add a new employee in the dictionary
Change an existing employee's name,department and job title in the dictionary
Delete an employee from the dicionary
Quit the program
Enter a choice:
I expected the values that i put initially to be in the second output
but it is only displaying blanks
First: Your Employee import is incorrect. If your filename is employee.py, you should write:
from employee import Employee
because your program can't find the file named Employee.py.
Second: Try not to use while True. It can easily throw your program in the infinite loop. For example: If you will select the fourth choice - Delete an employee from the dicionary - you will never return to the main menu because you can't break your infinite loop.
Third: Your Employee.__init__ creates empty fields:
class Employee:
def __init__(self, name, emplpoyeeid, department, job_title):
self.__name = ""
self.__employeeid = ""
self.__department = ""
self.__job_title = ""
and you use no setters in the main module. Of course it will return empty strings for every field. Add setters to the main module or change employee.py to this:
class Employee:
def __init__(self, name, emplpoyeeid, department, job_title):
self.__name = name
self.__employeeid = emplpoyeeid
self.__department = department
self.__job_title = job_title

this program never makes it past the menu choices it continuously ask for a menu option??

I'm not sure why it keeps asking to enter a menu choice after I enter one!
When I run it consistently asks me to enter a number, but it doesn't run the functions associated with the numbers
not sure if you needed the class butI included it anyway
import pickle
class Contact:
def __init__(self, name, phone, email):
self.__name = name
self.__phone = phone
self.__email = email
def set_name(self, name):
self.__name = name
def set_phone(self, phone):
self.__phone = phone
def set_email(self, email):
self.__email = email
def get_name(self):
return self.__name
def get_phone(self):
return self.__phone
def get_email(self):
return self.__email
these are the menu options that I have, no matter what number i enter it asks me to enter another number
LOOK_UP = 1
ADD = 2
CHANGE = 3
DELETE = 4
QUIT = 5
FILENAME = 'contacts.txt'
def main():
mycontacts = load_contacts()
choice = 0
while choice != QUIT:
choice = get_menu_choice()
if choice == LOOK_UP:
look_up(mycontacts)
elif choice == ADD:
add(mycontacts)
elif choice == CHANGE:
change(mycontacts)
elif choice == DELETE:
delete(mycontacts)
save_contacts(mycontacts)
def load_contacts():
try:
input_file = open(FILENAME, 'rb')
contact_dct = pickle.load(input_file)
input_file.close()
except:
contact_dct = {}
return contact_dct
def get_menu_choice():
print()
print('Menu')
print('-------------------')
print('1. Look up an contact')
print('2. Add a new contact')
print('3. Change an existing contact')
print('4. Delet a contsct')
print('5. Quit the program')
print()
choice = int(input('Enter your choice: '))
while choice < LOOK_UP or choice > QUIT:
choice = int(input('Enter a vaild choice: '))
return choice
def look_up(mycontacts):
name = input('Enter a name: ')
print(mycontacts.get(name, 'That name is not found'))
def add(mycontacts):
name = input('Name: ')
phone = input('Phone: ')
email = input('Email: ')
entry = contact.Contact(name, phone, email)
if name not in mycontacts:
mycontacts[name] = entry
print('The entry has been added.')
else:
print('That name already exists.')
def change(mycontacts):
name = input('Enter a name: ')
if name in mycontacts:
phone = input('Enter the new phone number: ')
email = input('New Email: ')
entry = contact.Contact(name, phone, email)
mycontacts[name] = entry
print('information updated')
else:
print('not found')
def delete(mycontacts):
name = input('Enter a name: ')
if name in mycontacts:
del mycontacts[name]
print('Entry deleted')
else:
print('That name not found')
def save_contacts(mycontacts):
output_file = open(FILENAME, 'wb')
pickle.dump(mycontacts, output_file)
output_file.close()
main()
I believe the problem is in the following function:
def get_menu_choice():
print()
print('Menu')
print('-------------------')
print('1. Look up an contact')
print('2. Add a new contact')
print('3. Change an existing contact')
print('4. Delet a contsct')
print('5. Quit the program')
print()
choice = int(input('Enter your choice: '))
while choice < LOOK_UP or choice > QUIT:
choice = int(input('Enter a vaild choice: '))
return choice
First issue: If the first choice entered is within bounds, it is never returned from get_menu_choice().
Second issue: If the first choice entered is not within bounds, your while loop just returns the immediate next choice.
How to fix it: Move the return statement outside the while loop in get_menu_choice(). Also, move choice = get_menu_choice() to the bottom of the while loop in main(), and set choice's initial value to get_menu_choice().
Hope this helps.
P.S. What happens if the choice entered by the user is not an integer? What happens if the user enters a character, string, or control character? I would consider additional error-handling for erroneous input.

Python dictionaries and formatting

I am trying to solve the same a problem that does the following...
Create a program that stores Employee objects in a dictionary. Use the employee ID number as the key. The program should present a menu that lets the user perform the following actions:
Look up an employee in the dictionary
Add a new employee to the dictionary
Change an existing employee’s name, department, and job title in the
dictionary
Delete an employee from the dictionary
Quit the program
When the program ends, it should pickle the dictionary and save it to a file. Each time the program starts, it should try to load the pickled dictionary from the file. If the file does not exist, the program should start with an empty dictionary.
I found another user that posted the question here but I am having some different problems.
How should I quit the program? I tried break but it failed
miserably.
I know my formatting is atrocious but I can't figure out where it is
going wrong.
Here is what I have so far:
def main():
if os.path.exists("employee.dat"):
file = open("employee.dat","rb")
employee_dictionary = pickle.load(file)
file.close()
else:
emp1 = Employee("Susan Myers", 47899, "Accounting", "Vice President")
emp2 = Employee("Mark Jones", 39119, "IT", "Programmer")
emp3 = Employee("Joy Rogers", 81774, "Manufacturing", "Engineer")
employee_dictionary = {emp1.get_ID_number(): emp1.get_name()+ '' + emp1.get_dept()+ '' + emp1.get_job_title(),\
emp2.get_ID_number(): emp2.get_name()+ '' + emp2.get_dept()+ '' + emp2.get_job_title(),\
emp3.get_ID_number(): emp3.get_name()+ '' + emp3.get_dept()+ '' + emp3.get_job_title()}
#should I add another function here to call the employee_dictionary?
choice = 'y'
while choice.upper()== 'Y':
print("Make a selection from the following actions:")
print("Lookup an employee in the dictionary: 1")
print("Add a new employee to the dictionary: 2")
print("Change an existing employee's name, department, and job title in the dictionary: 3")
print("Delete an employee from the dictionary: 4")
print("Quit the program: 5")
selection = input("Make your selection: ")
if int(selection) == 1:
id_number = input("What is the employee's ID number?")
if int(id_number) in employee_dictionary.keys():
print(employee_dictionary[int(id_number)])
else:
print("The employee does not exist.")
else:
if int(selection) == 2:
id_number = input("What is the employee's ID number?")
if int(id_number) in employee_dictionary.keys():
print('That employee already exists.')
else:
name = input("Enter the name of the employee:")
dept = input("Enter the department of the employee:")
title = input("Enter the job title of the employee:")
emp4 = Employee(name,int(id_number), dept, title)
employee_dictionary[emp4.get_ID_number()]= emp1.get_name()+ '' + emp4.get_dept()+ '' + emp4.get_job_title()
print("The employee was added.")
else:
if int(selection) == 3:
id_number = input("What is the employee's ID number?")
if int(id_number) in employee_dictionary.keys():
name = input("Enter the name of the employee:")
dept = input("Enter the department of the employee:")
title = input("Enter the job title of the employee:")
emp4 = Employee(name,int(id_number), dept, title)
employee_dictionary[emp4.get_ID_number()]= emp1.get_name()+ '' + emp4.get_dept()+ '' + emp4.get_job_title()
print("The employee record has been updated.")
else:
print("Record not found.")
else:
if int(selection) == 4:
id_number = input("What is the employee's ID number?")
print("Deleted: ", employee_dictionary.pop(int(id_number),"Record not found."))
else:
if int(selection)!=5:
print("")
#break
choice = input("Do you want to make another selection (y or n)?")
file = open('employee.dat','wb')
pickle.dump(employee_dictionary,file)
file.close()
main()

Categories