How do I undo what I'm currently writing before close()? - python

for i in range(0,5):
f = open("StudentRecords.txt", "a")
try:
f.write(input("Name: ")+"\n")
f.write(str(int(input("ID: ")))+"\n")
f.write(str(float(input("GPA: ")))+"\n")
except ValueError:
print("Error: You entered a String for ID or GPA.")
f.close()
Here for example if I tried to write a string for GPA, I will catch the error and the program will move on, but the Name and ID of the same iteration will still be written
I want it to only write if all the 3 data are valid.

As the comments said, the best approach is to validate all the data before writing anything. But if you really need to undo, you can do it by saving the file position before each record, seeking back to it, and truncating to remove everything written after.
And rather than reopening the file for each record, you should open it once before the loop. Use with to close it automatically when the block is finished.
with open("StudentRecords.txt", "w") as f:
for i in range(0,5):
try:
filepos = f.tell()
f.write(input("Name: ")+"\n")
f.write(str(int(input("ID: ")))+"\n")
f.write(str(float(input("GPA: ")))+"\n")
except ValueError:
print("Error: You entered a String for ID or GPA.")
f.seek(filepos)
f.truncate()

The simple solution is to save the inputs in variables first, and then save to file.
for i in range(0,5):
f = open("StudentRecords.txt", "a")
try:
name = input("Name: ")+"\n"
ID = str(int(input("ID: ")))+"\n"
GPA = str(float(input("GPA: ")))+"\n"
f.write(name + ID + GPA)
except ValueError:
print("Error: You entered a String for ID or GPA.")
f.close()
That being said, I would suggest updating the code a little more:
for i in range(0,5):
name = input("Name: ") + "\n"
try:
ID = str(int(input("ID: "))) + "\n"
GPA = str(float(input("GPA: "))) + "\n"
with open("StudentRecords.txt", "a") as f:
f.write(name + ID + GPA)
except ValueError:
print("Error: You entered a String for ID or GPA.")
Using with means you won't have to deal with the f.close(), among other things, and so you won't forget it. And since the name = ... line doesn't seem to need a try-except block, we can move it outside.

Others have shown you a way to validate your data, but right now the program just stops if the user makes a mistake. You really want some way for them to correct their error and continue.
To put this in your main routine would require a separate loop and try/except structure for each number, which isn't too bad right now with two values, but gets unwieldy as you add more.
So instead of repeating ourselves, let's write a function that repeats until the user enters a valid number. We can pass in the type of number we want (int or float).
def inputnum(prompt, T=float):
while True:
try:
return T(input(prompt))
except ValueError:
print(">>> You entered an nvalid number. Please try again.")
Then call that function to get your numbers (combined with some other small improvements):
with open("StudentRecords.txt", "a") as f:
for i in range(5):
name = input("Name: ")
ID = inputnum("ID: ", int)
GPA = inputnum("GPA: ", float)
f.write(f"{name}\n{ID}\n{GPA}\n")

Related

Add numbers and strings in python

This may seem like a duplicate but the other ones don't apply. So I am trying to make a piggy bank but I cannot figure out how to add a new line while I am using numbers. Right now I am using strings because it is the only way to add a new line. However, when I add the two numbers, it adds them like string. For example, if you entered 5.93 twice. It would print "5.935.93". So, I have to convert it to a string but then I won't be able to add a new line. Here is my code:
def piggybank():
file = open('piggybank.txt','r+')
money = input('How much money are you adding?')
file.write(money + '\n')
for line in file:
money += line
print("You now have:\n", money)
file.close()
In the third line I could make money a float but then in the fourth line I wouldn't be able to add a new line. Can somebody help?
You could keep money as an Integer, but when writing, use %s. Also, if you want to write to a file, you need to make a new variable set to open('piggybank.txt', 'wb') to write to the file.:
def piggybank():
filew = open('piggybank.txt','wb')
file = open('piggybank.txt','rb')
money = input('How much money are you adding?')
filew.write('%s\n' % money)
for line in file:
money += line
print("You now have:\n%s" % money)
filew.close()
file.close()
You can do this :
def piggybank():
file = open('piggybank.txt','rb')
money = input('How much money are you adding?')
file.write(str(money) + "\n")
for line in file:
money += float(line.strip())
print("You now have:\n" + str(money))
file.close()
You can convert to floats when your doing the math.
float(money) += float(line)
Addtion could be done between numeric objects.You need to notice that input() will give you a str(string) type object. And you need to convert str to float using float().
By trail and error,I've found following solition.Refernece doc links are strip() doc, open() doc.
def piggybank():
file = open('piggybank.txt','a') #open file for appending to the end of it.
money = input('How much money are you adding? ')
file.write(money + '\n') # Write strings to text file.
file.close()
file = open('piggybank.txt','r')
sum = float(0) # initialize sum with zero value.
for line in file:
sum += float(line.strip('\n')) # srtip '\n' and convert line from str to float.
print("You now have: %s" % sum)
file.close()

The Python file problems

FileName = input("Please enter the name of your text file: ")
APPEND = "a"
WRITE = "w"
File = (FileName + ".txt")
List = []
Name = " "
while Name != "DONE" :
Name = input("Please enter the guest name (Enter DONE if there is no more names) : ").upper()
List.append(Name)
List.remove("DONE")
print("The guests list in alphabetical order, and it will save in " + FileName + " :")
List.sort()
for U in List :
print(U)
File = open(FileName , mode = APPEND)
File.write(U)
File.close()
print("File written successfully.")
Ok guys, I am sorry that I am asking this question over and over, but it annoys me. I don't see any bugs through the code, but the list from the text file ONLY APPEARS ONE NAME. Thanks!
I believe what you are looking for is this:
with open(FileName , mode = APPEND) as f:
for U in List :
print(U)
f.write(U)
f.write("\n")
print("File written successfully.")
using with will allow you to open the file, and python with automatically close it for you should an exception occur while it's in use. You want to open the file before you enter your loop, then append within the loop, and finally, print your success message after closing the file (outside the with). Indentation is important! :)
According to the indentation I see above, you are calling the File open, File write, and File close methods after the loop for U in List. So only the last name will get appended to the file.
(Of course, maybe your indentation is wrong above...)
You're printing the iteration variable 'U' each time, not saving it anywhere. Write the 'U' variable each time to a file and it should work.

Unsure how to get user input from a multiple line loop - Python

I have been trying to create a program that lets users name, write and save documents, here is what I have come up with so far:
doc_name = str(input("Document Name: "))
end = ""
for line in iter(input, end):
document = "\n".join(iter(input, end))
pass
try:
savefile = open("/home/" +doc_name+ ".txt", "w")
savefile.write(x)
savefile.close()
print("Document - " +doc_name+ "\nSuccessfully saved.\n\n")
except:
print("An error occurred.\nUnable to save document.\n\n")
The 'for loop' I have used was from the following page:
Raw input across multiple lines in Python but I am unsure how to use the input from this loop, so I am able to save it to a textfile.
I need the input in this line of code in the place of x:
savefile.write(x)
I am using Python 3.2.3 for this program (if that helps?).
I would like to know how the user input entered during the for loop can be stored in a varible and then used at some other point in the program.
Thanks.
doc_name = input("Document Name: ") # don't need to cast to str
end = ""
result = [] # I recommend initializing a list for the lines
for line in iter(input, end): # you only need this single input call
result.append(line) # add each line to the list
try:
# using "with" in this manner is guaranteed to close the file at the end
with open("/home/" +doc_name+ ".txt", "w") as savefile:
for line in result: # go through the list of lines
# write each one, ending with a newline character
savefile.write(line + '\n')
except IOError:
print("An error occurred.\nUnable to save document.\n\n")
else: # print this if save succeeded, but it's not something we want to "try"
print("Document - " +doc_name+ "\nSuccessfully saved.\n\n")
You only need to use pass when Python expects statements (such as in an indented block) but you have no statements for it to execute - it's basically a placeholder. The common use is when you want to define your program's functions (e.g., def myfunction(a, b):) but you don't have the actual content for them yet.

Python ExceptIndex issue?

I have a tab delimited file with 8 columns that has the following context for example
Timestamp Process TID Area Category EventID Level Message Correlation
06/21/2014 09:19:02.94 wsstracing.exe (0x068C) 0x0698 SharePoint Foundation Tracing Controller Service 5152 Information Tracing Service started.
06/21/2014 09:19:09.94 hostcontrollerservice.exe (0x063C) 0x0670 SharePoint Server Unified Logging Service b8fx High ULS Init Completed (hostcontrollerservice.exe, Microsoft.Office.Server.Native.dll)
http://pastebin.com/f9dmrQtU
The code I have currently
try:
with open('text.log') as f:
for l in f:
print(l.strip().split("\t")[5], end=" "),
print(l.strip().split("\t")[7], end=" "),
print(l.strip().split("\t")[8], end="\n")
except IndexError:
pass
Gives me
EventID Message Correlation
5152 Tracing Service started. Press any key to continue . . .
As you can see it stops after the first entry because there is nothing in the 8th column anymore.
When what I need is it to print is something like even if there is nothing under the correlation column
EventID Message Correlation
1124 blahblahblah blahblah
However when I have the following code
try:
with open('text.log') as f:
for l in f:
print(l.strip().split("\t")[5], end=" "),
print(l.strip().split("\t")[7])
but prints it in the correct format could anyone provide some assistance?
Your try is wrapped around the loop, so as soon as one error occurs that try block stop executing and jumps to the except block, meaning no more iterations can happen.
Instead, you can just put the try/except inside the for loop.
with open('text.log') as f:
for l in f:
try:
print(l.strip().split("\t")[5], end=" "),
print(l.strip().split("\t")[7], end=" "),
print(l.strip().split("\t")[8], end="\n")
except IndexError:
pass
However, since you know that there could be no 8th element, its not really exceptional and will hide errors if you have no 6th or 7th element.
Instead, try and control your logic better with:
with open('text.log') as f:
for l in f:
x = l.strip().split("\t")[5:] # Grab the elements you want...
x.pop(1) #... but remove the element you don't
print(" ".join(x)) # Now print them
Why are you wrapping the whole thing in a try block?
with open('text.log') as f:
for line in f:
txt = l.strip().split("\t") # split once
for col in (5,7,8):
try:
_end = "\n" if col == 8 else " "
print(txt[col], end=_end)
except IndexError:
print("\t", end=_end) # print a blank column
When you do the .strip() you are losing the trailing tabs, so when you split() it the line is shorter. Besides that, you are doing the same operation multiple times.
Try this instead:
with open('text.log') as f:
for l in f:
fields = l.split('\t')
print(fields[5], end=" "),
print(fields[7], end=" "),
print(fields[8], end="\n")

I'm having a small issue creating a file in my program

I'm writing a program which has the user enter some names and it creates a file with these names. I'm using Python 3.2.
number = eval(input("How many names are there? "))
#Say the user enters 2
outfile = open('names.txt', 'w')
for i in range(number):
name = input("Enter a name >> ")
#Say the user first enters Bob
#Then the user enters Joe
print (name, file=outfile)
outfile.close()
print ("Names have been written to file")
It works but there's one problem. The file that now shows up only reads one line: "Joe". None of the other names appear, only the last one.
You have this code: -
for i in range(number):
name = input("Enter a name >> ")
#Say the user first enters Bob
#Then the user enters Joe
print (name, file=outfile)
You print statment should be inside the loop..
for i in range(number):
name = input("Enter a name >> ")
print (name, file=outfile)
Indentation! As your code is written now, the statement print (name, file=outfile) is executed once, and outside of the loop. So the last time name was set to anything is the one which remains.
To fix this, make sure that statement writing to the file is called right after it is input, and for that to happen, you should indent it as deep as the input statement, to be called as much times as the input is being taken.

Categories