TestForge | 📊 Plogger ✍️ Blog 📚 Docs
TestForge Blog

Python AI 가이드 · 02

기본 문법

AI 라이브러리를 쓰기 전에 알아야 할 핵심 문법만 다룹니다. 전체 문법보다 자주 쓰는 패턴을 중심으로 정리합니다.

1. 자료형

# 기본 자료형
name: str = "TestForge"
score: float = 95.5
count: int = 42
is_active: bool = True

# 컬렉션
tags: list[str] = ["ai", "backend", "cloud"]
config: dict[str, int] = {"timeout": 30, "retry": 3}
unique: set[str] = {"python", "golang", "rust"}
point: tuple[int, int] = (37, 127)  # 불변

# None 체크
result = None
if result is None:
    print("아직 결과 없음")

2. 함수와 타입 힌트

AI 코드에서는 타입 힌트를 쓰는 것이 좋습니다. IDE 자동완성과 오류 감지가 크게 좋아집니다.

from typing import Optional

def calculate_score(
    answers: list[bool],
    weights: Optional[list[float]] = None,
) -> float:
    """정답 목록으로 가중 점수를 계산합니다."""
    if weights is None:
        weights = [1.0] * len(answers)
    total = sum(w for a, w in zip(answers, weights) if a)
    return total / sum(weights) * 100

score = calculate_score([True, False, True], [2.0, 1.0, 3.0])
print(f"점수: {score:.1f}점")  # 점수: 83.3점

# lambda

normalize = lambda x, mn, mx: (x - mn) / (mx - mn)
scores = [70, 85, 95, 60]
normalized = list(map(lambda x: normalize(x, min(scores), max(scores)), scores))

3. 리스트 컴프리헨션

# 기본
squares = [x**2 for x in range(10)]
evens   = [x for x in range(20) if x % 2 == 0]

# 딕셔너리 컴프리헨션
word_len = {w: len(w) for w in ["python", "ai", "model"]}
# {'python': 6, 'ai': 2, 'model': 5}

# 2D 배열 평탄화
matrix = [[1, 2], [3, 4], [5, 6]]
flat   = [n for row in matrix for n in row]

# 실전: 에러 로그 추출
logs   = ["INFO start", "ERROR timeout", "INFO done"]
errors = [log for log in logs if log.startswith("ERROR")]

4. 클래스와 dataclass

from dataclasses import dataclass, field

@dataclass
class InvestorSignal:
    code: str
    buy_pressure: float
    vwap_deviation: float
    block_trade: bool = False
    tags: list[str] = field(default_factory=list)

    @property
    def is_strong_buy(self) -> bool:
        return self.buy_pressure > 0.65 and self.vwap_deviation > 0

    def __repr__(self) -> str:
        signal = "매수" if self.is_strong_buy else "중립"
        return f"[{self.code}] {signal} (강도={self.buy_pressure:.2f})"

sig = InvestorSignal(code="005930", buy_pressure=0.72, vwap_deviation=0.8)
print(sig.is_strong_buy)  # True

5. 예외 처리

import httpx

def fetch_stock_data(code: str) -> dict:
    try:
        resp = httpx.get(f"https://api.example.com/stock/{code}", timeout=5)
        resp.raise_for_status()
        return resp.json()
    except httpx.TimeoutException:
        print(f"[{code}] 요청 타임아웃")
        return {}
    except httpx.HTTPStatusError as e:
        print(f"[{code}] HTTP {e.response.status_code}")
        return {}
    except Exception as e:
        print(f"[{code}] 예상치 못한 오류: {e}")
        return {}
    finally:
        print(f"[{code}] 조회 완료")

6. 제너레이터

from pathlib import Path

def load_logs_lazily(log_dir: str):
    for path in Path(log_dir).glob("*.log"):
        with open(path) as f:
            for line in f:
                yield line.strip()

for line in load_logs_lazily("./logs"):
    if "ERROR" in line:
        process(line)