'While' condition is not satisfied - python

i am having a bit of trouble understanding why the "while" loop in my code doesn't stop when the condition is met.
"""
:param duration: how long the loop will last in hours
:param time_pause: every x seconds the loop restarts
"""
time_start = readTime()
time_now = readTime()
time_end = time_start.hour + duration
time_sleep = conf.SETTINGS["LIGHT_UNTIL"]
print('Time when the script was started \n', time_start)
print('Script ends', time_end)
try:
while time_now.hour <= time_end or time_now.hour < time_sleep:
temp.read_temp_humidity()
lights.Lights_Time()
water.water_plants_1ch(ch_number=2, time_water=2)
time.sleep(time_pause)
time_now = readTime()
except KeyboardInterrupt:
# here you put any code you want to run before the program
# exits when you press CTRL+C
print("Keyboard interrupt \n", readTime()) # print value of counter`
The readTime() function uses this:
try:
ds3231 = SDL_DS3231.SDL_DS3231(1, 0x68)
print( "DS3231=\t\t%s" % ds3231.read_datetime() )
print( "DS3231 Temp=", ds3231.getTemp() )
return ds3231.read_datetime()
except: # alternative: return the system-time:
print("Raspberry Pi=\t" + time.strftime( "%Y-%m-%d %H:%M:%S" ) )
return datetime.utcnow()`
The first condition of the while loop is never met and the loop ends only on the second condition.
Can somebody help me?

It is evident from your code that, you are using an 'OR' between these conditions as in (x or y).
So the loop will continue its execution until both of these conditions equate to a false value.
ex : Consider the following while loop
`while( x || y)
{
//Do something
}`
Here the loop will continue to function as long as any one among x or y continue to
return true, the exit condition is when both x & y returns false.(NB : x & y are
assumed to be 2 different conditions in the pseudo code)
you said : "The first condition of the while loop is never met and the loop ends only on the second condition". From this I infer that, the first condition('time_now.hour <= time_end') is always false and the control flow exits the loop only when the second condition('time_now.hour < time_sleep') also becomes false.
POSSIBLE SOLUTIONS
You calculate 'time_end' as 'time_start.hour + duration'. So here you might have to check whether the variable 'duration' actually holds the correct/expected value, see if you ran into any errors in the calculation of 'duration'.
If you want the looping to stop when any one of the conditions is false, then you must use an 'and' operator instead of an 'or'.
ex : Consider the following while loop
`while( x && y)
{
//Do something
}`
Here the loop will continue to function as long as both x and y continue to return
true, the exit condition is when any one among them returns false.(NB : x & y
are assumed to be 2 different conditions in the pseudo code)
You should ensure that the variables in the looping conditions are getting updated in accordance with your intended logic on looping, any errors in the dynamic calculation of the variables that determine the looping condition will yield the wrong result, for example in your code the looping variables for your first condition are 'time_now.hour' and 'time_end', so make sure they are getting updated with the intended values on looping(you might have any logical errors in the calculation).
I think your issue will be fixed on following solution 1 given above.

Related

How do I run a conditional statement "only once" and every time it changes?

I might be asking a simple question. I have a python program that runs every minute. But I would like a block of code to only run once the condition changes? My code looks like this:
# def shortIndicator():
a = int(indicate_5min.value5)
b = int(indicate_10min.value10)
c = int(indicate_15min.value15)
if a + b + c == 3:
print("Trade posible!")
else:
print("Trade NOT posible!")
# This lets the processor work more than it should.
"""run_once = 0 # This lets the processor work more than it should.
while 1:
if run_once == 0:
shortIndicator()
run_once = 1"""
I've run it without using a function. But then I get an output every minute. I've tried to run it as a function, when I enable the commented code it sort of runs, but also the processing usage is more. If there perhaps a smarter way of doing this?
It's really not clear what you mean, but if you only want to print a notification when the result changes, add another variable to rembember the previous result.
def shortIndicator():
return indicate_5min.value5 and indicate_10min.value10 and indicate_15min.value15
previous = None
while True:
indicator = shortIndicator()
if previous is None or indicator != previous:
if indicator:
print("Trade possible!")
else:
print("Trade NOT possible!")
previous = indicator
# take a break so as not to query too often
time.sleep(60)
Initializing provious to None creates a third state which is only true the first time the while loop executes; by definition, the result cannot be identical to the previous result because there isn't really a previous result the first time.
Perhaps also notice the boolean shorthand inside the function, which is simpler and more idiomatic than converting each value to an int and checking their sum.
I'm guessing the time.sleep is what you were looking for to reduce the load of running this code repeatedly, though that part of the question remains really unclear.
Finally, check the spelling of possible.
If I understand it correctly, you can save previous output to a file, then read it at the beginning of program and print output only if previous output was different.

Recalling a function iteratively

I have a question about recalling my function within a loop.
Below is my code:
List_new = myfunction()
for items in List_new:
if(my condition is TRUE):
Execute some commands
if(my condition is FALSE):
recall myfunction()
My problem is that I am loading "List_new" using myfunction(). How can I change "List_new" iteratively when my condition is False. I want to reload the function especially when the condition is FALSE. This means I keep calling the function until it is false and then execute the final output from myfunction().
Thank you in advance for your help.
I am going to assume the list generated by myfunction() is a constant size.
You can use a while loop:
List_new = myfunction()
index=0
while index < len(List_new):
items = List_new[index]
if(my condition is TRUE):
#Execute some commands
i+=1
if(my condition is FALSE):
List_new = myfunction()
Keep in mind that this solution will have an infinite loop if myfunction() continuously generates false values. If you can guarantee that all values will eventually be True then it should always terminate.

How to jump out the current while loop and run the next loop whenever meeting a certain condition?

The Python script that I am using is not exactly as below, but I just want to show the logic. Let me explain what I am trying to do: I have a database, and I want to fetch one population (a number A) a time from the database until all numbers are fetched. Each time fetching a number, it does some calculations (A to B) and store the result in C. After all fetched, the database will be updated with C. The while condition just works like a 'switch'.
The thing is that I don't want to fetch a negative number, so when it does fetch one, I want to immediately jump out the current loop and get a next number, until it is not a negative number. I am a beginner of Python. The following script is what I could write, but clearly it doesn't work. I think something like continue, break or try+except should be used here, but I have no idea.
for _ in range(db_size):
condition = True
while condition:
# Get a number from the database
A = db.get_new_number()
# Regenerate a new number if A is negative
if A < 0:
A = db.get_new_number()
B = myfunc1(A)
if B is None:
continue
C=myfunc2(B)
db.update(C)
Use a while loop that repeats until the condition is met.
for _ in range(db_size):
condition = True
while condition:
# Get a number from the database
while True:
A = db.get_new_number()
if A is None:
raise Exception("Ran out of numbers!")
# Regenerate a new number if A is negative
if A >= 0:
break
B = myfunc1(A)
if B is None:
continue
C=myfunc2(B)
db.update(C)
My code assumes that db.get_new_number() returns None when it runs out. Another possibility would be for it to raise an exception itself, then you don't need that check here.

while loop does not pass to another while loop

i have two functions with while loop, the results from the first loop is used in the second one as an until condition, but when calling the two functions in the main it execute only the first one and it doesn't even enter the second function it just give me the results of the first loop.
in the first function self.user_association() there is a linear optimization using PULP i though it is the one causing the problem but it was not because when calling the loop function block_estimated_access_link() in the second one it works just fine but my program does not work that way because as i said i use the results from the first loop in the second one. Here is the code, can someone tell me what am i doing wrong or what is the problem exactly?
def block_Estimation_ACCESS_LINK(self):
while (self.iteration < self.Iter_max):
self.User_association()
self.estimated_access_power()
self.calcul_alpha()
self.calcul_rate_am()
self.User_association()
self.iteration += 1
def block_bg_power_allocation(self):
EPS = 0.0000000000001
RamTot = 0
while (self.iteration < self.Iter_maxB):
self.calcul_power_backhaul()
print('backhaul Pok=', self.p_ok)
self.calcul_delta()
self.calcul_rok()
for i in self.station:
for j in self.users:
self.Ram = numpy.delete(self.Ram, self.Ram[0])
RamTot = sum(self.Ram)
if EPS <= (self.Rok[i] - sum(self.Ram[i])):
self.iteration += 1
def main(self):
self.block_Estimation_ACCESS_LINK()
self.block_bg_power_allocation()
In the first function you're doing this:
self.iteration += 1
And then, in the second function your stop condition is:
while (self.iteration < self.Iter_maxB):
So the first function would increment self.iteration to self.Iter_max. Now, if self.Iter_maxB is the same value as self.Iter_max, your second functions loop will never execute. I suspect that's what's happening here. Check those two varaibles.
Fix would be something like this if you want to execute both those loops the same number of time:
def main(self):
self.block_Estimation_ACCESS_LINK()
self.iteration = 0
self.block_bg_power_allocation()

or condition in while loop python

Does or condition work in a while loop in python? I can't seem to make it work. This is the sample of how my code works.
newslot = 3
moved = False
while newslot > 0 or moved != True:
enabled = query something on the database where slot = newslot
if enabled:
print 'do something here'
moved = True
else:
newslot-=1
print 'slot disabled'
So when the newslot gets to value of zero it still proceeds to go inside the while loop.
I seem to be missing something here.
or is working as should be expected. A while loop will continue until its condition is false. If its condition is two separate conditions connected with an or, it will only be false when the two conditions are both false.
Your loop will continue repeating until moved is false and newslot is <= 0. I'm guessing you actually want to use and in this case, as you want the loop to stop once either condition is met.

Categories