All about python functions !
Tags: python, beginners, tutorial, learning
Published: 2023-07-03 05:00:00

## Python Functions: An Introduction for Beginners

Functions are an essential concept in Python programming that helps make your code more organized, reusable, and easier to understand. In this article, we will explore the fundamentals of Python functions, including their syntax, arguments, scope, and more. We will also introduce you to some useful concepts like first-class members, higher-order functions, and built-in functions such as `map`, `lambda`, and `filter`. Let's dive in and learn about Python functions step by step!

## What are Functions?

In simple terms, functions are like mini-programs within your code that perform specific tasks. They allow you to bundle a set of instructions together and give it a name, making it easier to reuse that code whenever you need it. Functions take input values, perform operations on them, and may return a result.

## Syntax of Python Function

To define a function in Python, you need to follow a specific syntax:

```python
def function_name(arguments):
    # Code block
    # Perform actions
    # Return a value (optional)
```

Let's break down the different parts of this syntax:

- `def`: This keyword signifies the start of a function definition.
- `function_name`: Choose a meaningful name for your function that reflects its purpose. It should be written in lowercase letters with underscores for multi-word names.
- `arguments`: These are the values you can pass to a function to perform specific operations.
- `:`: A colon marks the end of the function declaration and the start of the code block.
- Code block: This indented section contains the actual instructions and actions performed by the function.
- `return` (optional): If you want your function to provide a result, you can use the `return` keyword followed by the desired value. If you omit the `return` statement, the function will return `None` by default.

## Doc string
To provide a documentation string (docstring) for a function in Python, you can include a multiline comment immediately after the function declaration. The docstring serves as a description of the function's purpose, arguments, and expected behavior. Here's an example:

```python
def greet(name):
    """
    Greets a person by printing a welcome message.
    
    Parameters:
    name (str): The name of the person to greet.
    """
    print(f"Hello, {name}!")

greet("Alice")
```

In the above example, the docstring is enclosed within triple quotes (`"""`) i.e, multiline string. It provides a clear explanation of the purpose of the `greet` function and describes its parameter:

- `name (str)`: The name of the person to greet.

Including docstrings in your functions is good practice as it helps other developers understand how to use your function correctly and encourages the use of self-documenting code. You can access the docstring of a function using the `__doc__` attribute, like so:

```python
print(greet.__doc__)
```

Output:
```
Greets a person by printing a welcome message.
    
Parameters:
name (str): The name of the person to greet.
```
## TIP
- If you have came this far this means you really want to learn about functions so here is a tip, I believe visualising makes programming very easy and fun !

![pythontutor](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/2wvr59bvk53gja3ft2ki.png)



- so while you learn about functions use [python tutor](https://dev.to/coderatul/debug-and-visualize-your-python-code-with-pythontutorcom-29ba) website, it helps us to visualise flow of execution 

## Arguments of Python Function

### Positional Arguments

Positional arguments are the most basic type of arguments in Python functions. They are defined in a specific order in the function's declaration and correspond to the order in which you provide values when calling the function. Here's an example:

```python
def greet(name, age):
    print(f"Hello, {name}! You are {age} years old.")

greet("Alice", 25)  # Output: Hello, Alice! You are 25 years old.
```

### Default Arguments

Python allows you to assign default values to function arguments. These default values are used when you don't provide a value for the corresponding argument during the function call. This feature provides flexibility and convenience. Here's an example:

```python
def greet(name, age=30):
    print(f"Hello, {name}! You are {age} years old.")

greet("Bob")  # Output: Hello, Bob! You are 30 years old.
```

### Keyword Arguments

Keyword arguments allow you to specify values for selected arguments by using their corresponding parameter names. This way, you can skip some arguments or change their order while calling the function. Keyword arguments provide greater flexibility, especially when a function has many parameters. Here's an example:

```python
def greet(name, age):
    print(f"Hello, {name}! You are {age} years old.")

greet(age=35, name="Charlie")  # Output: Hello, Charlie! You are 35 years old.
```

### *args and **kwargs

In some cases, you may not know the exact number of arguments you want to pass to a function. Python offers two special syntaxes to handle such situations:

- `*args` represents positional arguments as a tuple, allowing you to pass a variable number of arguments.
- `**

kwargs` stands for keyword arguments as a dictionary, enabling you to pass a variable number of keyword arguments.

These features provide flexibility when you want to work with an unknown number of inputs. Here's an example:

```python
def multiply(*args):
    result = 1
    for num in args:
        result *= num
    return result

print(multiply(2, 3, 4))  # Output: 24

def greet(**kwargs):
    for key, value in kwargs.items():
        print(f"{key}: {value}")

greet(name="Alice", age=25)  # Output: name: Alice, age: 25
```

## First-Class Members and Higher-Order Functions

In Python, functions are considered first-class members, which means they can be treated just like any other data type. This property allows you to assign functions to variables, pass them as arguments to other functions, and even return them from other functions. Functions that operate on other functions are known as higher-order functions. This capability empowers you to write more modular and flexible code. Here's a simple example:

```python
def greet():
    print("Hello!")

def run_function(func):
    func()

run_function(greet)  # Output: Hello!
```

## Local and Global Scope of Function

In Python, each function has its own local scope, which means variables defined within the function are only accessible inside that function. However, if a variable is defined outside any function, it has global scope and can be accessed from any function within the module.

Here's an example that demonstrates local and global scope:

```python
x = 10  # Global variable

def print_number():
    y = 5  # Local variable
    print(x + y)

print_number()  # Output: 15
```

In the above example, `x` is a global variable accessible within the `print_number` function, while `y` is a local variable accessible only within the function.

### Global Keyword

Python provides the `global` keyword to explicitly specify that a variable inside a function should be treated as a global variable. This allows you to modify the value of a global variable from within a function. Here's an example:

```python
x = 10  # Global variable

def modify_global():
    global x  # Declare x as a global variable
    x += 5

modify_global()
print(x)  # Output: 15
```

By using the `global` keyword, the `modify_global` function is able to access and modify the value of the global variable `x`.
## Lifetime of a Function

The lifetime of a function starts when it is defined and ends when it is no longer referenced or when the program terminates. Functions can be called multiple times during their lifetime, allowing you to reuse the code within them.

## Bonus: map, lambda, and filter Functions

Python provides several built-in higher-order functions that can simplify your code. Let's briefly introduce three useful ones: `map`, `lambda`, and `filter`.

### map

The `map` function applies a given function to each element of an iterable and returns a new iterator containing the results. This function allows you to perform the same operation on multiple elements simultaneously. Here's an example using `map` to calculate the squares of a list of numbers:

```python
numbers = [1, 2, 3, 4, 5]

squared_numbers = map(lambda x: x ** 2, numbers)
print(list(squared_numbers))  # Output: [1, 4, 9, 16, 25]
```

### lambda

Lambda functions, also known as anonymous functions, are small, one-line functions without a name. They are typically used for simple operations and can be passed directly as arguments to higher-order functions. Here's an example:

```python
add = lambda x, y: x + y
print(add(2, 3))  # Output: 5
```

### filter

The `filter` function creates an iterator from elements of an iterable for which a provided function returns `True`. It effectively filters out elements that don't meet a specified condition. Here's an example filtering even numbers:

```python
numbers = [1, 2, 3, 4, 5]

even_numbers = filter(lambda x: x % 2 == 0, numbers)
print(list(even_numbers))  # Output: [2, 4]
```

## Conclusion

Python functions are a fundamental concept in

 programming and play a crucial role in structuring your code. By understanding their syntax, arguments, scope, and lifetime, you can make your code more modular, reusable, and efficient. Additionally, the concepts of first-class members, higher-order functions, and built-in functions like `map`, `lambda`, and `filter` can further enhance your code. Now that you have a good grasp of Python functions, go ahead and apply this knowledge to write clean and powerful code in your Python projects!

I hope you found this beginner-friendly guide to Python functions helpful. If you have any questions or suggestions, feel free to leave a comment below.