I am trying to be "Python-esque" in my code, where I am trying to call three functions, in succession, the second one only gets called if the first one doesn't produce a result, and the third one only if the first and second don't...
sky = "none"
while sky == "none":
sky = searchUnguided(inframe, skysearch, debug=debug)
sky = searchPQ(ad, skysearch, maxpq, debug=debug)
sky = searchAB(ad, maxpq, debug=debug)
break
Each of these functions searchUnguided, searchPQ and searchAB returns a value, which is none by default but can be changed to something else. It's these "something else" cases that I want to stop the while sky == "none" loop on. Yet, it doesn't work as I expect it to, and all three functions are called even when the first one returns something other than none.
Example of one function (have verified it returns non-none values as expected):
def searchUnguided(filename, skysearch, debug=False):
utdate = filename[1:9]
n = int(filename[11:15])
skyout = "none"
for ndiff in skysearch:
sn = n - ndiff
skyim = "N" + utdate + "S" + str(sn).zfill(4)
fskyim = os.path.join(rawdir, skyim + ".fits")
try:
sad = AD.read(fskyim, mode='readonly')
if getstate(sad, "frozen") != "none":
# we found a sky!
skyout = skyim
break
except:
continue
return skyout
Am I misunderstanding the way the while loop works? I can always use nested if statements but that seems so long-winded...
Thanks in advance!
4 Answers 4
I think your understanding of what a while loop does is incorrect. The loop condition is only checked at the top of the loop, so, once before searchUnguided is called and never again (since you have a break statement after the last call). It is not tested in between the function calls.
What I think you want is something like this:
sky = searchUnguided(searchUnguided(inframe, skysearch, debug=debug)
if sky == "none":
sky = searchPQ(ad, skysearch, maxpq, debug=debug)
if sky == "none":
sky = searchAB(ad, maxpq, debug=debug)
# you may want another "if" here to do something else if sky is still "none"
Comments
The while loop will have no effect in this case, because the first time around it will evaluate to true and there will be no evaluation the second time around due to the break
looks like ifs are not a bad way to go
Comments
The function searchUnguided() breaks out from its own local FOR loop if it finds an answer other than none. It doesn't breaks out from the while loop. When the code is run, Line 2 checks if sky == 'none', if yes it continues to run. On Line 3, assuming that sky is being changed, it does not have any checks on it (Remember, the check is on Line 2). Therefore, the rest of the code runs before the break on Line 6 comes in.
I will probably do something like this:
sky = "none"
while sky == "none":
sky = searchUnguided(inframe, skysearch, debug=debug)
if sky != "none":
break
sky = searchPQ(ad, skysearch, maxpq, debug=debug)
if sky != "none":
break
sky = searchAB(ad, maxpq, debug=debug)
break
There might be a better answer, but this will work.
Comments
This line: while sky == "none": The while-loop condition will only be checked after every loop. So in this case all functions would be executed before the next check of the condition will take place. However, due to the break; the while loop will be terminated anyhow. This makes this while loop just a rewritten version of a regular if-condition.
breakit will run forever...