Writing a list into a text file - python

Using windows 10
Here's a sample of my code, where the problem is:
if choice2 == "d":
amount = int(raw_input("How much money would you like to deposit? Current balance: %i : " % intBalance))
newBalance = intBalance + amount
print "Current balance: %i" %newBalance
f.close()
os.remove("accounts.txt")
f = open("accounts.txt", "a+")
fileVar.remove(accessedAccount[2])
fileVar.remove(accessedAccount[1])
fileVar.remove(accessedAccount[0])
f.write(accessedAccount[0] + "\n")
f.write(accessedAccount[1] + "\n")
newBalance = str(newBalance)
f.write(newBalance + "\n")
for item in fileVar:
f.write("%s\n" %item)
test = raw_input("Waiting for input")
At the bottom is the code that writes the information of the list (called fileVar) into the text file (called f). It does write the information to the list but it messes up the order of the lines which cannot happen with the program I am making because the file must be able to be read back to the program to work later on.
Here is my entire code for context:
import os
import string
again = "y"
f = open('accounts.txt', 'a+')
fileVar = f.read().splitlines()
print fileVar
accessedAccount = []
data = f.read()
choice = raw_input("What would you like to do? (add/remove a bank account, access a bank account): ")
if choice == "a":
while again == "y":
accName = raw_input("Account owner's name: ")
accType = raw_input("Account type: ")
accBal = "0"
f.seek(0, 2)
f.write(accName + "\n")
f.write(accType + "\n")
f.write(accBal)
f.write("\n")
again = raw_input("Add another account?: ")
if choice == "a2":
account = raw_input("What is the name of the account you wish to access?: ")
for i, line in enumerate(fileVar):
if account in line:
for j in fileVar[i:i+3]:
print j
accessedAccount.append(j)
print accessedAccount
balance = accessedAccount[2]
intBalance = int(balance)
print accessedAccount
choice2 = raw_input("This is your bank account. What would you like to do now? (Withdraw/deposit, exit): ")
if choice2 == "d":
amount = int(raw_input("How much money would you like to deposit? Current balance: %i : " %intBalance))
newBalance = intBalance + amount
print "Current balance: %i" %newBalance
f.close()
os.remove("accounts.txt")
f = open ("accounts.txt", "a+")
fileVar.remove(accessedAccount[2])
fileVar.remove(accessedAccount[1])
fileVar.remove(accessedAccount[0])
f.write(accessedAccount[0] + "\n")
f.write(accessedAccount[1] + "\n")
newBalance = str(newBalance)
f.write(newBalance + "\n")
for item in fileVar:
f.write("%s\n" %item)
test = raw_input("Waiting for input")
if choice2 == "w":
amount = int(raw_input("How much money would you like to withdraw? Current balanace: %i : " %intBalance))
newBalance = intBalance - amount
print "Current Balance: %i" %newBalance
f.close()
os.remove("accounts.txt")
f = open ("accounts.txt", "a+")
fileVar.remove(accessedAccount[0])
fileVar.remove(accessedAccount[1])
fileVar.remove(accessedAccount[2])
f.write(accessedAccount[0] + "\n")
f.write(accessedAccount[1] + "\n")
newBalance = str(newBalance)
f.write(newBalance + "\n")
for item in fileVar:
f.write("%s\n" %item)
test = raw_input("Waiting for input")
if choice == "r":
removeChoice = raw_input("What is the name of the account you wish to remove?: ")
f.close()
os.remove("accounts.txt")
f= open("accounts.txt", "a+")
for i, line in enumerate(fileVar):
if removeChoice in line:
for j in fileVar[i:i+3]:
accessedAccount.append(j)
fileVar.remove(accessedAccount[0])
fileVar.remove(accessedAccount[1])
fileVar.remove(accessedAccount[2])
for item in fileVar:
f.write("%s\n" %item)
f.close()
for example, the original text file looks like this:
Ryan
Savings
0
John
Chequings
0
Carly
Savings
0
when it is re-written with edited information, what it is supposed to look like, if 300 dollars were added to Carly's account:
Carly
Savings
300
Ryan
Savings
0
John
Chequings
0
What it looks like instead:
Carly
Savings
300
John
Chequings
Ryan
0
Savings
0
Thank you in advance :)

Not a direct answer to your question, but some pointers which may end up making it much easier for both yourself and others to debug your code.
1) Functions are your friend. See if you can take small tasks and break them up into functions. For example, writing out someone's balance to a file could be a small function, which you might call like:
def write_balance_to_file(account_details):
...function code goes here...
account_details = {name:"Ryan", account:"Savings", balance:1000}
write_balance_to_file(account_details)
Opening and closing the file should be handled within that function, and preferably using:
with open('filename', 'a+') as f:
f.write("A thing to write")
Note that you don't need to close the file manually when doing this.
2) Use a dictionary for storing a person's account details, rather than a list. Multiple accounts can be stored as a list of dictionaries. This makes it a lot easier to read as call such as:
f.write(accessedAccount[0] + "\n")
which becomes:
f.write(accessedAccount['name'] + '\n')
You can then pass in this dictionary to the write_balance_to_file method you will create. :)
3) Consider a tab-separated format for your accounts.txt file. Remember to escape/remove any tabs in your user input. This way each account will be on one line.
4) Possibly a little way in the future for you, but be aware that unit-testing exists, and is good practice. In essence, you can write tests (usually using a test framework such as py.test) which test each function/class/module under different input conditions. Anything that you can't break up into small, testable code fragments (functions or classes) is probably not good code. Writing tests is a great way to identify bugs in your code, and often helps to clarify your thinking. ALWAYS TEST!

For a minimal change that will solve the issue, this is the code that needs to change:
for i, line in enumerate(fileVar):
if account in line:
for j in fileVar[i:i+3]:
print j
accessedAccount.append(j)
This records which entries are part of the accessedAccount however later on you just remove the first occurence of these entries:
fileVar.remove(accessedAccount[2])
fileVar.remove(accessedAccount[1])
fileVar.remove(accessedAccount[0])
but if the entry is something as simple as 0 then it will not necessarily remove it from the correct place, so instead pop the accessed account out of the fileVar when putting them into accessedAccount:
for i, line in enumerate(fileVar):
if account in line:
for j in range(3):
print i+j
accessedAccount.append(fileVar.pop(i+j))
#break # you probably want to stop checking by this point
This will remove the relevent lines from fileVar and put them in accessedAccount so the order of lines will not be messed up by using .remove, and then obviously comment out the calls to .remove:
## fileVar.remove(accessedAccount[2])
## fileVar.remove(accessedAccount[1])
## fileVar.remove(accessedAccount[0])
This should fix the immediate problem of taking out the wrong lines.

Related

Collecting user input. Reading and writing to text files in python

Basically what I want to do is have the notepad list show up in python so the user can see what is on the list without opening the file. I have done that. Now I want to have the user input a product that they want, and save it, and print out the product and the price. This is what the text file looks like:
000,67463528,50mm bolts,2.20
001,34512340,plain brackets,0.50
002,56756777,100mm bolts,0.20
003,90673412,l-shaped brackets,1.20
004,45378928,normal brackets,0.80
005,1638647,10mm bolts,0.10
006,14372841,plain brackets,1.29
007,29384754,200mm bolts,0.50
008,12345768,screwdriver,10.99
So far I can add products to the end of the code, and I can insert text at a certain line number. I am working out how to print out a receipt based on user input. I am new to python studying this as a hobby, any help would be greatly appreciated. Thanks!
This is the python code:
def search():
gtin = input("What is the GTIN code? ")
des = input("What is the name of the product? ")
price = input ("What is the price of the product? ")
position_str = input("What line do you want this inserted at? ")
print("This is the list now: ")
position = int(position_str)
with open("task2.txt", "r") as a_file:
data = a_file.readlines()
data.insert(position, "00" + position_str + "," + gtin + "," + des + "," + price + "\n")
data = "".join(data)
with open("task2.txt", "w") as a_file:
a_file.write(data)
input()
with open('task2.txt','r')as Task2:
print('{0:<19} {1:<19} {2:<19} {3:<19}'.format("\nNo.","GTIN-8","Item Name","Price"))
for row in Task2:
row=row.strip()
eachItem=row.split(",")
print('{0:<19} {1:<19} {2:<19} {3:<19}'.format(eachItem[0],eachItem[1],eachItem[2],eachItem[3]))
print()
def add():
print("The data you put here will be added onto the end ")
gtin = input("What is the GTIN-8? ")
des = input("What is the description? ")
price = input("What is the price? ") #gets all the info they want to add
print("This is the list now: ")
with open("task2.txt","a") as a_file:
a_file.writelines(" ," + gtin + "," + des + "," + price + "\n")
a_file.close()
print("Product has been added")
with open('task2.txt','r')as Task2:
print('{0:<19} {1:<19} {2:<19} {3:<19}'.format("\nNo.","GTIN-8","Item Name","Price"))
for row in Task2:
row=row.strip()
eachItem=row.split(",")
print('{0:<19} {1:<19} {2:<19} {3:<19}'.format(eachItem[0],eachItem[1],eachItem[2],eachItem[3]))
print()
def reciept():
print()
#this is the menu. this is where the user will make choices on what they do
def menu():
print("What would you like to do?")
with open('task2.txt','r')as Task2:
print('{0:<19} {1:<19} {2:<19} {3:<19}'.format("\nNo.","GTIN-8","Item Name","Price"))
for row in Task2:
row=row.strip()
eachItem=row.split(",")
print('{0:<19} {1:<19} {2:<19} {3:<19}'.format(eachItem[0],eachItem[1],eachItem[2],eachItem[3]))
print()
print("1. Add a product onto a specific line number?")
print("2. Or add a product onto the end?")
print("3. Buy products and have them printed onto a reciept?")
choice=int(input("Which one?: "))
if choice==1:
search()
elif choice==2:
add()
elif choice==3:
reciept()
menu()
What to fix and documentation locations
Firstly, I also cannot seem to replicate exactly what you're doing so, I worked up my own solution to some extent...
If you provided a text document with the information in it, it might help with debugging.
That aside... I noticed that if you don't have your "task2.txt" file created, you don't have a way to create one.
This can be done with Task2 = open("task2.txt", "w"). Input / Output Documentation for Python 2.7
Secondly, some of the formatting can be improved by using expressions; I.E.,
\t [tab],
\n [newline],
\r [return],
So you can abide by PEP-8 standard rules. PEP-8 Documentation
Alright, so that's out of the way, what you need to do next is understand the different between open and with open... Not too much difference here, except that with open forces you to immediately jump into a loop. If the document doesn't have information in it, you result in an error (this is the issue I have right now).
Storing it as a list (task2 = open([file], 'r') is better as it allows you to utilize it later. You should also run a check to see if the file even exists...
Example
Thirdly, here are a few tips n' tricks:
import os
boolCheckOnFile = os.path.isfile("[Location to File]\\task2.txt")
# Check if it exists
if boolCheckOnFile==False:
# Create file, "w" for write
task2Creation = open("[Location to File]\\task2.txt", "w")
# Close the file to reopen and read it or write to it...
task2Creation.close()
# Again "w" for write, "a" for append, "r" for read, "r+" for read/write...
task2 = open("[Location to File]\\task2.txt", "r+")
From here, you can write to the file by enacting str.write(information). But it's always best to close the file when you're actually done with the file... So the changes you made to it are permanent str.close().
Word of advice, print() # print "()", you must fill it, so at least do a newline, like so:
print("\n")
What I did to fix some beginners issues
Finally, below is my iteration of the corrected version (for just the menu portion of your script)...
def menu():
print("What would you like to do?")
# Check if file exists
if os.path.isfile('C:\\users\\[username]\\Desktop\\task2.txt')==False:
# Create it and promptly close it, so it is in the correct location
task1 = open('C:\\users\\[username]\\Desktop\\task2.txt','w')
task1.close()
# Open for read-write
task2 = open('C:\\users\\[username]\\Desktop\\task2.txt','r+')
# splits for new line break, making an array
info = task2.read().split("\n")
# Check to see if the file is empty
if len(info) is not 0:
print('{0:<19} {1:<19} {2:<19} {3:<19}'.format("\nNo.",
"GTIN-8",
"Item Name",
"Price"))
# Read each line of document
for line in info:
arrayOfItems = line.split(",")
print('{0:<19} {1:<19} {2:<19} {3:<19}'.format(arrayOfItems[0],
arrayOfItems[1],
arrayOfItems[2],
arrayOfItems[3]))
else:
print('You have no items listed!')
print("\n")
print("1. Add a product onto a specific line number?")
print("2. Or add a product onto the end?")
print("3. Buy products and have them printed onto a reciept?")
choice=int(input("Which one?: "))
if choice==1:
search()
elif choice==2:
add()
elif choice==3:
reciept()
menu()
Good luck and enjoy making python scripts and programs! It's fun and challenging at times. I was once in your shoes, just remember it gets easier as you keep working on it.
ALSO:
Check out some other Stack Overflowers works... Sometimes an easy solution like this can be resolved by looking at some other peoples work and questions...
Opening file for both reading and writing
Basic read and write
Lowercase examples plus reading and writing
Copying files for modifying documents and creating saves

How to read a first character from the last line of a file in python

I am writing a scoreboard thingie in python (I am fairly new to the language). Basically user inputs their name and I want the program to read the file to determine, the number that the user is assigned to.
For example, the names in the .txt file are:
Num Name Score
John Doe 3
Mitch 5
Jane 1
How do I now add user no.4 without the user typing the exact string to write, only their name.
Thanks a lot!
I suggest rethinking your design - you probably don't need the line numbers in the file, however you could just read the file and see how many lines there are.
This won't scale if you end up with a lot of data.
>>> with open("data.txt") as f:
... l = list(f)
...
This reads your header
>>> l
['Num Name Score\n', 'John Doe 3\n', 'Mitch 5\n', 'Jane 1\n']
>>> len(l)
4
So len(l)-1 is the last number, and len(l) is what you need.
the easiest way to get the number of lines is by using readlines()
x=open("scoreboard.txt", "r")
line=x.readlines()
lastlinenumber= len(line)-1
x.close()
with open('scoreboard.txt', 'a') as scoreboard: #FIle is opened for appending
username = input("Enter your name!")
scoreboard.write(str(lastlinenumber) + '. ' + str(username) + ": " + '\n')
scoreboard.close()
def add_user():
with open('scoreboard.txt', 'r') as scoreboard:
#Reads the file to get the numbering of the next player.
highest_num = 0
for line in scoreboard:
number = scoreboard.read(1)
num = 0
if number == '':
num == 1
else:
num = int(number)
if num > highest_num:
highest_num = num
highest_num += 1
with open('scoreboard.txt', 'a') as scoreboard: #FIle is opened for appending
username = input("Enter your name!")
scoreboard.write(str(highest_num) + '. ' + str(username) + ": " + '\n')
scoreboard.close()
Thank you guys, I figured it out. This is my final code for adding a new user to the list.

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')

How do I pass the contents of an list into an existing file?

exchangerates = []
newrate = float(input("Enter amount:"))
with open("ExchangeRates.txt","r") as readfile:
for line in readfile:
exchangerates.append(line.strip().split(","))
for line in exchangerates:
if line[0] == currency1 and line[1] == currency2:
line[2] = newrate
print("The exchange rate for",currency1,"and",currency2,"has been changed to",newrate)
next
return 0
This code works, but I need to know how to pass the information from the list created above, into the file, shown as "Exchangerates.txt". How would I do this?
sample input and output:
Enter currency 1:Yen
Enter currency 2:Dollar
Enter amount:3
The exchange rate for Yen and Dollar has been changed to 3.0
This is what happens in my code, which is expected. However it does not write to the file and the information is not changed within the file, this is my problem.
You can do it with simplier approach:
f = open("ExchangeRates.txt","r")
exchangerates = f.read()
f.close()
lines = exchangerates.split("\n")
# do the stuff you want to the list with the loops in list of lines
exchangerates = "\n".join(lines)
f = open("ExchangeRates.txt","w")
f.write(exchangerates)
f.close()
A particularly easy way of doing this would be to use Pickle, something like this does what I think you're attempting:
import pickle
try:
with open("ExchangeRates.txt", "rb") as readfile:
exchangerates = pickle.load(readfile)
except FileNotFoundError:
exchangerates = {}
currency1 = input("Enter currency 1: ")
currency2 = input("Enter currency 2: ")
newrate = input("Enter exchange rate: ")
if currency1 in exchangerates:
if currency2 not in exchangerates[currency1] or exchangerates[currency1][currency2] != newrate:
exchangerates[currency1][currency2] = newrate
print("The exchange rate for",currency1,"and",currency2,"has been changed to",newrate)
else:
exchangerates[currency1] = {currency2: newrate}
print("The exchange rate for",currency1,"and",currency2,"has been changed to",newrate)
with open("ExchangeRates.txt", "wb") as writefile:
pickle.dump(exchangerates, writefile)
Note that this stores the exchange rates as a dictionary like: {'USD': {'GBP': 1.6, 'YEN': 3}}. It'd be fairly simple to have it add/check and update the inverse exchange rate too if that was desired.

Python- Saving Results to a File and Recalling Them

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"))

Categories