Skip to content

Python

Status of Python versions

How-to

String

padding 0
f'{n:03}'
'%03d' % n
'{0:03d}'.format(n)
'{foo:03d}'.format(foo=n)
'{:03d}'.format(n)

data struct

Sorting Techniques — Python 3.12.3 documentation

sort by key
sorted(student_tuples, key=lambda student: student[2])
assign new dict with new key value
record.data = {**record.data, "new_key": "new_value"}

datetime, time, calendar

找每個月的最後一天是幾號

import calendar

week_day_of_first_day, num_days = calendar.monthrange(year, month)
# weekday_of_first_day: 0-6 (Mon...)

file and directories

mkdir
Path.mkdir(parents=True, exist_ok=True) # parents=True: mkdir -p, exist_ok: ignore error if folder exist

copy files or folder
import shutil

shutil.copyfile(src, dst)

# 2nd option
shutil.copy(src, dst)  # dst can be a folder; use shutil.copy2() to preserve timestamp
via: https://stackoverflow.com/a/123212/644070

Issues

函式預設輸入值如果是 listdictionaryinstance of most classes (mutable object),在函式定義的時候就建立了,之後載呼叫同一個函式會持續保留裡面的數值。

ref: - chatGPT: https://chat.openai.com/share/4be34b81-3eb6-4d99-99cf-20881e2fc831 - python docs: https://docs.python.org/3/tutorial/controlflow.html#default-argument-values

datetime

datetime — Basic date and time types — Python documentation

format codes

strptime
datetime.strptime(row['last_login'], '%Y-%m-%d %H:%M:%S+00') # 2021-01-01 12:03:34+00
datetime.strptime(row['created_time'], '%Y-%m-%d %H:%M:%S.%f+00') # # 2021-01-01 12:03:34.934533+00

csv

BOM header

encoding='utf-8-sig'

Packages

PIL, PILLOW

Image.ANTIALIAS 新版改成 Image.Resampling.LANCZOS

Build exe file

GUI

SQLAlchemy

join

query = session.query(UserSong)
query = query.join(Song, Song.id == UserSong.song_id)
query = query.filter(
    and_(
        UserSong.user_id == user.id, 
        UserSong.is_liked.is_(True),
        Song.genre == 'rock'
    )
)
join, group by
session.query(Collection.name, func.count(Record.collection_id)).select_from(Record).join(Record.collection).group_by(Collection).all()

Note: important to place with_entities after the join

query = query.with_entities(func.count())
liked_count = query.scalar()

sql_qry = select([foo.c.id.label("id"), 
                  foo.c.title.label("title"), 
                  bar.c.name.label("name")], 
                 foo.c.id == bar.c.foo_id)

my_result_qry = session.query(MyResult).from_statement(sql_qry)

ref:

Celery

查看節點統計資訊
celery -A your_project inspect stats

tatal: {'task.xxx': 數字} -> 執行的次數

查看正在執行的任務
celery -A your_project inspect active
查看活躍的 Workers
celery -A your_project_name status
restart worker
celery -A your_project_name worker --loglevel=info
同時處理 4 個任務
celery -A your_project_name worker --concurrency=4

JSON

query json
Person.query.filter(Person.source_data['pid'].astext == x)
要加 astext 不然找不到 (就如同->>, 沒加astext就是->)

要重新給一個值,不然程式會以為沒變

Update json field data
record = session.query(YourModel).first()
record.data = {**record.data, "new_key": "new_value"}  # Reassign with a new dictionary
session.commit()

Reference

Learning Resource

Cookbook

copy 100x100 images
import os
from pathlib import Path
import shutil


def copy100(prefix):
    for r, d, l in os.walk('./source-dir'):
        for f in l:
            p = Path(r, f)
            if p.suffix.upper() == '.JPG':
                target = Path('target-dir', f'{prefix}-{f}')
                shutil.copyfile(p, target)


for i in range(100):
    copy100(f'{i:03}')
change all file with JPG extension to jpg (lower-case)
from pathlib import Path
import os

for r, d, f in os.walk('/path/to'):
    for x in f:
        if '.JPG' in x:
            p = Path(r, x)
            p.rename(Path(r, x.replace('.JPG', 'jpg')))