mirror of
https://github.com/dholerobin/Lecture_Notes.git
synced 2025-07-01 13:06:29 +00:00
Added Refresher Functions
This commit is contained in:
parent
8a939e4210
commit
6d8ff5ca21
601
Academy DSA Typed Notes/Python Refresher/Refresher Functions
Normal file
601
Academy DSA Typed Notes/Python Refresher/Refresher Functions
Normal file
@ -0,0 +1,601 @@
|
||||
# Refresher: Functions
|
||||
|
||||
### Recap
|
||||
|
||||
* DRY RUN - Running code line by line, we run the code just like the compiler does without using human intelligence.
|
||||
* Loops - instead of writing the code multiple times, we use loops to perform the same task
|
||||
* Nested Loops - These are loops inside loops.
|
||||
* We usually use `i` for rows and `j` for columns.
|
||||
---
|
||||
|
||||
### QUIZ 1
|
||||
|
||||
What will the sequence be generated by the following?
|
||||
|
||||
```c
|
||||
range(-5,0,1)
|
||||
```
|
||||
|
||||
|
||||
### Choices
|
||||
- [ ] -5,-4,-3,-2,-1,0
|
||||
- [ ] Nothing
|
||||
- [ ] 0,-1,-2,-3,-4,-5
|
||||
- [x] -5,-4,-3,-2,-1
|
||||
---
|
||||
|
||||
|
||||
### QUIZ 2
|
||||
|
||||
What will the sequence be generated by the following?
|
||||
|
||||
```c
|
||||
range(-10,-5,-1)
|
||||
```
|
||||
|
||||
### Choices
|
||||
- [ ] -10,-9,-8,-7,-6,-5
|
||||
- [ ] -10,-9,-8,-7,-6
|
||||
- [x] Nothing
|
||||
- [ ] -6,-7,-8,-9,-10
|
||||
---
|
||||
|
||||
### QUIZ 3
|
||||
|
||||
What will be the output of the following?
|
||||
|
||||
```cpp
|
||||
for i in range(1,10):
|
||||
if(i % 3 == 0):
|
||||
break
|
||||
print(i, end = ' ')
|
||||
```
|
||||
|
||||
### Choices
|
||||
|
||||
- [ ] 1 2 3 4 5 6 7 8 9
|
||||
- [x] 1 2
|
||||
- [ ] 1 2 4 5 7 8 9
|
||||
- [ ] 1 2 4 5 6 7 8
|
||||
---
|
||||
|
||||
|
||||
### QUIZ 4
|
||||
|
||||
What will be the output of the following?
|
||||
|
||||
```cpp
|
||||
for i in range(0,4):
|
||||
for j in range(0,i):
|
||||
print('a', end = '')
|
||||
print()
|
||||
```
|
||||
|
||||
### Choices
|
||||
- [ ] a
|
||||
aa
|
||||
aaa
|
||||
|
||||
- [x] aaaa
|
||||
aaaa
|
||||
aaaa
|
||||
aaaa
|
||||
|
||||
- [ ] aaa
|
||||
aa
|
||||
a
|
||||
---
|
||||
|
||||
## Need for functions
|
||||
<img src="https://d2beiqkhq929f0.cloudfront.net/public_assets/assets/000/068/628/original/upload_6b000fa46e9e4e2cfb7a880d2397b9ee.jpg?1711016664" width=500 />
|
||||
|
||||
* We are working at a banking facility. We are to code the receipt that is printed after the ATM transaction. It is something like:
|
||||
|
||||
```cpp
|
||||
******************
|
||||
Transaction Complete
|
||||
Thank you for visiting
|
||||
******************
|
||||
```
|
||||
so we will write the code for this:
|
||||
|
||||
```python
|
||||
print('*' * 5)
|
||||
print("Transaction complete")
|
||||
print("Thank you for visiting")
|
||||
print('*' * 5)
|
||||
```
|
||||
* Now for every type of transaction same message will be printed. And for every transaction contained in the big file of 10000 lines of code, we have the same 4 lines for different transactions.
|
||||
* This is not following the DRY(Do not repeat yourself) principle. Which is a bad practice.
|
||||
* Let us say the back says they don't want to print `thank you` they wish to print `thanks` instead. So we will have to update it at all the places separately.
|
||||
* Functions are like alias - I can write a line of code and I can name it `abc`. Everywhere I can call abc the same piece of code will be executed.
|
||||
* Functions make code modular.
|
||||
* Now if there are any changes, we change it in one place and it will reflect in all the other places.
|
||||
|
||||
## Syntax of Defining a Function
|
||||
**Defining a function**
|
||||
```python
|
||||
def function_name():
|
||||
# actions
|
||||
```
|
||||
|
||||
**To Call the function**
|
||||
```python
|
||||
function_name()
|
||||
```
|
||||
|
||||
<img src="https://d2beiqkhq929f0.cloudfront.net/public_assets/assets/000/068/629/original/upload_b7ac907afcf96335954b43b7261fffb8.jpg?1711017155" width=500 />
|
||||
|
||||
|
||||
* The naming convention for a function is the same as variables.
|
||||
* It should be composed of alphabet, number, and underscore
|
||||
* should start with an alphabet or underscore
|
||||
* It should not be a keyword
|
||||
* In Python we use snake case. (there are two cases camel case and snake case).
|
||||
|
||||
## Return Statement
|
||||
* Functions not only put some code in a block they return something.
|
||||
* Example function
|
||||
```python
|
||||
def area_circle_rad_5(){
|
||||
print(3.14 * 5 * 5)
|
||||
}
|
||||
area_circle_rad_5()
|
||||
```
|
||||
**Output**
|
||||
```plaintext
|
||||
78.5
|
||||
```
|
||||
* This is how we define a function and call it. Now we want to add `1` to it or `2` to it. Can't we take it to a variable?
|
||||
* This is what return statements are for. It is like a black box where you want some task to be done. But after the task is done you want it to return some value as well.
|
||||
* So the syntax is something like:`
|
||||
```python
|
||||
def function_name():
|
||||
return 5;
|
||||
|
||||
abc()
|
||||
a = abc()
|
||||
print(a)
|
||||
```
|
||||
**Output**
|
||||
```plaintext
|
||||
5
|
||||
```
|
||||
* We are storing the return value of the function in a variable `a`. Now we can print this variable as usual.
|
||||
* Unlike other programming languages in Python we are not required to define the return type with the function name.
|
||||
<img src="https://d2beiqkhq929f0.cloudfront.net/public_assets/assets/000/068/630/original/upload_ae1b2652f049d3b49fca0fee9f86188b.png?1711017411" width=500 />
|
||||
|
||||
**Note:** Functions execution ends at return. Once a return statement is found rest of the lines of the code will not be executed. It is just like a break in loops.
|
||||
If you do return without any value, it will return `None`.
|
||||
```python
|
||||
def abc():
|
||||
return
|
||||
abc()
|
||||
```
|
||||
|
||||
## Parameter and Argument in Function
|
||||
* Let us say we want to calculate the area of a circle whose radius `10`. We will again write the code as
|
||||
```python
|
||||
def area_circle_rad_10():
|
||||
print(3.14 * 10 * 10)
|
||||
```
|
||||
* So for every different radius we will write a different code? This is not a good practice.
|
||||
* In Python we can take as many parameters as required. So we can simply take radius as a parameter from the use.
|
||||
```python
|
||||
def area_circle(radius):
|
||||
return (3.14 * (radius ** 2))
|
||||
|
||||
area = area_circle(5)
|
||||
```
|
||||
* If you want multiple parameters you can simply separate them by comma, their types are not required.
|
||||
* If the function is not returning anything by default it will return `None`.
|
||||
* In Python, a parameter is a variable used in a function definition, while an argument is an actual value passed to the function during a call.
|
||||
* About the above function `radius` used in the `area_circle()` function is a parameter, the `5` passed to it while calling is an argument.
|
||||
* But people use it interchangeably.
|
||||
|
||||
## Execution of A Function in Python
|
||||
* Python compiler executes line-by-line
|
||||
* Everything in Python is an object of a class.
|
||||
* Function is also a class.
|
||||
* Function is just like a variable, a variable gets declared in a single line, and functions get declared in multiple lines.
|
||||
* In Python if you call a function without defining it, it will show an error.
|
||||
* We can call a function inside a function.
|
||||
* Let us say we have a bank function to do transactions for saving accounts. We have multiple functions to check the balance, to execute the transaction, to print the thank you message, etc.
|
||||
|
||||
## Scope of a Variable
|
||||
```python
|
||||
a = 1
|
||||
def arae_circle(radius):
|
||||
area = 3.14 * (radius ** 2)
|
||||
return area
|
||||
b = area_circle(10)
|
||||
print(a)
|
||||
print(area)
|
||||
print(b)
|
||||
```
|
||||
* Whatever we have done so far, we have done it in global scope.
|
||||
* Here `a` and `b` are global variables. But `area` is a local variable to the function `area_circle`. It can only be accessed in the function. As the execution of the function is over the Python compiler frees up the memory. Thus `area` is no longer a valid memory location.
|
||||
* Though we can do this:
|
||||
```python
|
||||
a = 1
|
||||
def arae_circle(radius):
|
||||
area = 3.14 * (radius ** 2)
|
||||
print(a)
|
||||
return area
|
||||
b = area_circle(10)
|
||||
print(a)
|
||||
print(area) # this will give error
|
||||
print(b)
|
||||
```
|
||||
* This is because `a` is a global variable and can be accessed everywhere.
|
||||
<img src="https://d2beiqkhq929f0.cloudfront.net/public_assets/assets/000/068/631/original/upload_41ba15091ecbf33a56f68319d2098e4c.png?1711017589" width=500 />
|
||||
|
||||
* In Python variables defined in `if` or `for` loops can be used outside their block as well but it is not true for the functions.
|
||||
|
||||
```python
|
||||
a = 1
|
||||
def abd():
|
||||
a = 2
|
||||
print(a)
|
||||
abc()
|
||||
```
|
||||
|
||||
**Output**
|
||||
```plaintext
|
||||
2
|
||||
1
|
||||
```
|
||||
* So, this will have two variables called `a`. One is global and another is local. When we say `print(a)` it will refer to the local variable and print its value.
|
||||
* To update or use global we use the following syntax:
|
||||
|
||||
```python
|
||||
a = 1
|
||||
def abc():
|
||||
global a
|
||||
a = 2
|
||||
print(a)
|
||||
abc()
|
||||
print(a)
|
||||
```
|
||||
**Output**
|
||||
```plaintext
|
||||
2
|
||||
2
|
||||
```
|
||||
Here global variable `a` is reused and its value is changed inside a function.
|
||||
|
||||
---
|
||||
|
||||
### QUIZ 5
|
||||
|
||||
Is this a valid function?
|
||||
|
||||
```python
|
||||
def print_hello:
|
||||
print('Hello')
|
||||
```
|
||||
### Choices
|
||||
- [ ] Yes
|
||||
- [x] No
|
||||
|
||||
There are no paranthesis in the function and they are must in a function.
|
||||
|
||||
```python
|
||||
def print_hello():
|
||||
print('Hello')
|
||||
```
|
||||
---
|
||||
|
||||
### QUIZ 6
|
||||
|
||||
Is this a valid function?
|
||||
|
||||
```python
|
||||
def print_name():
|
||||
print('Hello', name)
|
||||
```
|
||||
|
||||
|
||||
# Choices
|
||||
- [ ] Yes
|
||||
- [x] No
|
||||
|
||||
The variable name must be taken as an argument.
|
||||
|
||||
---
|
||||
|
||||
### QUIZ 7
|
||||
|
||||
How many times the function foo is called?
|
||||
|
||||
```python
|
||||
|
||||
foo()
|
||||
foo()
|
||||
for i in range(1,5):
|
||||
foo()
|
||||
```
|
||||
|
||||
### Choices
|
||||
- [ ] 5
|
||||
- [x] 6
|
||||
- [ ] 7
|
||||
- [ ] 8
|
||||
---
|
||||
|
||||
### QUIZ 8
|
||||
|
||||
What will be the output of the following?
|
||||
|
||||
```python
|
||||
def area_rectangle(l, b):
|
||||
area = l * b
|
||||
area_circle(3, 4)
|
||||
print(area)
|
||||
```
|
||||
# Choices
|
||||
- [ ] 12
|
||||
- [ ] 7
|
||||
- [x] Error
|
||||
---
|
||||
|
||||
There is no function named `area_cirle()`.
|
||||
|
||||
### QUIZ 9
|
||||
|
||||
What will be the output of the following?
|
||||
|
||||
```python
|
||||
def foo(a):
|
||||
if(a):
|
||||
return 100
|
||||
a += 20
|
||||
return a
|
||||
print(foo(0))
|
||||
```
|
||||
### Choices
|
||||
- [ ] 100
|
||||
- [ ] 120
|
||||
- [x] 20
|
||||
- [ ] Nothing
|
||||
|
||||
A function's execution ends once a `return` is encountered.
|
||||
|
||||
If you do return without any value, it will return None. Though this is not helpful it is still valid.
|
||||
```python
|
||||
def abc():
|
||||
return
|
||||
abc()
|
||||
```
|
||||
|
||||
### QUIZ 10
|
||||
|
||||
What will be the output of the following?
|
||||
|
||||
```python
|
||||
def solve(a, b):
|
||||
print('Function Started')
|
||||
return 0
|
||||
c = a + b
|
||||
print('Function Ends')
|
||||
c = solve(2, 3)
|
||||
print(c)
|
||||
```
|
||||
### Choices
|
||||
- [ ] Function Started
|
||||
Function Ends
|
||||
5
|
||||
- [ ] Function Started
|
||||
Function Ends
|
||||
0
|
||||
|
||||
- [ ] Function Started
|
||||
0
|
||||
Function Ends
|
||||
|
||||
- [x] Function Started
|
||||
0
|
||||
|
||||
|
||||
We are doing early exit via return `0` and therefore the result is `0`.
|
||||
|
||||
|
||||
## Positional and Keyword Arguments
|
||||
Let us consider an example:
|
||||
```python
|
||||
def bio_data(name, age, gender):
|
||||
print("Name: ", name)
|
||||
print("Age: ", age)
|
||||
print("Gender: ", gender)
|
||||
|
||||
bio_data(23, "Male", "Aakar")
|
||||
```
|
||||
|
||||
#### **`What is the problem with the above code?`**
|
||||
|
||||
* **The order of the parameter matters**, age will printed with the name, and so on
|
||||
* Python has two types of arguments **Positonal** and **Keyword**.
|
||||
* The above function call is referred to as positional arguments. Where order or position of arguments matters.
|
||||
* The other one is keyword argument. Here we have to give the name of the argument but the order doesn't matter.
|
||||
* The name must be the same as given in the function definition.
|
||||
```python
|
||||
bio_data(name = "Aakar", gender = "Male", age = 23)
|
||||
```
|
||||
**Note:** A single call can have both together, but the Keyword argument must always be after positional arguments. Python will show an error if not done this way.
|
||||
**Cannot Do**
|
||||
```python
|
||||
bio_data("Aakar", age = 23, "Male")
|
||||
```
|
||||
**Must Do**
|
||||
```python
|
||||
bio_data("Aakar", age = 23,gender = "Male")
|
||||
```
|
||||
|
||||
## Default and Non-default Arguments
|
||||
* Let us say we are writing the above function. For example, people don't like having to declare their gender. So, we can give the default argument gender with the value `Unspecified` in Python.
|
||||
```python
|
||||
def bio_data(name, age, gender = "Unspecified"):
|
||||
print("Name: ", name)
|
||||
print("Age: ", age)
|
||||
print("Gender: ", gender)
|
||||
|
||||
bio_data(23, "Aakar")
|
||||
```
|
||||
Now, it is both ways okay even if we define or do not define the argument.
|
||||
|
||||
**Note:** A single call can have both together, but the Non-default argument must always be after default arguments. Python will show an error if not done this way.
|
||||
**Cannot Do**
|
||||
```python
|
||||
bio_data(name, age = 23, gender)
|
||||
```
|
||||
**Must Do**
|
||||
```python
|
||||
def bio_data(name, age, gender = "Unspecified"):
|
||||
```
|
||||
|
||||
### QUIZ 11
|
||||
|
||||
What is the correct way of calling this function?
|
||||
|
||||
```python
|
||||
def print_biodata(name, age, gender):
|
||||
print('Name', name)
|
||||
print('Age', age)
|
||||
print('Gender', gender)
|
||||
```
|
||||
|
||||
### Choices
|
||||
- [ ] print_biodata('Hari', 'Male', 23)
|
||||
|
||||
- [ ] print_biodata('Male', 'Hari', 23)
|
||||
|
||||
- [x] print_biodata('Hari', 23, 'Male')
|
||||
|
||||
- [ ] print_biodata(23, 'Hari', 'Male')
|
||||
---
|
||||
|
||||
|
||||
### QUIZ 12
|
||||
|
||||
What will be the output of the following?
|
||||
|
||||
```python
|
||||
def print_biodata(name, age = 23, gender = 'Female'):
|
||||
print('Name', name)
|
||||
print('Age', age)
|
||||
print('Gender', gender)
|
||||
```
|
||||
### Choices
|
||||
- [x] Yes
|
||||
- [ ] No
|
||||
|
||||
First there should be non-default arguments and then the default arguments.
|
||||
|
||||
### QUIZ 13
|
||||
|
||||
Which of the function call is correct?
|
||||
|
||||
```python
|
||||
def print_biodata(name, age = 23, gender = 'Female'):
|
||||
print('Name', name)
|
||||
print('Age', age)
|
||||
print('Gender', gender)
|
||||
```
|
||||
|
||||
### Choices
|
||||
- [ ] `print_biodata(name='Hari', 23)`
|
||||
- [ ] `print_biodata('Hari', 23, age=23)`
|
||||
- [x] `print_biodata('Hari')`
|
||||
- [ ] `print_biodata()`
|
||||
|
||||
* 1st option - `name` is a keyword argument and the age is a positional argument. Positional argument cannot come after keyword argument.
|
||||
* 2nd option - In the above quiz we are defining age twice which is not valid.
|
||||
* 3rd argument - Rest two arguments are default
|
||||
* 4th option - We still need name argument as name is not a default argument.
|
||||
|
||||
* `*args` - opens a list/tuple (arguments)
|
||||
* **`kwags` - opens a dictionary (keyword arguments)
|
||||
* `*` is used for opening a single-dimension iterator.
|
||||
* Let us say there exists a function that takes an unspecified number of parameters.
|
||||
* This can be achieved with the help of `*args` and `**kwargs`. This lets us pass as many arguments as we want.
|
||||
|
||||
```python
|
||||
def abc(a, b, *args, **kwargs):
|
||||
print(a, b)
|
||||
print(args)
|
||||
print(kwargs)
|
||||
|
||||
abc(2,3,4,5, name = "Hari",age = 23)
|
||||
```
|
||||
**Output**
|
||||
```plaintext
|
||||
2 3
|
||||
[4, 5]
|
||||
{"name" : "Hari"
|
||||
"age" : 23}
|
||||
```
|
||||
* You cannot have more than one `*args` or `**kwargs` as their behavior of it is unspecified.
|
||||
|
||||
|
||||
## Docstrings
|
||||
* Python provides a special functionality **doc strings** just like comments but slightly different than multiline comments.
|
||||
* If someone wants to know how the function works they have to come to the code and see. So many Python code readers and default Python provides a documentation of functions and classes and these are called **Doc String**
|
||||
* You have to write a multiline comment right after the function definition.
|
||||
```python
|
||||
def bio_data(name, age, gender = "Unspecified"):
|
||||
"""
|
||||
This function prints the bio-data using the information provided
|
||||
|
||||
|
||||
Args:
|
||||
name
|
||||
age
|
||||
gender
|
||||
|
||||
Returns:
|
||||
None
|
||||
"""
|
||||
print("Name: ", name)
|
||||
print("Age: ", age)
|
||||
print("Gender: ", gender)
|
||||
```
|
||||
To read the doc string, just add a `?` after it.
|
||||
```python
|
||||
bio_data?
|
||||
```
|
||||
|
||||
## Question - Simple Interest
|
||||
* Take two parameters, how much they want to invest, and how long they want to invest it for.
|
||||
* Simple interest - 7%.
|
||||
* Write a function `print_interest`
|
||||
|
||||
|
||||
```python
|
||||
si = 7
|
||||
principal = int(input("How much you want to invest>"))
|
||||
time = float(input("How long you want to invest it for (in years)?"))
|
||||
|
||||
def print_interest(principle, time):
|
||||
result = principle * time * si / 100
|
||||
return result
|
||||
|
||||
result = print_interest(principle, time)
|
||||
print(result)
|
||||
```
|
||||
|
||||
### Question - Simple Interest
|
||||
* **Round function** in Python rounds the number. It takes the number and the precision we want. It rounds off this number and returns it.
|
||||
```python
|
||||
round(3.1415,2) -> 3.14
|
||||
```
|
||||
* Given a radius `R`, print the area of a circle but up to two decimal places only.
|
||||
|
||||
|
||||
```python
|
||||
PI = 3.14159
|
||||
def print_area(radius):
|
||||
area = PI * (radius ** 2)
|
||||
|
||||
result = print_area(5)
|
||||
print(result)
|
||||
```
|
Loading…
x
Reference in New Issue
Block a user