Python 102! Introduction to Python : Intermediate Concepts.
Tags: python, devops, datascience, machinelearning
Published: 2021-07-23 16:27:22

![image](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/qm4dtxr8ij0tjnztx8pu.png)
 

In the first part of python boot camp by [Lux Academy](https://twitter.com/lux_academy) and [Data Science East Africa](https://twitter.com/DSEAfrica), we covered the basic python concepts, these included: 

- Python Installation and development environment set up.

- Comments and statements in Python.

- Variables in Python. 

- Keywords, identifiers and literals.

- Operators in Python. 

- Comparison operators and conditions 

- Data types in Python

- Control flow.

- Functions in Python.


You can use [this link](https://dev.to/grayhat/python-101-introduction-to-python-3kg5) to read more about the concepts  if you have not yet read. 

In this second part of the tutorial we are going to cover the intermediate python concepts, these includes: 

- Basics data structures, these lists, tuples, dictionary set. 

- Functions and recursion. 

- Anonymous or lambda function in Python.

- Global, Local and Nonlocal.

-  Python Global Keyword.

-  Python Modules.

-  Python Package.

- Classes in Python.  

- Closures and decorators

- Inheritance and Encapsulation. 



### **Basics data structures lists, tuples, dictionary set.** 

A data structure  is a way of describing a certain  way to organise pieces data so that operations  and algorithms can be more easily applied, for example a tree type data structure often allows for efficient searching  algorithms, so whenever you are implementing search component in your program it is advisable to use a tree data structure.

Basically, data structure in general computer  science it is just a way of organising data to make certain operations easier or harder. 

**Questions:** What is the difference between data types and data structures? 

In layman’s language we can say data structures are specialised formats for organising and storing data in a program. Think of them as data with added structure.  

In Python you can use the built-in types like list, sets, tuples, etc or define your own using classes and functions. 

1) **List** - lists are ordered  collection  of items, you can create them using **[ ]** or **list()** constructor. 

- To access or edit values in a list use index or indices.
- To add items use the append() method.
- To remove items use remove or del statement.

```python
# how to create a list.
todo = ['sleep', 'clean', 'sleep']

# how to access or edit a list items.
todo[0] = 'vacuum'

# how to add an items. 
todo.append('mow yard')

# how to remove an items
todo .remove('sleep')

```

### **Tuples** 

Tuple are ordered collection of item like lists but immutable, that is unchangeable.  

We create by providing comma separated values within optional **()**  or use tuple() constructor. Once you have created a tuple you can not change it, that is you can not add, edit or remove any of the items in it.  

```Python  
# how to create a tuple 
student = ("freshman", 15, 4.0)

# how to access an item
print(student[0])

# how to access items
print(student[0:2])

# Hoe to delet a tuple
del student
```

### **Dictionary.**
Dictionaries are used to store data values in key:value pairs.

A dictionary is a collection which is ordered*, changeable and does not allow duplicates.

```Python 
mycar = {
  "brand": "Ford",
  "model": "Mustang",
  "year": 1964
}
```

### **Sets**
Sets are used to store multiple items in a single variable, we can also define a set as a collection which is both unordered,   unindexed and doesn’t support duplicates.

```Python 
myset = {"apple", "banana", "cherry"}
print(myset)
```


### **Function in Python.** 

A function is block of organised  re-usable set of instructions that is used to perform some related actions. 


**For Example:**

> If you have 16 lines of code which appears 4 times in a program, you don't have to repeat it 4 times. You just write a function and call it.  

**Functions enables:**

- Re-userbility of code minimises  redundancy. 

- Procedural  decomposition  makes things organised. 

**In python we have two types of functions:**

1). User defined  functions.
 
2). Built in functions.  

```python 

def my_function(x):
    return list(dict.fromkeys(x))
    mylist = myfunction(["a", "b", "c", "d"])
    print(mylist)

my_function()
```

### **Parameters and arguments**

A parameter is the variable defined within the parentheses during function definition. Simply they are written when we declare a function. 
```python
def sum(a,b):
  print(a+b)
    
# Here the values 1,2 are arguments
sum(1,2)
```
 

An **argument** is a value that is passed to a function when it is called. It might be a variable, value or object passed to a function or method as input. They are written when we are calling the function. 

```Python 
def sum(a,b):
  print(a+b)
    
# Here the values 1,2 are arguments
sum(1,2)
```

### **Decorator.**

A decorator is a design pattern in Python that allows a user to add new functionality to an existing object without modifying its structure. Decorators are usually called before the definition of a function you want to decorate.

```python
from fastapi import FastAPI

app = FastAPI()

#Here is the decorator 
@app.get("/")
async def root():
    return {"message": "Hello World"}
```


### **Anonymous or lambda function in Python.**

Lambda Function, also referred to as 'Anonymous function' is same as a regular python function but can be defined without a name. While normal functions are defined using the def keyword, anonymous functions are defined using the lambda keyword. However, they are restricted to single line of expression.


```python

lambda arguments: expression 

``` 

Lambda functions can have any number of arguments but only one expression. The expression is evaluated and returned. Lambda functions can be used wherever function objects are required.

```Python

double = lambda x: x * 2

print(double(5))

```


### **Python Global, Local and Nonlocal variables.**

In Python, a variable declared outside of the function or in global scope is known as a **global variable.** This means that a global variable can be accessed inside or outside of the function.

```python
x = "global"

def foo():
    print("x inside:", x)


foo()
print("x outside:", x)
```

A variable declared inside the function's body or in the local scope is known as a **local variable**

```python
def foo():
    y = "local"


foo()
print(y)
```


**Nonlocal** variables are used in nested functions whose local scope is not defined. This means that the variable can be neither in the local nor the global scope.

```python
def outer():
    x = "local"

    def inner():
        nonlocal x
        x = "nonlocal"
        print("inner:", x)

    inner()
    print("outer:", x)


outer()
```