---
# System prepended metadata

title: Functions

---

# Functions Introduction 

---
title: Agenda
description:
duration: 300
card_type: cue_card
---

### Agenda 

1. What are functions?
2. Function with parameters
3. Function with default arguments
4. Difference between `print` and `return`
5. Positional and Keyword arguments
6. Scope of Variables
7. Lambda Functions

---
title: Introducing Functions
description:
duration: 900
card_type: cue_card
---

### What are functions?

- A function is a set of instructions that can be **called / invoked** whenever needed.
- Once you've defined a function, you can use it multiple times throughout your program.
- This reduces the effort of rewriting the same logic at different places.

Code
```python
def prepare_for_guests(): # Defining a function
  
  # Body of the function
  print("Dust all the rooms")
  print("Arrange the living area")
  print("Go and get drinks & snacks!")
  print("Don't misbehave in front of the guests!")
  print("Touch their feet when you greet them!")

prepare_for_guests() # Calling / Invoking the function
```

> Output

    Dust all the rooms
    Arrange the living area
    Go and get drinks & snacks!
    Don't misbehave in front of the guests!
    Touch their feet when you greet them!

### Question: Write a piece of code which cooks tea.

**Motivation:** 
- Focus on why encapsulation of code inside functions is good. 
- Clarify doubts (if any) on where functions are advantegous
over loops.

Code
```python=
def make_tea():
    print("I am making tea")
    
make_tea() # call
```

> Output

    I am making tea

Code
```python=
# We can use a For loop to call the function 5 times.

for i in range(5):
    make_tea()
```

> Output

    I am making tea
    I am making tea
    I am making tea
    I am making tea
    I am making tea

Code
```python=
def make_tea():
  for i in range(5):
    print("I am making tea")

make_tea()
```

> Output

    I am making tea
    I am making tea
    I am making tea
    I am making tea
    I am making tea

Encapsulating the independent logic into a separate entitiy/object to avoid code duplication.

---
title: Functions with parameters
description:
duration: 900
card_type: cue_card
---

### Functions with parameters -

Code
```python=
# Functions can accpet arguments or parameters

def sheldon_knock(name):
    print("knock knock ", name)

sheldon_knock("Scaler")
```

> Output

    knock knock Scaler

### Functions that can take multiple inputs -

**Motivation:**
- Explain positional mapping of arguments.
- Highlight errors that can occour if some argument is missing.

Code
```python=
# Introduce my family!

def introduce_family(father, mother, sibling):
    print("Father:", father)
    print("Mother:", mother)
    print("Sibling:", sibling)

introduce_family("Deepak", "Deepa", "Vidhi")
```

> Output

    Father: Deepak
    Mother: Deepa
    Sibling: Vidhi

Code
```python=
# Raises a TypeError, because 1 argument i.e. sibling was not provided.
introduce_family("A", "B")
```

> Output

    ---------------------------------------------------------------------------
    TypeError                                 Traceback (most recent call last)
    <ipython-input-10-231e98ef6f67> in <cell line: 2>()
          1 # Raises a TypeError - because 1 argument, that is, sibling was not provided
    ----> 2 introduce_family("A", "B")

    TypeError: introduce_family() missing 1 required positional argument: 'sibling'

Code
```python=
# Raises a NameError, when passing more than defined arguments.
introduce_family("A", "B", "C", "D")
```

> Output

    ---------------------------------------------------------------------------
    TypeError                                 Traceback (most recent call last)
    <ipython-input-11-294cbaa167ab> in <cell line: 2>()
          1 # Raises a NameError, when passing more than defined arguments
    ----> 2 introduce_family("A", "B", "C", "D")

    TypeError: introduce_family() takes 3 positional arguments but 4 were given

### Quick Revision

<img src="https://d2beiqkhq929f0.cloudfront.net/public_assets/assets/000/059/994/original/download.png?1703220381">

<img src="https://d2beiqkhq929f0.cloudfront.net/public_assets/assets/000/059/995/original/download_%281%29.png?1703220589">

---
title: Quiz-1
description: Quiz-1
duration: 60
card_type: quiz_card
---

# Question

Given a Python function :
```python=
def func(n):
  for i in range(n):
    print("hello")
```

In which of the following function calls, the code will get executed without any errors?

# Choices

- [ ] func(3.0)
- [x] func(3)
- [ ] func("hello")
- [ ] All of these

---
title: return keyword
description:
duration: 600
card_type: cue_card
---

### return keyword

<img src="https://d2beiqkhq929f0.cloudfront.net/public_assets/assets/000/059/996/original/download_%282%29.png?1703220689">

\
Code
```python=
def print_money(amount):
    print(2 * amount)

print_money(1000)
```

> Output

    2000

Code
```python=
def return_money(amount):
    return 2 * amount

# store money in variable
result_money = return_money(1000)
print(result_money)
```

> Output

    2000

A function execution gets over the second we return from it.

Code
```python=
def random():
    print("before return")
    return 1
    print("after return")
random()
```

> Output

    before return
    1

---
title: Quiz-2
description: Quiz-2
duration: 60
card_type: quiz_card
---

# Question

What will be the output of the following code?

```python=
def do_something(n):
    total = 0
    i = 1
    while i <= n:
        total += i
        i += 1
    return total

print(do_something(5))
```

# Choices

- [ ] 5
- [ ] 10
- [x] 15
- [ ] 25

---
title: Quiz-3
description: Quiz-3
duration: 60
card_type: quiz_card
---

# Question 
Consider the following Python code:

```python=
def gcd(a, b):
    while b != 0:
        a, b = b, a % b
    return a

x = gcd(48, 180)
print(x)
```

What will be the output of this code?

# Choices

- [x] 12
- [ ] 36
- [ ] 6
- [ ] 18

---
title: Break & Doubt Resolution
description:
duration: 600
card_type: cue_card
---

### Break & Doubt Resolution

`Instructor Note:`
* Kindly take this time (up to 5-10 mins) to give a short break to the learners.
* Meanwhile, you can ask the them to share their doubts (if any) regarding the topics covered so far.

---
title: Positional and Keyword arguments
description:
duration: 900
card_type: cue_card
---

### Positional and Keyword arguments

**Motivation**: Explain how positional arguments can cause problems and the role of keyword arguments.

Code
```python=
def introduce_family(my_name, sibling_name, father_name, mother_name):
    print("My name is", my_name)
    print("My sibling's is", sibling_name)
    print("My father's is", father_name)
    print("My mother's is", mother_name)

# Giving arguments in incorrect order
introduce_family("Nilesh", "Deepak", "Deepa", "Vidhi")
```

> Output

    My name is Nilesh
    My sibling's is Deepak
    My father's is Deepa
    My mother's is Vidhi

Code
```python=
# keyword arguments
introduce_family(my_name="Scaler",
                 father_name="Deepak",
                 mother_name="Deepa",
                 sibling_name="Vidhi")
```

> Output

    My name is Scaler
    My sibling's is Vidhi
    My father's is Deepak
    My mother's is Deepa

**Note:** We cannot have positional arguments after keyword arguments.

<img src="https://d2beiqkhq929f0.cloudfront.net/public_assets/assets/000/059/997/original/download_%283%29.png?1703221197">

### Setting default values to parameters -

- We can set the value of parameter to some default argument.
- This can only be done after defining the positional arguments.

Code
```python=
def simple_interest(p, t, r = 5): # default argument
    interest = (p * r * t) / 100
    return interest

simple_interest(50000, 3)
```

> Output

    7500.0

### So now two situations arise -

1. We pass all three values `simple_interest(50000, 3, 10)`. 
    * In this case the function will use the values we passed to calculate the simple interest. 
    * It will not use the default value that is present.
2. We do not pass anythin in place of the default argument `simple_interest(50000, 3)`. 
    * In this case the function will use the default value to calculate the simple interest.

---
title: Quiz-4
description: Quiz-4
duration: 60
card_type: quiz_card
---

# Question

What will be the output of the following code?

```python=
def multiply(num1=3, num2):
    return num1 * num2

print(multiply(2, 4))
```

# Choices

- [ ] 8
- [ ] TypeError
- [ ] 6
- [x] SyntaxError

---
title: Scope of Variables
description:
duration: 900
card_type: cue_card
---

### Scope of Variables

Code
```python=
a = 10 # Global Variable
def random():
    a = 50 # Local Variable
    print("Inside -", end = " ")
    print(a)
random()

print("Outside -", end = " ")
print(a)
```

> Output

    Inside - 50
    Outside - 10

-   The variable `a` in the function above is defined within the block
    of that function. The variable "a" inside the function random is a
    `local variable` and is only accessible inside the function.
-   The variable `a` outside the function body is accesible anywhere in
    the code below and hence it is called a `global variable`.


Code
```python=
a = 10 # Global Variable

# A local variable with name "a" is defined inside Random1.
def random1():
    a = 50 # Local Variable
    print("Inside Random1 -", end = " ")
    print(a)
random()

# No local variable with name "a" is defined inside Random2.
def random2():
    print("Inside Random2 -", end = " ")
    print(a)
random2()

print("Outside -", end = " ")
print(a)
```

> Output

    Inside Random1 - 50
    Inside Random2 - 10
    Outside - 10

-   If there is **no local definition** of a variable **within the function**, and that variable is called/used from within a function's body, the function would just use the **global variable**.

The `global` keyword in front of a variable name is used to tell python to use the global value of that variable.

Code
```python=
a = 10
def random():
    global a
    a = 20
    print(a)
random()
print(a)
```

> Output

    20
    20

---
title: Quiz-5
description: Quiz-5
duration: 60
card_type: quiz_card
---

# Question

What will be the output of the following code?

```python=
def function(var):
    print(var)

function(3)

var = 5
function(var)
```

A.
```
3
5
```
B.
```
3
3
```
C.
```
5
5
```
D.
```
5
3
```

# Choices
- [x] A
- [ ] B
- [ ] C
- [ ] D

---
title: Lambda Functions
description:
duration: 900
card_type: cue_card
---

### Lambda Functions

Functions having a single return statement in its body, are easily convertible to a **lambda function**.

**Syntax:**

    function_name = lambda arguments: expression

- `lambda` is the keyword that signifies the creation of a lambda function.
- `arguments` are the input parameters of the function.
- `expression` is the single expression or operation that the function performs.

Code
```python=
def random(x):
    return x + 10

random(5)
```

> Output

    15

Code
```python=
# lambda equivalent of above function

random = lambda x: x + 10   # passing the argument x
random(10)
```

> Output

    20

-   An important feature of random functions is that they are called **anonymous functions**.
-   We can omit or don't specify **function names** and directly define & call the function in **same line**.

Code
```python=
(lambda x: x + 10)(5)  # 5 is being sent as a value to the argument x
```

> Output

    15

---
title: Quiz-6
description: Quiz-6
duration: 60
card_type: quiz_card
---

# Question

What will be the output of the following code?

```python=
(lambda : print("Hello Scaler"))("Scaler")
```

# Choices

- [ ] Hello Scaler
- [ ] Hello Scaler Scaler
- [ ] Error, because lambda function cannot be called this way.
- [x] Error, because lambda function takes 0 arguments but 1 is given.

---
title: Practice Coding Question(s)
description: 
duration: 600
card_type: cue_card
---

### Practice Coding Question(s)

You can pick the following question and solve it during the lecture itself.

This will help the learners to get familiar with the problem solving process and motivate them to solve the assignments.

<span style="background-color: pink;">Make sure to start the doubt session before you start solving the question.</span>

Q. https://www.scaler.com/hire/test/problem/11739/
