Comparison of 2 code chunks - what's the difference? - python

So, I was working on some code trying to resolve a bug. This was the original chunk of code:
passrate = 90
for child in sorted_children:
if child.passrate >= passrate:
return child
return None
This code was buggy and this is it's fix:
passrate = 90
for child in sorted_children:
if child.passrate() >= passrate:
return child
return None
The only difference is the added parenthesis. So, child is a class and passrate() is it's method which lazy-loads and returns it's __passrate value. If it's not calculated yet, it calculates it before returning it.
When I used the debugger to see what was causing the problem, I saw that sometimes when passrate() was executing it was like code execution somehow ended up in a completely wrong instance of child's class.
I know that without the parenthesis a pointer to the function is returned, but as it's done inside a logical operation, the function should be executed immediately afterwards so the final result should be the same for both chunks of code. And sometimes it indeed was. But sometimes it wasn't for some reason, always in the same iterated child in every execution of the code.
If someone could explain what could have caused the problem, I'd appreciate it very much.
EDIT:
Thanks everyone for helping. The old code was clearly wrong. I have no idea how it worked at all in the past.

I think, as per python's rule if it's method, then it should be called with braces. If it's a property then you can call without braces as below:
class Hello(object):
#property
def hi(self):
print "hello"
def hifunc(self):
print "Hi function"
h=Hello()
print h.hi
print h.hifunc
print h.hifunc()
Output:
hello
None
<bound method Hello.hifunc of <__main__.Hello object at 0x0000000002B99358>>
Hi function
None
None is printed as my example function returns nothing. In your case, when you call with braces, your return values from function used for comparison.

Related

Python Thread() - Function Arg Tuple Not Working?

I'm attempting to thread a function call in my Python catastr^H^H^H^H^H^Hreation, and I've read up on how to use the threading.Thread() call. My function takes a simple string argument, so theoretically it should be as easy as:
thread = threading.Thread(target = my_func, args = (string_var, ))
bearing in mind that the args() needs to be a tuple. Got it. However, it appears as though I'm still doing something wrong because I continually get the barffage from Python:
TypeError: my_func() takes 1 positional argument but 2 were given
I'm a bit stumped here. Any guidance?
Thanks!
please provide some code for us to help you.
But before you do your post could be a possible duplicate of this post.
Seems the issue is that because it's a method (thanks gribvirus74 for the idea) and I'm attempting to thread it, it won't inherit the self. And that appears to be the issue. I moved the function outside of the class and called it with the Thread(). Works fine now.
If it's a method, then you can write the following code (assuming the class name is SomeClass and it has a method called foo with one argument):
x = SomeClass()
thread = threading.Thread(target=SomeClass.foo, args=(x, 'your method argument'))

Can I make a function print into shell only if called with print?

So I have a function that returns a value. I'd like it to write it into shell only when called with print.
So c.function() doesn't return anything, while print(c.function) returns the value I need
Edit: I probably worded the question wrong
I have a class function that goes over an iterable, performs different tasks based on elements of the iterable. After completing the tasks it returns a number of the tasks completed. I need the function to write into shell only when called as print(c.function(iterable)), and to show nothing when called as c.function(iterable), is that possible?
Thanks in advance
If you write a function like,
def foo():
a = "This works."
return a
then call the function in the script like
foo()
nothing gets printed.
However, if you assign the function return call to a variable like
b = foo()
and print(b), then you get the result printed.
Simply assign to a dummy variable when you want to hide the output:
>>> _ = c.function()
And call the function normally when you want to view the output:
>>> c.function()
'the value you need'
Just in case you need to view the result, you can:
>>> _
'the value you need'
Although _ is also used in some Python shells as a special variable for the last value evaluated, so this might not always work. You might be able to rig up a fancy solution by assigning to a simple name that points to a property that appends to a list, but that seems like a lot of effort.
FWIW IPython can be made to not echo the value with a semicolon (e.g. 1; doesn't print anything) or can be set to not automatically echo values plus it automatically records every input and output.

Python Mocking assert_called not working

I am able to successfully mock a function, and I am sure that the original is not called. I added a huge print statement to the original function and when I mock it, this print is not called. When I turn the mock back on, the print statement is not called.
However, my assert_called is failing saying it was never called. Has anyone ever experienced something like this?
class FooTestCase(unittest.TestCase):
#mock.patch('MyObj.helper_function')
def test_simple(self, mock_hf):
my_obj = MyObj()
# internally, this class imports HelperModule
# and the method calls helper_function
my_obj.do_something()
mock_hf.helper_function.assert_called()
return
My error response
AssertionError: Expected 'helper_function' to have been called.
Update
I just added the following lines right before the assertion
print mock_cw.method_calls
print mock_cw.mock_calls
method_calls is an empty list, while mock_calls is a list with 1 item which is
[call(arg1_expected_for_helper_fn, arg2_expected_for_helper_fn)]
Yet the assert still fails
Usually an error like this is a result of not patching the correct location. Try to patch the object itself with this:
#patch.object(MyObj, "helper_function")
def test_simple(mock_hf):
...
Since MyObj is (assumed to be) imported at the top of the test file, this patches the method on that object directly.
The issue is that I was checking to see if mock_hf.helper_function was called, but mock_hf is already mapped to the helper_function. I was more or less checking that helper_function.helper_function was called rather than just helper_function.
The assert line needed to be
mock_hf.assert_called()
I see the original poster has done this, but for anyone else stumbling on this as I did...
Don't forget you need to wrap your expected calls in a call object e.g.
mock_logger.assert_has_calls([call(expected_log_message_1), call(expected_log_message_2)])
If you don't do that, it will complain that the expected call did not happen and you will spend ages comparing the output to try and work out why (as I did!).

How do I perform some operation on the output of a function in Python?

I am trying to make a function's output behave as if it's my input. The goal is to make a new output from the old output.
I have some code that looks like this:
def func():
BLOCK OF CODE
func()
There is no return statement in the function and no parameters within the parenthesis.
When I type func() to call my function as shown above, I get the desired output, which is a bunch of printed statements. Now I want to do something with that output to get another output.
All I'm trying to do is effectively "pipe" the output of one function into the input of another function (or, if possible, not even worry about creating another function at all, and instead doing something more direct). I looked into Python 3 writing to a pipe
but it did not help me. I also tried defining another function and using the preceding function as a parameter, which did not work either:
def another_func(func):
print another_statement
another_func(func)
I also tried making a closure (which "kind" of worked because at least it printed the same thing that func() would print, but still not very encouraging):
def func():
def another_func():
print another_statement
BLOCK OF CODE
another_func()
Finally, I tried designing both a decorator and a nested function to accomplish this, but I have no parameters in my function, which really threw off my code (didn't print anything at all).
Any advice on how to manipulate a function's output like as if it is your input so that it's possible to create a new output?
You could achieve this by redirecting stdout using a decorator:
from StringIO import StringIO
import sys
def pipe(f):
def decorated(*args, **kwargs):
old,sys.stdout = sys.stdout,StringIO()
try:
result = f(*args, **kwargs)
output = sys.stdout.getvalue()
finally:
sys.stdout = old
return result, output
return decorated
You could then get the result, output pair from any decorated function, eg:
#pipe
def test(x):
print x
return 0
test(3) -> (0, '3\n')
However, I can't think of a good reason why you'd want to do this.
(Actually, that's not quite true; it is handy when writing unit tests for user IO, such as when testing student assignments in a software engineering course. I seriously doubt that that's what the OP is trying to do, though.)
Return the desired value(s) from the function - instead of printing the values on the console, return them as strings, numbers, lists or any other type that makes sense. Otherwise, how do you expect to "connect" the output of a function as the input to another, if there is no output to begin with?
Of course, printing on the console doesn't count as output unless you're planning to eventually use OS pipes or a similar mechanism to connect two programs on the console, but keep things simple! just use the function's return values and worry about pipes later if and only if that's necessary for your problem in particular.
After reading the comments: "connecting" two functions by printing on the console from one and reading from the console from the other would be a really bad idea in this case, first you have to grasp the way functions return values to each other, trust me on this one: you have to rethink your program! even though other answers (strictly speaking) answer your original question, that's absolutely not what you should do.
just for fun ... because OP asked for it
import StringIO
import sys
def func1():
for i in range(1,10):
print "some stuff %d"%i
def func2(func):
old_std = sys.stdout
sys.stdout = StringIO.StringIO()
try:
func()
return sys.stdout.getvalue().splitlines()
finally:
sys.stdout = old_std
print func2(func1)
You need to return a value from your function. This can be used to assign the value into another variable.
Say I define some function doubleThis that will double the input
def doubleThis(x):
print 'this is x :', x
return x * 2 # note the return keyword
Now I can call the function with 3, and it returns 6 as expected
>>> doubleThis(3)
this is x : 3
6
Now I have another function subtractOne that returns the input value, minus 1.
def subtractOne(i):
print 'this is i :', i
return i - 1
Now comes the answer to your question. Note that we can call the first function as the input to the second, due to the fact that it has a return value.
>>> subtractOne(doubleThis(3))
this is x : 3
this is i : 6
5

Check if there's something "waiting for" the return value of a function

I'm wondering if anyone can think up a way to check if a function needs to return a meaningful value in Python. That is, to check whether the return value will be used for anything. I'm guessing the answer is no, and it is better to restructure my program flow. The function in question pulls its return values from a network socket. If the return value is not going to get used, I don't want to waste the resources fetching the result.
I tried already to use tracebacks to discover the calling line, but that didn't work. Here's an example of what I had in mind:
>>> def func():
... print should_return()
...
>>> func()
False
>>> ret = func()
True
The function "knows" that its return value is being assigned.
Here is my current workaround:
>>> def func(**kwargs):
... should_return = kwargs.pop('_wait', False)
... print should_return
...
>>> func()
False
>>> ret = func(_wait=True)
True
The very second line of the body of import this says it all: "explicit is better than implicit". In this case, if you provide an optional argument, the code will be more obvious (and thus easier to understand), simpler, faster and safer. Keep it as a separate argument with a name like wait.
While with difficulty you could implement it magically, it would be nasty code, prone to breaking in new versions of Python and not obvious. Avoid that route; there lieth the path unto madness.
All functions return a value when they complete.
If you're asking if they should return at all, then you are actually asking about The Halting Problem
One approach might be to return an object with a __del__ method that relies on the garbage collector removing the unused value some time in the future.
Note that it won't happen immediately; it might not even happen at all :)
You might consider returning a future, or 'promise'. That is, return another function that, when executed, performs the necessary work to actually determine the result. I seem to be thinking that you want lazy evaluation, which is "evaluate only what you need" (more or less), rather than your question, which confusingly asks: "Evaluate only if it returns a value, which might be needed".
i have some code that kinda works using inspect module, but it might be prone to break like others mention.
inspect.stack()[1].frame.f_code.co_names[-1]
will be holding the function name when user didn't assign return value to anything, when user assign to var with name XXX, this var will hold XXX. Code comparing this vs the function name to decide whether user assign the return value to any var
import inspect
def func():
tmp = inspect.stack()[1].frame.f_code.co_names[-1]
should_return = tmp != 'func'
print("execute") # execute something
# if should_return False, end here without fetching result
if should_return:
print("fetching result, user assign to {}".format(tmp))
# fetching result and return the result here
>>> func()
execute
>>>
>>> xxx=func()
execute
fetching result, user assign to xxx
>>>
All functions in Python always return. If you don't explicitly return, functions return None.
===========
def func():
while True:
pass
This function does not return.
There is no way of determining if an arbitrary function will return. If you can, you have solved the Turing problem.

Categories

Resources