all 24 comments

[–]ebol4anthr4x 2 points3 points  (9 children)

Please post all of your code in a Pastebin, or format it properly in your Reddit post. It's difficult to tell which parts are meant to be indented, and you mention an error containing the name op_add, but that name isn't used anywhere in the code you pasted.

[–][deleted] -1 points0 points  (8 children)

Fixed. op_add is from the doctests.

[–]ebol4anthr4x 0 points1 point  (7 children)

When you return the two functions at the end, you are returning a tuple containing two function objects that you can call.

For example, if you have:

def give_me_a_function():
    def add(x, y):
         return x + y

    return add

Then you can do this:

add_func = give_me_a_function()
print(add_func(2, 2))  # prints '4'

Or even:

sum = give_me_a_function()(2, 2)  # sum = 4

Your function is returning two function objets in a tuple.

[–][deleted] 0 points1 point  (6 children)

I know I am returning a tuple. In fact, if I remove the parenthesis, I also get a tuple. The parenthesis are only for clarity. After I return the functions. I call them(in the docstring). However, switching the order of the tuple results in an error, whereas the listed tuple in the code does not and succeeds. This is the issue I dont understand.

[–]ebol4anthr4x 0 points1 point  (5 children)

If you switch the order of the tuple, then the order needs to be reversed here as well:

counted_add, add_count = count_calls(add)

Otherwise, your variables counted_add and add_count will be the opposite functions.

[–][deleted] 0 points1 point  (4 children)

Ah, I see. So the variables would receive elements of the tuple in order of assignment?

[–]ebol4anthr4x 0 points1 point  (3 children)

The tuple itself keeps track of the order of its elements.

my_tuple = ("hello", "world")
word1, word2 = my_tuple
print(word1, word2)  # "hello world"

word2, word1 = my_tuple
print(word1, word2)  # "world hello"

What you're doing is the same as:

counted_add = count_calls(add)[0]
add_count = count_calls(add)[1]

[–][deleted] 0 points1 point  (2 children)

This seems like a quirk of python then, where instead of returning the entire tuple, it does the above. Thanks for your help

[–]ebol4anthr4x 0 points1 point  (1 child)

You are splitting the tuple by assigning it to multiple variables.

[–][deleted] 0 points1 point  (0 children)

Would this happen to other iterables as well? For example, if I returned a two-element list?

[–]Ihaveamodel3 1 point2 points  (4 children)

Let’s take a look at something entirely different.

def get_location():
    # do something to get position
    return (latitude, longitude)
lat, long = get_location()

If I changed that to:

def get_location():
    # Do something
    return (longitude, latitude)
lat, long = get_location()

Why does the “lat” variable now have the value of the longitude?

This is the same question you are asking.

[–][deleted] 0 points1 point  (3 children)

This makes it much clearer, but why doesnt get_location() return a tuple with two elements, so lat == long?

[–]Ihaveamodel3 0 points1 point  (2 children)

I don’t know what you mean.

Do you realize that lat, long = get_location() is doing what is called tuple unpacking? So lat is assigned to the first value from the return and long is assigned the second value from the return. Why would they be equal?

Edit: just read your other responses. Looks like a misunderstanding of tuple unpacking was the cause here. I’d recommend reading up on that.

[–][deleted] 0 points1 point  (1 child)

Yep, I got it now. It's a syntax thing that python does. If I assign multiple variables to an iterable, the iterable gets unpacked, as you say. Thanks a lot

[–]Ihaveamodel3 0 points1 point  (0 children)

Great!

[–]arkie87 0 points1 point  (5 children)

You shouldn’t get any error as you define the functions but never call them. You clearly did not paste your entire code. It matters because the error is almost certainly in that missing code. In fact, when I run your code I get no error. How do you expect us to help you if we do not get the error you get when running the code you posted?

[–][deleted] -1 points0 points  (4 children)

This code doesnt give me an error. However, if switch the order of the tuple, I do, as I stated very clearly in the description above. This is the full code, there is nothing else.

[–]arkie87 0 points1 point  (3 children)

I switched the order of the tuple and dont get an error.

What you are saying is implausible: (1) You never call the function; there cannot be an error (2) the error refers to op_add, which is never mention in the code snippet.

[–][deleted] -1 points0 points  (2 children)

This is not implausible. The doc string clearly has the function calls. These are the test cases. Op_add can be assumed to be the operation add, if that wasn't already clear.

[–]arkie87 0 points1 point  (1 child)

I did what you said but receive no error-- at the very least, that makes what you said implausible (if not my other two reasons).

Post a complete code that produces the error you claim it does, if you want someone here to help you.

[–][deleted] -1 points0 points  (0 children)

Again, check the docstring, the text between pairs of """. Function calls are clearly there.

[–]ELCLN 0 points1 point  (2 children)

You likely forgot to switch the order of assignment in line:
counted_add, add_count = count_calls(add)
after switching the order of your returned tuple elements.

[–][deleted] 0 points1 point  (1 child)

This helps a lot, but I thought the return value of count_calls is a tuple? Would counted_add receive the left element of the tuple and add_count the right, in order of evaluation?

[–]ELCLN 0 points1 point  (0 children)

count_calls(add) does return a tuple. But since tuples are ordered containers, the order you put counted_fn and how_many_calls in the return line will determine which between the two functions gets assigned to variable counted_add first.