Python- Saving Results to a File and Recalling Them - python

I'm writing a program in Python that will store Student IDs, names, and D.O.B.s.
The program gives the user the ability to remove, add, or find a student. Here is the code:
students={}
def add_student():
#Lastname, Firstname
name=raw_input("Enter Student's Name")
#ID Number
idnum=raw_input("Enter Student's ID Number")
#D.O.B.
bday=raw_input("Enter Student's Date of Birth")
students[idnum]={'name':name, 'bday':bday}
def delete_student():
idnum=raw_input("delete which student:")
del students[idnum]
def find_student():
print "Find"
menu = {}
menu['1']="Add Student."
menu['2']="Delete Student."
menu['3']="Find Student"
menu['4']="Exit"
while True:
options=menu.keys()
options.sort()
for entry in options:
print entry, menu[entry]
selection=raw_input("Please Select:")
if selection =='1':
add_student()
elif selection == '2':
delete_student()
elif selection == '3':
find_students
elif selection == '4':
break
else:
print "Unknown Option Selected!"
The problem I am having is I cannot figure out how to have the program save any added records to a file when the program ends. It also would need to read back the records when the program restarts.
I keep trying to find tutorials for this sort of thing online, but to no avail. Is this the sort of code I'd want to add?:
f = open("myfile.txt", "a")
I'm new to Python so any help would be appreciated. Thanks so much.

It depends, if you want to actually save python objects, check out Pickle or Shelve, but if you just want to output to a text file, then do the following:
with open('nameOfYourSaveFile', 'w') as saveFile:
#.write() does not automatically add a newline, like print does
saveFile.write(myString + "\n")
Here's an answer that explains the different arguments to open, as in w, w+, a, etc.
As an example, say we have:
with open('nameOfYourSaveFile', 'w') as saveFile:
for i in xrange(10):
saveFile.write(name[i] + str(phoneNumber[i]) + email[i] + "\n")
To read the file back, we do:
names = []
numbers = []
emails = []
with open('nameOfYourSaveFile', 'r') as inFile:
for line in inFile:
#get rid of EOL
line = line.rstrip()
#random example
names.append(line[0])
numbers.append(line[1])
emails.append(line[2])
#Or another approach if we want to simply print each token on a newline
for word in line:
print word

import pickle,os
if os.path.exists("database.dat"):
students = pickle.load(open("database.dat"))
else:
students = {}
... #your program
def save():
pickle.dump(students,open("database.dat","w"))

Related

Listing a single entry by selecting ID and updating a single entry in Python

I'm creating a program which I will run in bash/terminal. When run, the programme is supposed to prompt the user with the question "Please add user ID". After entering an ID (not index) it should display the selected ID. eg: 1 should display the whole line of Will Smith.
The code I had implemented is as below but it displays the index. If I select 1, it would display the line of Jane Doe. Where am I going wrong?:
def show_single_user():
initialise = []
input_user_id = input("Please add user index.")
for i, row in enumerate(open("file.txt")):
if str(i) in input_user_id:
initialise.append(row)
print(initialise)
I have a similar issue when I want to delete a user ID, it randomly deletes a user instead of the ID requested. I don't want to delete based on index which starts at zero. Below is the code.
def delete_user_id():
text_file = open("file.txt", "r")
target_id = text_file.readlines()
text_file.close()
user_input = input("Add the ID to delete:")
del target_id[1]
new_file = open("file.txt", "w+")
# For loop iterating to delete the appropriate line
for line in target_id:
new_file.write(line)
new_file.close()
print("User ID successfully removed!")
input("Press any key to return to main menu")
delete_user_id()
Thanks
You should read the ID from the file.
def show_single_user():
initialise = []
input_user_id = input("Please add user index.")
for line in open("file.txt"):
id = line.split()[0]
if id == input_user_id:
initialise.append(row)
print(initialise)

Deleting a person from a file not in a list

For class I need to put names into a file then have the user type in the name they want to delete, and it deletes them. I almost have it it just deletes 2 people at once and I'm not sure why.
import os
def main():
found=False
search=input("Who would you like to delete? ")
student_grades = open("student_grades.txt", 'r')
temp_file= open('temp.txt', 'w')
descr = student_grades.readline()
while descr != '':
qty = (student_grades.readline())
descr = descr.rstrip('\n')
if descr != search:
temp_file.write(descr + '\n')
temp_file.write(str(qty) + '\n')
else:
found = True
descr = student_grades.readline()
student_grades.close()
temp_file.close()
os.rename('temp.txt', 'grades.txt')
if found:
print('The file has been updated.')
else:
print('That student was not found in the file.')
main()
There is also 2 files. student_grades.txt that has the names in it, and temp.txt with nothing. When typing in the name of the person, it can find them but it deletes 2 people instead of the one that was searched.
If you are using Python3.6+
from pathlib import Path
fname = "student_grades.txt"
def bak_file(old_name, new_name=None):
if new_name is None:
new_name = old_name + '.bak'
Path(new_name).write_bytes(Path(old_name).read_bytes())
print('-->', f'cp {old_name} {new_name}')
def main():
bak_file(fname)
lines = Path(fname).read_text().splitlines()
search = input("Who would you like to delete? ").strip()
if search in lines:
updated_lines = [i for i in lines if i != search]
Path(fname).write_text('\n'.join(updated_lines))
print(f'The file {fname} has been updated.')
else:
print('That student was not found in the file.')
if __name__ == '__main__':
main()
Are you sure it deletes two people? This qty = (student_grades.readline()) ... temp_file.write(str(qty) + '\n') makes me think that you might be adding unwanted new lines (no strip when getting the qty, but adding a new line when rewriting it), which might look like you removed two instead of one?
Eraw got it. It works now. I was following a program from my book and they had a slightly different scenario. I deleted qty = (student_grades.readline()) and temp_file.write(str(qty) + '\n') and this deletes only what needs to be deleted. Thanks!

Combine lines when writing to file in Python?

So I'm trying to write all this info to a .txt file, but due to the names being pulled from a .txt file that goes
Liam
Noah
William
etc...
When I write to a file, it puts the first and last names on separate lines from everything else.
I've looked on StackOverflow for a solution but I couldn't find anything specific enough.
password = input('Enter the Password you would like to use ')
open('names.txt', 'r+')
lines = open("names.txt").readlines()
firstName = lines[0]
words = firstName.split()
firstNameChoice = random.choice(lines)
open('names.txt', 'r+')
lines = open("names.txt").readlines()
lastName = lines[0]
words = lastName.split()
lastNameChoice = random.choice(lines)
def signUp():
randomNumber = str(random.randint(0,10000))
accountFile = open('accounts.txt', 'a')
accountFile.write(firstNameChoice)
accountFile.write(lastNameChoice)
accountFile.write(randomNumber)
accountFile.write('#')
accountFile.write(catchall)
accountFile.write(':')
accountFile.write(password)
accountFile.write('\n')
signUp()
Expectation would be everything printed to one line but that's not the case.
As a quick fix for your problem, you could merge all writing commands in one line:
with open('accounts.txt', 'a') as accountFile: # using a context manager is highly recommended
# with spaces
accountFile.write('{} {} {} # {} : {} \n'.format(
firstNameChoice,
lastNameChoice,
randomNumber,
catchall,
password
)
)
# without spaces
accountFile.write('{}{}{}#{}:{}\n'.format(
firstNameChoice,
lastNameChoice,
randomNumber,
catchall,
password
)
)
If my understanding is right then you want to write everything in one line.
The variables you are writing containing \n while writing into the file.
So you have to replace it with a ' '. Replace this code into your program like:
accountFile.write(firstNameChoice.replace('\n',' '))
accountFile.write(lastNameChoice.replace('\n',' '))
accountFile.write(str(randomNumber).replace('\n',' '))
accountFile.write('#'.replace('\n',' '))
#accountFile.write(catchall)
accountFile.write(':'.replace('\n',' '))
accountFile.write(str(password).replace('\n',' '))
Now it will print like this WilliamWilliam448#:dsada
By the way I dont know what you mean by catchall
The reason it puts it all on a new line is because the strings of your names contains the "\n" on the end because it has an enter to a new line. There is an easy fix for this.
Where you define your first and last name variables add .rstrip() at the end. Like this:
firstNameChoice = random.choice(lines).rstrip()
lastNameChoice = random.choice(lines).rstrip()
def signUp():
randomNumber = str(random.randint(0,10000))
accountFile = open('accounts.txt', 'a')
accountFile.write(f'{firstNameChoice} {lastNameChoice} {randomNumber} # {catchall}: {password} \n')

How do I create a text file that contain a list of results in python

I am studying JavaScript and Python at the moment, and I am reading and writing to text files in Python at the moment. Currently, I am trying to: write a program that should, when instructed to do so, create a file, that contains a list of students that need to re-sit and the number of marks they need to score to get a minimum of 85.
I have already written code that displays whether or not a student has hit the minimum score of 85, and if they haven't, how many more marks they need. But now I'm stuck. Any help would be very greatly appreciated, thanks!
Python:
def menu():
target = 85
with open('homework.txt','r') as a_file:
for l in a_file:
name, number = l.split(',')
number = int(number)
print(name + ': ' + ('passed' if number>=target else str(target - number)))
input()
Text File:
emma smith,79
noah jones,32
olivia williams,26
liam taylor,91
sophia green,80
mason brown,98
You just need to open a file to write the prints:
def menu():
target = 85
results = open("results.txt",'w')
with open('homework.txt','r') as a_file:
for l in a_file:
name, number = l.split(',')
number = int(number)
results.write(name + ': ' + ('passed' if number>=target else str(target - number)) + '\n')
input()
It sounds like you just want to pipe the results of your program into another textfile.
python file.py > results.txt should do the trick.
(I didn't check your algorithm, as you mention that it's doing what you want it to do already)
I guess this might do what you need ...
def menu():
out_file = open("results.txt", "w")
target = 85
with open("homework.txt", "r") as a_file:
for l in a_file:
name, number = l.split(",")
number = int(number)
out_file.write("{},{}\n".format(name, ('passed' if number>=target else str(target - number))))
menu()
It seems to me that you are trying to achieve the following:
Get the data from a text file, which you kind of did it
Get a user input to open a new text file: reSit = input("Enter file name for the re-sit: ")
Create a file to write to it fh = open(reSit ,'w')
write to a file fh.write(<a fails student> + '\n')
Close the file
if you want to append to a file replace 3 by fh = open(reSit ,'a')

Perform math equation inside of a loaded text file

I'm currently working on a simple little application that keeps track of wins and losses for any sort of game. I'm storing the win/loss count in separate text files as single numbers. What I want the program to be able to do is look into the specified text file, and simply add 1 to the existing number. For example, if the entire text file is simply "0" and I input "win" into the application, it will perform 0+1 and change the text file permanently to the result.
Here's what I've got so far:
ld = open("data/lossdata.txt", "r+")
wd = open("data/windata.txt", "r+")
hlp = open("data/help.txt", "r+")
losread = ld.read()
winread = wd.read()
helpread = hlp.read()
to_write = []
print("Welcome to Track Lad. For help, input \"help\"\nCurrent Win Count: "+winread+"\nCurrent Loss Count: "+losread)
inp = input("Input: ")
if inp == "w" or inp == "win":
for line in wd:
num = int(line) + 1
to_write.append(num)
wd.reload()
wd.seek(0)
for num in to_write:
wd.write(str(num)+'\n')
wd.close()
print("New Win Count: "+winread+"\nLoss Count: "+losread)
input("")
elif inp == "l" or inp == "loss":
ld.write("1")
print("New Loss Count: "+losread+"\nWin Count: "+winread)
input("")
elif inp == "help":
print(helpread)
input("")
else:
print("Invalid input, try again.")
input("")
Everything I've done so far is in the first if statement. I'm not getting any error when I run the code, even when I input "w", but the number in the text file doesn't change. Thanks in advance for any help, and I'll stay on the page to answer any questions that may help you figure out what's wrong.
I would recommend using a single file database like SQLIte instead of separated text files. You also can register all wins and losses (with timestamp, if you needed later).
import sqlite3
db = sqlite3.connect('winloss.db')
cursor = db.cursor()
cursor.execute('''
CREATE TABLE IF NOT EXISTS winloss (
id INTEGER PRIMARY KEY AUTOINCREMENT,
t TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
value TEXT
);
''')
db.commit()
def add_value(db, value):
cursor = db.cursor()
cursor.execute("INSERT INTO winloss(value) VALUES(?)", (value, ))
db.commit()
def add_win(db):
add_value(db, "win")
def add_loss(db):
add_value(db, "loss")
def count_value(db, value):
cursor = db.cursor()
cursor.execute("SELECT COUNT(*) FROM winloss where value=?", (value, ))
return cursor.fetchone()[0]
def count_win(db):
return count_value(db, "win")
def count_loss(db):
return count_value(db, "loss")
if __name__ == '__main__':
print "now"
print "win:", count_win(db)
print "loss:", count_loss(db)
print "adding values"
add_win(db)
add_win(db)
add_loss(db)
print "win:", count_win(db)
print "loss:", count_loss(db)
And it is easier to read and understand
As you seem to have very small data in your lossdata.txt and windata.txt, I would preferably do the following :
read the entire file content and store the data into variables (open the file in readmode, read data, then close the file),
overwrite the entire file content with the new value (open the file in writemode, write data, then close the file)
If you need to update a particular line of your file, know that it's better to make a copy of your input file and create the updated file as a new file. This is exactly what fileinput.input(inplace=1) does as noted in this SO answer.
So, try to do something like :
import fileinput
def process(line):
return int(line) + 1
for line in fileinput.input(inplace=1):
print process(line)

Categories