0

Intro: I'm a beginner python learning syntax at the moment. I've come across this concept of reading and writing files natively supported by python. I've figured to give it a try and find bugs after attempting looping reading and writing commands. I wanted to randomly pick a name from a name file and then writing it into a new file. My file includes 19239 lines of names, randrange(18238) generates from 0 - 18238, and, supposedly, would read a randomly read a line between 1 - 18239. The problem is that the code that reads and writes works without the for loop but not with the for loop.

My attempt:

from random import randrange
rdname = open("names.dat", "r")
wrmain = open("main.dat", "a")
rdmain = open("main.dat", "r")

for x in range(6):
    nm = rdname.readlines()[randrange(18238)]
    print(str(randrange(18238)) + ": " + nm)
    wrmain.write("\n" + nm)
...

Error code:

Exception has occurred: IndexError
list index out of range
8
  • 1
    Please supply the expected minimal, reproducible example. Show where the intermediate results differ from what you expected. We should be able to copy and paste a contiguous block of your code, execute that file, and reproduce your problem along with tracing output for the problem points. This lets us test our suggestions against your test data and desired output. Commented Oct 13, 2020 at 21:07
  • 1
    In particular, we expect you to perform the straightforward debugging before you post here. How many iterations did the loop run before the error? How many lines were in the file? What is the value of the index? Given this information, what don't you understand about the problem? Commented Oct 13, 2020 at 21:07
  • 1
    I wouldn't recommend opening the same file two times in two different modes, but you aren't using rdmain anyway. Commented Oct 13, 2020 at 21:12
  • 2
    Have you done any debugging at all? The issue should become obvious with minimal effort Commented Oct 13, 2020 at 21:12
  • 2
    Just use readlines() once and then use the list it returned each time in the for loop Commented Oct 13, 2020 at 21:12

2 Answers 2

2

Good luck with your programming journey.

The readlines() method. Has some non-intuitive behaviour. When you use the readlines() it "dumps" the entire content of the file and returns a list of strings of each line. Thus the second time you call the rdname.readlines()[randrange(18238)], the rdname file object is completely empty and you actually have an empty list. So functionally you are telling your programme to run [][randrange(18238)] on the second iteration of the loop.

I also took the liberty of fixing the random number call, as the way you had implemented it would mean it would call 2 different random numbers when selecting the name nm = rdname.readlines()[randrange(18238)] and printing the selected name and linenumber print(str(randrange(18238)) + ": " + nm)

...
rdname = open("names.dat", "r")
wrmain = open("main.dat", "a")
rdmain = open("main.dat", "r")

rdname_list = rdname.readlines()

for x in range(6):
    rd_number = randrange(18238)
    nm = rdname_list[rd_number]
    print(str(rd_number) + ": " + nm)
    wrmain.write("\n" + nm)
...
Sign up to request clarification or add additional context in comments.

1 Comment

Thank you very much, as well as for the second part.
1

rdname.readlines() exhausts your file handle. Running rdname.readlines() gives you the list of lines the first time, but returns an empty list every subsequent time. Obviously, you can't access an element in an empty list. To fix this, assign the result of readlines() to a variable just once, before your loop.

rdlines = rdname.readlines()
maxval = len(rdlines)
for x in range(6):
    randval = randrange(maxval)
    nm = rdlines[randval]
    print(str(randval) + ": " + nm)
    wrmain.write("\n" + nm)

Also, making sure your random number can only go to the length of your list is a good idea. No need to hardcode the length of the list though -- the len() function will give you that.

I highly recommend you take a look at how to debug small programs. Using a debugger to step through your code is immensely helpful because you can see how each line affects the values of your variables. In this case, if you'd looked at the value of nm in each iteration, it would be obvious why you got the IndexError, and finding out that nm becomes an empty list on readlines() would point you in the direction of the answer.

1 Comment

Thank you for you reccomendation to the "how to debug small programs". I'm really new, and not familar with how to debug at all.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.