Asking for help understanding the difference between return and print in function

Hey, everybody. I started functions a few days ago in Python Crash Course. I like this chapter, I understand a function’s purpose, but I’m not understanding the differences between print and return. I also have a question about assigning a variable to a function. I want to know what’s going on under the hood rather than just trying to memorize what I have to do in order for something to work. For example, from the book:

def get_formatted_name(first_name, last_name):
    """Return a full name, neatly formatted."""
    full_name = f"{first_name} {last_name}"
    return full_name.title()

# This is an infinite loop!

while True:
    print("\nPlease tell me your name:")
    print("(enter 'q' at any time to quit)")

    f_name = input("First name: ")
    if f_name == 'q':
        break

    l_name = input("Last name: ")
    if l_name == 'q':
        break

    formatted_name = get_formatted_name(f_name, l_name)
    print(f"\nHello, {formatted_name}!"

It seems like “formatted_name” is used as a variable of the function for organization, being specific when the function is called rather than just calling the function(please tell me if this is correct). In this case I can’t just call the function though. Why?

In some examples I’ve seen, if I used print and no return, it will show the result and “None”. Other instances it will show the same result, but people have said it’s different under the hood. My book said I could have easily made a function shorter with the same result, but says this, “However, when you consider working with a large program that needs to store many first and last names separately, functions like get_formatted_name() become very useful. You store first and last names separately and then call this function whenever you want to display a full name”, after it showed this code:

    """Return a full name, neatly formatted."""
    full_name = f"{first_name} {last_name}"
    return full_name.title()

musician = get_formatted_name('jimi', 'hendrix')
print(musician)

I can get the same result without using return and not using any variables for the function, but it seems like using return is good for if I want to have different variables for the same function in a program (musician, painter, etc.).

For the one in the first example with the while loop, I can’t just using the function.

Can someone explain all this to a beginner programmer? People have helped me understand what goes on with print before here when it comes to a while loop, and now printing is throwing me off again.

I don’t know if that’s your problem, but in the first code you wrote, you can’t call print because there is ) missing at the end.

Second, there is a difference between print and return. return is a Python instruction, it is part of the language. On the other hand print is a normal function, just like the get_formatted_name, just provided “for free” by the Python interpreter. You use it just like any other function.

Thanks for the reply.

I just didn’t paste the second parenthesis at the end by mistake (btw this is the book’s code).

Could you elaborate on this further or point me to the right direction?

I’ll try:

Things like “def”, “while”, “if”, “break” and “return” are the language instructions. Without them you wouldn’t be able to write and run anything, just like you wouldn’t be able to say anything meaningful in English without “a/an”, “the”, “to be” etc. They are like Lego bricks, you use them to build your program.

Functions are one of things you can construct with these bricks. They are a language construction that, among other things, let you organize a piece of code. Theoretically you could write programs that has no functions at all, and it would work. But one thing that is important in programming anywhere is that code that “just works” is not enough. It is also important to write a code you could understand and maintain in the future. At the beginning of your study they may look unnecessary and complicated, but believe me they are gold later.

PS: It seems that people you have mentioned in your post confused your mind a lot in this topic, which is reflected in how you wrote about the problem in your post (probably I’m no better in this regard, but I’m still learning! :wink: )
If I may suggest, try to write in 5-6 sentences what you want to be explained the most, because this is not clear from your post (however I have to praise you for using correct code formatting :smiley: - it is a thing a huge part of “newbies” seems not to “get it”)

1 Like

I definitely need to work on explaining my problem better! Thanks for pointing that out.

Thanks for trying to explain it to me. I’m still lost on it though. I get that return is instructing something to be done, but if return is not used, HOW does print show the same output? Does print show what the result would be if something WERE to actually be done to it? Does this mean return (or some other instruction) makes printing useless outside of something such as printing a list?

After the last code examples in the book, it has this one:

def print_models(unprinted_designs, completed_models):
    """
    Simulate printing each design, until none are left.
    Move each design to completed_models after printing.
    """
    while unprinted_designs:
        current_design = unprinted_designs.pop()
        print(f"Printing model: {current_design}")
        completed_models.append(current_design)

def show_completed_models(completed_models):
    """Show all the models that were printed."""
    print("\nThe following models have been printed:")
    for completed_model in completed_models:
        print(completed_model)

unprinted_designs = ['phone case', 'robot pendant', 'dodecahedron']
completed_models = []

print_models(unprinted_designs[:], completed_models)
show_completed_models(completed_models)

Why isn’t return or a different instruction used here (maybe it’s explained later on in the book)?

You are confusing printing text to a console with returning a value from a function.

You see, functions in Python are almost (that’s the key-word) like their mathematical collogues. They get something from outside, process it and return to the outside. The “outside” in question is the rest of your program.

print is, as I stated earlier, a normal function like any other function in Python. What is it different from a pure mathematical function is it has a side-effect, namely it prints what it gets to the console. In other words: it interacts with outside of your program (the operating system) and orders it it to print this-and-that.

Of course this print function, like any function in Python, must also return something to inside of your program. This “something” is None — a special value denoting…well…nothing. However like any value in Python it can be assigned to a variable. It is “no tea” you can have at tea party :wink:

So in short: print returns no value to your program but gives something to the OS.

That helps me a little bit. It’s a starting point for me to learn this. I’ve been studying the rest of your post. It’s still confusing to me though (again, I’m new to programming). I’m going to refer back to your post as I continue to research this (and continue to go along and learn from my book).

Thanks!

Before I offer my own explanation: If I put difference between print and return into a search engine, the first result I get is from Stack Overflow:

Which links to a more authoritative duplicate (full disclosure - I did quite a bit of editing work there, and also have an answer post there):

I also see several off-site explanations, such as:

Did you find any of these? Were they not helpful?

That’s the wrong way around, and slightly inaccurate. You assign the result of calling the function, to the variable. After which, the variable names the value that the function computed.

You certainly can “just call the function”. But to make the result show up in the f-string that you print on the next line, you should put the function call inside the {} of the f-string. Like so:

print(f"\nHello, {get_formatted_name(f_name, l_name)}!"

f-strings are magical. The compiler takes them apart ahead of time, and turns them into instructions to do whatever calculations are inside the {}, stringify the results for each of those and then put the string together from those pieces (the stringified calculations and the literal text in between them). When you just use a variable name inside {}, the calculation is simple: it just means “use the value named by this variable”. If you put a function call, it means to call the function and use the value that was returned. If you use some math, like f'{1 + 2}', it means to compute that and use the result. All of these are expressions. If you don’t recognize that term, you should go back in the book and check if it’s explained earlier.

The point of return is that it signals what the result is when calling the function.

The point of print is that it puts some text on the screen.

These two things have absolutely nothing to do with each other.

No, it is not. It is saying what the result is from doing the thing.

In the exact same way that it shows output when print is used: it prints what you tell it to print.

If you say print(foo()), it prints whatever foo() returns. If it reached a return while running foo, it returns the result calculated on that line. If it gets to the end, it returns None, and that’s what will get printed in the print(foo()).

If you say print(bar), it prints whatever bar is. It does not matter how bar got that value.

Because, inside the function, it is printing something that was just calculated and assigned to current_design; outside the function, it calls print_models but prints completed_models. The code show_completed_models(completed_models) does not care about print_models returning anything, because it doesn’t say print_models anywhere in it. But, when print_models was called, it changed the list that completed_models names, so now show_completed_models(completed_models) can print the updated list contents.

You ask, “Why isn’t return or a different instruction used here?” It isn’t always necessary for a function to have a return statement. What happens when you get to the return statement is that it goes back to where the function was originally called, and it passes any value returned back with it. If you don’t intend to pass back a value, you don’t need a return statement.

If you take this function as an example:

def useless():
    result = 2 + 2

When you call useless(), it adds 2 and 2, gets 4, and stores that in result, just like what is written. However, you can’t see the addition taking place, and result goes away when the function ends, so the function doesn’t have much use.

But, if you have a function that prints something:

def hello():
    print("Hello!")

When you call hello(), there’s still no value saved, but this time, you can see the result of what it does—calling print makes something appear on your terminal, so this one is more useful.

A function can also do something else that is visible outside of the function, without returning anything:

def double_them(some_list):
    for index, value in enumerate(some_list):
        some_list[index] = value * 2

my_list = [1, 2, 3, 4, 5]
print(f"The original list: {my_list}")
double_them(my_list)
print(f"Doubled: {my_list}")
double_them(my_list)
print(f"Again: {my_list}")

Output:

The original list: [1, 2, 3, 4, 5]
Doubled: [2, 4, 6, 8, 10]
Again: [4, 8, 12, 16, 20]

The list is changed, even though it isn’t assigned back to my_list. But, if you wanted to keep your original list, as well, you might think this function is a little rude—it just goes ahead and modifies what you gave it, so you would have to make a copy first.

Let’s take a function that does return something:

import math
def area_of_circle(radius):
    return math.pi * radius**2

whole_area = area_of_circle(5)
print(f"{whole_area:.2f}")

You mentioned before that this could be made shorter by replacing the return statement with a call to print. But, just like the last function, with the list that we might not want changed—what if we don’t want to print this result? What about this:

half_of_the_area = area_of_circle(5) / 2
print(f"Half of the area: {half_of_the_area:.2f} square meters")
third_of_the_area = area_of_circle(5) / 3
print(f"One third of the area: {third_of_the_area:.2f} square meters")

You wouldn’t want to need slightly different functions for all of these calculations, so you just have a function that does one thing, and then return a result so it can be used further elsewhere in the program.

To answer your other questions: “How does print show the same output?” Whatever is passed to print shows up on your terminal.
“Does this mean return makes printing useless?” No, because nothing would show up on your terminal until you use the print function.

1 Like