1. ð ã¯ããã«
ååã¯DRYã»KISSã»åäžè²¬ä»»ãªã©ã®ã³ãŒãèšèšååãåŠã³ãŸããã
ä»å㯠ã³ã¡ã³ããšããã¥ã¡ã³ã ã解説ããŸãïŒ
â» ãªããµã³ãã«ã³ãŒãã¯ãã¹ãŠPythonã䜿çšããŠããŸãã
ãè¯ãã³ãŒãã¯ã³ã¡ã³ããªãã§èªãããã§ãè¯ãã³ã¡ã³ãã¯ã³ãŒããè¶ ãã䟡å€ãæã€ãã
ã³ã¡ã³ãã¯ãäœãããŠããããã§ã¯ãªããããªãããããŠãããããäŒããããã®ãã®ã§ãã
ãã®èšäºãèªãã°ïŒ
- â è¯ãã³ã¡ã³ãã»æªãã³ã¡ã³ãã®éããããã
- â ãäœããã§ã¯ãªãããªãããæžãç¿æ £ãã€ã
- â docstringã®æžãæ¹ãããã
- â ããžãã¯ãã³ããŒãæé€ããæ¹æ³ãããã
2. ð¬ ã³ã¡ã³ãã®çš®é¡
ã³ã¡ã³ãã«ã¯å€§ãã2çš®é¡ãããŸãã
| çš®é¡ | ç®ç | äŸ |
|---|---|---|
| ð ã€ã³ã©ã€ã³ã³ã¡ã³ã | ã³ãŒãã®æšªã»äžã«æžãçã説æ | # ãŠãŒã¶ãŒIDãæ€çŽ¢ããŒã«äœ¿ã |
| ð docstring | 颿°ã»ã¯ã©ã¹ã®ä»æ§ãæžãææž | """ãŠãŒã¶ãŒãååŸããã""" |
3. â æªãã³ã¡ã³ãã®5ãã¿ãŒã³
ãã¿ãŒã³â ïŒã³ãŒãã®å 容ããã®ãŸãŸæžãïŒæå³ããªãïŒ
# â ã³ãŒããæ¥æ¬èªã«ç¿»èš³ããã ãïŒèªãã°ãããïŒ
# iã1å¢ãã
i += 1
# ãŠãŒã¶ãŒãªã¹ããã«ãŒããã
for user in users:
# ãŠãŒã¶ãŒåã衚瀺ãã
print(user.name)
# â
ã³ã¡ã³ãããªããŠãã³ãŒããèªã£ãŠãã
for user in users:
print(user.name)
ã³ãŒããèªãã°ãããããšãã³ã¡ã³ãã«æžããŠãæå³ããããŸããã
ãã³ãŒãã®ç¿»èš³ãã¯ã³ã¡ã³ãã®ä»äºã§ã¯ãããŸããã
ãã¿ãŒã³â¡ïŒå€ããªã£ãã³ã¡ã³ãïŒåãã€ãã³ã¡ã³ãïŒ
# â ã³ãŒãã¯å€ãã£ãã®ã«ã³ã¡ã³ããå€ããŸãŸ
# 管çè
ã®ã¿ã¢ã¯ã»ã¹å¯èœ
def get_all_users() -> list[User]:
# â å®éã«ã¯å
šãŠãŒã¶ãŒãã¢ã¯ã»ã¹ã§ããããã«å€æŽãããã®ã«
# ã³ã¡ã³ããæŽæ°ãããŠããªãïŒ
return db.query("SELECT * FROM users")
â ïž å€ãã³ã¡ã³ãã¯ãªãã³ã¡ã³ãããæå®³ã§ãã
ã³ãŒããä¿®æ£ãããšãã¯å¿ ãã³ã¡ã³ããäžç·ã«ç¢ºèªã»æŽæ°ããŸãããã
åãã€ãã³ã¡ã³ãã¯ãã°ã®åå ã«ãªããŸãã
ãã³ãŒãã¯åãã€ããªãããã³ã¡ã³ãã¯ç°¡åã«åãã€ãã
ã³ã¡ã³ãã¯æžããç¬éãããè ãå§ããããã®ã§ãåžžã«ã¡ã³ããã³ã¹ã®ã³ã¹ããçºçããŸãã
ããã¿ã«ã³ã¡ã³ããå¢ããã®ã§ã¯ãªãããŸãã³ãŒãèªäœãã·ã³ãã«ã§èªã¿ãããæžãããšãåªå ããŸãããïŒKISSååïŒã
ã³ã¡ã³ãã¯ãã³ãŒãã§ã¯äŒããããªãæ å ±ãã«ã ã䜿ãã®ãéåã§ãã
ãã¿ãŒã³â¢ïŒã³ã¡ã³ãã¢ãŠããããã³ãŒã
# â 䜿ããªããªã£ãã³ãŒããã³ã¡ã³ãã¢ãŠãããŠæ®ããŠãã
def calculate_price(price: int, quantity: int) -> int:
# total = price * quantity * 1.08 # æ§æ¶è²»çšç
# if total > 10000:
# total = total * 0.9 # æ§å²åŒããžãã¯
total = price * quantity * 1.10
return total
â ïž ã³ã¡ã³ãã¢ãŠããããã³ãŒãã¯åé€ããŸãããïŒ
ãåŸã§äœ¿ããããããªãããããšããçç±ã§æ®ããã¡ã§ããã
Gitã§ç®¡çããŠããã®ã§ãã€ã§ãéå»ã®ã³ãŒãã«æ»ããŸãã
ã³ã¡ã³ãã¢ãŠããããã³ãŒãã¯ã³ãŒãããŒã¹ãæ±æãã
ããªãæ®ã£ãŠããã®ãããšããæ··ä¹±ãçã¿ãŸãã
ãã¿ãŒã³â£ïŒèªæãªããšãæžãã³ã¡ã³ã
# â èªãã°ããããããã³ã¡ã³ã
class User:
# ã³ã³ã¹ãã©ã¯ã¿
def __init__(self, name: str, email: str):
self.name = name # åå
self.email = email # ã¡ãŒã«
ãã¿ãŒã³â€ïŒTODOã»FIXMEãæŸçœ®ãã
# â ïž TODOãäœã¶æãæŸçœ®ãããŠããã®ã¯NG
# TODO: ããšã§ããªããŒã·ã§ã³è¿œå ãã
# FIXME: ãã®èšç®ãæ£ããã確èªããïŒ2幎åã®ã³ã¡ã³ãïŒ
def calculate_discount(price: int) -> int:
return price * 0.9
ð¡ TODOã³ã¡ã³ãã¯æžããªãå¿ ãæéã»æ åœãæèšãã
# TODO(Alice, 2026-04-01): ããªããŒã·ã§ã³ã远å ããæéã®ãªãTODOã¯æ°žé ã«æ®ãç¶ããŸãã
4. â è¯ãã³ã¡ã³ãã®3ãã¿ãŒã³
ãã¿ãŒã³â ïŒããªãããæžã
# â ãäœããããŠããããæžããŠããïŒã³ãŒããèŠãã°ãããïŒ
# ãªã¹ããéé ã«ãã
users.reverse()
# â
ããªããããããŠããããæžã
# ææ°ã®ãŠãŒã¶ãŒãå
é ã«è¡šç€ºããããã«éé ã«ãã
users.reverse()
# â
ããªããã®è¯ãäŸïŒããžãã¹ããžãã¯ã®èæ¯ãäŒãã
# éæç¡æã®éŸå€ã¯5000åïŒ2024幎4æã®äŸ¡æ Œæ¹å®ã§3000åãã倿ŽïŒ
FREE_SHIPPING_THRESHOLD = 5000
# â
ããªããã®è¯ãäŸïŒãããããããã°ãé²ã
# urllibã®ããã©ã«ãã¿ã€ã ã¢ãŠãã¯ç¡éãªã®ã§æç€ºçã«èšå®ãã
response = requests.get(url, timeout=30)
# â
ããªããã®è¯ãäŸïŒæå³çãªåŠçã§ããããšãäŒãã
# åé€ãã©ã°ãç«ãŠãã ãã§ç©çåé€ããªãïŒç£æ»ãã°ã®èŠä»¶ã®ããïŒ
user.is_deleted = True
db.save(user)
# â
ããªããã®è¯ãäŸïŒè«Šããã¢ãããŒããèšé²ããïŒå
人ã®èœãèžãŸããªãïŒïŒ
# asyncio.run()ã䜿ããšJupyterç°å¢ã§ãšã©ãŒãçºçããããã
# 代ããã«loop.run_until_complete()ã䜿ã£ãŠããŸãã
# â» asyncio.run()ã«æ»ããããªããããããªãããèŠæ³šæã
loop = asyncio.get_event_loop()
loop.run_until_complete(main())
ð¡ ã諊ããã¢ãããŒãããæ®ãããšã®äŸ¡å€
ãæåã¯Aã®æ¹æ³ã詊ãããããã®ãã°ãçºçããããããããŠBã®æ¹æ³ãæ¡çšã
ãšããã³ã¡ã³ãã¯ãæªæ¥ã®ããŒã ã¡ã³ããŒã
ãããããã£ãšã¹ããŒãã«æžãããããïŒããšå€æŽããŠåããã°ãèžãäºæ ãé²ã
匷åãªããªã¢ã«ãªããŸãã
ãã¿ãŒã³â¡ïŒè€éãªã¢ã«ãŽãªãºã ã®èª¬æ
# â
è€éãªåŠçã«ã¯èª¬æãå¿
èŠ
def calculate_moving_average(data: list[float], window: int) -> list[float]:
"""ç§»åå¹³åãèšç®ããã
ç§»åå¹³åïŒçŽè¿Nåã®ããŒã¿ã®å¹³åãé çªã«èšç®ãããã®ã
æ ªäŸ¡ãã£ãŒããæ°æž©ã®æšç§»ãªã©ããã¬ã³ããææ¡ããã®ã«äœ¿ãããã
Args:
data: å
ã®ããŒã¿ãªã¹ã
window: å¹³åãåãæéïŒNåïŒ
Returns:
ç§»åå¹³åã®ãªã¹ãïŒé·ã㯠data - window + 1ïŒ
"""
result = []
for i in range(len(data) - window + 1):
avg = sum(data[i:i + window]) / window
result.append(avg)
return result
ãã¿ãŒã³â¢ïŒå€éšã®å¶çŽã»ä»æ§ãžã®åç §
# â
å€éšã®ä»æ§ã»ããã¥ã¡ã³ããžã®åç
§
# RFC 5321ã«åŸãã¡ãŒã«ã¢ãã¬ã¹ã®æå€§é·ã¯254æå
MAX_EMAIL_LENGTH = 254
# â
APIã®å¶éãžã®åç
§
# GitHub APIã®ã¬ãŒãå¶éïŒèªèšŒæžã¿ã§5000ãªã¯ãšã¹ã/æé
# https://docs.github.com/en/rest/overview/rate-limits
MAX_REQUESTS_PER_HOUR = 5000
5. ð docstringãæžãã
docstringãšã¯ïŒ
docstringïŒããã¯ã¹ããªã³ã°ïŒãšã¯ã颿°ã»ã¯ã©ã¹ã»ã¢ãžã¥ãŒã«ã®
ã仿§æžããã³ãŒãã®äžã«æžãããã®ã§ãã
help()颿°ãIDEã®ããã¥ã¡ã³ã衚瀺æ©èœã§ãåç §ãããŸãã
Googleã¹ã¿ã€ã«ã®docstringïŒPythonïŒ
ãã®ã·ãªãŒãºã®ã³ãŒãäŸã§äžè²«ããŠäœ¿ã£ãŠããGoogleã¹ã¿ã€ã«ã§ãã
def send_email(
to: str,
subject: str,
body: str,
cc: list[str] | None = None,
) -> bool:
"""ã¡ãŒã«ãéä¿¡ããã
SMTPãµãŒããŒãçµç±ããŠã¡ãŒã«ãéä¿¡ããã
éä¿¡ã«å€±æããå Žåã¯Falseãè¿ãïŒäŸå€ã¯çºçããªãïŒã
Args:
to: éä¿¡å
ã¡ãŒã«ã¢ãã¬ã¹
subject: ä»¶å
body: æ¬æ
cc: CCã«è¿œå ããã¡ãŒã«ã¢ãã¬ã¹ã®ãªã¹ãïŒçç¥å¯ïŒ
Returns:
éä¿¡æåãªã Trueã倱æãªã False
Raises:
ValueError: ã¡ãŒã«ã¢ãã¬ã¹ã®åœ¢åŒãäžæ£ãªå Žå
Examples:
>>> send_email("alice@example.com", "ä»¶å", "æ¬æ")
True
"""
...
docstringã®åã»ã¯ã·ã§ã³
| ã»ã¯ã·ã§ã³ | å¿ é | å 容 |
|---|---|---|
| 1è¡ãµããªãŒ | â å¿ é | 颿°ãäœãããã1æã§ |
| 詳现説æ | ä»»æ | åäœã®è©³çŽ°ã»æ³šæç¹ãªã© |
Args |
åŒæ°ãããã° | åŒæ°åã»èª¬æ |
Returns |
æ»ãå€ãããã° | æ»ãå€ã®èª¬æ |
Raises |
äŸå€ãããã° | çºçããäŸå€ãšæ¡ä»¶ |
Examples |
ä»»æ | 䜿çšäŸ |
TypeScriptã®JSDoc
/**
* ã¡ãŒã«ãéä¿¡ããã
*
* SMTPãµãŒããŒãçµç±ããŠã¡ãŒã«ãéä¿¡ããã
* éä¿¡ã«å€±æããå Žåã¯falseãè¿ãã
*
* @param to - éä¿¡å
ã¡ãŒã«ã¢ãã¬ã¹
* @param subject - ä»¶å
* @param body - æ¬æ
* @param cc - CCã«è¿œå ããã¡ãŒã«ã¢ãã¬ã¹ã®ãªã¹ãïŒçç¥å¯ïŒ
* @returns éä¿¡æåãªãtrueã倱æãªãfalse
* @throws {Error} ã¡ãŒã«ã¢ãã¬ã¹ã®åœ¢åŒãäžæ£ãªå Žå
*
* @example
* ```ts
* await sendEmail("alice@example.com", "ä»¶å", "æ¬æ");
* ```
*/
async function sendEmail(
to: string,
subject: string,
body: string,
cc?: string[]
): Promise<boolean> {
...
}
ð¡ TypeScriptã®JSDocã§ã¯åãæžããªããŠããïŒ
å€ãJavaScriptã®ã³ãŒãã§ã¯@param {string} toã®ããã«
äžæ¬åŒ§ã§åãæå®ããã¹ã¿ã€ã«ãããèŠãããŸãã
ãããã¢ãã³ãªTypeScriptã§ã¯ã
VS Codeãªã©ã®ãšãã£ã¿ãã³ãŒãåŽã®åå®çŸ©ãèªåã§èªã¿åã£ãŠãããããã
JSDocã«åãæžãå¿ èŠã¯ãããŸããã
ãã©ã¡ãŒã¿ãŒåãšèª¬æã ãæžãã°ååã§ãã
å€ãã³ãŒãããŒã¹ã§@param {string}ãèŠãããŠãæ ãŠãªãããã«ããŸãããã
docstringã«æžãã¹ãã»æžããªããŠããããš
| æžãã¹ãããš | æžããªããŠããããš |
|---|---|
| 颿°ã®ç®çã»åäœã®æŠèŠ | ã³ãŒããèŠãã°ãããããš |
| åŒæ°ã®æå³ã»å¶çŽ | åæ å ±ã ãïŒåãã³ãã§ååïŒ |
| æ»ãå€ã®æå³ | å®è£ ã®è©³çްïŒã³ãŒããèŠãã°ãããïŒ |
| çºçãããäŸå€ | èªæãªåŠçã®èª¬æ |
| äœ¿ãæ¹ã®äŸ | |
| 泚æç¹ã»å¯äœçš |
6. ð¢ ããžãã¯ãã³ããŒãæé€ãã
ããžãã¯ãã³ããŒãšã¯ïŒ
ããžãã¯ãã³ããŒãšã¯ãã³ãŒãã®äžã«çªç¶çŸãããæå³ã®ããããªãæ°å€ãã®ããšã§ãã
èªãã 人ãããã®æ°åã£ãŠäœã ã£ãïŒããšæã£ããããžãã¯ãã³ããŒã§ãã
# â ããžãã¯ãã³ããŒã ããã®ã³ãŒã
def process_order(price: int, quantity: int, user_rank: int) -> int:
if quantity > 100: # ãã®100ã¯äœïŒ
price = price * 0.85 # ãã®0.85ã¯äœïŒ
if user_rank >= 3: # ãã®3ã¯äœïŒ
price = price * 0.95 # ãã®0.95ã¯äœïŒ
tax = price * quantity * 0.10
if tax > 50000: # ãã®50000ã¯äœïŒ
tax = 50000
return price * quantity + tax
# â
宿°ã«æå³ã®ããååãã€ãã
BULK_ORDER_THRESHOLD = 100 # ãŸãšãè²·ãå²åŒã®éŸå€ïŒåïŒ
BULK_DISCOUNT_RATE = 0.85 # ãŸãšãè²·ãå²åŒçïŒ15%åŒãïŒ
PREMIUM_RANK_THRESHOLD = 3 # ãã¬ãã¢ã äŒå¡ã®æäœã©ã³ã¯
PREMIUM_DISCOUNT_RATE = 0.95 # ãã¬ãã¢ã äŒå¡å²åŒçïŒ5%åŒãïŒ
TAX_RATE = 0.10 # æ¶è²»çšç
MAX_TAX_AMOUNT = 50000 # çšé¡ã®äžéïŒåïŒ
def process_order(price: int, quantity: int, user_rank: int) -> int:
"""泚æã®åèšéé¡ãèšç®ããã
Args:
price: å䟡
quantity: æ°é
user_rank: ãŠãŒã¶ãŒã®ã©ã³ã¯
Returns:
çšèŸŒåèšéé¡
"""
if quantity > BULK_ORDER_THRESHOLD:
price = int(price * BULK_DISCOUNT_RATE)
if user_rank >= PREMIUM_RANK_THRESHOLD:
price = int(price * PREMIUM_DISCOUNT_RATE)
tax = min(int(price * quantity * TAX_RATE), MAX_TAX_AMOUNT)
return price * quantity + tax
ããžãã¯ãã³ããŒã宿°åããã¡ãªãã
| ã¡ãªãã | 説æ |
|---|---|
| ð æå³ãããã |
0.85 ãã BULK_DISCOUNT_RATE ã®æ¹ãæå³ãäŒãã |
| ð§ ä¿®æ£ã1ãæã§æžã | çšçãå€ãã£ãŠã TAX_RATE ã1ãæçŽãã ãïŒDRYååãšãé£åïŒ |
| ð æ€çŽ¢ãããã | 宿°åã§æ€çŽ¢ãããšäœ¿ã£ãŠããå Žæãå šéšèŠã€ãã |
ããžãã¯ãã³ããŒä»¥å€ã泚æ
æ°å€ã ãã§ãªãæååã®ããžãã¯ãã³ããŒãèŠæ³šæã§ãã
# â æååã®ããžãã¯ãã³ããŒ
if user.role == "admin": # ãã® "admin" ããã¡ãã¡ã«æ£ãã°ããšå±éº
allow_access()
if order.status == "pending": # ã¹ãã«ãã¹ã«æ°ã¥ãã«ãã
send_reminder()
# â
宿°ãŸãã¯åæåïŒEnumïŒã«ãŸãšãã
from enum import Enum
class UserRole(Enum):
"""ãŠãŒã¶ãŒã®ããŒã«ã"""
ADMIN = "admin"
EDITOR = "editor"
VIEWER = "viewer"
class OrderStatus(Enum):
"""泚æã®ã¹ããŒã¿ã¹ã"""
PENDING = "pending"
PROCESSING = "processing"
COMPLETED = "completed"
if user.role == UserRole.ADMIN:
allow_access()
if order.status == OrderStatus.PENDING:
send_reminder()
ð¡ Enumã«ãããšã¿ã€ãããšãã£ã¿ãå³åº§ã«æ€åºããŠãããïŒ
# â æååã ãšã¿ã€ãã«æ°ã¥ãã«ãã if user.role == "admn": # ã¹ãã«ãã¹ã§ãå®è¡æãŸã§æ°ã¥ããªã ð± # â Enumãªãã¿ã€ãããç¬éã«ãšãã£ã¿ãèµ€ç·ãåŒããŠããã if user.role == UserRole.ADIMN: # å³åº§ã«ãšã©ãŒãšãããïŒ ð¯æååããã®ãŸãŸäœ¿ããš
"admin"ã"admn"ãšæžãééããŠã
ããã°ã©ã ãåããŠããŸãããã°ã®çºèŠãé ããŸãã
UserRole.ADMINã®ããã«æžãã°ãšãã£ã¿ã
ããããªã¡ã³ããŒã¯ãªãããšå³åº§ã«æããŠãããŸãã
7. ð¯ ãŸãšã
è¯ãã³ã¡ã³ã vs æªãã³ã¡ã³ã
| â è¯ãã³ã¡ã³ã | â æªãã³ã¡ã³ã | |
|---|---|---|
| å 容 | ããªããããããŠããã | ãäœããããŠãããïŒã³ãŒãã®ç¿»èš³ïŒ |
| 鮮床 | ã³ãŒããšäžç·ã«æŽæ°ããã | å€ããªã£ãŠåãã€ã |
| é | å¿ èŠãªãšããã ã | èªæãªããšã«ãæžã |
| ã³ãŒã | ã³ãŒããèªãéšåã¯ã³ã¡ã³ããªã | ã³ã¡ã³ãã¢ãŠããããã³ãŒããæ®ã |
docstringã®ãã€ã³ã
| é ç® | ãã€ã³ã |
|---|---|
| ð 1è¡ãµããªãŒ | 颿°ãäœãããã1æã§ç°¡æœã« |
| ð Args | åŒæ°ã®æå³ã»å¶çŽãæžã |
| ð Returns | æ»ãå€ãäœãæå³ãããæžã |
| â ïž Raises | çºçãããäŸå€ãæžã |
ããžãã¯ãã³ããŒã®å¯ŸåŠæ³
| 察象 | å¯ŸåŠæ³ |
|---|---|
| æ°å€ | æå³ã®ããååã®å®æ°ã«çœ®ãæãã |
| æåå | 宿°ãŸãã¯Enumã«ãŸãšãã |
| è€æ°ã®é¢é£ããå€ | Enumã¯ã©ã¹ã«ãŸãšãã |
ã³ã¡ã³ãã®é»éã«ãŒã«ïŒ
â ã³ãŒãã§ãäœããäŒããã³ã¡ã³ãã§ããªãããäŒãã
â¡ ã³ãŒããå€ãããã³ã¡ã³ããå€ãã
⢠迷ã£ãããã³ã¡ã³ããªãã§ãèªããã³ãŒãããç®æã
次å㯠ãšã©ãŒãã³ããªã³ã° ã解説ããŸãïŒ
äŸå€åŠçã®åºæ¬ã»ãšã©ãŒã¡ãã»ãŒãžã®æžãæ¹ã»
é²åŸ¡çããã°ã©ãã³ã°ã®èãæ¹ãåŠã³ãŸãð
ð¬ 質åãææ³ãããã°ãã³ã¡ã³ãæ¬ã§ãæ°è»œã«ã©ãã!
ð 圹ã«ç«ã£ãããããã&ã¹ããã¯ããé¡ãããŸã!
ð ãããŸã§èªãã§ãã ãã£ãŠãæ¬åœã«ããããšãããããŸãã!
ð ã·ãªãŒãºèšäº
- ã第äžåãã³ãŒãã®åºæ¬æ§é
- ã第äºåãåœåèŠå
- ã第äžåãã³ãŒãã®èšèšåå
- ã第ååãã³ã¡ã³ãã»ããã¥ã¡ã³ãïŒãã®èšäºïŒ
- ã第äºåããšã©ãŒãã³ããªã³ã°ïŒè¿æ¥å ¬éïŒ
- ã第å åããã¹ãã»ãã¡ã€ã«æ§é ã»ããŒãžã§ã³ç®¡çïŒè¿æ¥å ¬éïŒ