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
Understanding Python's Call-By-Object Style of Passing Function Arguments
Django: Deploying an Application on Heroku with SQLite3 as the Database
Flask Application Traceback Doesn't Show Up in Server Log
Connecting Slots and Signals in Pyqt4 in a Loop
Inverting a Dictionary with List Values
How to Change an Image Size in Pygame
How to Install Another Version of Python to Virtualenv
How to Change the Name of a Django App
How to Execute a Python Script from the Django Shell
How to Delete the Contents of a Folder