オブジェクト指向言語経験Python初心者の備忘録

じっくり育てていこうと思います。

## 自作クラス

```python

class User:
    id: str
    name: str

    @staticmethod
    def valid_user_id(v: str) -> str:
        if not v or not len(v):
            raise Exception("ユーザーIDを正しく指定してください！")

    @classmethod
    def valid_user_name(cls, v: str) -> str:
        if not v or not len(v):
            raise Exception("ユーザー名を正しく指定してください！")

    def __init__(self, id: str, name: str, **kawrgs):
        self.id = User.valid_user_id(id)
        self.name = User.valid_user_name(name)

        # id, name以外にパラメータが与えられていたらセットしておく
        for k in kawrgs:
            setattr(self, k, kawrgs.get(k))

    def __str__(self) -> str:
        return f"ユーザーID={self.id} ユーザー名={self.name}"

    def __repr__(self) -> str:
        return self.to_json()

    def __bool__(self) -> bool:
        return self.id is not None and self.name is not None

    def to_json(self) -> str:
        return json.dumps(self.__dict__, ensure_ascii=False, indent=4)

async def main():
     v = User(
        id="1",
        name="１番さん",
        xxx="xxx",
        amount=999,
    )
    print(v)
    print(v.to_json())

if __name__ == "__main__":
    asyncio.run(main()) # main内でasync関数を使用する場合はこう実行する（ついで）

# ユーザーID=1 ユーザー名=１番さん

#{
#    "id": "1",
#    "name": "１番さん",
#    "xxx": "xxx",
#    "amount": 999
#}
```
## JSON

### Dict->JSONを人間に見やすく出力

```python
json_sample_dict: Dict[str, any] = {"id": "XX001", "name": "激辛マイケルズ兄さん"}
print(json_sample_dict)
print(json.dumps(json_sample_dict, ensure_ascii=False, indent=4))
# {'id': 'XX001', 'name': '激辛マイケルズ兄さん'}
# {
#    "id": "XX001",
#    "name": "激辛マイケルズ兄さん"
# }
```

### Dict->JSON strに変換

```Python
    dic = {
        "hoge": "xxx",
    }
    print(json.dumps(dic).replace("x", "y"))
# {"hoge": "yyy"}
```

### JSON strからdictに変換

```python
    print(
        json.loads(
            """
            {
                "hoge": "ggg"
            }
            """
        )
    )
# {'hoge': 'ggg'}
```

### 

## 辞書

### 値を取り出す

```python
    dic = {
        "hoge": "xxx",
    }
    print(dic.get("a", "aは無いよ！"))
    print(dic["a"])
# aは無いよ！
# 例外が発生しました: KeyError

# バラシて取り出す
x, y = {"A":1, "B":2}.values()
print(y)
# 2
```

### 値をセットする

```python
    dic = {
        "hoge": "xxx",
    }
    dic["a"] = "aだお"
    print(dic["a"])

    dic.setdefault("a", "xxx") # 既にそのキーで値がある時はセットされない
    dic.setdefault("b", "vvv")
    print(dic)

# aだお
# {'hoge': 'xxx', 'a': 'aだお', 'b': 'vvv'}

# forやifの内包表記で値を一発セットする
    dics = [
        {
            "hoge": "xxx",
        },
        {
            "hoge": "yyy",
        },
    ]
    
    [d.update(hoge=d.get("hoge") + "更新したぜ！") for d in dics]
    print(dics)
# [{'hoge': 'xxx更新したぜ！'}, {'hoge': 'yyy更新したぜ！'}]
```

### ループ
```python
# キーstrを順番に取り出す
for k in d.keys():
    ...

# 値を順番に取り出す
for v in d.values():
    ...

# キーと値を同時に順番に取り出す
for k, v in d.items():
    ...
```

### ソート
```python
dictlist: Dict[str, any] = [
    {"price":100, "name":"りんご"},
    {"price":50, "name":"みかん"},
    {"price":50, "name":"レモン"},
    {"price":120, "name":"なし"},
]
# keyにタプルを指定すると複数キーでソートできる
sorted_dictlist = sorted(dictlist, key=lambda x: (x["price"], x["name"]))
```

### 結合
```python
d1.update(d2) # d1が直接上書きされる

joined_dict = dict(**d1, **d2) # 別の入れ物としてreturnされる
```

## リスト
### 重複を弾く
```python
elems = ["", "あ", "え", "あ"]
elems = list(set(elems)) 
# ["", "あ", "え"]
```

### リストを条件で選別する
```python
elems = ["", "あ", "え"]
selected_list = [elem for elem in elems if elem != ""]
# ["あ", "え"]
```

### 一部を抽出する
```python
list_choise = mylist[1: 3]
list_choise = mylist[1:] #2番目以降を全て抽出する

# バラして取り出す
x, y = [1, 2]
print(y)
# 2
```

### ソート
```python
mylist.sort() # mylistが上書きされる

mylist.sort(reverse=True) #降順

new_list = sorted(mylist) # 別の入れ物としてreturnされる

# 逆順に並べ替える
print(*reversed([1, 2, 3]))
# 3 2 1
```

### 結合
```python
a.extend(b) # aが上書きされる

# 結合しつつリターン
    a = [1]
    b = [2]
    print(list([*a, *b]))
# [1, 2]
```

## タプル
### ソート
```python
sorted_str_list = sorted(str_tuple)
```

### listをtupleに変換
```python
tup = tuple([1, 2, 3, 4])
```

### tupleをlistに変換
```python
tup = list((1, 2, 3, 4))
```

## 文字
### strを分割する
```python
s = "a,b,c"
s.split(",") 
# ["a", "b", "c"]
```

### 連結
```python
joined_str = ",".join(["a", "b", "c"])
# "a,b,c"
```

### ソート
```python
sorted_char_list = sorted("bedac")
# ['a', 'b', 'c', 'd', 'e']
```

## 正規表現チェック

### Eメールアドレス
```python
if not re.match("[^@]+@[^@]+\.[^@]+", email_address):
    return False
```

## 画像

### 縦・横の短い方に合わせてできるだけ中央を正方形に切り抜く

```python
from PIL.Image import Image

def get_square_cropped_pillow_image(im: Image) -> Image:
    square_size = min(im.size)
    width, height = im.size
    box = None
    if width > height:
        top = 0
        bottom = square_size
        left = (width - square_size) / 2
        right = left + square_size
        box = (left, top, right, bottom)
    else:
        left = 0
        right = square_size
        top = (height - square_size) / 2
        bottom = top + square_size
        box = (left, top, right, bottom)
    return im.crop(box)
```

## 時間

### 現在日時を取得する

```python
from datetime import datetime

print(datetime.now().strftime("%Y-%m-%d %H:%M:%S"))
# 2022-02-09 16:54:46

print(datetime.utcnow().strftime("%Y-%m-%d %H:%M:%S"))
# 2022-02-09 07:54:46
```

### タイムゾーン変換する
```python
from datetime import datetime
from dateutil import tz

UTC = tz.gettz("UTC")
print(datetime.now(UTC).strftime("%Y-%m-%d %H:%M:%S"))
# 2022-02-09 07:54:46


JST = timezone(timedelta(hours=+9), "JST")

def to_jst(dt: datetime) -> datetime:
    if dt is None:
        return None
    return dt.astimezone(JST)
```

### 時間の加減操作

```Python
print(datetime.now() + timedelta(minutes=int(10)))
```
# Enum

```python
    class Fruit(str, Enum):
        APPLE = "APPLE"
        BANANA = "BANANA"

    if "POTATO" not in [v.value for v in Fruit]:
        print("フルーツじゃないよ！")
# フルーツじゃないよ！

    if Fruit("APPLE") in Fruit:
        print("フルーツだよ！")
# フルーツだよ！

    if "APPLE" in [v.value for v in Fruit]:
        print("フルーツだよ！")
# フルーツだよ！
```

# クラス

# 無名関数(lambda)
```python
add_a_and_b = lambda a, b=1: a + b
```

# インスタンスの型判定
```python
print(isinstance(["aaa"], List))
# True

print(isinstance("a", type("b")))
# True
```

# None(null)判定

```Python
v = None
print("Noneだよ！" if v is None else v)
# Noneだよ！

v = None
print("Noneだよ！" if not v else v)
# Noneだよ！

print(isinstance(None, type(None)))
print(not None)
print(None is None)
# True
# True
# True

# Pythonのこういうとこ好き
print(v or "Noneだよ！")
# Noneだよ！
```

## main

### 非同期関数を実行する
```python
import asyncio

async def main():
    print("非同期処理だよ！")


if __name__ == "__main__":
    asyncio.run(main())

# 非同期処理だよ！
```