Right now, I have the following class methods:
def check_capacity(self, at_index)
def update_capacity(self, at_index)
The former returns a Boolean, while the latter changes an instance variable. The problem is both methods do very similar things. I feel like I'm violating DRY?
I'd like to have one method:
def update_capacity(self, at_index)
which I can use as:
if update_capacity(at_index):
that would create the intended side-effects if the side-effects are desirable, and return False otherwise.
My attempt was to copy the instance variable, check to see if the copy was desirably changed, and then set the instance variable to the copy if correct and return True, or don't and return False otherwise. However, this doesn't work with mutable data structures (like lists)!
Should I just be doing this with a "deep copy"? Or is there a better way to go about doing this? I'd like to be as Pythonic as possible.
EDIT
The check_capacity iterates through the instance variable and checks if making the change would violate a condition.
The update_capacity iterates through the instance variable and makes the change, knowing the condition won't be violated.
Both have very similar code.
I have a hunch that those two functions together manage to straddle your problem without exactly hitting it on the head. If I have this right, you want to have update_capacity either change something or return False if changing something is not desired.
It seems to me that you will be able to achieve this functionality by adding the checking mechanism from check_capacity into update_capacity, performing the condition check before executing the body of update_capacity:
def update_capacity(self, at_index):
if <condition from check_capacity>:
<body of update_capacity>
else:
return False
Of course, this code will return None if the condition is true, so if you want to keep your function signatures tidy, you could return True or something depending on what fits the rest of your code.
If check_capacity is applied to more than one places, make it
a decorator that makes sure it throws an exception if the constraint/check
is not met.
Like
#check_capacity
def update_capacity(...)
# Does the job and does not return anything
If check_capacity is not used anywhere else, just put the logic inside
update_capacity.
Edit:
Also this
if update_capacity(at_index):
is ambiguous at best. Is the function going to see if I can update? Is it going to actually update/mutate something?
It is evident that these 2 functions must be separate.
Related
I just encountered a problem with #unittest.skipIf(expression). Well, the problem is that if I use variable in decorator that is declared and assigned a value before starting the test, and during the test the value of this variable is changed the effect is such that decorator includes the old value. For example:
class Settings(object):
flag=False
class TestCase(object):
# during the test variable is changed (in this module or another)
Settings.flag=True
#unittest.skipIf(Settings.flag==True)
def test_something(self):
...
Value of Settings.flag can be changed in another module or this module (this doesn't matter). In both cases condition Setting.flag==True during call test_something still takes the 'False' value although it was already changed to 'True' value. It is very strange and I admit that I don't understand how this mechanism works. It seems that the value used in this decorator can't be changed during the test. Maybe there is some other interesting way to skip the test at the time of a particular condition, which may change during the test. Does anyone have an idea how to approach this problem?
Yes, this is expected behavior. Function arguments are evaluated when the function is called. The decorator is a function that's called when the function being decorated is defined. Therefore, the flag is tested when the decorated function is defined. The decorator has no way to know what the test even was; it only sees True or False (or more likely, truthiness or falsiness) so it can't store the condition away for later evaluation.
For skipIf() to work as you want, it would need to take a function (e.g. lambda: Settings.flag==True) rather than a Boolean value. Then it would be able to evaluate this condition later, when the decorated function is actually called. But it doesn't actually work that way. (This would probably be an easy enhancement to add, though.)
You may be able to work around this by not importing the module containing your unit tests until after the value of Settings.flag has been established. This will defer the definition (and thus the decoration) of your test functions until then, and the decorator will have access to the desired value of the flag. Not knowing how your code is structured, I don't know whether this is practical for you.
Additionally, something looks fishy about Settings.flag==True... can't quite put my finger on it... ;-)
Due to the scoping rules of Python, all variables once initialized within a scope are available thereafter. Since conditionals do not introduce new scope, constructs in other languages (such as initializing a variable before that condition) aren't necessarily needed. For example, we might have:
def foo(optionalvar = None):
# some processing, resulting in...
message = get_message()
if optionalvar is not None:
# some other processing, resulting in...
message = get_other_message()
# ... rest of function that uses message
or, we could have instead:
def foo(optionalvar = None):
if optionalvar is None:
# processing, resulting in...
message = get_message()
else:
# other processing, resulting in...
message = get_other_message()
# ... rest of function that uses message
Of course, the get_message and get_other_message functions might be many lines of code and are basically irrelevant (you can assume that the state of the program after each path is the same); the goal here is making message ready for use beyond this section of the function.
I've seen the latter construct used several times in other questions, such as:
https://stackoverflow.com/a/6402327/18097
https://stackoverflow.com/a/7382688/18097
Which construct would be more acceptable?
Python also has a very useful if syntax pattern which you can use here
message = get_other_message() if optional_var else get_message()
Or if you want to compare strictly with None
message = get_other_message() if optional_var is not None else get_message()
Unlike with example 1) you posted this doesn't call get_message() unnecessarily.
In general second approach is better and more generic because it doesn't involve calling get_message unconditionally. Which may be ok if that function is not resource incentive but consider a search function
def search(engine):
results = get_from_google()
if engine == 'bing':
results = get_from_bing()
obviously this is not good, i can't think of such bad scenario for second case, so basically a approach which goes thru all options and finally does the default is best e.g.
def search(engine):
if engine == 'bing':
results = get_from_bing()
else:
results = get_from_google()
I think it's more pythonic to not set an explicit rule about this, and instead just keep to the idea that smallish functions are better (in part because it's possible to keep in your mind just when new names are introduced).
I suppose though that if your conditional tests get much more complicated than an if/else you may run the risk of all of them failing and you later using an undefined name, resulting in a possible runtime error, unless you are very careful. That might be an argument for the first style, when it's possible.
The answer depends on if there are side effects of get_message() which are wanted.
In most cases clearly the second one wins, because the code which produces the unwanted result is not executed. But if you need the side effects, you should choose the first version.
It might be better (read: safer) to initialize your variable outside the conditions. If you have to define other conditions or even remove some, the user of message later on might get an uninitialized variable exception.
I recently had to implement a small check for any variables that might have not been initialized (and their default value is None). I came up with this:
if None in (var1, var2, var3):
error_out()
While, in my eyes, bordering on beautiful, I was wondering - is this a good way to do it? Is this the way to do it? Are there any cases in which this would produce some unexpected results?
First things first: your code is valid, readable, concise... so it might not be the way to do it (idioms evolves with time and new language features) but it certainly is one of the way to do it in a pythonic way.
Secondly, just two observations:
The standard way to generate errors in python is to raise Exceptions. You can of course wrap your exception-raising within a function, but since it's quite unusual I was just wondering if you chose this design for some specific reason. Since you can write your own Exception class, even boilerplate code like logging an error message to file could go within the class itself rather than in the wrapping function.
The way you wrote your test is such that you won't be able to assign None as a value to your variables. This might be not a problem now, but might limit your flexibility in the future. An alternative way to check for initialisation could be to simply not declare an initial value for the variable in question and then do something along the lines of:
try:
self.variable_name
except NameError:
# here the code that runs if the variable hasn't been initialised
finally:
# [optional] here the code that should run in either case
A just slightly different way to do it would be to use the built-in all method; however, this will also catch false-ish values like 0 or "", which may not be what you want:
>>> all([1, 2, 3])
True
>>> all([None, 1, 2])
False
>>> all([0, 1])
False
Allow me to leave my two cents here:
>>> any(a is None for a in [1,0])
False
>>> any(a is None for a in [1,0, None])
True
So one can:
def checkNone(*args):
if any(arg is None for arg in args):
error_out()
Nothing new here. Just IMHO maybe the part any arg is None is more readable
I find myself writing a lot of code that resembles the following:
ans = call_function()
if ans:
return ans
...
Is there a clean way to make this a 1 or 2 liner? An "example" of such a paradigm might be
if x as call_function():
return x
It seems that as long as ans is not None, you can just return it, based on your implied usage.
if ans is not None:
return ans
I'm not sure what you're doing after your if, but perhaps you're doing the following:
ans = call_function()
if ans:
return ans
else:
return default
In which case it you can simply do:
return call_function() or default
It may make sense to refactor the code which would follow your if statement into another function. There is a (not unwise) school of thought which emphasizes making each function do one very specific thing.
In this case, you could write something like this:
ans = call_function()
return ans if ans is not None else following_code()
or, if you are really testing for a truthy value (rather than specifically testing for not None):
return call_function() or following_code()
In the not None case, you can still avoid assigning to the temp variable ans by writing a function like this:
def fallback(test_value, routine, *args, **kwargs):
return test_value if test_value is not None else routine(*args, **kwargs)
and then using it like this:
return fallback(call_function(), following_code,
arg_to_following_code, following_code_kwarg=keywordarg_value)
This might be useful if you're doing this sort of thing very frequently, but in general it will just make your code a bit harder to read, because people will not be familiar with your fallback function. The original form used in your question is bulky, but it has a readily recognizable shape that people will be used to seeing. It also does things in a very measured fashion, one logical action per line, as is the norm in Python.
On the other hand, it can be good to cut out extraneous local variables, since these can lead to bugs due to typos or confusion about scope.
Wanting to embed assignments in if statements is probably one of the more common feature requests we see for Python. The problem is that such embedded assignment proposals typically only work for the very limited cases where the value you want to store and the condition you want to check are identical (e.g. your example falls into that trap and would be useless if you instead needed to check a more specific condition like if ans is not None:).
If the extra line really offends you, you can collapse the if statement to a one-liner (if ans: return ans). A lot of people hate that style, though.
However, I question your basic premise that "I want to know if this function returns something meaningful, and if it is, then that is the result of this function as well, otherwise I will fall back and calculate my result some other way" isn't sufficient justification for using a properly scoped local variable.
Knowing whether or not another function has finished the job for you sounds pretty damn important to me.
In a function, I need to perform some logic that requires me to call a function inside a function. What I did with this, like:
def dfs(problem):
stack.push(bache)
search(root)
while stack.isEmpty() != 0:
def search(vertex):
closed.add(vertex)
for index in sars:
stack.push(index)
return stack
In the function, dfs, I am using search(root), is this is the correct way to do it?
I am getting an error: local variable 'search' referenced before assignment
There are many mysterious bug-looking aspects in your code. The wrong order of definition (assuming you do need the search function to be a nested one) and the syntax error from the empty while loop have already been observed, but there are more...:
def dfs(problem):
stack.push(bache)
search(root)
what's bache, what's stack, what's root? If they're all global variables, then you're overusing globals -- and apparently nowhere ever using the argument problem (?!).
while stack.isEmpty() != 0:
what's this weird-looking method isEmpty? IOW, what type is stack (clearly not a Python list, and that's weird enough, since they do make excellent LIFO stacks;-)...? And what's ever going to make it empty...?
def search(vertex):
closed.add(vertex)
...don't tell me: closed is yet another global? Presumably a set? (I remember from a few of your Qs back that you absolutely wanted to have a closed dict, not set, even though I suggested that as a possibility...
for index in sars:
...and what's sars?!
stack.push(index)
return stack
what a weird "loop" -- one that executes exactly once, altering a global variable, and then immediately returns that global variable (?) without doing any of the other steps through the loop. Even if this is exactly what you mean (push the first item of sars, period) I don't recommend hiding it in a pseudo-loop -- it seriously looks like a mystery bug just waiting to happen;-).
You need to de-indent your search function. The way you have it set up right now you are defining your search function as a part of the completion of your dfs call. Also, encapsulation in a class would help.
Thats the wrong order. Try this:
def dfs(problem):
def search(vertex):
closed.add(vertex)
for index in sars:
stack.push(index)
return stack
stack.push(bache)
search(root)
while stack.isEmpty() != 0:
Either define search before you call it, or define it outside of dfs.
you have to define the function before using it
root doesn't seem to be available in your scope - make sure it's reachable
You don't have body to your for your while loop. That is probably causing problems parsing the code. I would also suggest putting the local function definition before it is used, so it is easier to follow.