> For the complete documentation index, see [llms.txt](https://petercheng7788.gitbook.io/developer-note/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://petercheng7788.gitbook.io/developer-note/programming-language/python.md).

# Python

## Data Types

| Text Type:      | `str`                              |
| --------------- | ---------------------------------- |
| Numeric Types:  | `int`, `float`, `complex`          |
| Sequence Types: | `list`, `tuple`, `range`           |
| Mapping Type:   | `dict`                             |
| Set Types:      | `set`, `frozenset`                 |
| Boolean Type:   | `bool`                             |
| Binary Types:   | `bytes`, `bytearray`, `memoryview` |
| None Type:      | `NoneType`                         |

```python
x = 5
# Check the typing and get the type
print(type(x), isInstance(x, str))
```

### String&#x20;

* F-String was introduced in Python 3.6, which can be used to concatenate the string and variable

```python
age = 36
txt = f"My name is John, I am {age}"
print(txt)
```

### Logical

* `and` : &&
* `or`: ||
* `not`: !

```python
a = True
b = False
if not b:
    print("b is false ar")
if a or b:
    print("a or b is true")
if a and b:
    print("a and b are true")

# Result
# b is false ar
# a or b is true
```

* `is` vs `==`
* `is` is more strict than `==`, as it also validate the object reference

```python
x = ["apple", "banana"]
y = ["apple", "banana"]
z = x

print(x is z)

# returns False because z is the same object as x

print(x is y)

# returns True because x is not the same object as y, even if they have the same content

print(x == y)

# to demonstrate the difference betweeen "is not" and "!=": this comparison returns False because x is equal to y


# Result
# True
# False
# True
```

### Boolean

* `()`, `[]`, `{}`, `""` , `0` , `None`  , will equal to false&#x20;

```python
a = {}
if a:
    print("Yeah")
else:
    print("Nope")

# result: Nope
```

### List

```python
thislist = ["apple", "banana", "cherry"]
# cherry
print(thislist[-1])
# ['cherry', 'orange', 'kiwi']
print(thislist[2:5])
# add the element on the specific position
thislist.insert(2, "watermelon")
# append the element to the last position
thislist.add("lemon") 
# pop the element on specific position, if arg is none, pop the last element
thislist.pop(1)
# Looping 
thislist = ["apple", "banana", "cherry"]
for x in thislist:
  print(x)
  
# Join List
list1 = ["a"]
list2 = [1]
list3 = list1 + list2
print(list3)
# ["a", 1]
```

* List Comprehension is similar with map method on javascript, having syntax sugar to create new array from a array

```python
fruits = ["apple", "banana", "cherry", "kiwi", "mango"]
newlist = [x for x in fruits if "a" in x]
print(newlist)
# ['apple', 'banana', 'mango']


fruits = ["apple", "banana", "cherry", "kiwi", "mango"]
newlist = [x if x != "banana" else "orange" for x in fruits]
print(newlist)
# ['apple', 'orange', 'cherry', 'kiwi', 'mango']


def add(x:int):
    return x + 1
arr = [1 ,2 ,3 ,4 ,5]
arr2 = [ y for item in arr if (y:=add(item)) <=3]
print(arr2)
# [2,3]

```

<pre class="language-python"><code class="lang-python"><strong>thislist = ["apple", "banana", "cherry"]
</strong># Create new list with different reference
mylist = thislist.copy()
print(thislist is mylist)

# Same reference
yourlist = thislist
print(thislist is yourlist)

# Result
# False
# True
</code></pre>

### Tuple

* A tuple is a collection which is ordered and **unchangeable**.

```python
mytuple = ("apple", "banana", "cherry")
```

### Set

* A set is a collection which is *unordered*, *unchangeable\**, and *unindexed*

```python
myset = {"apple", "banana", "cherry"}
```

### Dictionaries

* Dictionaries which is similar with json object from javascript, containing key-value pair

```python
thisdict = {
  "brand": "Ford",
  "model": "Mustang",
  "year": 1964
}

# Loop the key
# brand , model, year
for x in thisdict:
  print(x)

# Ford
print(thisdict["brand"])

# Will crash, don't try to access non-existing key
print(thisdict["brands"])

# Check the key is existed
# False
print("brands" in thisdict)

# Directly add or edit attribute
thisdict["year"] = 2018
# remove attribute 
thisdict.pop("model")

# convert string to dictionaries
newobj = json.loads('{ "name":"John", "age":30, "city":"New York"}')
# stringify the dictionaries
newStr = json.dumps(thisdict)
```

## Function

* Here is the example of closure

```python
def test():
    def test2():
        return "test"
    return test2

# Result
# test
print(test()())
```

* In function , you can assign a default value to function argument, but need to take care of `list`, `dict`,  as they are mutable and have unexpected behaviors

```python
class Test:
    def fn(
        self,
        param:list = []
    ):
        param.append(1);
        print(param);
test = Test();
test2 = Test();
test.fn()
test2.fn()

// Output:
// [1]
// [1, 1]
```

* From above the result, since the default parameter is mutable, so the value is accumulated
* Here is the fix below, by setting default parameter as None

```python
class Test:
    def fn(
        self,
        param:list = None
    ):
        param = [] if param is None else param
        param.append(1);
        print(param);
test = Test();
test2 = Test();
test.fn()
test2.fn()

// Output:
// [1]
// [1]
```

## Lambda

* lambda function is a small anonymous function with a simple return value

```python
def myfunc(n):
  return lambda a : a * n

mydoubler = myfunc(2)

# Result: 22
print(mydoubler(11))
```

## Class

```python
# In the class declarification, self must included, self is equal to this
class Person:
  # init which equal to constructor function
  def __init__(self, name, age):
    self.name = name
    self.age = age
  # To customize tthe format when accessing the class instance directly
  def __str__(self):
    return f"{self.name}({self.age})"

p1 = Person("John", 36)

# John
print(p1.name)
# John(36)
print(p1)
```
