> For the complete documentation index, see [llms.txt](https://dshub.gitbook.io/ds-hub/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://dshub.gitbook.io/ds-hub/python/basics/functions.md).

# Functions

Functions in Python are blocks of reusable code that perform specific tasks. They allow you to break down your program into smaller, more manageable pieces, making your code more organized, modular, and easier to maintain. Functions are a fundamental concept in Python and are used extensively in Python programming. Here's how functions work in Python:

1. **Defining a Function:** To create a function, you use the `def` keyword, followed by the function name, a pair of parentheses `()`, and a colon `:` to indicate the beginning of the function block. The function block is indented to define the scope of the function.

   ```python
   def greet(name):   # <-Function Header
       # Function Documentation, i.e. Docstring
       """This function greets the person passed in as a parameter.""" 
       print(f"Hello, {name}!")   # <-Function Body
   ```

   In the above example, we've defined a function called `greet` that takes one parameter `name`.
2. **Calling a Function:** To execute a function and perform the tasks defined inside it, you call the function by its name, passing any required arguments within the parentheses.

   ```python
   greet("Alice")
   ```

   This call to the `greet` function with the argument `"Alice"` will print "Hello, Alice!" to the console.
3. **Function Parameters:** Functions can accept zero or more parameters (also known as arguments) that are used to pass data into the function. Parameters are defined within the parentheses when defining the function.

   ```python
   def add_numbers(a, b): 
       """This function adds two numbers and returns the result."""
       result = a + b 
       return result
   ```

   In this example, the `add_numbers` function takes two parameters, `a` and `b`, and returns their sum.
4. **Function Return Values:** Functions can return values using the `return` statement. The value returned by the function can be assigned to a variable or used directly.

   ```python
   result = add_numbers(5, 3)
   ```

   The `add_numbers` function returns `8`, which is then assigned to the variable `result`.
5. **Docstrings:** It's a good practice to include a docstring **(a triple-quoted string)** at the beginning of your function to provide documentation and describe the purpose of the function and its parameters.

   ```python
   def multiply(a, b): 
   """This function multiplies two numbers and returns the result."""
       result = a * b 
       return result
   ```

   Docstrings are used to generate documentation using tools like Python's `help()` function.
6. **Scope:** Variables defined inside a function have **local scope**, meaning they are only accessible within that function. Variables defined outside functions have **global scope** and can be accessed from anywhere in the code.
7. **Default Arguments:** You can specify default values for function parameters, allowing you to call the function with fewer arguments if needed.

   ```python
   def power(base, exponent=2): 
       """This function calculates the power of a number."""
       result = base ** exponent 
       return result
   ```

   In this example, the `exponent` parameter has a default value of `2`, so you can call `power(3)` to calculate 3^2, or `power(3, 4)` to calculate 3^4.
8. **Arbitrary Argument Lists:** You can use `*args` and `**kwargs` to pass a variable number of non-keyword and keyword arguments, respectively, to a function.

   ```python
   def print_args(*args, **kwargs): 
       """This function prints the arguments passed to it."""
       print("Positional arguments:", args)
       print("Keyword arguments:", kwargs)
   ```

   `*args` allows you to pass a variable number of positional arguments, and `**kwargs` allows you to pass a variable number of keyword arguments.

Functions are a fundamental building block in Python programming and are essential for structuring your code, making it more readable, modular, and maintainable. They allow you to encapsulate logic, promote code reusability, and simplify complex tasks. Understanding how to define, call, and work with functions is a key skill for Python developers.
