Py3.Ch.11. Function arguments -- Project: The Nile

Hi everyone, I’m new to Python. This problem is from codecademy – python 3 – Ch.11 Function Arguments – Project: Neil

I have several questions:

  1. I used * to unpack tuples, but it’s wrong. When can we omit * in the function parameters?

  2. Line 9: I un-indent “distance = get_distance(from_lat, from_long, to_lat, to_long)” and it gave me this following error:

    The correct is following (put the distance inside the function), why this works?

Here is my code (it will give you error message):
from nile import get_distance, format_price, SHIPPING_PRICES
from test import test_function

Define calculate_shipping_cost() here:

def calculate_shipping_cost(*from_coords, *to_coords, shipping_type):
(from_lat, from_long) = from_coords
(to_lat, to_long) = to_coords
distance = get_distance(from_lat, from_long, to_lat, to_long)

There’s quite a lot going on here so it’s hard to pin down which bit is causing trouble.

There is syntax for using *args in the definition of a function, the so-called arbitrary arguments but you can only use it once and it must come after any positional arguments. It works in the following way-

def func(*args):
    # arguments passed to args are wrapped in a tuple

func(1, 'ten', 3, int)  # we pass multiple arguments
Out: <class 'tuple'>  # args is a tuple
# elements are the arguments passed (in order)
(1, 'ten', 3, <class 'int'>)

See the following for more info- function arbitrary arguments, def(*args)

From what I understand your arguments are already being passed as two tuples, something like from_coords == (54.5, -12.3). As you saw in your final image one of the ways of unpacking a sequence like this when you know the length assigning it to the same number of identifiers-

lat, lon = from_coords

There is an operator for unpacking tuples * but it’s not the same as when used in a function definition: unpacking with *. You could perhaps use it when calling the function though, e.g. a function that expects four arguments-

func(*from_coords, *to_coords)
# This behaves in the following way (two, two element tuples unpacked)
func(from_coords[0], from_coords[1], to_coords[0], to_coords[1])
# Note how it *unpacks* the tuple and passes the items individually

Spend a bit of time working out the differences here before moving on as they may cause confusion in the future otherwise.
Reading part of the Python docs on defining functions might help-

1 Like

Wow, this is extremely helpful! Thank you for your thoughtful answer!