Welcome to the Treehouse Community

The Treehouse Community is a meeting place for developers, designers, and programmers of all backgrounds and skill levels to get support. Collaborate here on code errors or bugs that you need feedback on, or asking for an extra set of eyes on your latest project. Join thousands of Treehouse students and alumni in the community today. (Note: Only Treehouse students can comment or ask questions, but non-students are welcome to browse our conversations.)

Looking to learn something new?

Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and a supportive community. Start your free trial today.

Python Python Basics Functions and Looping Returning Values

Ira Salem
Ira Salem
3,031 Points

Can someone explain how this works

import math

def split_check(total, number_of_people):
    return math.ceil(total / number_of_people)

total_due = float(input("What is the total?  "))
number_of_people = int(input("how many people?  "))

amount_due = split_check(total_due, number_of_people)

print("Each person owes ${}".format(amount_due))

So what you are seeing is code that is supposed to split up a check between a number of people.

My confusion with this code is figuring out how does it work? In the "def" line and the "return" line we are looking for "total" and "number_of_people". Beneath that we are seeking input from the user asking for their total and storing it in "total_due".

To put my question simply.... In the def and return statement shouldn't it read:

def split_check(total_due, number_of_people):
    return math.ceil(total_due / number_of_people)

instead of just:

def split_check(total, number_of_people):
    return math.ceil(total / number_of_people)

??????

3 Answers

Alex Koumparos
seal-mask
.a{fill-rule:evenodd;}techdegree
Alex Koumparos
Python Development Techdegree Student 36,861 Points

Hi Ira,

Short answer: no.

Longer answer, you are confusing your global variable name (total_due) with the internal name of the function's parameter (total). So in the example code above, the function has a parameter named total that you give a value when you call it. You could call it with a number literal, e.g., if the check was $100 and you had 2 people:

split_check(100, 2)

Inside the function, split_check has a variable named total that has the value 100.

Alternatively you could have stuck that 100 into a variable first and then called the function:

some_variable = 100
split_check(some_variable, 2)

It makes no difference to split_check whether the value being passed in is a literal (e..g, 100), or a variable that itself contains a value (e.g., some_variable).

Finally, you could call the function and be totally explicit:

some_variable = 100
another_variable = 2
split_check(total=some_variable, number_of_people=another_variable)

Which calls attention to the fact that the value you are passing in doesn't affect the name of the parameter in the function.

Hope that clears everything up

Cheers

Alex

I was also confused like Ira Salem, how does it know which argument to use? for the total variable if you change it, the same result. But when you change the number_of_people variable you get this error:

Traceback (most recent call last):
File "check_please.py", line 10, in <module>
amount_due = split_check(total_due, number_of_people)
NameError: name 'number_of_people' is not defined

Why does changing the 2nd parameter, number_of_people, cause an error, but when changing the total variable, nothing happens?

Alex Koumparos
seal-mask
.a{fill-rule:evenodd;}techdegree
Alex Koumparos
Python Development Techdegree Student 36,861 Points

Hi @Mathew V L,

When you declare a function with some arguments, e.g.,

def my_function(some_arg, another_arg):

Each argument has a name that is used as the variable name inside the function.

Python allows, but does not require, that when you call a function you provide those names. So, the following function calls are equivalent:

first_call = my_function(1, 2)

second_call = my_function(some_arg=1, another_arg=2)

When you call a Python function without the names, Python reads them in the same order as they are declared in the function. So in first_call, above, we know that 1 will be assigned to some_arg and 2 will be assigned to another_arg.

Python calls these 'Positional arguments'.

When you call a Python function with the names, Python reads them as though they were a dictionary, so Python doesn't care about the order, it just cares about matching the names, so given the following:

third_call = my_function(another_arg=2, some_arg=1)

second_call is equivalent to third_call. Python calls these 'Keyword arguments'

It does get a bit more complicated when you mix and match positional arguments and keyword arguments, the most important thing to remember being that any keyword arguments must come after all positional arguments.

Hope that clears everything up for you,

Cheers

Alex

Thanks! that definitely clears all questions I had

Hai Phan
Hai Phan
2,442 Points

The function always looking for values of "total" and "number_of_people" As you can see this code here at line 8: amount_due = split_check(total_due, number_of_people) we actually do call this fuction with total argument is now equal to the value has stored in total_due before remember we have assigned total_due to the number when we input