Python Defining Functions

In the last lesson you learned what functions are and why they matter in Introduction to Functions. You saw the idea of a function. Now you get to make one yourself.

๐Ÿค” Why Define Your Own Function?

Say you write three lines of code that print a welcome message. Then you need that same welcome in five different places in your program. So you copy those three lines five times. Now fifteen lines all say the same thing. Change the message once and you have to find and fix all five copies.

That copying is the pain. Defining a function is the cure. You write those lines once and give them a name. After that you can run them by name anytime you want.

So why bother with functions at all? A few plain reasons:

  • You avoid repeating the same code. Write it once, call it everywhere.
  • You give a piece of logic a name. calculate_total() reads like English, so the code explains itself.
  • You can test and fix it in one place. Find a bug? You fix the one function, and every caller gets the fix for free.

๐Ÿณ What โ€œDefiningโ€ Actually Means

Think of a recipe card. Writing the recipe down is one job. Actually cooking the dish is a different job. You can write a recipe and never cook it. You can also cook it ten times from the one card.

Defining a function is like writing the recipe card. You tell Python โ€œhere are the steps, remember them under this name.โ€ Python reads them and stores them. It does not run them yet. It just keeps them ready.

Running the function later is like cooking from the card. That part is called calling, and we will get to it in a moment.

๐Ÿ› ๏ธ The def Syntax, Part by Part

Here is the shape of every function definition in Python. This one takes a name and greets that person.

def greet(name):
print("Hello,", name)

Let us read def greet(name): piece by piece. Each part has a job:

  • def is the keyword that tells Python โ€œa function is starting here.โ€ It is short for define.
  • greet is the function name you pick. You use this name later to run the function. The rules are the same as variable names: lowercase, words joined with underscores.
  • () are the parentheses. Inside them you list the inputs the function expects. Here there is one input called name. Empty parentheses are fine too when the function needs no input.
  • name inside the parentheses is a parameter. It is a placeholder for a value you will hand in later.
  • : is the colon. It ends the first line and says โ€œthe body comes next.โ€
  • The indented line below is the body. These are the actual steps Python will run when the function is called.

The colon and the indentation are not decoration. Python uses the indentation to know which lines belong inside the function. Drop the colon or forget to indent, and Python stops with an error. This is the same colon-and-indent rule you already met with if statements and loops.

Note

The body must be indented, usually four spaces. Every line at that same indent is part of the function. The first line that goes back to the left margin is outside the function again.

๐Ÿƒ Defining Is Not Running

Here is the part that surprises people. If you only define a function, nothing prints. The function exists, but you never told Python to run it. Try this.

def greet(name):
print("Hello,", name)

Output

Nothing. Empty. No greeting. And that is correct.

You only wrote the recipe card. You never cooked from it. Python read the definition, remembered greet, and moved on. To actually run the body, you have to call the function. You do that by writing its name followed by parentheses, and passing in a value.

def greet(name):
print("Hello,", name)
greet("Riya")

Output

Hello, Riya

That last line, greet("Riya"), is the call. The name says which function to run. The parentheses say โ€œrun it now.โ€ And "Riya" is the value you hand in. So defining writes the steps, and calling runs them.

Tip

A quick way to remember it: def greet makes the function exist. greet("Riya") makes the function happen.

๐ŸŽ Parameters vs Arguments

These two words get mixed up a lot, so let us pin them down. They sound similar but they point at different things.

  • A parameter is the name in the definition. It is the placeholder. In def greet(name):, the parameter is name.
  • An argument is the real value you pass when you call. In greet("Riya"), the argument is "Riya".

So the parameter is the empty box, and the argument is what you put in the box. Same function, different arguments each time you call it.

def greet(name):
print("Hello,", name)
greet("Riya")
greet("Arjun")
greet("Alex")

Output

Hello, Riya
Hello, Arjun
Hello, Alex

See how name stayed the same in the definition, but the argument changed on each call? That one parameter let the same function greet three different people. That is the whole power of passing values in.

โ†ฉ๏ธ return vs print

Now a really important pair. print and return look like they do the same thing, but they do not. This trips up almost everyone at first, so go slow here.

  • print just shows text on the screen. It is for the human looking at the output.
  • return hands a value back to the code that called the function, so the rest of your program can use it.

Let us see a function that only prints. It shows the result, but it does not give it back.

def add_print(a, b):
print(a + b)
result = add_print(2, 3)
print("result holds:", result)

Output

5
result holds: None

Walk through what happened. add_print(2, 3) printed 5 on its own. But it never returned anything. So when you wrote result = add_print(2, 3), there was no value to store. Python put None in result. None is Pythonโ€™s word for โ€œnothing here.โ€ That is why the last line says result holds: None.

Now the same idea, but with return instead.

def add_return(a, b):
return a + b
result = add_return(2, 3)
print("result holds:", result)

Output

result holds: 5

This time add_return did not print anything by itself. It handed 5 back to the caller. So result actually holds 5, and now you can use it. You can add to it, save it, or pass it into another function.

So here is the rule of thumb:

  • Use print when you just want to show something to a person.
  • Use return when the value needs to keep living in your program after the function ends.

Caution

A function with no return gives back None. So if you do x = my_function() and x is None, the usual cause is that the function printed the value instead of returning it.

๐Ÿ“„ Documenting With a Docstring

When you write a function, it helps to leave a short note saying what it does. Python has a built-in spot for that. A docstring is a triple-quoted string written on the first line inside the function.

Here is a function with a docstring sitting right under the def line.

def area_of_circle(radius):
"""Return the area of a circle for the given radius."""
return 3.14159 * radius * radius
print(area_of_circle(5))
help(area_of_circle)

Output

78.53975
Help on function area_of_circle in module __main__:
area_of_circle(radius)
Return the area of a circle for the given radius.

The line """Return the area...""" is the docstring. It does not change what the function does. It is just a note for humans. But Python keeps it, so when someone runs help(area_of_circle), they see exactly what the function is for. Editors and tools read it too. So a one-line docstring is a small habit that pays off later.

๐Ÿงฎ A Function That Calculates and Returns

Let us build something real. A shop wants the final price after a discount. We give it the price and the discount percent, and it hands back the amount to pay.

def final_price(price, discount_percent):
"""Return the price after applying a percentage discount."""
discount = price * discount_percent / 100
return price - discount
to_pay = final_price(1000, 20)
print("Pay:", to_pay)

Output

Pay: 800.0

Read it from the top. final_price takes two parameters, price and discount_percent. Inside, it works out the discount amount, then subtracts it from the price. The return hands the final number back. So to_pay holds 800.0, and you can print it, save it, or run it through more code. Because it returns the value, this function fits into a bigger program. It does not just shout the answer at the screen and forget it.

โœ‰๏ธ A Function That Formats a Message

Functions are great for building text too. Here is one that takes a name and an order number, and returns a tidy confirmation line.

def order_message(name, order_id):
"""Return a friendly order confirmation message."""
return "Hi " + name + ", your order #" + str(order_id) + " is confirmed."
print(order_message("Riya", 1042))

Output

Hi Riya, your order #1042 is confirmed.

This function glues the pieces into one sentence and returns it. We used str(order_id) because order_id is a number, and you cannot join a number to text directly. Notice it returns the message instead of printing it. So the caller decides what to do with it. You might print it, send it in an email, or show it on a web page. The function just builds the text. That flexibility is exactly why returning beats printing for most real work.

๐Ÿ” Calling Again and Again Is the Whole Point

Once a function is defined, you can call it as many times as you like. Each call runs the body again, fresh, with whatever arguments you pass.

def greet(name):
print("Hello,", name)
greet("Riya")
greet("Arjun")
greet("Alex")

Output

Hello, Riya
Hello, Arjun
Hello, Alex

One definition, three calls, three greetings. See how you wrote the logic just once? If you ever want to change the wording, you edit the single line inside greet. Every call picks up the new version on its own. No hunting through copies.

๐Ÿท๏ธ Naming Your Functions Well

A function name is the first thing a reader sees, so make it earn its place. A few simple habits:

  • Use lowercase letters with underscores between words, like final_price or order_message. This is the standard Python style.
  • Start with a verb when the function does an action, like greet, calculate_tax, or save_file. The verb tells the reader what happens.
  • Say what it does, not how. area_of_circle is clear. func1 tells you nothing.

So a good name reads almost like a sentence at the call site. total = calculate_tax(price) explains itself. You barely need a comment.

๐Ÿ“‹ Defining vs Calling at a Glance

This small table sums up the two jobs you just learned.

Action What you write What Python does
Define def greet(name): then an indented body Remembers the steps under the name. Runs nothing yet.
Call greet("Riya") Runs the body now, with the argument you pass.

โš ๏ธ Common Mistakes

A few small slips trip up almost everyone when they start writing functions.

Forgetting the colon at the end of the def line. Python expects it and stops without it.

# โŒ Avoid: no colon after the parentheses
def greet(name)
print("Hi", name)
# โœ… Good: colon ends the def line
def greet(name):
print("Hi", name)

Not indenting the body. Python cannot tell which lines belong to the function.

# โŒ Avoid: body is not indented
def greet(name):
print("Hi", name)
# โœ… Good: body is indented under def
def greet(name):
print("Hi", name)

Defining a function but never calling it, then wondering why nothing happens. The definition alone prints nothing. You have to call it.

# โŒ Avoid: defined but never called, so nothing runs
def greet(name):
print("Hi", name)
# โœ… Good: define, then call to actually run it
def greet(name):
print("Hi", name)
greet("Riya")

Expecting a printed value to come back. If a function only prints, it returns None. So storing it gives you nothing useful.

# โŒ Avoid: this prints but returns None, so total is None
def add(a, b):
print(a + b)
total = add(2, 3) # total is None
# โœ… Good: return the value so total actually holds it
def add(a, b):
return a + b
total = add(2, 3) # total is 5

Trying to call the function before it is defined. Python reads top to bottom, so the def has to come first.

# โŒ Avoid: calling before the function exists
greet("Riya")
def greet(name):
print("Hi", name)
# โœ… Good: define first, then call
def greet(name):
print("Hi", name)
greet("Riya")

โœ… Best Practices

A handful of small habits keep your functions clean and easy to read.

  • Pick a name that says what the function does. show_menu tells you far more than func1.
  • Use a verb in the name when the function performs an action, like greet, print_total, or save_file.
  • Add a short docstring under the def line so the next person knows what the function is for.
  • Return a value when the caller needs it, and only print when you truly just want to show something.
  • Keep the body focused on one job. A function that does one clear thing is easier to reuse and fix.
  • Stick to four spaces for the body indent and stay consistent through the whole file.

๐Ÿงฉ What Youโ€™ve Learned

A quick recap of what you can now do.

  • โœ… You can define a function with def, a name, () with parameters, a :, and an indented body.
  • โœ… You know defining only stores the steps. It does not run them until you call.
  • โœ… You can tell a parameter (the placeholder in the definition) from an argument (the real value you pass).
  • โœ… You know print shows text, while return hands a value back to the caller, and a function with no return gives None.
  • โœ… You can add a docstring and read it later with help().
  • โœ… You can name functions clearly and spot the common slips: missing colon, missing indent, expecting a printed value to be returned, and calling before defining.

Check Your Knowledge

Test what you learned. Pick an answer for each question, then click Check.

  1. 1

    What does the def keyword do?

    Why: def begins a function definition, telling Python to remember the steps under the name you give.

  2. 2

    In def greet(name): ... and the call greet("Riya"), which is the argument?

    Why: name is the parameter (the placeholder in the definition). "Riya" is the argument, the real value passed when you call.

  3. 3

    A function only uses print and never return. You write x = the_function(). What does x hold?

    Why: print shows text but does not hand a value back. With no return, the function gives None, so x is None.

  4. 4

    Which line is required right after the function name and parentheses?

    Why: The def line must end with a colon, which tells Python the indented body comes next.

๐Ÿš€ Whatโ€™s Next?

Right now you pass one or two values into a function. Next you will learn more ways to pass information in, including default values and naming your arguments when you call.

Function Arguments

Share & Connect