#   # 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)`

``````  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.

``````  def add(a, b):
return a + b

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.

``````  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`

``````  '''Formal Function'''
return x + y

'''Lambda Function - 1'''

'''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.

``````  def add(*nums):
total = 0
for n in nums:
total += n

# 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.

``````  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

• ``````  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()`.

``````  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
``````