Home > Blockchain >  How do I undo what I'm currently writing before close()?
How do I undo what I'm currently writing before close()?

Time:10-01

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.

CodePudding user response:

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

CodePudding user response:

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.

CodePudding user response:

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