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

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.

Related

Do we need i=i as a parameter when using subTest with a for loop?

Is it necessary to write i=i in the example below?
What is the point of writing i=i, when the testing works in both cases(writing it or not):
def test_cart_add_many_items(self):
for i in [2,3,4]:
with self.subTest(i=i):
self.assertEqual(self.cart.add_surfboards(i), f'Successfully added {i} surfboards to cart!')
self.cart = surfshop.ShoppingCart()
I tried looking in the documentaion, but didn't find the required info.
Only if you want i in the context (though if you don't, there's probably no reason to use subTest)
Without using a subtest, execution would stop after the first failure, and the error would be less easy to diagnose because the value of i wouldn’t be displayed:
https://docs.python.org/3/library/unittest.html#distinguishing-test-iterations-using-subtests

Toggle X-Ray Mode in Maya using Python

I'm trying to bind some Python code to a key so I can toggle X-Ray mode in Maya.
One thing that's confusing me is that when I run this line of code...
def xrayQuery():
cmds.modelEditor('modelPanel4', q=True, xr=True)
xrayQuery()
no result is returned, even though I've queried xray mode. But when I run just the command without the function...
cmds.modelEditor('modelPanel4', q=True, xr=True)
I get what I expected the first time, which is a boolean result based on whether or not xray mode is enabled. Can anyone tell me why this is?
I'm very new to python inside Maya, so any help will be much appreciated! Thanks!
You need to call return if you want the user-defined function to return the same output as called inside.
Like below:
def xrayQuery():
return cmds.modelEditor('modelPanel4', q=True, xr=True)
On a side note, if you could explain the purpose to write a function instead of calling the original function, it would be helpful to understand the use-case
So I've figured out a way to simplify what I was trying to achieve, which was a few lines of code to toggle the x-ray view mode on and off for a specific viewport. I was able to eliminate the need for if else statements by using the 'not' operator in this block of code:
import maya.cmds as cmds
def xray_toggle():
result = cmds.modelEditor('modelPanel4', q=True, xr=True)
cmds.modelEditor('modelPanel4', e=True, xr=not result)
xray_toggle()

Python: Why my function returns None and then executes

So, I have a function which basically does this:
import os
import json
import requests
from openpyxl import load_workbook
def function(data):
statuslist = []
for i in range(len(data[0])):
result = performOperation(data[0][i])
if result in satisfying_results:
print("its okay")
statuslist.append("Pass")
else:
print("absolutely not okay")
statuslist.append("Fail" + result)
return statuslist
Then, I invoke the function like this (I've added error handling to check what will happen after stumbling upon the reason for me asking this question), and was actually amazed by the results, as the function returns None, and then executes:
statuslist = function(data)
print(statuslist)
try:
for i in range(len(statuslist)):
anotherFunction(i)
print("Confirmation that it is working")
except TypeError:
print("This is utterly nonsense I think")
The output of the program is then as follows:
None
This is utterly nonsense I think
its okay
its okay
its okay
absolutely not okay
its okay
There is only single return statement at the end of the function, the function is not recursive, its pretty straightforward and top-down(but parses a lot of data in the meantime).
From the output log, it appears that the function first returns None, and then is properly executed. I am puzzled, and I were unable to find any similar problems over the internet (maybe I phrase the question incorrectly).
Even if there were some inconsistency in the code, I'd still expect it to return [] instead.
After changing the initial list to statuslist = ["WTF"], the return is [].
To rule out the fact that I have modified the list in some other functions performed in the function(data), I have changed the name of the initial list several times - the results are consistently beyond my comprehension
I will be very grateful on tips in debugging the issue. Why does the function return the value first, and is executed after?
While being unable to write the code which would at the same time present what happened in my code in full spectrum, be readable, and wouldn't interfere with no security policies of the company, I have re-wrote it in a simpler form (the original code has been written while I had 3 months of programming experience), and the issue does not reproduce anymore. I guess there had be some level of nesting of functions that I have misinterpreted, and this re-written code, doing pretty much the same, correctly returns me the expected list.
Thank you everyone for your time and suggestions.
So, the answer appears to be: You do not understand your own code, make it simpler.

Theano's function() reports that my `givens` value is not needed for the graph

Sorry for not posting entire snippets -- the code is very big and spread out, so hopefully this can illustrate my issue. I have these:
train = theano.function([X], output, updates=update_G,
givens={train_mode=:np.cast['int32'](1)})
and
test = theano.function([X], output, updates=update_G,
givens={train_mode=:np.cast['int32'](0)})
to my understanding, givens would input the value of train_mode (i.e. 1/0) wherever it's needed to compute the output.
The output is computed in the lines of this:
...
network2 = Net2()
# This is sort of a dummy variable so I don't get a NameError when this
# is called before `theano.function()` is called. Not sure if this is the
# right way to do this.
train_mode = T.iscalar('train_mode')
output = loss(network1.get_outputs(network2.get_outputs(X, train_mode=train_mode)),something).mean()
....
class Net2():
def get_outputs(self, x, train_mode):
from theano.ifelse import ifelse
import theano.tensor as T
my_flag = ifelse(T.eq(train_mode, 1), 1, 0)
return something if my_flag else something_else
So train_mode is used as an argument in one of the nested functions, and I use it to tell between train and test as I'd like to handle them slightly differently.
However, when I try to run this, I get this error:
theano.compile.function_module.UnusedInputError: theano.function was
asked to create a function computing outputs given certain inputs, but
the provided input variable at index 1 is not part of the computational
graph needed to compute the outputs: <TensorType(int32, scalar)>.To make
this error into a warning, you can pass the parameter
on_unused_input='warn' to theano.function. To disable it completely, use
on_unused_input='ignore'.
If I delete the givens parameter, the error disappears, so to my understanding Theano believes that my train_mode is not necessary for compute the function(). I can use on_unusued_input='ignore' as per their suggestion, but that would just ignore my train_mode if they think it's unused. Am I going around this the wrong way? I basically just want to train a neural network with dropout, but not use dropout when evaluating.
why you use "=" sign? I think, it made train_mode not readable, my code works well by writing:
givens = {train_mode:1}

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