Functions in Python

Functions are one of the fundamental building blocks in Python programming. They are used when you have a block of statements that needs to be executed multiple times within the program. Instead of writing the block of statements repeatedly, you can encapsulate this block within a function, which you can then call from other parts of the program. By defining a function, you write the code once but can execute it any number of times. Functions also help reduce the size of the program by eliminating redundant code. Functions can be categorized into two main types: built-in functions and user-defined functions.

Built-In Functions in Python

Python comes with a comprehensive set of built-in functions that are readily available without the need for any imports. These functions are implemented in C for efficiency and are part of the Python Standard Library. Here's a detailed look at some of the key built-in functions:

  • abs()

    • Syntax: abs(x)
    • Description: Returns the absolute value of a number. The absolute value is the distance of a number from zero, without regard to direction. It works with both integers and floating-point numbers.
    • Example:
      print(abs(-5))   # Outputs: 5
      print(abs(3.14)) # Outputs: 3.14
  • min()

    • Syntax: min(arg_1, arg_2, ..., arg_n)
    • Description: Returns the smallest of two or more arguments. It can take multiple arguments or an iterable (like a list) and returns the minimum value among them.
    • Example:
      print(min(3, 5, 2, 8))          # Outputs: 2
      print(min([10, 20, 30]))        # Outputs: 10
  • max()

    • Syntax: max(arg_1, arg_2, ..., arg_n)
    • Description: Returns the largest of two or more arguments. It can take multiple arguments or an iterable (like a list) and returns the maximum value among them.
    • Example:
      print(max(3, 5, 2, 8))          # Outputs: 8
      print(max([10, 20, 30]))        # Outputs: 30
  • divmod()

    • Syntax: divmod(a, b)
    • Description: Takes two numbers and returns a pair of numbers: the quotient and the remainder when dividing a by b. If a and b are integers, the result is (a // b, a % b). If either a or b is a floating-point number, the result is (q, a % b), where q is the quotient as a whole number.
    • Example:
      print(divmod(7, 3))       # Outputs: (2, 1)
      print(divmod(7.5, 3))     # Outputs: (2.0, 1.5)
  • pow()

    • Syntax: pow(x, y[, z])
    • Description: Returns x raised to the power of y, which is equivalent to x ** y. It also supports an optional third argument z for modular exponentiation: pow(x, y, z) returns (x ** y) % z.
    • Example:
      print(pow(2, 3))       # Outputs: 8
      print(pow(2, 3, 5))    # Outputs: 3 (since (2 ** 3) % 5 = 8 % 5 = 3)
  • len()

    • Syntax: len(object)
    • Description: Returns the number of items in an object. This can be a string, list, tuple, dictionary, or other iterable types.
    • Example:
      print(len("hello"))      # Outputs: 5
      print(len([1, 2, 3]))    # Outputs: 3
  • print()

    • Syntax: print(*objects, sep=' ', end='\n', file=sys.stdout, flush=False)
    • Description: Outputs data to the standard output (typically the console). It can handle multiple arguments and supports formatting options such as sep (separator between items) and end (string appended after the last value).
    • Example:
      print("Hello, Students!")   # Outputs: Hello, Students!
      print("Hello", "Students", sep=", ") # Outputs: Hello, Students
  • type()

    • Syntax: type(object)
    • Description: Returns the type of an object. Useful for debugging and verifying the data type of a variable.
    • Example:
      print(type(42))         # Outputs: <class 'int'>
      print(type("hello"))    # Outputs: <class 'str'>
  • int(), float(), str()

    • Syntax: int(x), float(x), str(x)
    • Description: Convert values to integer, floating-point, and string types, respectively.
    • Examples:
      print(int("123"))       # Outputs: 123
      print(float("3.14"))    # Outputs: 3.14
      print(str(42))          # Outputs: '42'
  • sum()

    • Syntax: sum(iterable, /, start=0)
    • Description: Returns the sum of all items in an iterable (e.g., a list of numbers). An optional start value can be provided to add to the sum.
    • Example:
      print(sum([1, 2, 3, 4]))       # Outputs: 10
      print(sum([1, 2, 3], start=10)) # Outputs: 16

Commonly Used Modules

Python modules are files containing Python code, which can define functions, classes, and variables. The standard library comes with many modules that provide a wide range of functionalities. Here are some commonly used modules:

  1. math: Provides mathematical functions and constants. Useful for scientific calculations.

    import math
     
    print(math.ceil(5.4))     # Outputs: 6
    print(math.sqrt(4))       # Outputs: 2.0
    print(math.pi)            # Outputs: 3.141592653589793
    print(math.cos(1))        # Outputs: 0.5403023058681398
    print(math.factorial(6))  # Outputs: 720
    print(math.pow(2, 3))     # Outputs: 8.0
    • math.ceil(x): Returns the ceiling of x, which is the smallest integer greater than or equal to x.
    • math.sqrt(x): Returns the square root of x.
    • math.pi: Represents the mathematical constant π (pi), approximately equal to 3.141592653589793.
    • math.cos(x): Returns the cosine of x radians.
    • math.factorial(x): Returns the factorial of x, which is the product of all positive integers less than or equal to x.
    • math.pow(x, y): Returns x raised to the power of y.
  2. datetime: Handles dates and times. It includes classes like date, time, datetime, and timedelta.

    from datetime import datetime
    now = datetime.now()
    print(now)  # Outputs: current date and time

    Output:

    2024-08-15 09:06:42.467780
  3. random: The random module generates random numbers and performs random selections. To use its functions, you first need to import the module.

    import random
    print(random.random())        # Outputs: a random floating-point number between 0 and 1
    print(random.randint(1, 10))  # Outputs: a random integer between 1 and 10

    Output:

    0.8847834558592387
    6
  4. os: Provides a way to interact with the operating system, including file operations and environment variables.

    import os
    print(os.getcwd())  # Outputs: current working directory
  5. sys: Provides access to system-specific parameters and functions, including command-line arguments and Python’s path.

    import sys
    print(sys.argv)  # Outputs: list of command-line arguments

The built-in function dir() returns a sorted list of strings containing the names of functions, classes, and variables as defined in the module or object. For example, you can find all the functions and attributes supported by the math module by passing the module name as an argument to the dir() function.

Example Usage of dir():

import math
print(dir(math))

Output:

['__doc__', '__loader__', '__name__', '__package__', '__spec__', 'acos', 'acosh', 'asin',
'asinh', 'atan', 'atan2', 'atanh', 'ceil', 'copysign', 'cos', 'cosh', 'degrees', 'e', 'erf',
'erfc', 'exp', 'expm1', 'fabs', 'factorial', 'floor', 'fmod', 'frexp', 'fsum', 'gamma',
'gcd', 'hypot', 'inf', 'isclose', 'isfinite', 'isinf', 'isnan', 'ldexp', 'lgamma', 'log',
'log10', 'log1p', 'log2', 'modf', 'nan', 'pi', 'pow', 'radians', 'sin', 'sinh', 'sqrt',
'tan', 'tanh', 'tau', 'trunc']

This output lists various functions and constants available in the math module.

Another built-in function you may find useful is help(), which invokes the built-in help system. The argument to the help() function can be a module, function, class, method, keyword, or documentation topic, and it prints a related help page to the console.

Example Usage of help():

import math
help(math.gcd)

Output:

Help on built-in function gcd in module math:

gcd(*integers)
    Greatest Common Divisor.

This output provides information about the gcd() function in the math module, explaining that it computes the greatest common divisor of two numbers.

Installing and Using Third-Party Libraries

Third-party modules or libraries can be installed and managed using Python’s package manager pip.

Installing a Module:

pip install arrow
  • Explanation: The pip install arrow command installs the arrow library, which provides a user-friendly approach to handling dates and times.

Example Usage of arrow Library:

import arrow
 
a = arrow.utcnow()
print(a)  # Outputs: current date and time in UTC

Output:

2024-08-15T09:30:15.817038+00:00
  • Explanation:
    • arrow.utcnow() returns the current date and time in UTC.
    • The now() method provides the current date and time, including the timezone offset.

Function Definition and Calling Syntax

You can create your own functions and use them wherever needed. User-defined functions are reusable code blocks created by users to perform specific tasks in a program.

Function Definition Syntax

In Python, a function definition consists of the def keyword followed by:

  1. Function Name: The name of the function. The function’s name must follow the same naming rules as variables: it can include letters, numbers, or underscores, but it cannot start with a number. Also, a keyword cannot be used as a function name.

  2. Parameters: A list of parameters enclosed in parentheses and separated by commas. Some functions do not have any parameters at all, while others may have one or more parameters.

    def function_name(parameter_1, parameter_2, ..., parameter_n):
        statement(s)
  3. Colon: A colon is required at the end of the function header. The first line of the function definition, which includes the name of the function, is called the function header.

  4. Function Body: The block of statements that define the body of the function starts on the next line of the function header and must have the same indentation level.

The def keyword introduces a function definition. The term "parameter" or "formal parameter" refers to the variables found in the function definition. Defining a function does not execute it; it simply names the function and specifies what to do when it is called. Calling the function actually performs the specified actions with the provided parameters.

Function Call Syntax

The syntax for calling a function is:

function_name(argument_1, argument_2, ..., argument_n)

Arguments are the actual values passed into the function. There must be a one-to-one correspondence between the formal parameters in the function definition and the actual arguments of the calling function. When a function is called, the formal parameters are temporarily "bound" to the arguments, and their initial values are assigned.

A function should be defined before it is called. The block of statements in the function definition is executed only when the function is called. Normally, statements in a Python program are executed sequentially. Function definitions do not alter the flow of execution of the program. When you call a function, control passes from the calling function to the function definition. After the block of statements in the function definition is executed, control returns to the calling function and proceeds with the next statement. The Python interpreter keeps track of the flow of control between different statements in the program.

Documentation Strings (Docstrings)

The first statement within the function body can optionally be a documentation string, or docstring. Docstrings are used to produce documentation automatically. They are enclosed in triple quotes. For example:

""" This is a single-line docstring """

or

""" This is
    a multiline
    docstring """

When control returns to the calling function from the function definition, the formal parameters and other variables in the function definition no longer contain any values.

Special __name__ Variable

Before executing the code in the source program, the Python interpreter automatically defines a few special variables. If the Python interpreter is running the source program as a stand-alone main program, it sets the special built-in __name__ variable to "__main__". After setting up these special variables, the interpreter reads the program to execute the code found at indentation level 0. The block of statements in the function definition is not executed unless the function is called.

if __name__ == "__main__":
    statement(s)

The special variable __name__ with the value "__main__" is the entry point of your program. When the Python interpreter reads the if statement and sees that __name__ equals "__main__", it will execute the block of statements present there.

Example Program

def function_definition_with_no_argument():
    print("This is a function definition with No Argument")
 
def function_definition_with_one_argument(message):
    print(f"This is a function definition with {message}")
 
def main():
    function_definition_with_no_argument()
    function_definition_with_one_argument("One Argument")
 
if __name__ == "__main__":
    main()

Output:

This is a function definition with No Argument
This is a function definition with One Argument

When coding Python programs, it is best practice to place all relevant calling functions inside the main() function definition. Since the above program is a stand-alone main source program, the Python interpreter assigns the string value "__main__" to the built-in special variable __name__, which is checked for equality using the if condition. If the condition is True, the interpreter calls the main() function. In the main() function definition, there are two function calls. You can have any number of function definitions and their calls in your program. When the function at line 8 is called without any arguments, control flows to the function definition at line 1 and displays the statement at line 2. After executing the function definition at line 1, control returns to the main() function and starts executing the next statement. Next, the function call at line 9 with one argument is executed. Control moves to the function definition at line 4, assigns the string value to the message parameter, and displays the passed string value at line 5.

The return Statement and Void Functions

In Python, functions can return values using the return statement, or they can be "void" functions that do not return any value. Understanding how to use return and the concept of void functions is essential for creating effective Python programs.

The return Statement

The return statement is used to exit a function and optionally pass an expression back to the caller. When a function is called, it executes the statements in its body until it encounters a return statement or reaches the end of the function. The value specified by return is sent back to the caller and can be used in further computations or operations.

Syntax:

def function_name(parameters):
    # function body
    return expression
  • Expression: This is the value or result that you want to return to the caller. It can be any valid Python expression, including variables, literals, or computations.

If no return statement is present, or if a return statement does not include an expression, the function returns None by default.

Example of Function with Return Value:

def add_numbers(a, b):
    result = a + b
    return result
 
def main():
    sum_value = add_numbers(5, 3)
    print(f"The sum is {sum_value}")
 
if __name__ == "__main__":
    main()

Output:

The sum is 8

In this example, add_numbers is a function that takes two parameters, computes their sum, and returns the result. In the main function, this result is captured in the variable sum_value and then printed.

Void Functions

A "void" function is a function that performs an operation but does not return a value. Such functions are often used for their side effects, like modifying a global variable, printing to the console, or changing the state of an object.

Syntax for Void Functions:

def function_name(parameters):
    # function body
    # no return statement

Example of Void Function:

def print_message(message):
    print(message)
 
def main():
    print_message("Hello, Students!")
 
if __name__ == "__main__":
    main()

Output:

Hello, Students!

In this example, print_message is a void function that prints the provided message to the console. It does not return any value.

Scope of Variables

The scope of a variable refers to the region of the program where the variable is accessible. In Python, the scope of variables is divided into several categories:

  1. Local Scope: Variables defined inside a function are local to that function. They are only accessible within that function and are not visible outside of it.

    def local_scope_example():
        local_variable = "I am local"
        print(local_variable)  # Accessible here
     
    local_scope_example()
    # print(local_variable)  # Error: local_variable is not accessible here

    Output:

    I am local

    Note: The second print statement will raise a NameError because local_variable is not defined in the global scope.

  2. Global Scope: Variables defined outside of all functions are global variables. They can be accessed from any function within the same module.

    global_variable = "I am global"
     
    def global_scope_example():
        print(global_variable)  # Accessible here
     
    global_scope_example()
    print(global_variable)  # Accessible here as well

    Output:

    I am global
    I am global
  3. Enclosing Scope: When dealing with nested functions, variables in the outer function’s scope are accessible to the inner function. This is also known as the nonlocal scope.

    def outer_function():
        enclosing_variable = "I am enclosing"
     
        def inner_function():
            print(enclosing_variable)  # Accessible here
     
        inner_function()
     
    outer_function()

    Output:

    I am enclosing
  4. Built-in Scope: This is the scope of built-in names like print(), len(), etc. These are available everywhere in your code.

    print(len("Hello"))  # Built-in functions and types are always accessible

    Output:

    5

Variable Lifetime

The lifetime of a variable is the duration for which the variable exists in memory. In Python:

  • Local Variables: Their lifetime begins when the function is called and ends when the function exits. They are created when the function starts and destroyed when the function terminates.

  • Global Variables: Their lifetime lasts as long as the program is running. They are created when the program starts and destroyed when the program terminates.

  • Enclosing Variables: Their lifetime lasts as long as the enclosing function is executing. Once the outer function exits, the enclosing variables are no longer accessible.

Default Parameters

Default parameters allow you to specify default values for function parameters. This means that if a caller does not provide a value for that parameter, the default value will be used.

Syntax:

def function_name(parameter1=default_value1, parameter2=default_value2):
    # function body

Example of Default Parameters:

def greet(name="Student"):
    print(f"Hello, {name}!")
 
greet()           # Uses default value
greet("Eniv")    # Uses provided value

Output:

Hello, Student!
Hello, Eniv!

In this example, greet has a default parameter name with the default value "Student". If no argument is passed, "Student" is used; otherwise, the provided argument is used.

Important Points:

  1. Order Matters: Parameters with default values must be placed after parameters without default values. This is because Python matches arguments to parameters in order.

    def example(a, b=2, c=3):
        print(a, b, c)
     
    example(1)         # Outputs: 1 2 3
    example(1, 4)      # Outputs: 1 4 3
    example(1, 4, 5)   # Outputs: 1 4 5
  2. Mutable Default Values: Be cautious with mutable default values like lists or dictionaries. If you use a mutable default value and modify it, the change will persist across function calls.

    def append_to_list(value, list=[]):
        list.append(value)
        return list
     
    print(append_to_list(1))  # Outputs: [1]
    print(append_to_list(2))  # Outputs: [1, 2]  # Default list persists

    To avoid this issue, use None as a default value and initialize the mutable object inside the function.

    def append_to_list(value, list=None):
        if list is None:
            list = []
        list.append(value)
        return list
     
    print(append_to_list(1))  # Outputs: [1]
    print(append_to_list(2))  # Outputs: [2]
How's article quality?

Last updated on -

Page Contents