A function allows you to define a reusable block of code that can be executed many times within your program.
Functions allow you to create more modular and [DRY](https://en.wikipedia.org/wiki/Don%27t_repeat_yourself) solutions to complex problems.
While Python already provides many built-in functions such as `print()` and `len()`, you can also define your own functions to use within your projects.
Functions are blocks of code that can be reused simply by calling the function. This enables simple, elegant code reuse without explicitly re-writing sections of code. This makes code both more readable, makes for easier debugging, and limits typing errors.
A function always returns a value,The `return` keyword is used by the function to return a value, if you don't want to return any value, the default value `None` will returned.
The function name is used to call the function, passing the needed parameters inside parentheses.
```python
# this is a basic sum function
def sum(a, b):
return a + b
result = sum(1, 2)
# result = 3
```
You can define default values for the parameters, that way Python will interpretate that the value of that parameter is the default one if none is given.
```python
def sum(a, b=3):
return a + b
result = sum(1)
# result = 4
```
You can pass the parameters in the order you want, using the name of the parameter.
```python
result = sum(b=2, a=2)
# result = 4
```
However, it is not possible to pass a keyword argument before a non-keyword one
```Python
result = sum(3, b=2)
#result = 5
result2 = sum(b=2, 3)
#Will raise SyntaxError
```
Functions are also Objects, so you can assign them to a variable, and use that variable like a function.
```python
s = sum
result = s(1, 2)
# result = 3
```
### Notes
- If a function definition includes parameters, you must provide the same number of parameters when you call the function.
- Python interprets the function block only when the function is called and not when the function is defined. So even if the function definition block contains some sort of error,the python interpretar will point that out only when the function is called.