How to delete the pickled object from a file? - python

I've got a problem while I was doing a program. My program is to create a class student and there are some variables under that and my task is to add the students in a serializable file and delete the students whenever user wants to. I have written the code for adding the students but I am stuck while delete the object. I am very thankful if anyone could help me how to delete a pickled object from a file?
my code is:
import pickle
n = int(input("Enter number of students you want to enter:"))
for i in range(0,n):
name = input("Enter student name: ")
roll = input("Enter roll number: ")
sex = input("Enter sex: ")
sub = input("Enter subject: ")
tot = input("Enter total: ")
s = Student(name,roll,sex,sub,tot)
infile = open("pb.txt","ab")
pickle.dump(s,infile)
infile.close()
and my student class is:
class Student:
def __init__(self,name,roll,sex,sub,tot):
self.name = name
self.roll = roll
self.sex = sex
self.sub = sub
self.tot = tot

One way could be to pickle a list of students. Then when you want to delete, you can read from file, delete as normal e.g. students.remove(), and then pickle again.

Pickle files aren't editable, and they were never meant to be. If you need to track individual pickled items, look at the shelve module - this lets you treat an external collection of (pickled) objects like a dictionary with string keys.

Related

Save input as text file in python

I got a simple python code with some inputs where a user has to type name, age, player name and his best game.
Now I want that all these inputs from the user were saved as a text file or something like this.
I tried
with open ("Test_", "a") as file:
User_input = file.write(input("here type in your name"))
I tried it with with open ... n where I create a new text file before which I open in python and add something. But everything I tried failed. Hope my English is good enough to understand what kind of problem I have.
import csv
OUTFILE = 'gameplayers.csv'
def main():
player = []
morePlayer = 'y'
while morePlayer == 'y':
name = input('Enter your name: ')
age = input('Your age: ')
playerName = input('Your player name: ')
bestGame = input('What is your best game: ')
player.append([name, age, playerName, bestGame])
morePlayer = input('Enter information of more players: (y, n): ')
with open(OUTFILE, 'a', encoding='utf_8') as f:
csvWriter = csv.writer(f, delimiter=',')
csvWriter.writerows(player)
if __name__ == '__main__':
main()
If you want to keep adding new data, use a otherwise, use w to overwrite. I've used a in this example:
name = input('Name: ')
age = input('Age: ')
best_game = input('Best Game: ')
with open('user_data.txt', 'a') as file:
file.write(f'Name: {name} - Age: {age} - Best Game: {best_game}\n')
First of all, you need to know the difference between 'a' and 'w' in with open. 'w' stands for write, meaning every time you call it, it will be overwritten. 'a' stands for append, meaning new information will be appended to the file. In your case, I would have written the code something like this
userInput = input(“Enter your name: “)
with open(“filename.txt”, “a”) as f:
f.write(userInput)
If you instead want to overwrite every time - change the 'a' to a 'w'.

How to delete given element from a python dictionary?

I am practicing python and doing an exercise where I have to ask for input of different information from patients of a hospital (name, last name, etc) this information has to be saved in a different json file. I managed to do it however I also have to make it so, with an input, I can remove/edit a specific patient from the dictionary (along with all of their info) while keeping the others intact.
I was thinking that maybe I could assign a number to every patient that's added, so this patient can be tracked with the number, however I'm not sure how to code that. I did however made a function to clear everything from the json file, but it has to remove/edit someone specific, not everyone.
My code so far is:
import json
def read_file(file_name):
obj_arch = open(file_name, 'rt', encoding='utf-8')
str_contenido = obj_arch.read()
res = json.loads(str_contenido)
obj_arch.close()
return res
def save_file(file_name, lista):
obj_arch = open(file_name, 'wt', encoding='utf-8')
str_content_to_save = json.dumps(lista)
print(str_content_to_save)
obj_arch.write(str_content_to_save)
obj_arch.close()
opcion = int(input("choose an option: 1 - read. 2 - save"))
if opcion == 1:
lista = read_file('prueba_json.json')
print("Full list:")
print(lista)
else:
lista = read_file('prueba_json.json')
while True:
print("--- PATIENT INFO ---")
Name = input("Input name: ")
Lastname = input("Input lastname: ")
DateB= input("Input date of birht: ")
repeat = input("Do you want to add more info?: ")
clean_file = input("Clean everything from the json file? (yes/no): ")
lista.append({
"Name": Name,
"Lastname": Lastname,
"Date of Birth": DateB
})
if repeat == 'no' or repeat == 'NO':
break
save_file('prueba_json.json',lista)
With this I was able to sabe the patients info in the json file, but how can I write another input like "Insert number of patient to remove or delete" to do that?
In order to clean the whole json file I've done it with this:
def clean_json():
with open('prueba_json.json', 'w') as arc:
arc.writelines(["[{}]"])
if clean_file == "yes" or clean_file == "YES":
clean_json()
Maybe I could adapt some of this to remove or delete someone instead of the whole file?

How can I create an input that will loop and create a new list each time?

in case it isn't already obvious im new to python so if the answers could explain like im 5 years old that would be hugely appreirecated.
I'm basically trying to prove to myself that I can apply some of the basic that I have learnt into making a mini-contact book app. I don't want the data to save after the application has closed or anything like that. Just input your name, phone number and the city you live in. Once multiple names are inputted you can input a specific name to have their information printed back to you.
This is what I have so far:
Name = input("enter name here: ")
Number = input("enter phone number here: ")
City = input("enter city here: ")
User = list((Name, Number, City))
This, worked fine for the job of giving python the data. I made another input that made python print the information back to me just to make sure python was doing what I wanted it to:
print("Thank you! \nWould you like me to read your details back to you?")
bck = input("Y / N")
if bck == "Y":
print(User)
print("Thank you! Goodbye")
else:
print("Goodbye!")
The output of this, is the list that the user creates through the three inputs. Which is great! I'm happy that I have managed to make it function so far;
But I want the 'Name' input to be what names the 'User' list. This way, if I ask the user to input a name, that name will be used to find the list and print it.
How do I assign the input from Name to ALSO be what the currently named "User" list
You will need to create a variable which can store multiple contacts inside of it. Each contact will be a list (or a tuple. Here I have used a tuple, but it doesn't matter much either way).
For this you could use a list of lists, but a dictionary will be more suitable in this case.
What is a dictionary?
A dictionary is just like a list, except that you can give each of the elements a name. This name is called a "key", and it will most commonly be a string. This is perfect for this use case, as we want to be able to store the name of each contact.
Each value within the dictionary can be whatever you want - in this case, it will be storing a list/tuple containing information about a user.
To create a dictionary, you use curly brackets:
empty_dictionary = {}
dictionary_with_stuff_in_it = {
"key1": "value1",
"key2": "value2"
}
To get an item from a dictionary, you index it with square brackets, putting a key inside the square brackets:
print(dictionary_with_stuff_in_it["key1"]) # Prints "value1"
You can also set an item / add a new item to a dictionary like so:
empty_dictionary["a"] = 1
print(empty_dictionary["a"]) # Prints 1
How to use a dictionary here
At the start of the code, you should create an empty dictionary, then as input is received, you should add to the dictionary.
Here is the code I made, in which I have used a while loop to continue receiving input until the user wants to exit:
contacts = {}
msg = "Would you like to: \n - n: Enter a new contact \n - g: Get details for an existing contact \n - e: Exit \nPlease type n, g, or e: \n"
action = input(msg)
while action != "e":
if action == "n": # Enter a new contact
name = input("Enter name here: ")
number = input("Enter phone number here: ")
city = input("Enter city here: ")
contacts[name] = (number, city)
print("Contact saved! \n")
action = input(msg)
elif action == "g": # Get details for an existing contact
name = input("Enter name here: ")
try:
number, city = contacts[name] # Get that contact's information from the dictionary, and store it into the number and city variables
print("Number:", number)
print("City:", city)
print()
except KeyError: # If the contact does not exist, a KeyError will be raised
print("Could not find a contact with that name. \n")
action = input(msg)
else:
action = input("Oops, you did not enter a valid action. Please type n, g, or e: ")
#can be easier to use with a dictionary
#but its just basic
#main list storing all the contacts
Contact=[]
#takes length of contact list,'int' just change input from string to integer
contact_lenght=int(input('enter lenght for contact'))
print("enter contacts:-")
#using for loop to add contacts
for i in range(0,len(contact_lenght)):
#contact no.
print("contact",i+1)
Name=input('enter name:')
Number=input('enter number:')
City=input("enter city:")
#adding contact to contact list using .append(obj)
Contact.append((Name,Number,City))
#we can directly take input from user using input()
bck=input("Thank you! \nWould you like me to read your details back to you?[y/n]:")
#checking if user wants to read back
if bck=='y':
u=input("enter your name:")
#using for loop to read contacts
for i in range(0,len(Contact)):
#if user name is same as contact name then print contact details
if u==Contact[i][0]:
print("your number is",Contact[i][1])
print("your city is",Contact[i][2])
else:
#if user doesnt want to read back then print thank you
print("Good bye")
For this purpose you should use a dictionary.
The key of every entry should be the string 'User[0]' that corresponds to the person's name.
The contents of every entry should be the list with the information of that user.
I'll give you an example:
# first we need to create an empty dictionary
data = {}
# in your code when you want to store information into
# the dictionary you should do like this
user_name = User[0] # this is a string
data[user_name] = User # the list with the information
If you want to access the information of one person you should do like this:
# user_you_want string with user name you want the information
data[user_you_want]
Also you can remove information with this command:
del data[user_you_want_to_delete]
You can get more information on dictionaries here: https://docs.python.org/3/tutorial/datastructures.html#dictionaries
You should start by defining a class to support name, phone and city. Once you've done that, everything else is easy.
class Data:
def __init__(self, name, city, phone):
self.name = name
self.city = city
self.phone = phone
def __eq__(self, other):
if isinstance(other, str):
return self.name == other
if isinstance(name, type(self)):
return self.name == other.name and self.city == other.city and self.phone == other.phone
return False
def __str__(self):
return f'Name={self.name}, City={self.city}, Phone={self.phone}'
DataList = []
while (name := input('Name (return to finish): ')):
city = input('City: ')
phone = input('Phone: ')
DataList.append(Data(name, city, phone))
while (name := input('Enter name to search (return to finish): ')):
try:
print(DataList[DataList.index(name)])
except ValueError:
print('Not found')

Class to collect data from user

I am learning python from scratch and am stuck with classes what I am trying to achieve as follows:
Problem statement: "Collect the data of different students into an array and display."
I am trying to achieve this using classes.
Below is my code which I am trying out. Need help on how to get the values of different question into one single dimensional array.
i.e.
["brittos school", "Ahmedabad", "Francis", "34", " 36", "anthony's school", "Mumbai", "Sam", "45", " 55"]
Where 34 36 are the marks of the subject.
class Mack:
def getmarks(self,numberofsubjects,numberofstudents,sub):
marks=[]
for i in range(numberofstudents):
self.sname=input("Enter your School Name: ")
a.append(marks)
self.city=input("Enter the School City: ")
a.append(marks)
self.name=input("Enter your Name")
a.append(marks)
a=[]
for j in range(numberofsubjects):
a.append(int(input(f"Enter the Marks for {sub[j]} ")))
marks.append(a)
def show(self):
print("My Name is: ",self.name)
print("My City is: ",self.city)
sub=[]
numberofstudents=int(input("Input the number of students"))
numberofsubjects=int(input("Input the number of subjects"))
for i in range(0, numberofsubjects):
ele = input(f"enter the subject name :{i+1}")
sub.append(ele)
ab=Mack()
for i in range(0,numberofstudents):
ab.getmarks(numberofstudents,numberofsubjects,sub)
First of all, you are using the same loop outside the getmarks function and inside it so for example if I input number of students as 2. It will run 4 times which is incorrect. Loop over number of students once. Secondly a is not defined anywhere so if you want the list of all the input I'd suggest creating a as a member variable of this class.
I think this code below is what you need
class Mack:
def getmarks(self,numberofsubjects,numberofstudents,sub):
marks=[]
a = []
for i in range(numberofstudents):
self.sname=input("Enter your School Name: ")
a.append(self.sname)
self.city=input("Enter the School City: ")
a.append(self.city)
self.name=input("Enter your Name")
a.append(self.name)
for j in range(numberofsubjects):
a.append(int(input(f"Enter the Marks for {sub[j]} ")))
marks.append(a)
return a
def show(self):
print("My Name is: ",self.name)
print("My City is: ",self.city)
sub=[]
numberofstudents=int(input("Input the number of students"))
numberofsubjects=int(input("Input the number of subjects"))
for i in range(0, numberofsubjects):
ele = input(f"enter the subject name :{i+1}")
sub.append(ele)
ab=Mack()
result = ab.getmarks(numberofstudents,numberofsubjects,sub)
print(result)
Although this is a very bad approach to do what you are trying to do. What I would suggest is to create a Student Class like.
class Student:
def __init__(self, name, sname, cname, subjects, marks):
self.name = name
self.sname = sname
self.cname = cname
self.subjects = subjects
self.marks = marks
where subjects and marks would lists of subjects and marks. You can also create a dictionary if you want where subject would be key and marks would be value. After that, you can simple create a list of this class and take input for every element of that Student list.

Having problems pickling and loading for class

So the prompt is:
Phase 1: Employee Class
Write a class named Employee that holds the following data about an employee in attributes: name, ID Number, department, and job title.
Once you have written the class, write a program that creates three Employees objects to hold the following data:
Name, ID Number, Department, Job Title
Susan Meyers 47899 Accounting Vice President
Mark Jones 39119 IT Programmer
Joy Rodgers 81774 Manufacturing Engineer
The program should store this data in the three objects, then display the data for each employee on the screen.
Phase 2: Employee Management System
This exercise assumes you have created the Employee class for Phase 1. 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 the 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.
SO for the most part I was able to create the class, and I was able to create the menu, I'm having problems with putting the employees in the file and loading so that I can use the menu. Here's my code:
import EmployeeClass
import pickle
def lookup(dictionary):
id_num = input("What is the employee's ID number")
if id_num in dictionary.keys():
print(id_num, ":", dictionary[id_num].str())
else:
print("I'm sorry we don't have that number in our registry. Try again")
lookup(dictionary)
def add(dictionary):
name = input("What is their name?")
id_num = input("What is their ID number?")
department = input("What department do they work in?")
title = input("What position do they hold?")
entry = EmployeeClass.Employee(name, id_num, department, title)
dictionary[id_num] = entry
return dictionary
def change(dictionary):
id_num = input("Enter the ID Number off the employee you would like to change:")
if id_num in dictionary.keys():
tempID = id_num
newName = input("What would you like to change the name to?")
newID = input("What would you like to change their ID Number to?")
newDepartment = input("What department does this person work in?")
newTitle = input("What title does this person hold?")
entry = EmployeeClass.Employee(newName, newID, newDepartment, newTitle)
dictionary[newID] = entry
del dictionary[tempID]
print("Employee changed successfully")
else:
print("Employee not found. Try again")
def delete(dictionary):
id_num = input("Enter the ID Number of the employee that would like to delete")
if id_num in dictionary.keys():
del dictionary[id_num]
else:
print("That employee was not found")
def save_close(dictionary):
output_file = open('employee.dat', 'wb')
pickle.dump(dictionary, output_file)
output_file.close()
def main():
employee_data = open("employee.dat", 'wb')
emp1 = EmployeeClass.Employee("Susan Myers", 47899, "Accounting", "Vice President")
emp2 = EmployeeClass.Employee("Mark Jones", 39119, "IT", "Programmer")
emp3 = EmployeeClass.Employee("Joy Rodgers", 81774, "Manufacturing", "Engineer")
pickle.dump(emp1, employee_data)
pickle.dump(emp2, employee_data)
pickle.dump(emp3, employee_data)
employee_data.close()
input_file = open('employee.dat', 'rb')
pickle.load(input_file)
input_file.close()
employee_dictionary = {}
next = True
while next:
print("Welcome to the the Employee Management System. Would you like to:\n")
print("Lookup an employee? Press 1 \n")
print("Add a new employee? Press 2 \n")
print("Alter an existing employee? Press 3 \n")
print("Delete an existing employee's information? Press 4 \n")
print("Save and Close? Press 5 \n")
user_choice = input(int())
menu = {"1": lookup, "2": add, "3": change, "4": delete, "5": save_close}
x = menu[user_choice](employee_dictionary)
if user_choice == 2:
employee_dictionary.update(x)
if user_choice ==3:
employee_dictionary.update(x)
if user_choice ==4:
employee_dictionary.update(x)
main()
So luckily I was able to figure out the pickling problem thanks to someone who answered, but after that when loading the menu it says that my Employee object has not attribute keys. Thank you for your responses!
What you're doing wrong is you're not assigning the depickled file to any variable.
You need to change this block of code
input_file = open('employee.dat', 'rb')
pickle.load(input_file)
input_file.close()
employee_dictionary = {}
to
input_file = open('employee.dat', 'rb')
employee_dictionary=pickle.load(input_file)
input_file.close()
Only then would you be able to access the pickled dictionary.

Categories