# Functions

Functions are a fundamental building block in Python programming, allowing you to organize code, promote reusability, and simplify complex tasks. It takes input arguments (optional) and returns a result (optional).

### Using function

* Functions are groups of code that have a name and can be called using parentheses.
    
* `print('abc').`Here, `print` is the function name, and `'abc'` is the function’s argu‐ ment.
    

### Defining and Calling Functions

* Function syntax: `def function_name(parameters)`
    
    ```python
    def greet(name):
        print("Hello, " + name + "!")
    
    greet("Nirmal")  # Output: Hello, Nirmal!
    greet("Retrica")    # Output: Hello, Retrica!
    ```
    

### Parameters and Return Values

* Parameters are placeholders for values passed to a function.
    
* Functions can have multiple parameters.
    
* Return statement: specifies the value a function should return.
    
    ```python
    def add(a, b):
        return a + b
    
    result = add(3, 5)
    print(result)  # Output: 8
    ```
    

### Recursive Functions

* A function can call itself, creating a recursive function.
    
* Useful for solving problems that can be broken down into smaller instances.
    
    ```python
    def factorial(n):
        if n == 0:
            return 1
        else:
            return n * factorial(n - 1)
    
    print(factorial(5))  # Output: 120
    ```
    

### Anonymous(lambda) Functions

* An anonymous function, also known as a `lambda function`, is a function in Python that is defined without a name.
    
* It is a compact way of creating small, one-line functions without the need for a formal function definition.
    
* Syntax is : `lambda arguments: expression`
    
    ```python
    '''Formal Function'''
    def add(x,y):
        return x + y
    print(add(2,3))# output = 5
    
    '''Lambda Function - 1'''
    add = lambda x,y:x+y
    print(add(2,3)) # output = 5
    
    '''Lambda Function - 2'''
    print((lambda x,y:x+y)(2,3))# output = 5
    ```
    

### \*args and \*\*kwargs

**\*args and \*\*kwargs** are useful when you do not know how many arguments will be passed to your function. They allow you to pass a variable number of arguments to a function.

**\*args**

* The `*args` syntax allows you to pass a variable number of non-keyword arguments to a function.
    
* It collects arguments into a tuple.
    
    ```python
    def add(*nums):
        total = 0
        for n in nums:
            total += n
        return total
    
    print(add(1, 2, 3))
    # output = 6
    ```
    

**\*\*kwargs**

* The `**kwargs` syntax allows you to pass a variable number of keyword arguments to a function.
    
* It collects arguments into a dictionary.
    
    ```python
    def userDetails(**user):
          for key,value in user.items():   
              print(f'{key} is a {value}')
    
    userDetails(name="Nirmal", age=23, country="Nepal")
    
    #Output:
    #name is a Nirmal
    #age is a 23
    #country is a Nepal
    ```
    

**Using both args and kwargs**

* ```python
    def combineArgs(arg1, arg2, *args, **kwargs):
        print(arg1)
        print(arg2)
        print(args)
        print(kwargs)
    
    combineArgs(1, 2, 3,4,5, key1='a', key2='b')
    ```
    

### Built-in Functions

* Some built-in functions are : `print()`, `len()`, `input()`, `range()`, `type()`, `int()`, `float()`, `str()`, `max()`, `min()`, `abs()`, `sum()`, and `round()`.
    
    ```python
    import math
    print(math.sqrt(16))  # Output: 4.0
    
    # Example 2: len()
    my_list = [1, 2, 3, 4, 5]
    print(len(my_list))# Output: 5
    
    # Example 3: input()
    name = input("Enter your name: ")
    print("Hello,", name)
    
    # Example 4: range()
    for num in range(5):
        print(num)
    # Output: 0 1 2 3 4
    
    # Example 5: type()
    x = 10
    print(type(x))# Output: <class 'int'>
    
    # Example 6: int(), float(), str()
    num1 = "10"
    num2 = int(num1)
    print(num2)# Output: 10
    
    # Example 7: max(), min()
    my_list = [3, 7, 2, 9, 5]
    print(max(my_list))# Output: 9
    
    # Example 8: abs()
    x = -5
    print(abs(x))# Output: 5
    
    # Example 9: sum()
    my_list = [1, 2, 3, 4, 5]
    print(sum(my_list))# Output: 15
    
    # Example 10: round()
    x = 3.14159
    print(round(x, 2))# Output: 3.14
    ```
