# UD - FLASK - PY Basic

## 1. Main

### 1.1

```python
if __name__ == '__main__':
    app()
```

### 1.2 id

string, bool, number & tuple are immutable; list is muttable

```python
a = []
b = a
c = []
print(id(a), id(b), id(c)) # 4380261704 4380261704 4380259400
```

### 1.3 avoid using mutable for default parameters

```python
from typing import List


class Student:
    def __init__(self, name: str, grades: List[int] = []):  # This is bad!
        self.name = name
        self.grades = grades

    def take_exam(self, result):
        self.grades.append(result)


bob = Student("Bob")
rolf = Student("Rolf")
bob.take_exam(90)
print(bob.grades)    # [90]
print(rolf.grades)   # [90]     # Whaaaaaat
```

fix

```python
class Student:
    def __init__(self, name: str, grades: Optional[List[int]] = None): # fix
        self.name = name
        self.grades = grades or []  # fix: New list created if None
    ...
```

## 2. Basic

```python
# string format
name = 'pi'
pi = 3.1415926
text = '{} = {:.2f}'.format(name, pi)
print(text)
```

```python
# list, tuple, set
l = ['Bob', 'Rolf', 'Anne'] # ordered
t = ('Bob', 'Rolf', 'Anne') # ordered + immutable
s = {'Bob', 'Rolf', 'Anne', 'Anne'} # unordered + unique
# list -> append, []
# set -> add -> no [] -> difference / union / intersection
```

```python
friends = ["Rolf", "Bob"]
abroad = ["Rolf", "Bob"]
print(friends == abroad)  # True   # compare element
print(friends is abroad)  # False  # compare object id
```

```python
# loop
if 'a' in ['c', 'b']:
    print('case 1')
elif a == c:
    print('case 2')
else:
    print('case 3')


for idx, val in enumerate(ints):
    print(idx, val)
```

```python
# list comprehension
nums = [1, 2, 3, 4, 5]
outputs = [n + 1.5 for n in nums if (n % 2) == 0] # [3.5, 5.5]
```

```python
# spread
person = ('Bob', 42, 'Mechanic')
name, _, profession = person

head, *tail = [1, 2, 3, 4, 5] # head = 1, tail = [2, 3, 4, 5]
```

```python
users = [
    (0, "Bob", "password"),
    (1, "Rolf", "bob123"),
    (2, "Jose", "longp4assword"),
    (3, "username", "1234"),
]

username_mapping = {user[1]: user for user in users}
userid_mapping = {user[0]: user for user in users}
```

## 3. Func

```python
# lambda
add = lambda x, y: x + y

# map
sqs = [1, 3, 5, 9]
doubled = map(lambda x: x * 2, sqs)

# args & kwargs
def both(*args, **kwargs):
    print(args)   # (1, 3, 5)
    print(kwargs) # {'age': 25, 'name': 'Bob'}

both(1, 3, 5, name="Bob", age=25)
```

## 4. Class

```python
class Student:
    def __init__(self, name, *grades):
        self.name = name
        self.grades = grades
        self.age = 18

    def __str__(self):
        return 'Person {}, {} years old'.format(self.name, self.age)

    def average(self):
        return sum(self.grades) / len(self.grades)

student = Student("Bob", 36, 67, 90, 100, 100)
print(student) # __str__ 
print(student.average())
```

Static methods = just place a method inside a class (Module)

Class methods = factories.

```python
class Book:
    TYPES = ('hardcover', 'paperback')

    def __init__(self, name, book_type, weight):
        self.name = name
        self.book_type = book_type
        self.weight = weight

    def __repr__(self):
        return '<Book {}, {}, weighing {}g>'.format(self.name, self.book_type, self.weight)

    @classmethod
    def hardcover(cls, name, page_weight):
        return cls(name, cls.TYPES[0], page_weight + 100)

heavy = Book.hardcover('Harry Potter', 1500)
print(heavy) # <Book Harry Potter, hardcover, weighing 1600g>
```

```python
# inheritance
class Device:
    def __init__(self, name, connected_by):
        ...

class Printer(Device):
    def __init__(self, name, connected_by, capacity):
        super().__init__(name, connected_by)
        ...
```

## 5. Import

```python
import sys
print(sys.path) # ['', '/Users/jason/workspace/python/playground', ...]

print(__name__) # __main__ or path_for_importing
```

## 6. FP

### 6.1 Decorator, func with params

```python
import functools

user = {'username': 'jose', 'access_level': 'admin'}

def make_secure(func):
    @functools.wraps(func) # define func as wrapper & keep its name
    def secure_function(*args, **kwargs): # pass func params
        if user['access_level'] == 'admin':
            return func(*args, **kwargs)
        else:
            return 'No admin permissions!'

    return secure_function


@make_secure
def get_password(panel):
    if panel == 'admin':
        return '1234'
    elif panel == 'billing':
        return '8901'


print(get_password('admin'))   # 1234
print(get_password('billing')) # 8901
```

### 6.2 Decorator, decorator with params

one more layer to return decorator

```python
import functools

def make_secure(access_level): # one more layer to return a decorator.
    def decorator(func):
        @functools.wraps(func)
        def secure_function(*args, **kwargs):
            if user['access_level'] == access_level:
                return func(*args, **kwargs)
            else:
                return 'No permission!'

        return secure_function

    return decorator


@make_secure('admin') # runs the make_secure function, which returns decorator
def get_admin_password():
    return 'admin: 1234'

@make_secure('user')
def get_dashboard_password():
    return 'user: user_password'

user = {'username': 'anna', 'access_level': 'user'}

print(get_admin_password())
print(get_dashboard_password())

user = {'username': 'anna', 'access_level': 'admin'}

print(get_admin_password())
print(get_dashboard_password())
```


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://huang-jason.gitbook.io/python/ud-flask-1.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
