If statement executes when it's false - python

I am getting "Knob already attached to a node" when i try to add a knob
i get this when i try to run my code from menu.py button.. if i run the script from the script editor i don't get the error.. why is that?
for i in nuke.allNodes():
if not i.knob("tempMb"):
if sum0 == 0:
nuke.message("first tmp knob created")
i.addKnob(t)
elif sum0 != 0:
nuke.message("second tmp knob created")
else:
nuke.message("no nob created")
Even though i check if there is a knob named tempMb .. it still executes it as if there was not, when there is..
edit: "t" is earlier defined as Int_Knob...
Thanks!

Try the following solution:
import nuke
t = nuke.Int_Knob( 'tempMb', 'tempMb' )
for i in nuke.allNodes():
if not i.knob("tempMb"):
if nuke.exists("sum0"):
nuke.message("First tmp knob created")
i.addKnob(t)
else:
nuke.message("Second tmp knob created")
else:
nuke.message("No knob created")

First I'm going to change the elif to just else because your if condition is already testing the elif condition and I don't see how that would be changing while in this code.
for i in nuke.allNodes():
if not i.knob("tempMb"):
if sum0 == 0:
nuke.message("first tmp knob created")
i.addKnob(t)
else:
nuke.message("second tmp knob created")
else:
nuke.message("no nob created")
Second I'm assuming that i.knob(string) doesn't check for the existence of a knob by that name, or your code would behave more as you expected. So when I read the docs it seems like a couple of things may happen:
The nodes might or might not be knobs in the list returned. If you know you only want knobs you could filter by class type. I think that might look like nuke.allNodes(nuke.Knob).
I don't think a nuke.Knob.knob(str) is a test for its name or label. I read the docs as implying that your test should be: if i.name != "tempMb": or possibly if i.label != "tempMb" it depends on how you created t.
Moving on though, I think there may be a logical error here. If you have 2 nodes (and if you make the above changes, let's assume they're both knobs), and as you loop over all nodes the first one is the tempMb, then when you check the second one it won't be that and you'll try to add t, which I assume is named tempMb too. So that's why it looks to you as though the negative condition is always occurring.
You need to restructure in one of two ways:
Before the loop, set a false boolean, in the loop set it to true when the knob is tempMb is found; you may as well exit the loop as soon as this occurs. After the loop check the boolean to see if it's safe to add t.
I see a possible function nuke.exists(s) which tells you if you have any "item" named s.
Maybe remove the loop and write the following:
if not nuke.exists("tempMb"):
# Add your knob. I'm actually not seeing `addKnob` in the docs.

nuke.exists("Name of Knob") will check if your knob exists. Try using that in your if statement.
More details on Nuke forum.
See also Documentation on nuke.exists

Related

How to use the command "with" conditionally without duplication of code

I am trying to use with before executing a block of code, but only if a condition is met, but (at least the common) usage of with doesn't appear to support that unless I duplicate the block of code.
More concretely, I know I can do the following:
if condition:
with blah_blah():
my_code_block
else:
my_code_block
But that's unsatisfying during development since any change I make to my_code_block must be made twice. What I want to do (conceptually) is:
if condition:
with blah_blah():
else:
my_code_block
That doesn't work, though. Is there a way to accomplish what I'm trying to do?
For anyone that's interested in my particular use, I'm trying to write code that runs a batch of examples in pytorch, with torch.no_grad() if I'm in evaluation mode and without it if I'm in train mode. So what I want to do becomes
if mode == 'eval':
with torch.no_grad():
else:
run_batch(features, labels)
Use the with statement, but with a nullcontext context manager if necessary.
from contextlib import nullcontext
with blah_blah() if condition else nullcontext():
my_code_block
nullcontext takes an optional argument that it will return if your with statement expects something to be bound with as. For example,
with nullcontext("hello") as f:
print(f) # outputs "hello"
I was wondering if it could be accomplished with:
def myrunner(myfunc,usecontext=True):
if usecontext:
with blahblah():
myfunc()
else:
myfunc()
def myfunc()...
myrunner(myfunc,usecontext=false)
But looking at it, I don't see how the context can effect myfunc.

Don't understand why I get an "Expected an indented block" error with Pyomo

I would like to use the following code from Pyomo Accessing solver status and termination conditions
results = opt.solve(instance) # Solving a model instance
instance.load(results) # Loading solution into results object
if (results.solver.status == SolverStatus.ok) and (results.solver.termination_condition == TerminationCondition.optimal):
# Do something when the solution in optimal and feasible
elif (results.solver.termination_condition == TerminationCondition.infeasible):
# Do something when model in infeasible
else:
# Something else is wrong
print “Solver Status: ”, result.solver.status
Hoever, I get an error saying Expected an indented block at the elif. When inserting an indented block, I get the error Invalid syntax. I posted a screenshot of both cases. I do not understand why I get this error? I just copied and pasted the code from the official pyomo website. Do you have any idea why I am getting this error and how I can get rid of it?
You likely need to have at least 1 line of executable code within each if or elif block. Right now, you just have a comment line.
While you are "shelling out" the program, just put the command pass in each block and see if that helps. So:
if (something >= something_else):
# do something
pass
else:
# do the other thing
pass
....
When code is laid out using whitespace like python, you need something actually in the block to show that it's there. A comment isn't enough as these are ignored.
Your code currently looks like:
if ... :
# comment where block should be
elif ... :
print "something"
The comment doesn't count as an indented block.
If you really have no code to put in there yet, you can use the no-op statement pass:
if ... :
# todo
pass
elif ... :
print "something"

check for 'item not in mylist' causes python to crash

Good evening,
I am trying to build a list of backpointers. In there, I want to avoid duplicates. As far as i know i cant use a dict or set, because the items to be stored are not hashable. I implented the following code:
while k in range(limit):
try:
if path not in path_backp:
path_backp.append(path)
continue
else:
Log.Message(path.Item[k].Text)
path = path.Item[k].Items
limit = path.Count
scan(path, path_backp, e, 0)
k = k +1
except AttributeError:
path = path_backp.pop()
limit = path.Count
k = k + 1
the part to avoid double entities of course is:
if path not in path_backp:
path_backp.append(path)
continue
else:
[...]
Im running python inside TestComplete, which has (limited) debugging functions.
When I enable the debugger and track what is happening, the first check works. The if-routine gets executed, and because path_backp is an empty dict, path gets appended, so that afterwards path_backp[0] equals path and I get back to to the while-routine.
But when the if-routine gets executed the 2nd time (so when path_backp is no empty dict anymore), the debugger freezes for what seems an infinite amount of time.
same happens, by the way, when I implemented:
if path not in path_backp:
path_backp.append(path)
without any continue or else.
Can anyone explain to me why this is happening and how I can handle the situation?
Many thanks,
b.

Python Global Variable Not Working

I have an extremely long program for a Canasta game that I am writing, in it there is a variable that ends the turn of the player if it equals a certain value. However, the turn repeats itself.
I have read many different articles and posts on forums like this one, but none of these seem to work. I even have a debug system to print the value of the variable before the if statement, and the variable is the right value, but the if statement doesn't see the same value.
I can't give the entire code, as it is extremely long, but I can give the sections that use this variable. I am using Python 2.7.2 and cannot make files separate from the main file to import.
The first line of the program is:
endTurn=1
The following function is called when conditions to win the game are met, but I have not been able to test that this works because of the bug.
def winGame(player):
global endTurn
gameWinner=player
gameWinner["score"]+=100
endTurn=0
The following function is called when a move is made. The variable decide is a raw_input() variable.
def move(player,decide):
global endTurn
theMove=decide.lower()
#if player says to end turn
if theMove=="end":
#until player discards something
discarded=0
while not discarded:
displayHand(player)
#ask player for discard
discard=int(raw_input(" Enter the list number of the card you wish to discard:"))-1
#if discard ID is in player's hand length
if not discard<0 and not discard>len(player["hand"])-1:
#add card to discard pile and remove from hand
discardPile.append(player["hand"][discard])
del(player["hand"][discard])
discarded=1
debug("Before changing, endTurn is %s"%str(endTurn))
endTurn = 0
debug("After changing, endTurn is %s"%str(endTurn))
if theMove=="new book":
newBook(player)
if theMove=="add to book":
addBook(player)
Here is where the turn should be ended. turn(thePlayer) repeats the function. The debug statement shows the correct value, 0, but the if still reads a 1. The function this is in also has the global endTurn at the top.
debug("If ending turn, endTurn of %s should be 0."%str(endTurn))
if endTurn==1:
turn(thePlayer)
Any help is greatly appreciated!
EDIT: The code is available at http://labs.codecademy.com/CV9z#:workspace. I ask that anyone viewing the code does not modify it, so that other people can see the true code.
I fixed the bug. I removed the endTurn variable and instead made the function that ends the turn just do the turn of the next player. It also simplified my code a bit.
I am wondering though, is using this method of running a function inside of itself over and over and over again (without leaving) rather messy or maybe slowing down my program?
EDIT: I now realize that this answer does not exactly help with anyone else who is stuck with global variables...
The previous answer I posted was just wrong, as it was based on a misinterpretation of the namespace docs as I had read them (Thanks to TheifMaster for pointing out my error), so this is a SEVERELY EDITED ANSWER:
The problem is in the while loop that I was able to read when the link to the entire code was posted after the erroneous answer I gave earlier.
while gameWinner==0:
endTurn=1
turn(player1)
if not gameWinner==0:
endTurn=1
turn(player2)
The game can never get to player two in this loop until gameWinner!=0.
I added the entire code to my sandbox and changed it to:
while gameWinner==0:
endTurn=1
turn(player1)
if gameWinner==0: #if player1 did not win yet
endTurn=1
turn(player2)
However, the game is still buggy... No one can win! gameWinner is not changed globally by the winGame() function until you add it to the global statement as I have shown here.
def winGame(player):
global endTurn, gameWinner
gameWinner=player
gameWinner["score"]+=100
debug("gameWinner == " + str(gameWinner))
endTurn=0

Python - What's the use of if True:?

I just came accross the following code in an existent project, which I'm working on:
if True:
x = 5
y = 6
return x+y
else:
return 'Something
Inside the if True are lots of conditions and some will also return the function already.
Why would somebody write in that way? The code contained some other bugs also, but was just wondering about the if True: statement as it didn't make any sense to me. Probably also pretty stupid to ask it, but was wondering hehe.
It might be a remnant of debugging or refactoring. It may be that instead of True, there was orginally a condition or variable there but it has now been replaced by True. The developer perhaps left it there without refactoring or cleaning it up all the way.
If you're free to edit the code as you wish and you're sure that the else is no longer needed, then you can remove it. It indeed makes no sense to have code in your codebase that will never run.
True doesn't necessarily mean True
True = False
if not True :
print "True is false" # This prints ok
Honestly, I don't think anyone would code like this.
Does not make any sense to me, my guess is that someone wanted to have two distinct code paths that he could alternate between a'la using #if 1 .. #else -> #if 0 ... for debugging or such purposes.
Other possibility was that, as #SimeonVisser suggested, the original developer was refactoring or cleaning up the code (and did not have an emulator that allows one to easily remove 1 step of indentation from a block of code)
It could be a flag used for debugging.
It's simply used to ensure that the else: block is never executed.
I have used if True: for some blocks to ensure that my code really does what I want. Usage for debugging or refactoring.
All in all it makes no real sense to use this in an application but for testing or debugging it's somehow acceptable.

Categories

Resources