What Does "While True" Mean in Python

How to break the While True statement on the same error 3 times

You can add a variable keeping track of the last error's type, and a counter for the how many of those occurred, which resets if an error of a different type appeared. If the counter hits 3, then exit accordingly.

last_exception, counter = None, 0
while True:
try:
# some error here
raise ValueError
except Exception as e:
if type(e) is not last_exception:
last_exception, counter = type(e), 0
counter += 1
if counter == 3:
break

While true loop in python breaks without waiting for condition to become true

There are somethings to do:

  • Indent the break, so it's inside the if
  • You're reading the same data over and over again, so remove the while loop since you probably already have one updating the data.

Final code:

try:
df1 = pd.read_csv(io.StringIO(dfs[4].to_csv(index=False)), skiprows=1, header=[0,1])
c = df1.iat[1,3]
print(c)
if (c == "Margaret"):
df1.to_csv("break.csv", mode='a', header=False)
print("Margaret found")
break
except Exception as e:
print("waiting...")
continue

If statement returning False in While True loop (Python)

while X repeats when X equals to True so in while True it's always True. It only breaks with break statement.
In your code, you only check the value inside the while loop with if so neither you break the while loop nor you change True to False in while True.

If you want to use while:

i = 0
while i < 10:
i += 1
print(i)

Or

i = 0
while True:
if i < 10:
i += 1
print(i)
else:
break

Without while:

for i in range(10):
print(i)

Python while True loop not iterating over when running my game

Your main problem is that you are placing break statements before the print statements, meaning the while loop stops before it reaches the print statements.

e.g:

    # If dragon health is negative or null - game over
elif dragon_hp <= 0:
break #Break should not be here
print(f'The Dragon lost the battle!')
# If player health is negative - game over
elif my_hp <= 0:
break #Break should not be here
print(f'The {character} lost the battle!')

Instead, try:

    # If dragon health is negative or null - game over
elif dragon_hp <= 0:
print(f'The Dragon lost the battle!')
break
# If player health is negative - game over
elif my_hp <= 0:
print(f'The {character} lost the battle!')
break

Also, one tip: you should be using classes for your characters, as it is easier to manage classes. It keeps the characters and their variables together, so you don't have to constantly make more than 1 variable when creating a new character.

An example for your characters:

class character:
def __init__(self,name,damg=0,hp=0):
self.damage=damg
self.hp=hp
self.name=name

You would then create a new character like:

wizard=character("Wizard",150,70)

Call on each attribute like:

wizard.hp
# returns 70
wizard.name
# returns "Wizard"
wizard.damage
# returns 150

If you keep the characters like this, it means you can run more efficient code, for example I would just out the new character objects in a list, and then put in an attack for loop that iterates over the list of characters and prints out the damage they did, their health, and their name. E.g.

character_list=[wizard,elf,human] #some imaginary list
for x in character_list:
print(f"{x.name} attacked the dragon!")
print(f"{x.damage} was dealt.")
print(f"{x.name} has {x.hp} left")

Also, you can edit these as normal.
e.g., take our wizard from above:

# oh no! some event caused your wizard to lose health!
wizard.hp-=10
# returns 60 when called again

I hope that was a satisfactory explanation.

Why does the 'while true' loop cause an infinite loop?

Each while loop checks its own statement (the one just after the word while).

So, the first one goes on until the statement condition<10 becomes false, and then it finishes, and the next loop starts.
The next loops does not check if the first condition becomes false, it checks if the statement True becomes false - which it never does!

Print value from while True: in Python

The print(variable) statement will never be reached, to solve this you can do something like this:

import threading, time

variable = None
def loopFunction():
global variable # The loopFunction will be using the global variable defined before, without this the variable will be treated as local.
while True:
variable = False # bool(False) is False
time.sleep(6)
variable = True # bool(True) is True
time.sleep(6)

# The loopFunction will be running until the program ends on a new thread
loop = threading.Thread(target = loopFunction, args = ())
loop.start()

# Rest of your code
for i in range(10):
print(variable)
time.sleep(3)

Where the loopFunction will be running on a different thread, so the rest of the code will be reached.

If you only want to check the time since the program starts, you can simply do something like:

import time

start = time.time()

# Rest of your code
for i in range(10):
print((time.time()-start)%12>6)
time.sleep(3)

Which will give you the same result.

python: while True vs while (condition) efficiency

I put those snippets in two functions:

def first():
a=100000000
while a > 0:
a-=10

def second():
a=100000000
while True:
a-=10
if a <= 0:
break

And then used timeit.timeit and it was actually the second that was consistently timed as taking longer (although for really negligible difference).

from timeit import timeit

timeit(first, number=100)
timeit(second, number=100)

I then inspected the bytecode by basically copying the example from the dis docs. This revealed that the bytecode is almost the same for both snippets, the only difference being in how the opcodes are ordered and that the second includes one additional instruction, namely BREAK_LOOP.

import dis
from collections import Counter

first_bytecode = dis.Bytecode(first)
for instr in first_bytecode:
print(instr.opname)

second_bytecode = dis.Bytecode(second)
for instr in second_bytecode:
print(instr.opname)

# easier to compare with Counters
first_b = Counter(x.opname for x in first_bytecode)
sec_b = Counter(x.opname for x in second_bytecode)

Finally, one might think the order might make a difference (and it could), but in order to make a fair comparison second should first check for the break condition before subtracting from a. Consider then a third function:

def third():
a=100000000
while True:
if a <= 0:
break
a-=10

Comparing the bytecode of the third you'll see it is in fact ordered the same as the bytecode of the first, the only difference being a single BREAK_LOOP jammed somewhere in the middle.

If anything I hope this shows you how insignificant execution of one opcode usually is with respect to the overall performance of code. I think the immortal words of Donald Knuth are particularly well suited for the occasion:

We should forget about small efficiencies, say about 97% of the time: premature optimization is the root of all evil.



Related Topics



Leave a reply



Submit