Using a tuple to Input the parameters of a function

Hello,

I’m on the INTRODUCTION TO FUNCTIONS: MULTIPLE RETURN VALUES section of the Python course. I was playing around with the function on the “questions asked by coders” page at What actually happens when returning multiple values in a function?

MY QUESTION: Why does a function not accept a tuple as an input for it’s parameters? As I understand it, a tuple is a sequence of items. I tried to use a tuple with 3 items in it to define the 3 parameters of a function, but it gives me an error. Why wouldn’t that work. Here’s what I did:

INPUT
def times_ten(a, b, c):
a = a * 10
b = b * 10
c = c * 10
return a,b,c

# Each variable will be assigned to each value in the returned tuple,
# in the order they appear.
t = (3, 4, 8)
times_ten(t) 
print(a,b,c)

OUTPUT
Traceback (most recent call last):
File “C:/Users/gene/PycharmProjects/Giraffe 3/venv/play.py”, line 11, in
times_ten(t)
TypeError: times_ten() missing 2 required positional arguments: ‘b’ and ‘c’

HOWEVER, when I do the following, the programs runs with no errors:

INPUT
def times_ten(a, b, c):
a = a * 10
b = b * 10
c = c * 10
return a,b,c

# Each variable will be assigned to each value in the returned tuple,
# in the order they appear.
a, b, c = (3, 4, 8)
times_ten(3, 4, 8)
print(a, b, c)
print(times_ten(a, b, c))

OUTPUT
3 4 8
(30, 40, 80)

The only difference is that in the first instance, I used a tuple, t = (3, 4, 8) to define the parameters of the function and in the 2nd instance I defined the parameter of the function as a, b, c = (3, 4, 8). Thanks.

Ah, but you haven’t.

Your function definition is def times_ten(a, b, c): - each of these parameters is mandatory. When you’re doing:

t = (3, 4, 8)
times_ten(t)

you’re creating a tuple in t and passing that as the argument to the parameter a. Your function still expects there to be arguments passed for the parameters b and c, so you get the TypeError you’re receiving.

If you wanted the option to pass all the parameters as a single tuple in the first parameter, you could do this:

def times_ten(a, b = 0, c = 0):
    if isinstance(a, tuple):
        b = a[1]
        c = a[2]
        a = a[0]

    return (a*10,b*10,c*10)

t = (2,4,6)
print(times_ten(t)) # prints "(20, 40, 60)"

print(times_ten(3,5,7)) # prints "(30, 50, 70)"

What we’re doing here instead is giving b and c default values, to make them optional parameters. We can now call our times_ten function with a single parameter, a, then inside the function we test to see whether a is a tuple.

If it is, we expand it out so that we have values in b and c. If we call times_ten with the full 3 arguments, we override the default values and don’t need to do anything funky to return their values multiplied by ten.

Does that help? :slight_smile:

Edit: Got distracted, missed the last bit of my post off…

Alternatively, there is a built-in method for doing this within Python already.

(Thought I’d show you a way of doing it long-hand, though.)

def expand_times_ten(a, b, c):
    return (a*10,b*10,c*10)

t = (1,3,5)
print(expand_times_ten(*t)) # prints "(10, 30, 50)"

The *t tells Python to expand out the tuple, filling all the parameters. :slight_smile:

More info here…

3 Likes

Yes thank you. The function was waiting for three inputs. When I said:

times_ten(t)

the function was waiting for two more variables. Even though I define the tuple “t”, when I call the function, “t” itself is only one variable of the function.

Thanks again.

We have, as with the above illustration, the option of unpacking at the function end.

>>> t = 1, 3, 5
>>> def expand_times_ten(u):
    a, b, c = u
    return a * 10, b * 10, c * 10

>>> expand_times_ten(t)
(10, 30, 50)
>>> 

Note how Python interpreted the comma separated return values as a sequence, hence we see the tuple in the response. The same applies in our definition of t; it too is interpreted as a sequence.

1 Like

Thanks. I’m a real newbie to coding and Python is my first course. I’m still wrapping my head around lots of things but enjoying the process. I’m sure I don’t get all the nuances of the helpful responses, but I am trying. For example, it’s the first time that I see something like a, b, c = u ; where there are 3 variables (?) on the left and only one variable on the right. Not quite sure what to make of that.

1 Like

The variable on the right is a tuple containing three values. We unpack all three values into separate variables in the order they appear in the tuple. Note that in this case we are aware of how many values are in the tuple argument so know how many variables to include in the assignment.

As you are still new to this, I won’t go into detail about how we could have an unknown number of values in the argument, so cannot implement code in the same informed manner. We would need to exploit both the star syntax at the calling end, and splat syntax at the parameter end. Don’t get absorbed with this, just now, but bookmark it and come back when you have finished most of the Introduction to Python track.

>>> def expand_times_ten(*u):         # splat
    return tuple([x * 10 for x in u])

>>> t = 1, 3, 5, 7, 9, 11
>>> expand_times_ten(*t)              # star
(10, 30, 50, 70, 90, 110)
>>> 

To repeat, let this go until later. You might already know about the tuple() constructor, but it’s very likely you will not understand the code inside, known as a list comprehension. It will come up when you reach the more advanced concepts, so just wait until then and continue your studies in this unit.

1 Like

" it’s the first time that I see something like a, b, c = u "

Just to clarify: When I wrote the sentence above, I know what a tuple is but I never saw a tuple written “backwards”. I thought that the tuple variable “t” would always be found on the left side of the equation and the values “a,b,c” would always be found on the right.

I agree. I’ll come back to this later. I’m still learning to walk :slight_smile:

2 Likes

Now you see that there are equivalent expressions on each side of the operation.

u = 1, 3, 7, 13
a, b, c, d = u