0

I am a beginner of python, I tried to test the while loop. For below code, I can get the answer, but still get the out of range error. I know the available seat is much larger than the name list, and all people can get a seat. The result showed the answer that I want. But it shows out of range. How can fix the out of range problem? Thanks

name_list=["Peter", "John", "Gary", "Amy"]
available_seat=10
entered_people=0
while available_seat > entered_people:
    element=name_list[entered_people]
    print(element +" can enter.")
    entered_people+=1
print("Next time please.")

Peter can enter. John can enter. Gary can enter. Amy can enter. IndexError: list index out of range

Gary CL.
  • 13
  • 1
  • `name_list[entered_people]` is valid only if `entered_people` is a value from 0 to 3. You get `IndexError` when it is outside of this range. – Code-Apprentice Mar 19 '22 at 08:50
  • you know there are `for` loops that are specifically meant to be used to iterate over iterables such as lists – Matiiss Mar 19 '22 at 09:04
  • @Matiiss yes, I know the for loops, but just want to try if using while loop can solve it. – Gary CL. Mar 19 '22 at 09:13

5 Answers5

0

You should iterate over the list of names rather than using this while loop. That way you won't try to access an index that doesn't exist in the name_list array. You can also get rid of the entered_people variable and only use available_seats and decrement it by 1 everytime someone enters. Here is a much cleaner solution.

Code

name_list=["Peter", "John", "Gary", "Amy"]
available_seats = 10

for name in name_list:
    if available_seat > 0:
        print(name +" can enter.")
        available_seats -= 1
    else:
        print(name +" can't enter.")

Output

Peter can enter.
John can enter.
Gary can enter.
Amy can enter.
DollarAkshay
  • 2,063
  • 1
  • 21
  • 39
  • 1
    there is also `enumerate` so that you don't need to do this subtraction – Matiiss Mar 19 '22 at 09:05
  • @DollarAkshay Thanks, I use for loop at first. But want to try if while loop can solve it. Thanks for your reply! – Gary CL. Mar 19 '22 at 09:15
  • @GaryCL. Definitely use this for loop syntax. Its more "pythonic" and cleaner looking code. Please do not forget to select an answer as accepted answer. – DollarAkshay Mar 19 '22 at 09:19
0

You get IndexError because you are trying to use an index beyond the size of the list. One way to fix the problem is to check this in the while condition:

while available_seat > entered_people and entered_people < len(name_list):
Code-Apprentice
  • 81,660
  • 23
  • 145
  • 268
  • Thanks, it can fix the index error. But it print the answer "Next time please." also. I try to figure it out. Thanks a lot! – Gary CL. Mar 19 '22 at 09:06
  • @GaryCL. Please post a new question. Be sure to explain what you are trying to accomplish with this program. – Code-Apprentice Mar 19 '22 at 09:31
0

If you still want to use a while loop, you can go about it this way. Make an iterator to go through the elements in name_list. If you are able to reach the last element then your iterator should be equal to the length of name_list. "Next time please" won't be printed in that case. See the code below:

name_list=["Peter", "John", "Gary", "Amy"]
available_seat= 10

length = len(name_list)
i = 0 # Variable to iterate through name_list

while available_seat and (i < length):
    print(name_list[i] + " can enter.")
    i += 1
    available_seat -= 1
    
# Only print "Next time please" if you did not reach last person in name_list
if i != length:
    print("Next time please")
Emmanuel
  • 245
  • 2
  • 5
0

I hope following may help. len is used identify len of the name list.

name_list=["Peter", "John", "Gary", "Amy", "gg", "xx", "yy", "dd", "kk", "mm"]

available_seat=10 
entered_people=0

while available_seat >= entered_people:
    if entered_people == available_seat:
        print("Next time please.")
        break
    elif entered_people < len(name_list) and entered_people != available_seat:
        element=name_list[entered_people]
        print(element +" can enter.")
        entered_people+=1
        #print(entered_people)
    elif len(name_list) < available_seat:
        print(f"We have still {available_seat - len(name_list)} seat available.")
        break

sample outputs:

Peter can enter. John can enter. Gary can enter. Amy can enter. baris can enter. xx can enter. yy can enter. dd can enter. kk can enter. We have still 1 seat available.

Peter can enter.
John can enter.
Gary can enter.
Amy can enter.
We have still 6 seat available.
Baris Ozensel
  • 433
  • 1
  • 3
  • 11
-2

Catch the IndexError and break the loop:

while available_seat > entered_people:
    try:
        element=name_list[entered_people]
    except IndexError:
        print("All people seated!")
        break

    print(element +" can enter.")
    entered_people+=1
ForceBru
  • 43,482
  • 10
  • 63
  • 98
  • A better solution would be to avoid the `IndexError` in the first place. – Code-Apprentice Mar 19 '22 at 08:51
  • If you want the exception to end the loop, put the try/except around the loop instead of inside it. Then you won't need the break. – khelwood Mar 19 '22 at 08:54
  • @Code-Apprentice, not necessarily: https://stackoverflow.com/questions/12265451/ask-forgiveness-not-permission-explain. Asking forgiveness is at least as good as asking for permission. – ForceBru Mar 19 '22 at 08:54
  • @khelwood, however, I'd like to be sure that the exception occurred _on this specific line_, not elsewhere in the loop. If OP adds other code to the body of the loop, that code could produce an unrelated `IndexError` that I don't want to catch. I'm catching this specific exception because I know exactly why it happened - because all people have been given a seat. Catching it here also lets me report it correctly. – ForceBru Mar 19 '22 at 08:57
  • I mean, if you know the exact reason in this likely single-threaded environment, then you might as well _ask for permission_, which would seemingly reduce the amount of code needed too, depending on implementation. It is as though intentionally letting an exception happen when you could prevent it seems "wrong" in a way. It is a solution nonetheless so I don't know why this was downoted – Matiiss Mar 19 '22 at 09:23