ashen one
ashen one

Reputation: 15

program can't move past a write method

Here is my code:

with open('exr.txt','r+') as exr:
    while True:
        exr.write((input('enter your name ')+'\n'))
        b=exr.readlines()
        if 'q' in b:
            break
    print('names entered:')
    for c in b:
        print('-',c)

It never gets past the write() method and keeps prompting me for names even after entering 'q', any help is appreciated

Upvotes: 1

Views: 52

Answers (2)

tobias_k
tobias_k

Reputation: 82899

There are (at least) three problems with your approach:

  1. it seems like exr.readlines() does not work as you expected here, with r+, so a "q" entered in the current "session" is not read
  2. in contrast to that, a "q" entered in a previous session is read, as they remain in the names file, i.e. the loop breaks immediately in any later execution
  3. you are testing whether "q" is in b, but you append a \n to each input, and readlines includes those line-end characters, so b can only ever contain "q\n"

It seems like both reading and writing are using the same position in the file. You can get the position with exr.tell() and set it with exr.seek(x). This way, you can see that:

  • at the beginning of the loop, exr.tell(), i.e. the position is at 0, meaning your first write will overwrite whatever data is at the beginning of the file
  • after write, the position is at k+1 for a name with k letters and the additional \n
  • now readlines reads all data from that position (i.e. after the name you just entered) up to the end of the file
  • now, the file position is at the end, and all subsequent write calls will append names to the end of the file, advancing the file position further to the new end, and readlines will read nothing, as the pointer is already at the end of the file

You could use exr.seek(0) to reset the position in the file to the beginning (or any other position before the last line), but while this (together with 3.) fixes the immediate problem, you still should not do it.

Instead, just store the input in a variable and check the value of that variable before adding it to the file or breaking from the loop.

with open('exr.txt', 'a') as exr:
    while True:
        name = input('enter your name ')
        if name == "q":
            break
        else:
            exr.write(name + '\n')

Upvotes: 2

Majd Thaher
Majd Thaher

Reputation: 47

the .readlines() method returns a list and not a string so when youre looking for q in a list of names ["jasper, "qar"] python sorta thinks this: is the element "q" in this list? is "q" equal to "jasper" or "qar"? nope. so you have to iterate through each element in b to go through each letter in each name in the list.

i would do something like this:

with open('exr.txt','r+') as exr:
while True:
    exr.write((input('enter your name ')+'\n'))
    b=exr.readlines()
    for name in b:
       for letter in name: 
           if 'q' in b:
              break
print('names entered:')
for c in b:
    print('-',c)

hope this is the answer youre looking for :)

Upvotes: 0

Related Questions