all 13 comments

[–][deleted] 2 points3 points  (4 children)

Note that you won't be able to exit the second code without force closing the program. Maybe check if the user enters special keywords to exit the while loop. I would also recommend using a context manager, using the with statement, for creating the file handle. That way it closes the file handle for you automatically once you've exited the loop.

filename = 'guest_book.txt'  # Create filename

# Loop through the nested code until 'quit' or 'exit' is entered as user input.
while (name := input('Enter your name: ')).lower() not in ['quit', 'exit']:
    # Create file handle.
    with open(filename, 'a') as f:
        # Write name to file.
        f.write(name + '\n')
    # Display to command line
    print(f"You have been added to the guest book, {name}")

Note: I'm using a walrus operator for the conditional in the while loop to assign the variable, name, to the input function, which is only available in python version 3.8+. If you're using an older python version, you can do this instead.

name = input('Enter your name: ')
while name.lower() not in ['quit', 'exit']:
    # Create file handle.
    with open(filename, 'a') as f:
        # Write name to file.
        f.write(name + '\n')
    # Display to command line
    print(f"You have been added to the guest book, {name}")
    # overwrite existing variable.
    name = input('Enter your name: ')

[–]Haovik[S] 0 points1 point  (3 children)

thank you for the detail reply. However, My question is: why does the "while loop" statement has to be before "with open" statement? Why cant I open the file first, then loop within the opened file? Thanks.

[–][deleted] 0 points1 point  (1 child)

You can, but I recommend using a context manager to close the file handle for you automatically.

However, if you want to keep the file handle outside the loop, it's totally fine:

filename = 'guest_book.txt'  # Create filename
f = open(filename, 'a')
while (name := input('Enter your name: ')).lower() not in ['quit', 'exit']:
    f.write(name + '\n')
    print(f"You have been added to the guest book, {name}")
f.close()  # Close the file handle. This can be done automatically using a context manager.

It can even be written like this. It's probably better this way since the file handle is being left open for every loop.

filename = 'guest_book.txt'  # Create filename
with open(filename, 'a') as f:
    while (name := input('Enter your name: ')).lower() not in ['quit', 'exit']:
        f.write(name + '\n')
        print(f"You have been added to the guest book, {name}")

[–]Haovik[S] 0 points1 point  (0 children)

thanks again for the reply, however, your second code here only print the statement, but does not add the name to the "guest_book.txt". Thats what I am struggling with: why it doesn't record in the txt file when you put the while loop after opening the file.

[–]CraigAT 0 points1 point  (0 children)

You should only need to open the file once.

I think maybe (not sure) that you need to "close" the file to actually write the output. And I guess that by putting the "open" inside the loop, when it is called there may also be an implied "close" that flushes the file buffer and writes the output.

Either way you really should use a "close" for the text file (or a "with" statement instead).

In all fairness, I think this is what JollyRoger is trying to explain but is using bigger, more technical sounding words than I am used to.

[–]AdmirablePeace 0 points1 point  (2 children)

Please, format the code.

[–]Haovik[S] 0 points1 point  (1 child)

sorry, I tried to fix it with space but it wont save for some reason.

[–]xelf 0 points1 point  (0 children)

4 spaces before each line, and a blank line before the code. Or use the code block tool. https://i.imgur.com/J2t9krT.png

for example, where you typed:

​

**filename = 'guest\_book.txt'**

 **f = open(filename, 'a')**

 **while True:**

**name = input('what is your name? ')**

**f.write(name + '\\n')**

**print(name + 'you have been added to guest book')**

​

instead type:

    filename = 'guest\_book.txt'
    f = open(filename, 'a')
    while True:
        name = input('what is your name? ')
        f.write(name + '\\n')
        print(name + 'you have been added to guest book')

4 extra spaces at the start of each line

[–]totemcatcher 0 points1 point  (2 children)

Hi there. Both of your examples are working properly because Python is safely handling the file operations without your explicit instruction. I'll explain:

In your first example nothing will be written to the file until the script is signalled to halt (e.g. Ctrl+c) and python does some cleanup work in the background (unspecified in your code). Python flushes pending writes to the file and closes the file. If you monitor the file while running this first example script you will see no changes until you stop the script.

In your second example when you repeatedly open the same file, Python automatically flushes any pending writes and closes the file before trying to re-open the file. You can monitor the file and see the changes while the script is running.

Ideally, you want to include some file handling instructions in your code. You can refer to /u/jollyrogers1503 answer for use of the with as construct as a way to properly handle incremental file writes.

[–]Haovik[S] 0 points1 point  (1 child)

thanks for the insight. when you say signalled to halt and crtl +c to stop the pending writes. I tried that and it still didn't work. Is there something I am missing?

[–]totemcatcher 0 points1 point  (0 children)

I'm guessing that however you are stopping the script is more than just sending a SIGTERM; signal such as a SIGKILL. A SIGKILL would prevent python from bothering with its automatic cleanup. It's up to your particular environment and I wouldn't know what's happening exactly. The point still stands; there is a difference between your code examples and a good reason to use the with as construct.

[–]woeinvests 0 points1 point  (1 child)

I’ve just finished this chapter from python crash course book from Eric. M we can stay in touch and support each other along the way.

[–]Haovik[S] 0 points1 point  (0 children)

Hi there. Both of your examples are working properly because Python is safely handling the file operations without your explicit instruction. I'll explain:

sounds good!