Pickle file with many objects - python

I cannot get my file to store multiple instances of contacts. After adding new contact and trying to print them, it comes up with "IndexError: list index out of range" error. What shall I do to make it work?
import pickle
class People():
def __init__(self, name, surname, age, mobile_no, home_no):
self.name = name
self.surname = surname
self.age = age
self.mobile_no = mobile_no
self.home_no = home_no
def DisplayContacts(self):
print("First Name: \t", self.name)
print("Surname: \t", self.surname)
print("Age: \t", self.age)
print("Mobile Number: \t", self.mobile_no)
print("Home Number: \t", self.home_no)
print()
def addContact():
newname = str(input("First name: \t"))
newsurname = str(input("Surname: \t"))
newage = int(input("Age: \t"))
newmobile_no = int(input("Mobile Number: \t"))
newhome_no = int(input("Home Number: \t"))
newContact = People(newname, newsurname, newage, newmobile_no, newhome_no)
return newContact
cont = 1
contacts = []
while cont == 1:
user = input("Do you want to add contact? (Y/N)")
if user == "Y" or user == "y":
print ("works")
contacts.append(addContact())
file = open("CList.pickle", "ab")
pickle.dump(contacts, file, pickle.HIGHEST_PROTOCOL)
file.close()
else:
print ("111")
cont = 0
useropen = input("open file? (Y/N)")
if useropen == "Y" or useropen == "y":
with open ("CList.pickle", "rb") as pickled_file:
contacts = pickle.load(pickled_file)
print(contacts[0].surname)
print(contacts[1].surname)
else:
print("Null")

Simply appending a picked object to a file is not the same thing as pickling a list. EAch time you append, you've created another pickled record. Read the file multiple times to get your list:
with open ("CList.pickle", "rb") as pickled_file:
contacts = []
try:
while True:
contacts.append(pickle.load(pickled_file))
except EOFError:
pass
Now, instead of appending the list of contacts (which would give you a list of lists with many duplicates), just pickle the new contact:
with open("CList.pickle", "ab") as _file:
while True:
user = input("Do you want to add contact? (Y/N)")
if user == "Y" or user == "y":
print ("works")
pickle.dump(addContact(), _file, pickle.HIGHEST_PROTOCOL)
else:
print ("111")
break

Related

python sava data into txt file

I have problem to create a full coding python file handling. I need all data functions in python will be save in txt file. Below is my coding.
def getListFromFile(fileName):
infile = open(fileName,'r')
desiredList = [line.rstrip() for line in infile]
infile.close()
return desiredList
def main():
staffRegistration()
staffLogin()
regList = getListFromFile("registration.txt")
createSortedFile(regList, "afterreg.out")
loginList = getListFromFile("login.txt")
createSortedFile(userLogin, "afterlogin.out")
checkFileRegistration()
checkFileLogin()
def checkFileRegistration():
print("\nPlease check afterreg.out file")
def checkFileLogin():
print("\nPlease check afterlogin.out file")
def staffRegistration():
regList = []
name = input("Name: ")
s = int(input("Staff ID (e.g 1111): "))
regList.append(s)
s = int(input("Staff IC (without '-'): "))
regList.append(s)
s = int(input("Department - 11:IT Dept 12:ACC/HR Dept 13:HOD 41:Top
Management (e.g 1/2/3/4): "))
regList.append(s)
s = int(input("Set username (e.g 1111): "))
regList.append(s)
s = int(input("Set Password (e.g 123456): "))
regList.append(s)
f = open("registration.txt",'w')
f.write(name)
f.write(" ")
for info in regList:
f.write("%li "%info)
f.close
f1 = open("afterreg.out",'w')
f1.writelines("Registration Successful\n\n")
f1.close()
def staffLogin():
serLogin = input("\nProceed to login - 1:Login 2:Cancel (e.g 1/2): ")
if userLogin == "1":
username = input("\nUsername (e.g 1111): ")
l = int(input("Password: "))
if userLogin == "2":
print("\nLogin cancelled")
f = open("login.txt",'w')
f.write(username)
f.write(" ")
for info in userLogin:
f.write("%li "%info)
f.close
f1 = open("afterlogin.out",'w')
f1.writelines("Logged in successful")
f1.close()
def createSortedFile(listName, fileName):
listName.sort()
for i in range(len(listName)):
listName[i] = listName[i] + "\n"
outfile = open(fileName,'a')
outfile.writelines(listName)
outfile.close()
main()
Actually, this program should have five requirements. First is staffRegistration(), staffLogin(), staffAttendance(), staffLeaveApplication(), approval() but I have done for two requirements only and I get stuck at staffLogin(). I need every function will be save in txt file (I mean the data in function).
In line 32 you try to convert a String into Integer. Besides, in your main function, you have an unresolved variable userLogin.
The other problem is in line 43 (staffLogin function), You want to write a long integer but you pass a string. I have tried to fix your code except for userLogin in main.
def getListFromFile(fileName):
infile = open(fileName,'r')
desiredList = [line.rstrip() for line in infile]
infile.close()
return desiredList
def main():
staffRegistration()
staffLogin()
regList = getListFromFile("registration.txt")
createSortedFile(regList, "afterreg.out")
loginList = getListFromFile("login.txt")
createSortedFile(userLogin, "afterlogin.out")
checkFileRegistration()
checkFileLogin()
def checkFileRegistration():
print("\nPlease check afterreg.out file")
def checkFileLogin():
print("\nPlease check afterlogin.out file")
def staffRegistration():
regList = []
name = input("Name: ")
s = int(input("Staff ID (e.g 1111): "))
regList.append(s)
s = int(input("Staff IC (without '-'): "))
regList.append(s)
s = input("Department - 11:IT Dept 12:ACC/HR Dept 13:HOD 41:Top Management (e.g 1/2/3/4): ")
regList.append(s)
s = int(input("Set username (e.g 1111): "))
regList.append(s)
s = int(input("Set Password (e.g 123456): "))
regList.append(s)
f = open("registration.txt",'w')
f.write(name)
f.write(" ")
for info in regList:
f.write("%li "%info)
f.close
f1 = open("afterreg.out",'w')
f1.writelines("Registration Successful\n\n")
f1.close()
def staffLogin():
userLogin = input("\nProceed to login - 1:Login 2:Cancel (e.g 1/2): ")
if userLogin == "1":
username = input("\nUsername (e.g 1111): ")
l = int(input("Password: "))
if userLogin == "2":
print("\nLogin cancelled")
f = open("login.txt",'w')
f.write(username)
f.write(" ")
for info in userLogin:
f.write("%s "%info)
f.close
f1 = open("afterlogin.out",'w')
f1.writelines("Logged in successful")
f1.close()
def createSortedFile(listName, fileName):
listName.sort()
for i in range(len(listName)):
listName[i] = listName[i] + "\n"
outfile = open(fileName,'a')
outfile.writelines(listName)
outfile.close()
main()
There are a lot of problems in the staffLogin() function. e.g. the result of the first input()is bound to serLogin, but this should be userLogin.
If that is corrected, a password is read from the user, but nothing is ever done with it. Should the password be treated as an integer?
Also, if the user enters 2 at first prompt, the code will not set username but it will still try to write username to the file. That will raise a NameError exception.
Finally, the code attempts to write the characters in userLogin to the file as though they are integers. Not only will that not work, it doesn't make sense. Perhaps this should be writing the password to the file?

Adding a error message in Python as well as commands

#!/usr/bin/env python3
import csv
# a file in the current directory
FILENAME = "contacts.csv"
def write_contacts(contacts):
with open(FILENAME, "w", newline="") as file:
writer = csv.writer(file)
writer.writerows(contacts)
def read_contacts():
contacts = []
with open(FILENAME, newline="") as file:
reader = csv.reader(file)
for row in reader:
contacts.append(row)
return contacts
def list_contacts(contacts):
for i in range (len(contacts)):
contact= contacts[i]
print(str(i+1) +"."+ contact[0])
print()
def view_contact(contacts):
pos = int(input("Number: "))
if not (pos-1)in range(len(contacts)):
print(str(pos) + ' not in list, try again')
view(contacts)
return
contact = []
print(name + email + phone+".\n")
print()
def delete_contact(contacts):
index = int(input("Number: "))
contact = contacts.pop(index -1)
write_contacts(contacts)
print(contact[0]+" was deleted.\n")
def add_contact(contacts):
name=input("Name: ")
email=input("Email: ")
phone=input("Phone number: ")
contact= []
contact.append(name)
contact.append(email)
contacts.append(contact)
write_contacts(contacts)
print(name + " was added.\n")
def display_menu():
print("Contact Manager")
print()
print("COMMAND MENU")
print("list - List all contacts")
print("view - View a contact")
print("add - Add a contact")
print("delete- Delete a contact")
print()
print()
def main():
display_menu()
contacts = read_contacts()
while True:
command = input("Command: ")
if command.lower() == "list":
list_contacts(contacts)
elif command.lower()== "view":
view_contact(contacts)
elif command.lower()== "add":
add_contact(contacts)
elif command.lower()== "delete":
delete_contact(contacts)
break
else:
print("Not a valid command. Please try again.\n")
print("Bye!")
if __name__ == "__main__":
main()
This all my code. I'm trying to figure out how to make the delete and view commands display an error message when the user enters a number that is invalid but it's not working. I'm also trying to view a contact when the user selects a specific number form list which would then display the email name and phone number of that selected number. I'm currently stuck
The errors im getting are
raceback (most recent call last):
, line 93, in
main()
, line 81, in main
view_contact(contacts)
, line 32, in view_contact
view(contacts)
NameError: name 'view' is not defined
I don't think you has a good start with list into cvs using append, anyway is your example.
You can use remove to remove your contact from list, see examples with list: http://www.thegeekstuff.com/2013/06/python-list
when the user select a specific number from list , just read by stepping to the number phone because you add with: name + email + phone.
adding an error message , use: try except finally

File Access in python

Whenever I go to load a text file for my program it displays the info in the text file yet when I input the roster function it does not display the text file and show it is available to be modified. Is it something with how I created the text file in the first place or is my coding for loadData not written correctly i think i may be confused on the difference between just setting up a function just to read back the file instead of actually opening the text file to be able to modify it.
dict_member = {}
players = dict_member
class Players:
def __init__(self, name, number, jersey):
self.name = name
self.number = number
self.jersey = jersey
def display(self):
print('Printing current members\n')
for number, player in dict_member.items():
print(player.name + ', ' + player.number + ', ' + player.jersey)
def add(self):
nam = input("Enter Player Name\n ")
numb = input("Enter Player Number\n ")
jers = input("Enter Jersey Number\n ")
dict_member[nam] = Players(nam, numb, jers)
def remove(self, name):
if name in dict_member:
del dict_member[name]
def edit(self, name):
if name in dict_member:
nam = input("Enter Different Name\n")
num = input("Enter New Number\n ")
jers = input("Enter New Jersey Number\n ")
del dict_member[name]
dict_member[name] = Players(nam, num, jers)
else:
print("No such player exists")
def saveData(self):
roster = input("Filename to save: ")
print("Saving data...")
with open(roster, "r+") as rstr:
for number, player in dict_member.items():
rstr.write(player.name + ', ' + player.number + ', ' + player.jersey)
print("Data saved.")
rstr.close()
def loadData(self):
dict_member = {}
roster = input("Filename to load: ")
file = open(roster, "r")
while True:
inLine = file.readline()
if not inLine:
'break'
inLine = inLine[:-1]
name, number, jersey = inLine.split(",")
dict_member[name] = (name, number, jersey)
print("Data Loaded Successfully.")
file.close()
return dict_member
def display_menu():
print("")
print("1. Roster ")
print("2. Add")
print("3. Remove ")
print("4. Edit ")
print("5. Save")
print("6. Load")
print("9. Exit ")
print("")
return int(input("Selection> "))
print("Welcome to the Team Manager")
player_instance = Players(None, None, None)
menu_item = display_menu()
while menu_item != 9:
if menu_item == 1:
player_instance.display()
elif menu_item == 2:
player_instance.add()
elif menu_item == 3:
m = input("Enter Player to Remove\n")
player_instance.remove(m)
elif menu_item == 4:
m = input("Enter Player to Edit\n")
player_instance.edit(m)
elif menu_item == 5:
player_instance.saveData()
elif menu_item == 6:
player_instance.loadData()
menu_item = display_menu()
print("Exiting Program...")
Try this:
def loadData(self):
file = open(input("Filename to load: "), "r")
text = file.read()
file.close()
for line in text:
name, number, jersey = (line.rstrip()).split(',')
dict_member[name] = (name, number, jersey)
print("Data Loaded Successfully.")
return dict_member
def saveData(self, dict_member):
file = open(input("Filename to save: "), "a")
for number, player in dict_member.items():
rstr.write(player.name + ', ' + player.number + ', ' + player.jersey)
print("Data saved.")
file.close()
What I think was the error was you using "break" in string from instead of the command, break (no quotes required). I optimized the code a little so maybe it will work now? If not, what exactly happens? Try debugging as well as checking your file.
you didnt load your data into dict_member before displaying the roster
when you load your data in the loadData function you redefine dict_member
so it will "shadow" the outer dict_member so when the display function is called dict_member will always be empty
so you probably want to remove this line
def loadData(self):
# **remove this line --->** dict_member = {}
roster = input("Filename to load: ")
file = open(roster, "r")
while True:
inLine = file.readline()
if not inLine:
break
inLine = inLine[:-1]
name, number, jersey = inLine.split(",")
dict_member[name] = (name, number, jersey)
print("Data Loaded Successfully.")
file.close()
return dict_member

Writing and retrieving pickled object to a file

I'm doing creating a address book for a computer science class, where we are supposed to have a list of objects "contact" written to a file when the program closes and read from the file when the program starts. However, after the data is written to the file, once it is read it does not seem to keep its object form.
import pickle
class Contact:
#Creating the class with the attributes I want
def __init__(self, firstname, lastname, number, areacode, city):
self.firstname = firstname
self.lastname = lastname
self.number = number
self.areacode = areacode
self.city = city
def __str__(self):
return "({0} {1}, {2}, {3}, {4})".format(self.firstname, self.lastname, self.number, self.areacode, self.city)
#reading the object
def opendata():
readable = []
addresses = []
A = open("Address_book", "rb+")
addresses = A.read()
A.close
B = len(addresses)
if B != 0:
readable = pickle.loads(addresses)
return readable
else:
return addresses
def savedata(file):
addresses = open("Address_book", "wb+")
temp = pickle.dumps(file)
addresses.write(temp)
addresses.close()
def Address_manager():
Address = []
fromfile = opendata()
Address.append(fromfile)
while True:
print("add = add contact, modify = modify contact, search = search contacts, end = close program, print = print full list")
A = input("What do you want to do?: ")
if A == "end":
savedata(Address)
break
else:
if A == "print":
for i in Address:
print(str(i))
print("")
continue
elif A == "add":
Address.append(add_contact())
print("")
continue
elif A == "search":
lists2 = search_contact(Address)
A = 0
for i in lists2:
A += 1
print(A, str(i))
print("")
print("")
continue
elif A == "modify":
modified = modify_contact(Address)
Address.append(modified)
print("")
continue
def add_contact():
while True:
try:
A = Contact(input("First name: "), input("Last name: "), input("Phone Number: "), input("Area Code: "), input("City: "))
print(str(A))
B = input("Is this right?: (y/n)")
if B == "y":
print("Well done?")
return A
else:
print("Try Again")
continue
except:
print("bad data")
If I try to "print" the list after getting it from the file it prints them in the wrong form. What am I doing wrong and why?
Edit 1: I apologize for the less than efficient code.
Edit 2: Added function to add contact

Why are some variables not defined?

This is what I have to do:
Look up and print the student GPA
Add a new student to the class
Change the GPA of a student
Change the expected grade of a student
Print the data of all the students in a tabular format
Quit the program
import student
import pickle
lookup = 1
change = 2
add = 3
delete = 4
QUIT = 0
FILENAME = 'student.dat'
def main():
students_info = load_students()
choice = 0
load_students()
#add(students_info)
change_grade(students_info)
change_GPA(students_info)
#get_menu_choice()
look_up(students_info)
while choice != QUIT:
choice = get_menu_choice()
if choice == lookup:
look_up(students_info)
elif choice == add:
add(students_info)
elif choice == change:
change(students_info)
elif choice == delete:
delete(students_info)
save_students(students_info)
def load_students():
try:
input_file = open(FILENAME, 'rb')
students_dict = pickle.load(input_file)
input_file.close()
except IOError:
students_dict = {}
print(students_dict)
return students_dict
def get_menu_choice():
print()
print('Menu')
print("-------------------")
print('1. Look up ID')
print('2.....')
choice = int(input("Enter your choice:"))
return choice
def look_up(students_info):
ID = input('Enter ID:')
print(student_info.get(ID, "Not found!"))
## try:
## print(students_info[ID])
## except KeyError:
## print("Not found!")
def change_GPA(students_info):
ID = input("ID:")
if ID in students_info:
GPA= float(input("New GPA:"))
students=student.Student(ID,GPA,grade,work)
students_info[ID] = students
print ("This",students_info[ID])
else:
print("Not found!")
def change_grade(students_info):
ID = input("ID:")
if ID in students_info:
New_grade = input("Enter new grade:")
students=student.Student(ID,GPA,grade,work)
students_info[ID] = students
#new_grade = students_info[name]
else:
print("Not found!")
def add(students_info):
name = input("Enter the student name:")
ID= input("Enter student's ID:")
GPA= float(input("Enter GPA:"))
grade= input("Enter student's expected grade:")
work = input("Does the student work part time or full time?")
students=student.Student(name,ID,GPA,grade,work)
print(students_info['ID'])
def save_students(students_info):
output_file = open(FILENAME, 'wb')
pickle.dump(students_info, output_file)
output_file.close()
main()
Whenever I tried to change the GPA or grade it's not defined. How could I change one value from the dictionary studens_info?
As gus42 has commented, the errors you are getting are from the lines:
students=student.Student(ID,GPA,grade,work)
You've not defined grade or work in either of the places you do this (nor GPA in change_grade), so it should not be surprising that you're getting an error.
I think there are two ways to fix the issue:
The simplest way is to change your logic from creating a new Student object to modifying the one that already exists. I don't know exactly what the attribute names are in your Student class, but here's a reasonable guess at a solution:
def change_GPA(students_info):
ID = input("ID:")
if ID in students_info:
GPA= float(input("New GPA:"))
students_info[ID].GPA = GPA # assign new GPA to old student object
else:
print("Not found!")
def change_grade(students_info):
ID = input("ID:")
if ID in students_info:
grade = input("Enter new grade:")
students_info[ID].grade = grade # assign new grade to existing student object
else:
print("Not found!")
The other option is to replace the existing Student object with a new one with some different values. This is close to what your current code, but it only really makes sense if your Student objects are immutable (perhaps because you made the type with namedtuple?). To make it work (where your current code does not), you'll have to load the old values from the old Student object before making the new object:
def change_GPA(students_info):
ID = input("ID:")
if ID in students_info:
new_GPA = float(input("New GPA:"))
old_grade = students_info[ID].grade # load old values
old_work = students_info[ID].work
new_student = students.Student(ID, new_GPA, old_grade, old_work)
students_info[ID] = new_student # replace the old student with a new object
else:
print("Not found!")
def change_grade(students_info):
ID = input("ID:")
if ID in students_info:
new_grade = input("Enter new grade:")
old_GPA = students_info[ID].GPA
old_work = students_info[ID].work
new_student = students.Student(ID, old_GPA, new_grade, old_work)
students_info[ID] = new_student
else:
print("Not found!")

Categories

Resources