
생성 수정
IBM * 레드햇 AX 과정 · 16강
아토믹 디자인과 데이터 파이프라인 설계
2026년 6월 15일(월) ~ 6월 19일(금)
8. 아토믹 디자인 × 차원 × null
8.1 아토믹 디자인이란
아토믹 디자인(Atomic Design) — [UI 구성 방법론]인데, [화면을 원자 → 분자 → 유기체 → 템플릿 → 페이지 5단계로 쌓아 올린다]는 점에서 다른 컴포넌트 설계법과 구별된다.
프론트엔드 방법론으로 알려져 있지만, 이 교재에서는 다르게 씁니다. 5단계가 "차원"과 "인덱스"와 "추상/구상"에 동시에 대응하기 때문입니다.
8.2 종합 개념 매핑 테이블
| 단계 (Atomic Phase) | 인덱스 | 데이터 구조 (0 vs null) | 기하학·차원 관점 | 철학적 관점 | 소프트웨어 엔지니어링 |
|---|---|---|---|---|---|
| ATOMS (원자) | 0 | 0 (데이터의 시작점) | 0차원 (점, Point) — 위치만 있고 크기가 없음 | 존재적 최소 단위 · 감각의 최소 인지 요소 | 원시 타입 / 단일 데이터 (Primitive Type / Value) |
| MOLECULES (분자) | 1 | 1 (선형 결합) | 1차원 (선, Line) — 방향성과 연결성 발생 | 요소 간의 관계성 형성 · 선형적 결합의 시작 | 기본 객체 / 컴포넌트 조합 (Simple Object / Group) |
| ORGANISMS (유기체) | 2 | 2 (면적과 면) | 2차원 (면, Plane) — 두 개 이상의 축으로 구성 | 구체적인 형상의 실재 · 독립적 개체로 인식 가능 | 복합 컴포넌트 / 구조체 (Complex Data Structure) |
| TEMPLATES (템플릿) | (공백) | null (구조는 있으나 값 없음) | 추상 (Frame / Vector) — 차원을 연결하는 설계도 | 본질과 이데아(Idea) — 내용은 비어 있으나 틀을 규정 | 인터페이스 / 추상 클래스 |
| PAGES (페이지) | 3 | 3 (인스턴스 활성화) | 3차원 (입체, Space) — 실제 물질이 채워진 공간 | 현실 세계 / 실체 — 추상이 구체화된 최종 상태 | 인스턴스 / 런타임 객체 |
이 표에서 가장 중요한 것은 TEMPLATES 행이 숫자를 갖지 않는다는 점입니다.
0 → 1 → 2 → (공백) → 3. 순서대로 세다가 한 칸이 비어 있습니다.
그 빈칸이 null 이고, 그 자리가 추상입니다.
8.3 ⭐ 0과 null의 차이 — 부재의 미학
이 절이 축 4입니다.
0,1,2단계 (실재적 상태): 메모리에 명확한 공간을 차지하고 구체적인 값(수량, 형태)이 정의된 상태입니다. 통장 잔고가0원인 것처럼 '비어 있음' 자체가 하나의 명확한 정보(Data)로 존재하는 영역입니다.TEMPLATES단계 (null): 인덱스 숫자가 비어 있는 것처럼, 데이터가 아예 존재하지 않는 '부재(Absence)' 의 상태입니다. 틀(와이어프레임)만 존재할 뿐 알맹이가 없기 때문에, 계산이나 렌더링에 직접 참여할 수 없는 판단 유보의 영역입니다.PAGES단계 (3):null이었던 템플릿에 구체적인 데이터가 주입(Injection) 되면서, 다시 명확한 인덱스3을 부여받고 메모리에 실체화됩니다.
0 | null | |
|---|---|---|
| 뜻 | 비어 있음이라는 정보 | 부재(Absence) |
| 통장으로 치면 | 잔고가 0원인 계좌가 있음 | 계좌 자체가 없음 |
| 메모리 | 공간을 차지함 | 가리키는 곳이 없음 |
| 연산 가능? | O (0 + 5 = 5) | X (null + 5 → 에러) |
| 아토믹 단계 | ATOMS / MOLECULES / ORGANISMS | TEMPLATES |
⚠️ 파이썬에는
null이 없고None이 있습니다. 이름만 다르고 역할은 같습니다. 그래서 3.4절의engine = None이 그토록 위험했던 것입니다. 부재를 복사해 온 것이니까요.engine = 0이었다면 최소한 "0이라는 값이 들어 있다"는 사실이라도 남았을 것입니다.
8.4 차원 확장 관점
- 0차원(Atoms) → 1차원(Molecules) → 2차원(Organisms): 점이 모여 선이 되고, 선이 모여 면을 이루듯 컴포넌트가 결합하며 시각적 차원이 점진적으로 확장됩니다.
- 추상 단계(Templates): 2차원의 면적 요소들을 조합하여 3차원의 입체를 만들기 전, 구조적 규칙을 정의하는 '매개 차원' 입니다. 수학적 좌표계로 치면 공간을 형성하는 '수식'이나 '함수' 자체에 해당합니다.
- 3차원(Pages): 추상의 수식에 실제 상수(콘텐츠)가 대입되어 완성된, 인간이 경험할 수 있는 가장 입체적이고 최종적인 현실 화면입니다.
8.5 철학적 관점 — 칸트의 코페르니쿠스적 전환
경험론과 합리론의 융합: 0, 1, 2차원이 외부에서 주어지는 감각적 재료(경험론) 라면,
Templates(추상) 는 이를 받아들여 가공하는 인간 정신 내부의 인식 틀(합리론) 입니다.
"내용 없는 사유는 공허하고, 개념 없는 직관은 맹목적이다." — 칸트
이 문장을 이 장의 용어로 옮기면 이렇게 됩니다.
- 데이터(내용)가 없는 템플릿은 공허(
null) 합니다. — 추상 클래스만으로는 아무 일도 못 합니다. - 템플릿(개념)이 없는 아톰들은 맹목적입니다. — 규칙 없이 흩어진 컴포넌트는 화면이 되지 못합니다.
이 두 가지가 결합할 때 비로소 완전한 인식의 대상인 Pages(3차원) 가 탄생합니다.
8.6 6주차와 연결 — 왜 추상은 메모리에 올라갈 수 없는가
6주차에서 "추상은 메모리에 올라갈 수 없다" 고 배웠습니다.
ABC를 상속한 추상 클래스는 TypeError: Can't instantiate abstract class 를 뱉으며 인스턴스화를 거부합니다.
이제 그 이유를 축 4로 다시 말할 수 있습니다.
추상 클래스 = TEMPLATES = null = 부재
↓ 구현체를 주입(Injection)
인스턴스 = PAGES = 3 = 실체
추상은 값이 0인 게 아니라 값이 null입니다. 없는 것은 메모리에 올릴 수 없습니다.
6주차의 @abstractmethod 와 이번 주의 null 은 같은 사실의 다른 표기입니다.
| 이번 주 표기 | 값 | 6주차의 이름들 |
|---|---|---|
| TEMPLATES | null | 추상(Abstraction) · 포트(Port) · AndrewsArchitectRepository |
| PAGES | 3 | 구상(Concretion) · 어댑터(Adapter) · AndrewsArchitectPgRepository |
2.6절에서 "구상은 사라지지 않는다"고 했습니다. 이제 그 말의 뜻이 분명해집니다. 누군가는
null에 값을 넣어줘야 합니다. 그 자리가 의존성 조립소입니다.
9. 데이터 파이프라인 설계 3원칙
9.1 왜 원칙이 필요한가
이번 주 후반은 타이타닉 데이터를 실제로 정제하는 작업이었습니다. 전처리 코드는 금방 지저분해집니다. 컬럼을 더하고 빼고 바꾸다 보면, 어느 단계에서 원본이 오염됐는지 아무도 모르게 됩니다.
그래서 프레임워크를 먼저 세웁니다. 세 가지 원칙입니다.
9.2 원칙 ① 데이터는 불변 (Data Immutability)
Side Effect(부작용) 방지 — 입력으로 들어온 원본 데이터(train_set)를 직접 수정(inplace=True)하거나 오염시키면,
파이프라인 후속 단계(교차 검증, 추론 등)에서 데이터 일관성이 깨지고 디버깅이 불가능해집니다.
값 불변(Value Immutability) — 원본 데이터의 메모리 주소와 내부 값은 오직 읽기 전용(Read-Only) 으로만 다루어지며, 변경이 필요한 경우 항상 복사본을 생성하거나 새로운 객체를 할당해야 합니다.
# ❌ 원본을 직접 건드림
def feature_engineering(self, train_set):
train_set.fillna(0, inplace=True) # 호출한 쪽의 데이터가 조용히 바뀐다
return train_set
# ✅ 복사본을 만들어 작업
def feature_engineering(self, train_set):
df = train_set.copy() # 첫 줄이 항상 이것
df = df.fillna(0)
return df
⭐
.copy()한 줄이 이 원칙의 전부입니다. 그리고 그 한 줄을 빼먹는 순간 "어제까지 되던 게 오늘 안 된다"는 종류의 버그가 시작됩니다.
1장과 이어집니다. 원본을 바꾸지 않는 함수는 무상태에 가깝고, 무상태에 가까우면 멱등해집니다.
feature_engineering을 두 번 호출해도 같은 결과가 나오는 이유가 .copy() 입니다.
9.3 원칙 ② 타입 변환 (Type Transformation)
의미적 상태의 변화 — 입력 데이터가 원시 데이터 레코드 형태인 'Dataset' 이라면, 피처 엔지니어링 단계를 거쳐 반환되는 결과물은 모델이 즉시 학습할 수 있는 형태의 '피처 세트(Feature Set)' 라는 새로운 논리적 타입(상태) 으로 전환됩니다.
Dataset (원시 레코드) ──feature_engineering()──▶ Feature Set (학습 가능한 표)
Name, Sex, Ticket... title, sex, age_group...
문자·결측치 있음 전부 숫자, 결측치 없음
엄격한 데이터 규격화 — Python의 타입 힌팅(-> pd.DataFrame)을 강제함으로써, 메서드 내부에서 어떤 복잡한 연산(원-핫 인코딩, 스케일링, 결측치 대체 등)이 일어나든
최종 출력 형식의 일관성을 프레임워크 수준에서 보장합니다.
두 표가 모두
pd.DataFrame이지만 논리적으로는 다른 타입입니다. 6주차에서 Schema와 DTO가 둘 다 "그냥 클래스"였지만 역할이 달랐던 것과 같습니다. 경계를 넘으면 이름이 바뀐다 — 이 교재의 반복되는 규칙입니다.
9.4 원칙 ③ 프레임워크 기반 분리 (Framework & Abstraction)
비즈니스 로직에 집중 — 개발자는 데이터베이스에 연결하거나 파일 시스템에 데이터를 읽고 쓰는 하부 인프라 코드를 매번 구현할 필요가 없습니다.
규격 강제 — @abstractmethod 구조를 통해 프레임워크를 상속받는 모든 프로젝트가
반드시 동일한 인터페이스 규격으로 피처 엔지니어링 로직을 구현하도록 강제합니다.
9.5 데이터 흐름 구조
프레임워크 내부에서 데이터가 로드되고, 변환되어, 최종 저장소로 흘러가는 메커니즘입니다.
[인프라 레이어] [로직 레이어]
Database / File ──(Framework가 자동 로드)──> train_set (원래 값 불변 유지)
│
▼
Dataset (file) <──(Framework가 자동 저장)── pd.DataFrame 반환 (새로운 타입/값 변환)
- 입력 (Data Ingestion): 프레임워크 엔진이 DB나 파일에서 원본 데이터를 조회하여
train_set형태로 추상 메서드에 주입(Dependency Injection) 합니다. - 프로세스 (Feature Engineering): 사용자는 불변성 원칙을 지키며 파생 변수 생성 및 타입 변환 로직을 수행합니다.
- 출력 (Data Persistence): 메서드가 최종 변환된
pd.DataFrame을 반환하면, 프레임워크가 이를 다시 Database(Feature Store)에 적재하거나 파일 스토리지에 Dataset 파일로 격리 저장합니다.
여기서도 주입(Injection) 이라는 단어가 나왔습니다. 2장의
Depends와 같은 원리입니다. 내가 데이터를 가지러 가는 게 아니라, 프레임워크가 데이터를 들고 나를 부릅니다. 이것이 IoC입니다.
9.6 이상적인 구현 패턴 (참조 코드)
위 3가지 원칙(값 불변, 타입 변환, 프레임워크 규격)을 코드 수준에서 보장하기 위한 베이스 클래스 및 구현체 참조 구조입니다.
from abc import ABC, abstractmethod
import pandas as pd
class BaseDataPipeline(ABC):
"""
데이터 파이프라인의 인프라 및 흐름을 관장하는 프레임워크 베이스 클래스
"""
def run_pipeline(self, source_path: str):
# 1. 인프라 레이어에서 데이터 로드 (사용자는 이 과정을 신경 쓰지 않음)
print("[Framework] 데이터베이스 또는 파일로부터 로우 데이터 로드 중...")
raw_data = pd.read_csv(source_path)
# 2. 로직 레이어 호출 (추상 메서드 실행)
print("[Framework] 피처 엔지니어링 로직 파이프라인 진입...")
transformed_df = self.feature_engineering(raw_data)
# 3. 데이터 불변성 검증 및 후속 처리 (예: 원본 행 수 비교 등)
print("[Framework] 타입 변환 완료 및 데이터 검증 성공.")
# 4. 인프라 레이어로 최종 데이터 적재/저장
print("[Framework] 변환된 Feature Set을 Database/Dataset(File)로 저장 중...")
transformed_df.to_parquet("feature_store_dataset.parquet")
return transformed_df
@abstractmethod
def feature_engineering(self, train_set: pd.DataFrame) -> pd.DataFrame:
"""
[필수 구현] 피처 엔지니어링 추상 메서드
- train_set: 값 불변 (Read-Only)
- 반환값: 타입 변환이 완료된 새로운 pd.DataFrame
"""
pass
# ==========================================
# 실제 프로젝트 적용 (구현 예시)
# ==========================================
class CustomProjectPipeline(BaseDataPipeline):
def feature_engineering(self, train_set: pd.DataFrame) -> pd.DataFrame:
# [값 불변] 원본 복사본 생성하여 Side Effect 차단
df = train_set.copy()
# [타입 변환 및 값 변환 로직 전개]
# 예시 1: 범주형 문자열 데이터 -> 정수형 타입 변환 (astype)
if 'category_name' in df.columns:
df['category_code'] = df['category_name'].astype('category').cat.codes
# 예시 2: 수치형 데이터 변환 및 파생 피처 생성
if 'raw_value' in df.columns:
df['scaled_value'] = df['raw_value'] * 1.15
# [새로운 상태의 데이터프레임 반환]
return df
9.7 이 코드의 정체 — 템플릿 메서드 패턴
run_pipeline 이 전체 골격을 정하고, feature_engineering 한 칸만 자식에게 맡깁니다.
3주차에서 GoF 23패턴을 훑을 때 나왔던 템플릿 메서드(Template Method) 패턴 그대로입니다.
| 패턴 요소 | 이 코드에서 |
|---|---|
| 골격을 정의하는 메서드 | run_pipeline (구현되어 있음) |
| 하위에 위임하는 단계 | feature_engineering (@abstractmethod) |
| 얻는 것 | 모든 프로젝트가 같은 순서를 따름 |
| 잃는 것 | 순서 자체를 바꾸고 싶으면 프레임워크를 고쳐야 함 |
8장의 용어로 다시 읽으면 이렇습니다.
BaseDataPipeline은 TEMPLATES(null) 이고,CustomProjectPipeline은 PAGES(3) 입니다. 이름부터가 Template 입니다.
10. 도메인을 값으로 쪼개기 — Value Object와 프록시 입구
10.1 DDD의 아토믹 분해 — 왜 원시 타입을 쓰지 않는가
Pclass 컬럼은 그냥 int 입니다. 코드 어디서나 1, 2, 3 으로 돌아다닙니다. 문제는 두 가지입니다.
아무 정수나 들어올 수 있고(pclass = 7 도 파이썬은 막지 않습니다),
의미가 없습니다(if pclass == 1: 을 6개월 뒤에 읽으면 무슨 뜻인지 모릅니다).
값 객체(Value Object) 는 이 두 문제를 동시에 해결합니다. 3주차 용어 사전에 나왔던 그 VO입니다. 식별자 없이 속성값 조합으로 정의되는 불변 객체.
10.2 참조 구현 — pclass_vo.py
from dataclasses import dataclass
from enum import Enum
class PClassType(int, Enum):
"""상수 3개를 하나의 의미 그룹으로 (7.2절 Enum)"""
FIRST = 1
SECOND = 2
THIRD = 3
@dataclass(frozen=True) # frozen=True → 불변. Tuple 성격의 체
class PClass:
value: PClassType # Attribute (정적 속성)
@classmethod
def from_raw(cls, raw) -> "PClass":
"""원시 값을 검증해 VO 로 승격시키는 유일한 통로"""
if raw is None or (isinstance(raw, str) and not raw.strip()):
raise ValueError("PClass 값이 비어 있습니다.")
try:
return cls(PClassType(int(raw)))
except (TypeError, ValueError):
raise ValueError(f"PClass 로 인정할 수 없는 값입니다: {raw!r}")
@property
def is_first_class(self) -> bool: # Property (동적 속성)
return self.value is PClassType.FIRST
이 40줄 안에 이 장에서 배운 것이 거의 다 들어 있습니다.
| 코드 요소 | 이 장의 어느 절 |
|---|---|
class PClassType(int, Enum) | 7.2 상수와 열거형 |
@dataclass(frozen=True) | 7.4 Tuple = 상수 성격의 체 / 9.2 불변성 |
value: PClassType | 7.2 Attribute (정적 속성) |
@property is_first_class | 7.2 Property (동적 속성) |
from_raw() 의 ValueError | 9.3 타입 변환 — 경계에서 규격을 강제 |
from_raw() 자체 | 3주차 팩토리 패턴 |
from_raw가 왜 클래스 메서드인가: 빈 값이나 잘못된 값이 VO가 되기 전에 걸러져야 하기 때문입니다.
생성자에서 검증하면 이미 객체가 만들어진 뒤입니다. 문지기는 문 앞에 서 있어야 합니다.
10.3 상관관계로 VO를 정리하기
VO를 만들다 보면 컬럼 개수만큼 파일이 생깁니다. name_vo.py, ticket_vo.py, cabin_vo.py...
전부 필요할까요? 판단 기준은 생존율과의 상관관계입니다.
작업 순서는 ① 하틀리 시각화 인터랙터(crew_hartley_violin_interactor.py)로 상관관계 그래프를 생성하고,
② "생존률과 상관관계가 높은 순으로 상관관계율까지 포함해 분석해줘" 로 수치를 뽑은 뒤,
③ 그 결과를 그대로 붙여넣고 "상관관계 없는 VO는 삭제, 관계가 깊은 것은 DDD 원칙에 따라 임베디드 타입 또는 값 타입 구조로 수정" 을 요청하는 것입니다.
이 판단으로 name_vo 는 삭제가 베스트 프랙티스로 결론이 났습니다.
이름 자체는 생존과 무관합니다. 생존과 관련 있는 것은 이름에서 뽑아낸 호칭(Title) 이지 이름 전체가 아닙니다.
⭐ 도메인 모델은 "있는 컬럼을 다 옮기는 것"이 아닙니다. "이 업무에서 의미 있는 것만 남기는 것" 입니다. 그 판단 근거를 데이터에서 가져온 것이 이번 작업입니다.
10.4 프록시를 헥사고날 입구에 걸기
스미스 선장은 이 프로젝트의 단일 진입점입니다. 사용자는 잭·칼·로우·하틀리·앤드루스를 각각 부르지 않습니다. 스미스에게만 말을 겁니다.
async def chat(self, question: str) -> str:
train_set, test_set = await self.repository.find_datasets() # 데이터 조회
feature_set = self.lowe.feature_engineering(train_set) # 전처리
chart = self.hartley.get_correlation_chart(feature_set) # 상관관계 시각화
models = await self.jack.train_model(feature_set) # 학습
best = await self.cal.test_model(test_set) # 10개 모델 점수화·1등 선발
intent = self.andrews.analyze_intent(question) # 의도 분석 (CPU-bound → def)
return self._compose_answer(intent, best, chart)
이 구조의 정체: 타이타닉에서 스미스 선장에게 단일로 확인하게 만드는 것은 프록시(Proxy) 패턴을 헥사고날 아키텍처의 입구에 거는 것입니다.
10.5 프록시 · 퍼사드 · 어댑터 — 다시 구별하기
6주차에서 gateway가 퍼사드라고 배웠습니다. 그럼 스미스는 왜 프록시일까요. 셋 다 "앞에 서 있는 객체"라서 헷갈립니다. 왜 앞에 서 있는지가 다릅니다.
| 패턴 | 왜 앞에 서는가 | 인터페이스 | 이 프로젝트에서 |
|---|---|---|---|
| 어댑터 (Adapter) | 규격이 안 맞아서 번역하려고 | 원본과 다름 | AndrewsArchitectPgRepository |
| 퍼사드 (Facade) | 뒤가 복잡해서 단순한 창구를 주려고 | 원본과 다름(더 단순) | titanic_router gateway |
| 프록시 (Proxy) | 원본과 똑같이 생겼지만 접근을 통제하려고 | 원본과 같음 | 스미스 선장 |
스미스가 프록시인 이유: 스미스는 잭이나 칼이 제공하는 것과 다른 기능을 제공하지 않습니다. 같은 일을 하되 누가 언제 어떤 순서로 호출되는지를 통제하고, 여기에 캐싱·권한 검사·로깅을 나중에 끼워 넣기도 좋습니다. 그게 프록시의 전형적인 쓰임입니다.
⚠️ 실무에서는 하나의 클래스가 세 역할을 다 하는 경우가 흔합니다. 그럴 때 "이건 무슨 패턴인가"를 다투는 건 의미가 없습니다. "왜 이 객체가 앞에 서 있는가" 를 팀이 같은 말로 설명할 수 있으면 충분합니다.
11. 실습 — 이번 주에 손으로 한 것
11.1 타이타닉 머신러닝 전체 흐름 4단계
이번 주 실습의 뼈대입니다. 코드를 쓰기 전에 이 4단계를 종이에 적고 시작합니다.
[1] 데이터 준비 → [2] 정제(전처리) → [3] AI 학습 → [4] 결과 제출
| 파일 | 정체 | Survived 컬럼 | 비유 |
|---|---|---|---|
train.csv | 학습용 데이터 | 있음 (정답 포함) | 정답이 실린 교과서 |
test.csv | 평가용 데이터 | 없음 (정답 숨김) | 정답이 지워진 시험지 |
⚠️
test.csv의 정답을 학습에 쓰면 안 됩니다. 시험지를 보고 공부하면 점수는 100점이 나오지만 실제로는 아무것도 배우지 못한 상태입니다. 이걸 데이터 누수(Data Leakage) 라고 부릅니다.
11.2 전처리 매핑값
정제 단계에서 실제로 적용한 변환 규칙 전부입니다.
| 대상 | 변환 규칙 |
|---|---|
호칭(Title) — Name 에서 추출 | Mr→1, Ms→2, Mrs→3, Master→4, Royal→5, Rare→6 |
| 성별(Sex) | 남→0, 여→1 |
| 승선항(Embarked) | S(Southampton)→1, C(Cherbourg)→2, Q(Queenstown)→3 |
| 나이(Age) | 결측은 -0.5로 처리한 뒤 구간으로 나눠 0~7 로 변환.<br>Unknown / Baby / Child / Teenager / Student / Young Adult / Adult / Senior |
| 요금(Fare) | Low / Mid / High 구간으로 구간화(binning) |
💡 왜 하필
-0.5인가: 실제 나이는 절대 음수가 될 수 없습니다. 그래서-0.5는 "측정되지 않았음"을 나타내는 안전한 신호가 됩니다.0으로 채우면 "갓 태어난 아기"와 구별되지 않습니다. 8.3절의0과null문제가 데이터 전처리에서 이렇게 나타납니다.
요금(Fare)의 구간화를 7.3절의 척도로 보면 비율(ratio) 척도를 서열(ordinal) 척도로 낮추는 작업입니다. 정보를 잃는 대신 극단값(이상치)에 흔들리지 않는 안정성을 얻습니다.
11.3 여러 모델을 학습시켜 1등을 고르기
한 알고리즘만 쓰지 않습니다. 여러 모델을 학습시켜 최고 성능을 선택합니다.
| 알고리즘 | 한 줄 성격 |
|---|---|
| Decision Tree | 조건 분기를 반복해 분류 (3주차에 첫 모델링으로 다뤘습니다) |
| Random Forest | 결정트리를 여러 개 만들어 다수결 |
| Naive Bayes | 확률 기반. 각 특성이 독립이라고 가정 |
| KNN | 가까운 이웃 K명이 뭐였는지 보고 결정 |
| SVM | 두 집단을 가장 넓은 간격으로 가르는 경계선을 찾음 |
3주차에서 배운 검증 지표(정확도·정밀도·재현율·F1)로 점수를 매겨 1등을 선발합니다.
11.4 SRP 분리 — 잭과 칼
한 파일에 학습과 평가가 같이 들어 있으면 단일 책임 원칙(SRP) 위반입니다. 그래서 쪼갭니다.
passenger_jack_trainer_interactor.py 에 섞인 train / test 중
test 를 passenger_cal_tester_interactor.py 의
async def test_model(self, test_set) 로 위임해줘.
결과
| 담당 | 파일 | 책임 |
|---|---|---|
| 잭 (Jack) | passenger_jack_trainer_interactor.py | 학습만 |
| 칼 (Cal) | passenger_cal_tester_interactor.py | 10개 모델 점수화 후 1등 선발 |
6주차에서 본 원칙 그대로입니다. 파일 이름이 그 파일의 유일한 책임을 말해야 합니다.
trainer안에 test 가 있으면 이름이 거짓말을 하고 있는 것입니다.
11.5 심볼릭 링크로 하네스 구축
AI가 보는 문서와 사람이 보는 문서가 다르면 둘의 이해가 조용히 갈라집니다. 같은 파일을 두 곳에서 보게 만들면 갈라질 수 없습니다. 그 장치가 심볼릭 링크(Symbolic Link) 입니다.
tailor/CLAUDE.md ↔ vault/tailor/CLAUDE.md
taylor/CLAUDE.md ↔ vault/taylor/CLAUDE.md
vault 는 사람이 노트 앱으로 읽고 쓰는 자리, tailor/taylor 는 AI가 프로젝트 루트에서 읽는 자리입니다.
링크로 묶으면 한쪽을 고치면 다른 쪽도 즉시 같아집니다. 복사가 아니라 같은 파일이기 때문입니다.
# 관리자 권한 PowerShell
New-Item -ItemType SymbolicLink -Path "tailor\CLAUDE.md" -Target "..\vault\tailor\CLAUDE.md"
New-Item -ItemType SymbolicLink -Path "taylor\CLAUDE.md" -Target "..\vault\taylor\CLAUDE.md"
⚠️ 윈도우는 개발자 모드로 변경해야 심볼릭 링크 적용이 가능합니다.
설정 → 개인 정보 및 보안 → 개발자용 → 개발자 모드 [켬]켜지 않으면 관리자 권한 없이는 링크 생성이 거부됩니다.
💡 심볼릭 링크는 파일을 복사하지 않고 가리키기만 합니다. 3주차의 참조(Reference)와 같은 원리이고, 6주차 Clone/Copy 대비에서 "얕은 복사"에 해당하는 자리입니다.
11.6 깃허브 팀 프로젝트 설정
애자일 방식의 브랜치 운영입니다. 콜라보레이터 4명에게 각각 브랜치를 할당하고, 각자 자기 브랜치에서 작업하며, 리드가 머지합니다. 마지막으로 CI/CD 환경변수를 설정합니다. PM이 본인 브랜치를 받아가는 명령은 이렇습니다.
git clone -b pm https://github.com/<팀-계정>/<레포이름>.git
| 옵션 | 뜻 |
|---|---|
-b pm | pm 브랜치를 처음부터 체크아웃한 상태로 클론 |
| (생략 시) | 기본 브랜치(main)를 클론 |
💡
git clone후git checkout pm을 해도 결과는 같습니다. 하지만 팀원이 5명이면 한 줄로 끝내는 쪽이 실수가 적습니다.
11.7 도커 디스크 용량 확보 — vhdx 44GB 회수
증상: C 드라이브 237GB 중 12.2GB만 남음. 원인은 %LOCALAPPDATA%\Docker\wsl\disk\docker_data.vhdx (44.1GB)
삭제하려 하면 "파일이 System에서 열려 있으므로..." 라는 메시지가 나옵니다. 도커와 WSL을 꺼도 윈도우 가상화 기능이 파일을 물고 있기 때문입니다.
방법 1: CMD로 가상 디스크 연결 해제 (가장 빠름) — 관리자 권한 명령 프롬프트에서:
diskpart
select vdisk file="%LOCALAPPDATA%\Docker\wsl\disk\docker_data.vhdx"
detach vdisk
exit
방법 2: 윈도우 서비스 중지
Windows + R→services.msc- Docker Desktop Service, LxssManager 우클릭 → [중지]
docker_data.vhdx와ext4.vhdx삭제
방법 3: 재부팅 직후 (치트키) — 재부팅 후 Docker Desktop을 절대 켜지 말고 %LOCALAPPDATA%\Docker\wsl 의 disk, main 폴더 안 파일을 삭제합니다.
⚠️ 마지막에 휴지통 비우기까지 해야 44GB가 실제로 회수됩니다. 휴지통에 있는 동안은 여전히 C 드라이브를 차지합니다.
vhdx 는 컨테이너와 이미지가 실제로 사는 가상 디스크 파일이고, 컨테이너를 지워도 자동으로 줄지 않습니다.
4.4절의 볼륨 = 디스크 대응이 실제 용량 문제로 나타난 것입니다.
11.8 실리콘밸리 스캐폴딩 — 두 번째 앱 만들기
타이타닉으로 익힌 구조를 다른 도메인에 그대로 복제해 봅니다. 프랙탈이 정말 프랙탈인지 확인하는 작업입니다.
미드 실리콘밸리 캐릭터 5명을 페르소나로 잡고,
apps/titanic 을 참조해서 apps/silicon_valley 에 스캐폴딩해줘.
11.9 프로젝트 최초 실행단계 가이드 7단계
새 프로젝트를 팀으로 시작할 때의 순서입니다. 이 순서를 지키면 첫 주에 서로 부딪히지 않습니다.
| # | 단계 |
|---|---|
| ① | 팀원 5명의 페르소나(브랜치) 정의 |
| ② | 클린 아키텍처 생성 |
| ③ | /이름/myself 테스트용 스캐폴딩 |
| ④ | 홈화면·어드민화면 생성 |
| ⑤ | 백엔드 + 프론트 동시 구동 도커 설정 |
| ⑥ | 호스트 3000·8000 둘 다 에러 없이 실행 |
| ⑦ | localhost:3000 홈에서 [관리자] 클릭 시 로그인 없이 어드민 이동, localhost:8000/api/v1/이름/myself 로 5명 이름 출력 |
⑦번이 완료 판정 기준입니다. "돌아간다"가 아니라 "이 URL에서 이 결과가 보인다" 로 성공을 정의합니다. 6주차에서 "각 단계에서 로그가 찍히면 성공"이라고 했던 것과 같은 사고방식입니다.
⚠️ ⑦번의 "로그인 없이 어드민 이동"은 개발 초기 단계에서만 허용되는 설정입니다. 인증은 나중에 붙이되, 붙이는 것을 잊으면 안 됩니다.
11.10 다크모드 스펙 문서 연결
프론트엔드 규칙을 하네스 문서에 연결하는 방법입니다.
taylor/CLAUDE.md 맨 밑 ## 다크 모드 자리에 taylor/_docs/darkmode-spec.md 실행 링크를 걸고,
프로젝트 실행 시 다크모드가 적용되게 합니다.
## 다크 모드
프로젝트 실행 시 아래 스펙을 반드시 적용한다.
→ [darkmode-spec.md](./_docs/darkmode-spec.md)
💡 왜 CLAUDE.md 안에 스펙 전문을 쓰지 않는가: 최상위 문서는 지도여야 합니다. 지도에 모든 건물의 내부 구조를 그리면 지도로 쓸 수 없습니다. 최상위 문서는 규칙과 링크만, 상세는
_docs/아래에. 11.5절의 심볼릭 링크 하네스와 같은 철학입니다.
12. 이 주의 읽을거리와 그 맥락
12.1 SOLID, 개발자를 위한 진실 혹은 신화
🔗 https://tech.kakaobank.com/posts/2411-solid-truth-or-myths-for-developers/
왜 이 주에 이게 나왔는가: 2.8절에서 AI가 만든 코드가 DIP를 절반만 적용했다는 이야기를 했습니다. 그런데 "절반"을 판정하려면 원칙의 정확한 내용을 알아야 합니다.
이 글은 SOLID를 찬양하지 않고 어디까지가 진실이고 어디부터가 신화인지를 구별합니다.
즉 "이 원칙을 언제 굽혀도 되는가" 를 묻기 시작하는 자리에 있는 글입니다. 3.3절에서 DTO 대신 pd.DataFrame 을 쓰기로 한 판단이 정확히 그 질문이었습니다.
12.2 Vibe Coding 하는 비개발자는 개발자인가
🔗 https://tech.kakao.com/posts/697
왜 이 주에 이게 나왔는가: 이 주의 실습은 대부분 AI가 만든 코드를 검수하고 고치는 일이었습니다. 코드를 타이핑한 시간보다 "이게 규칙을 지켰는가"를 판정한 시간이 길었습니다.
그렇다면 그 일을 한 사람은 개발자인가. 이 질문은 이 교재를 읽는 비전공자에게 특히 중요합니다. 2.8절의 검수 체크리스트 5문항이 이 글에 대한 이 교재의 답입니다.
코드를 쓸 줄 아는 것과 코드를 판정할 줄 아는 것은 다른 능력이고, 이제 값이 나가는 쪽은 후자입니다.
12.3 도커 디스크 용량 확보 노트
🔗 https://share.evernote.com/note/ddfb8abc-07f4-7966-bb1b-bdbfe7c5b702
왜 이 주에 이게 나왔는가: 도커를 클래스와 인스턴스로 이해하는 것(4장)과, 도커가 실제로 44GB를 먹어치웠을 때 대응하는 것(11.7절)은 다른 종류의 지식입니다. 개념만 알면 디스크가 꽉 찼을 때 아무것도 못 합니다. 개념과 대응 절차는 항상 짝으로 배웁니다.
12.4 공공 데이터와 해커톤
- 충북과학기술혁신원
- 문체부 해커톤
- 문체부 데이터셋 (공공데이터포털)
왜 이 주에 이게 나왔는가: 이번 주에 처음으로 남이 만든 데이터셋(타이타닉)으로 전체 파이프라인을 돌려봤습니다. 같은 파이프라인은 다른 데이터셋에도 그대로 적용됩니다.
타이타닉은 연습용이지만, 공공데이터포털의 데이터는 실제 문제입니다.
9장의 BaseDataPipeline 을 상속해 feature_engineering 한 칸만 바꾸면, 그대로 해커톤 출품작이 됩니다.
연습과 실전 사이의 거리가 메서드 하나라는 것이 이 주의 결론입니다.
부록 A. 용어 사전
| 용어 | 영문 | 상위 범주 | 정의 |
|---|---|---|---|
| 무상태 | Stateless | 시스템 성질 | 이전 실행의 상태를 내부에 기억하지 않는 성질 |
| 순수 함수 | Pure Function | 함수 종류 | 외부 상태에 의존·변경하지 않고 입력만으로 결과가 정해지는 함수 |
| 멱등성 | Idempotence | 연산 성질 | 여러 번 수행해도 최종 자원 상태가 같은 성질. f(f(x)) = f(x) |
| 안전 | Safe | 연산 성질 | 자원 상태를 아예 바꾸지 않는 성질. 멱등의 부분집합 |
| 멱등성 키 | Idempotency Key | HTTP 헤더 | 같은 요청임을 서버가 알아보게 하는 식별자 |
| 의존성 주입 | Dependency Injection (DI) | 기법 | 필요한 객체를 밖에서 넣어주는 것 |
| Depends | — | FastAPI 기능 | 의존성 트리를 선언하면 프레임워크가 안쪽부터 조립해 주는 장치 |
| 인터랙터 | Interactor | 구현체 | 유스케이스(input 포트)를 실제로 구현한 클래스 |
| AsyncSession | — | SQLAlchemy 객체 | 비동기 DB 세션. Repository 안에만 있어야 함 |
| 의존성 조립소 | — | 파일 역할 | 구상 객체가 태어나는 자리를 한 곳으로 모은 모듈 |
| 조기 캡처 | Early Capture | 파이썬 함정 | from m import x 가 import 시점의 값을 복사해 버리는 현상 |
| CPU-bound | — | 작업 분류 | 계산이 오래 걸리는 작업. def 로 선언 |
| I/O-bound | — | 작업 분류 | 바깥세상 응답을 기다리는 작업. async def 로 선언 |
| 이미지 | Image | Docker 개념 | 실행에 필요한 모든 것을 묶은 불변(Read-Only) 템플릿. 클래스에 대응 |
| 컨테이너 | Container | Docker 개념 | 이미지로부터 만들어져 격리 실행되는 프로세스. 인스턴스에 대응 |
| 볼륨 | Volume | Docker 개념 | 컨테이너 삭제와 무관하게 데이터를 보존하는 저장 공간. 디스크에 대응 |
| 모델 | Model | ML 결과물 | 입력을 넣으면 출력을 뱉는 예측 기계 |
| 알고리즘 | Algorithm | ML 재료 | 모델을 만들기 위한 논리적 틀. 아직 데이터를 만나지 않은 상태 |
| 형태소 분석기 | Morphological Analyzer | NLP 도구 | 문장을 의미 있는 최소 단위로 자르는 도구 |
| Kiwi | — | 형태소 분석기 | 한국어 문장 절단기. CPU-bound |
| EEVE | — | LLM | 이미 학습이 끝난 한국어 대형 언어 모델 |
| SVM | Support Vector Machine | ML 알고리즘 | 두 집단을 가장 넓은 간격으로 가르는 경계를 찾는 방법 |
| 파라미터 | Parameter | 최상위 범주 | 시스템이 작동하기 위해 쓰는 모든 변수의 통칭 |
| 모델 파라미터 | Model Parameter | 파라미터 하위 | 학습으로 자동 결정되는 값. 가중치·편향 |
| 하이퍼파라미터 | Hyperparameter | 파라미터 하위 | 사람이 학습 전에 설정하는 값. 학습률·에포크·배치 크기·은닉층 수 |
| 아규먼트 | Argument | 호출 시 값 | 함수를 호출할 때 실제로 넣는 값 |
| 자료 | Data | 가치 사슬 | 가공되지 않은 순수한 사실이나 값 |
| 정보 | Information | 가치 사슬 | 데이터에 맥락을 부여한 결과물 |
| 가치 | Value | 가치 사슬 | 정보로 의사결정을 해서 얻는 유용성 |
| 자료형 | Data Type | 수(數) 레이어 | 메모리에 저장될 형식을 정의하는 규칙 |
| 동적 타이핑 | Dynamic Typing | 언어 특성 | 실행 시점에 자료형을 자동 판단하는 방식 |
| 상수 | Constant | 수(數) 레이어 | 실행 동안 절대 변하지 않는 고정 값 |
| 열거형 | Enumeration (Enum) | 수(數) 레이어 | 상수들을 의미 있는 그룹으로 묶은 집합 |
| Attribute | — | 속성 종류 | 선언 시점에 결정되는 정적 속성 |
| Property | — | 속성 종류 | 런타임에 계산·제어되는 동적 속성 |
| 명목척도 | Nominal | 측정 척도 | 순서 없는 이름표. Sex·Embarked |
| 서열척도 | Ordinal | 측정 척도 | 서열은 있으나 간격 불명. Pclass |
| 등간척도 | Interval | 측정 척도 | 간격은 일정하나 절대 원점 없음. 온도·시각·pH |
| 비율척도 | Ratio | 측정 척도 | 절대 원점이 있어 배수가 성립. 나이·돈·몸무게 |
| 자료구조 | Data Structure | 체(體) 레이어 | 데이터를 효율적으로 관리하기 위한 논리적 뼈대 |
| 리스트 | List | 자료구조 | 순서 O, 변경 O. 변수 성격의 체 |
| 튜플 | Tuple | 자료구조 | 순서 O, 변경 X. 상수 성격의 체 |
| 딕셔너리 | Dictionary | 자료구조 | 키-값 쌍. 해시로 초고속 검색 |
| 데이터프레임 | DataFrame | 체(體) 레이어 | 행과 열의 2차원 표. 딕셔너리들을 담은 리스트 |
| 데이터셋 | Dataset | 체(體) 레이어 | 특정 목적을 위해 모은 데이터의 집합체 |
| 데이터베이스 | Database | DB 레이어 | 실시간 트랜잭션을 저장·조회하는 기저 저장소 (OLTP) |
| 데이터 웨어하우스 | Data Warehouse | DB 레이어 | 여러 DB를 ETL로 통합·축적한 분석 전용 창고 (OLAP) |
| 데이터 마트 | Data Mart | DB 레이어 | DW에서 부서·목적별로 쪼갠 서브 창고 |
| 데이터센터 | Data Center | 물리 레이어 | 모든 것이 실제로 전력을 쓰며 작동하는 빌딩 인프라 |
| 아토믹 디자인 | Atomic Design | UI 방법론 | 화면을 원자→분자→유기체→템플릿→페이지로 쌓는 설계법 |
| TEMPLATES | — | 아토믹 단계 | null. 인터페이스·추상 클래스 |
| PAGES | — | 아토믹 단계 | 3차원. 인스턴스·런타임 객체 |
| null | — | 값의 상태 | 부재(Absence). 값이 아예 없음 |
| 데이터 불변성 | Data Immutability | 설계 원칙 | 원본을 읽기 전용으로만 다루고 복사본에 작업하는 원칙. 사이드 이펙트(Side Effect) 방지 |
| 피처 세트 | Feature Set | 데이터 상태 | 모델이 즉시 학습할 수 있게 변환이 끝난 표 |
| 추상 메서드 | Abstract Method | 파이썬 문법 | @abstractmethod. 자식이 반드시 구현해야 하는 규격 |
| 템플릿 메서드 | Template Method | 행위 패턴 | 골격은 부모가 정하고 일부 단계만 자식에게 맡기는 패턴 |
| 값 객체 | Value Object (VO) | DDD 개념 | 식별자 없이 속성값 조합으로 정의되는 불변 객체 |
| 프록시 | Proxy | 구조 패턴 | 원본과 같은 인터페이스로 앞에 서서 접근을 통제하는 대리자 |
| 데이터 누수 | Data Leakage | ML 함정 | 평가용 정답이 학습에 섞여 들어가는 사고 |
| 심볼릭 링크 | Symbolic Link | OS 기능 | 다른 위치의 파일을 가리키는 링크. 복사가 아님 |
부록 B. 스스로 확인하기
먼저 답해보고, 막히면 옆의 절을 펼치세요.
| # | 질문 | 답이 있는 곳 |
|---|---|---|
| 1 | 무상태와 멱등성은 왜 같은 축에 놓을 수 없는가? | 1.1, 1.4 |
| 2 | DELETE가 404를 돌려주는데도 멱등한 이유는? | 1.3 |
| 3 | 무상태인데 멱등하지 않은 예를 하나 들 수 있는가? | 1.6 |
| 4 | Depends 체인은 어느 쪽부터 실행되는가? | 2.4 |
| 5 | 내 인터랙터가 클린한지 판정하는 한 가지 질문은? | 2.5 |
| 6 | 의존성 함수의 반환 타입은 추상인가 구상인가? 왜? | 2.6 |
| 7 | AI가 만든 코드에서 DIP 위반을 찾는 5문항은? | 2.8 |
| 8 | Kiwi 분석 함수에 async를 붙이면 왜 더 나쁜가? | 3.3 |
| 9 | from m import engine 이 None 을 물고 오는 이유는? | 3.5 |
| 10 | Image·Container·Volume은 각각 무엇에 대응하는가? | 4.5 |
| 11 | "SVM 모델을 다운로드했다"가 왜 틀린 말인가? | 5.2 |
| 12 | 모델 파라미터와 하이퍼파라미터를 가르는 질문 한 줄은? | 6.5 |
| 13 | 등간척도와 비율척도를 가르는 기준은? | 7.3 |
| 14 | List가 변수 성격, Tuple이 상수 성격인 이유는? | 7.4 |
| 15 | 데이터베이스와 데이터 웨어하우스의 차이는 크기인가? | 7.5 |
| 16 | TEMPLATES는 왜 0이 아니라 null인가? | 8.3 |
| 17 | 추상 클래스가 메모리에 못 올라가는 이유를 축 4로 설명하면? | 8.6 |
| 18 | 파이프라인 3원칙 중 .copy() 한 줄이 지키는 것은? | 9.2 |
| 19 | from_raw() 가 생성자가 아니라 클래스 메서드인 이유는? | 10.2 |
| 20 | 스미스가 퍼사드가 아니라 프록시인 이유는? | 10.5 |
| 21 | 결측 나이를 0 이 아니라 -0.5 로 채우는 이유는? | 11.2 |
| 22 | 도커 vhdx 44GB를 회수하는 세 가지 방법은? | 11.7 |
부록 C. 자주 하는 실수
| 실수 | 바로잡기 |
|---|---|
| "무상태 = 멱등성" | ❌ 서로 다른 질문입니다. POST는 무상태이면서 비멱등입니다 |
| "멱등하면 응답이 항상 같다" | ❌ 최종 자원 상태가 같은 것입니다. DELETE는 200 → 404 로 응답이 바뀝니다 |
| "GET은 멱등이니 안전하다" | ⚠️ 순서가 반대입니다. 안전 ⊂ 멱등. GET은 안전해서 멱등입니다 |
| "멱등성 키를 쓰면 무상태 유지" | ❌ 키를 기억해야 하므로 무상태를 일부 포기하는 것입니다 |
"Depends는 위에서부터 실행된다" | ❌ 안쪽(가장 깊은 의존성)부터 역으로 풀립니다 |
"인터랙터에서 commit() 해야 저장된다" | ❌ 트랜잭션 제어는 레포지토리·세션 관리 쪽 책임입니다 |
| "세션을 인터랙터에 넘겨야 편하다" | ❌ 그 순간 비즈니스 로직이 SQLAlchemy에 묶입니다 |
| "폴더를 네 개로 나눴으니 클린 아키텍처다" | ⚠️ 폴더 이름이 아니라 의존 방향이 기준입니다 |
| "AI가 만들었으니 구조는 맞을 것" | ❌ DIP를 절반만 적용한 코드가 흔합니다. 검수는 사람 몫입니다 |
"async를 다 붙이면 빠르다" | ❌ CPU-bound에 붙이면 이벤트 루프가 막히면서 더 나빠집니다 |
"from m import engine 이면 최신값이 온다" | ❌ import 시점의 값이 복사됩니다. import m 후 m.engine 으로 접근하세요 |
| "컨테이너를 지웠으니 용량이 줄었다" | ⚠️ vhdx 파일은 자동으로 줄지 않습니다 |
| "알고리즘 = 모델" | ❌ 알고리즘은 빈 틀, 모델은 데이터를 학습해 값이 채워진 상태입니다 |
| "SVM 모델을 다운로드했다" | ❌ 다운로드한 것은 라이브러리입니다. 모델은 학습해야 생깁니다 |
| "하이퍼파라미터는 학습하면서 정해진다" | ❌ 학습 전에 사람이 정합니다. 학습으로 정해지는 건 모델 파라미터입니다 |
| "파라미터와 아규먼트는 같은 말" | ❌ 정의할 때가 파라미터, 호출할 때가 아규먼트입니다 |
| "Pclass는 숫자니까 그냥 쓰면 된다" | ⚠️ 서열척도입니다. 3등실이 1등실의 3배라는 뜻이 아닙니다 |
| "DW는 DB의 큰 버전" | ❌ 크기가 아니라 목적(쓰기 vs 읽기·집계)이 다릅니다 |
"0과 null은 둘 다 비어 있음" | ❌ 0은 값이 있음, null은 부재입니다 |
| "전처리는 원본을 고쳐야 빠르다" | ❌ .copy() 없이 inplace=True 를 쓰면 후속 단계가 오염됩니다 |
| "결측 나이는 0으로 채우면 된다" | ⚠️ 갓난아기와 구별되지 않습니다. -0.5 처럼 불가능한 값을 씁니다 |
| "test.csv 로도 학습하면 점수가 오른다" | ❌ 데이터 누수입니다. 점수만 오르고 실력은 안 오릅니다 |
| "심볼릭 링크가 윈도우에서 안 만들어진다" | ⚠️ 개발자 모드를 켜야 합니다 |
부록 D. 날짜별 색인
이 장의 내용이 실제 수업에서 어느 날 다뤄졌는지입니다.
| 날짜 | 다룬 내용 | 이 장의 절 |
|---|---|---|
| 6/15 (월) | 무상태와 멱등성, HTTP 메서드별 판정표, 재전송과 분산 환경, FastAPI Depends 프랙탈 3단 구성, 인터랙터는 세션을 모른다, 추상 타입 반환, AI 생성 코드의 DIP 50% 문제와 수동 재편집, 깃허브 팀 브랜치 할당·git clone -b pm·CI/CD 환경변수 | 1, 2, 11.6 |
| 6/16 (화) | Docker와 OOP 매핑(Image/Container/Volume), 모델 vs 알고리즘, EEVE와 SVM, Kiwi 형태소 분석, 4단계 파이프라인, 파라미터 3종, 파라미터 vs 아규먼트, 타이타닉 ML 4단계, 데이터 4척도, 전처리 매핑값, 5개 알고리즘 비교, SRP 분리(잭·칼), 심볼릭 링크 하네스, 공공데이터·해커톤 | 4, 5, 6, 7.3, 11.1~11.5, 12.4 |
| 6/17 (수) | 수·체·DB 3층 지도, 자료형과 동적 타이핑, 변수·상수·Enum, Attribute와 Property, List/Tuple/Dictionary, DataFrame·Dataset, DB·DW·Mart·Center, async 판단 기준(CPU-bound/I-O-bound), Pandas 라우터는 def, 포트 인터페이스를 pd.DataFrame으로 통일, from module import 조기 캡처 버그, SOLID 정리 | 3, 7, 12.1, 12.2 |
| 6/18 (목) | 아토믹 디자인 × 차원 × null, 0과 null, 칸트, 데이터 파이프라인 3원칙, BaseDataPipeline 참조 코드, DDD 값 객체(PClassType·PClass·from_raw·is_first_class), 상관관계 기반 VO 정리와 name_vo 삭제, 스미스 체인과 프록시 입구, 도커 vhdx 44GB 회수 | 8, 9, 10, 11.7, 12.3 |
| 6/19 (금) | 실리콘밸리 페르소나 5명 스캐폴딩, 프로젝트 최초 실행단계 7단계 가이드, 3000·8000 동시 구동 도커 설정, 다크모드 스펙 문서 연결 | 11.8~11.10 |
부록 E. Gemini / NotebookLM 프롬프트
복습 문제 받기
이 8주차 교재만 근거로 8문제를 내줘. 비전공자 기준으로.
"무상태와 멱등성의 차이"와 "0과 null의 차이"는 반드시 포함해줘.
답은 바로 주지 말고, 내가 답한 다음에 채점하고
틀린 이유를 교재의 어느 절을 근거로 설명해줘. 교재에 없는 내용은 꺼내지 마.
인포그래픽 ① — 이 장의 중심 개념
「1.4 HTTP 메서드별 판정표」와 「1.7 왜 중요한가 — 분산 환경의 재전송」을 합쳐
인포그래픽 1장으로 만들어줘.
- 위쪽: GET / PUT / DELETE / POST 4칸. 각 칸에 무상태 O, 멱등 O/X 를 크게
- 아래쪽: 응답이 유실되어 클라이언트가 재전송하는 시퀀스 다이어그램
- POST 칸만 빨간색으로, 나머지 셋은 초록색으로
- "멱등성은 응답이 아니라 최종 자원 상태를 본다" 를 헤드라인으로
- 전문용어는 한글(영문) 병기
인포그래픽 ② — 의존성 주입 흐름
「2.4 해석 순서 — 안쪽부터 역으로 올라간다」를 세로 흐름도로 만들어줘.
- get_db → get_..._repository → get_..._use_case → Router 순서로 아래에서 위로
- 각 단계 오른쪽에 실제 생성되는 클래스명과 반환되는 추상 타입을 나란히
- "세션은 여기까지만" 이라는 빨간 선을 Repository 위에 가로로 긋기
- 왼쪽 세로 띠에 "추상 / 구상" 표시
인포그래픽 ③ — 3층 지도와 아토믹 계단
「7. 수·체·DB 3층 지도」와 「8.2 종합 개념 매핑 테이블」을 좌우로 나란히 놓은 한 장으로 만들어줘.
- 왼쪽: 4층(수) / 3층(체) / 2층(DB) / 1층(데이터센터) 를 위에서 아래로 쌓고,
각 층에 속하는 용어를 작은 것 → 큰 것 순서로. 3주차의 스칼라/벡터/매트릭스/텐서를 회색 글씨로 대응
- 오른쪽: ATOMS(0) → MOLECULES(1) → ORGANISMS(2) → TEMPLATES(null) → PAGES(3) 5단 계단.
TEMPLATES 칸만 점선 테두리에 반투명으로 (부재를 표현)
- 하단에 칸트 인용문 한 줄
막힐 때
8주차에서 "___" 가 이해가 안 돼.
이 교재의 판별 축 5개(기억/반복, 정적/동적, 기계학습/사람설정, 0/null, 수/체/DB)만
써서 다시 설명해줘. 교재에 없는 새 비유는 만들지 마.
미국식 분류로 다시 정리하기
이 교재에 나온 비유(엘리베이터 버튼, 시험과 공부시간, 기성품 뇌와 조립식 기계, 창고)를 전부 걷어내고,
"이것은 무엇의 한 종류인가 / 형제 개념과 무엇으로 갈리는가" 형식으로만
무상태·멱등성·안전·모델·알고리즘·모델 파라미터·하이퍼파라미터를 다시 정의해줘.
내 코드 검수 프롬프트
아래 FastAPI 코드를 8주차 2.8절의 검수 체크리스트 5문항으로 판정해줘.
각 문항마다 통과/실패와 근거가 되는 코드 줄을 인용하고,
실패한 항목은 어떻게 고쳐야 하는지 수정 코드를 보여줘.
교재에 없는 다른 원칙은 끌어오지 마.
앞 장과 연결 확인
이 교재에서 "3주차" 또는 "6주차" 라고 표시된 부분을 모두 찾아서,
그때 배운 개념이 8주차에서 어떤 새 이름으로 다시 나오는지 표로 정리해줘.
컬럼은 [앞 장의 개념 / 8주차에서의 이름 / 공통된 판별 축] 으로.
LangTailor