Reputation: 59
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!
Upvotes: 0
Views: 4011
Reputation: 104702
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"
Upvotes: 1
Reputation: 459
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
Upvotes: 1
Reputation: 3366
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.
Upvotes: 0
Reputation: 167
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.
Upvotes: 0