#!/usr/bin/env python3 """ AI 전문가 양성 과정 - 학습 진도 체크 시스템 각 파트별 완료 상태를 추적하고 학습 진도를 시각화합니다. """ import json import os import sys from datetime import datetime from pathlib import Path from typing import Dict, List, Optional class ProgressChecker: """학습 진도 체크 및 관리 클래스""" def __init__(self, progress_file: str = "learning_progress.json"): self.progress_file = progress_file self.progress_data = self._load_progress() # 파트별 체크리스트 정의 self.checklists = { "part_0": { "name": "Introduction", "items": [ "과정 소개 읽기", "AI 역사 학습", "개발 환경 설정", "Git 기본 사용법", "Jupyter Notebook 사용법" ] }, "part_1": { "name": "AI Development Environment", "items": [ "Python 설치 및 설정", "VSCode 설치 및 설정", "가상환경 생성 및 사용", "Poetry 설치 및 사용", "Docker 기본 개념 이해" ] }, "part_2": { "name": "Python Core Syntax", "items": [ "변수와 데이터 타입", "연산자와 표현식", "조건문과 반복문", "함수 정의와 호출", "예외 처리" ] }, "part_3": { "name": "Python Collections", "items": [ "리스트와 튜플", "딕셔너리와 세트", "문자열 조작", "컴프리헨션", "collections 모듈" ] }, "part_4": { "name": "Object Oriented Programming", "items": [ "클래스와 객체", "상속과 다형성", "캡슐화", "매직 메서드", "디자인 패턴 기초" ] }, "part_5": { "name": "AI Core Libraries", "items": [ "NumPy 기본 사용법", "Pandas 데이터 처리", "Matplotlib 시각화", "Scikit-learn 기초", "데이터 전처리" ] }, "part_6": { "name": "Machine Learning", "items": [ "지도학습 개념", "비지도학습 개념", "모델 평가 지표", "하이퍼파라미터 튜닝", "교차 검증" ] }, "part_7": { "name": "Deep Learning", "items": [ "신경망 기초", "PyTorch 사용법", "CNN 구현", "RNN/LSTM 구현", "Transformer 이해" ] }, "part_8": { "name": "Model Serving with FastAPI", "items": [ "FastAPI 기초", "API 설계", "모델 서빙", "Pydantic 스키마", "API 문서화" ] }, "part_9": { "name": "Production Ready API", "items": [ "프로덕션 환경 설정", "Docker 컨테이너화", "로깅과 모니터링", "보안 설정", "성능 최적화" ] }, "part_10": { "name": "Expert Path", "items": [ "AI 전문가 로드맵", "추천 학습 자료", "커리어 계획", "포트폴리오 작성", "네트워킹" ] }, "part_11": { "name": "MLOps", "items": [ "MLOps 개념", "CI/CD 파이프라인", "모델 버전 관리", "실험 추적", "모델 모니터링" ] }, "part_12": { "name": "Model Optimization", "items": [ "모델 경량화", "양자화 기법", "지식 증류", "추론 최적화", "하드웨어 가속" ] }, "part_13": { "name": "Generative AI", "items": [ "생성형 AI 개념", "LangChain 사용법", "RAG 구현", "AI 에이전트", "프롬프트 엔지니어링" ] }, "part_14": { "name": "AI Ethics", "items": [ "AI 윤리 개념", "편향성 탐지", "설명가능 AI", "개인정보 보호", "AI 거버넌스" ] }, "part_15": { "name": "Capstone Project", "items": [ "프로젝트 기획", "데이터 수집", "모델 개발", "API 구현", "배포 및 발표" ] } } def _load_progress(self) -> Dict: """진도 데이터 로드""" if os.path.exists(self.progress_file): try: with open(self.progress_file, 'r', encoding='utf-8') as f: return json.load(f) except json.JSONDecodeError: print(f"⚠️ {self.progress_file} 파일이 손상되었습니다. 새로 생성합니다.") return { "start_date": datetime.now().isoformat(), "last_updated": datetime.now().isoformat(), "parts": {} } def _save_progress(self): """진도 데이터 저장""" self.progress_data["last_updated"] = datetime.now().isoformat() with open(self.progress_file, 'w', encoding='utf-8') as f: json.dump(self.progress_data, f, ensure_ascii=False, indent=2) def mark_completed(self, part_id: str, item_index: int): """특정 항목을 완료로 표시""" if part_id not in self.checklists: print(f"❌ 알 수 없는 파트: {part_id}") return if part_id not in self.progress_data["parts"]: self.progress_data["parts"][part_id] = { "name": self.checklists[part_id]["name"], "completed_items": [], "start_date": datetime.now().isoformat(), "completion_date": None } if item_index not in self.progress_data["parts"][part_id]["completed_items"]: self.progress_data["parts"][part_id]["completed_items"].append(item_index) self.progress_data["parts"][part_id]["completed_items"].sort() # 모든 항목이 완료되면 완료 날짜 설정 if len(self.progress_data["parts"][part_id]["completed_items"]) == len(self.checklists[part_id]["items"]): self.progress_data["parts"][part_id]["completion_date"] = datetime.now().isoformat() self._save_progress() print(f"✅ {self.checklists[part_id]['name']} - {self.checklists[part_id]['items'][item_index]} 완료!") def mark_incomplete(self, part_id: str, item_index: int): """특정 항목을 미완료로 표시""" if part_id in self.progress_data["parts"]: if item_index in self.progress_data["parts"][part_id]["completed_items"]: self.progress_data["parts"][part_id]["completed_items"].remove(item_index) self._save_progress() print(f"❌ {self.checklists[part_id]['name']} - {self.checklists[part_id]['items'][item_index]} 미완료로 변경") def show_progress(self, part_id: Optional[str] = None): """진도 현황 표시""" if part_id: self._show_part_progress(part_id) else: self._show_overall_progress() def _show_part_progress(self, part_id: str): """특정 파트의 진도 표시""" if part_id not in self.checklists: print(f"❌ 알 수 없는 파트: {part_id}") return checklist = self.checklists[part_id] part_data = self.progress_data["parts"].get(part_id, {"completed_items": []}) print(f"\n📚 {checklist['name']} 진도 현황") print("=" * 50) completed_count = len(part_data["completed_items"]) total_count = len(checklist["items"]) progress_percent = (completed_count / total_count) * 100 print(f"진도: {completed_count}/{total_count} ({progress_percent:.1f}%)") print() for i, item in enumerate(checklist["items"]): status = "✅" if i in part_data["completed_items"] else "⭕" print(f"{status} {i+1:2d}. {item}") if completed_count == total_count: print(f"\n🎉 {checklist['name']} 완료!") if part_data.get("completion_date"): print(f"완료일: {part_data['completion_date'][:10]}") def _show_overall_progress(self): """전체 진도 현황 표시""" print("\n🚀 AI 전문가 양성 과정 - 전체 진도 현황") print("=" * 60) total_parts = len(self.checklists) completed_parts = 0 total_items = 0 completed_items = 0 for part_id, checklist in self.checklists.items(): part_data = self.progress_data["parts"].get(part_id, {"completed_items": []}) part_completed = len(part_data["completed_items"]) part_total = len(checklist["items"]) total_items += part_total completed_items += part_completed if part_completed == part_total: completed_parts += 1 progress_percent = (part_completed / part_total) * 100 status = "✅" if part_completed == part_total else "🔄" print(f"{status} {checklist['name']:<25} {part_completed:2d}/{part_total:2d} ({progress_percent:5.1f}%)") overall_progress = (completed_items / total_items) * 100 print("\n" + "=" * 60) print(f"📊 전체 진도: {completed_parts}/{total_parts} 파트 완료 ({overall_progress:.1f}%)") print(f"📈 완료된 항목: {completed_items}/{total_items}") if completed_parts == total_parts: print("\n🎉 축하합니다! 모든 파트를 완료하셨습니다!") def reset_progress(self, part_id: Optional[str] = None): """진도 초기화""" if part_id: if part_id in self.progress_data["parts"]: del self.progress_data["parts"][part_id] self._save_progress() print(f"🔄 {self.checklists[part_id]['name']} 진도가 초기화되었습니다.") else: self.progress_data["parts"] = {} self._save_progress() print("🔄 모든 진도가 초기화되었습니다.") def export_progress(self, filename: str = "progress_report.md"): """진도 리포트 생성""" with open(filename, 'w', encoding='utf-8') as f: f.write("# AI 전문가 양성 과정 - 학습 진도 리포트\n\n") f.write(f"생성일: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}\n\n") total_items = 0 completed_items = 0 for part_id, checklist in self.checklists.items(): part_data = self.progress_data["parts"].get(part_id, {"completed_items": []}) part_completed = len(part_data["completed_items"]) part_total = len(checklist["items"]) total_items += part_total completed_items += part_completed progress_percent = (part_completed / part_total) * 100 status = "✅" if part_completed == part_total else "🔄" f.write(f"## {status} {checklist['name']}\n\n") f.write(f"진도: {part_completed}/{part_total} ({progress_percent:.1f}%)\n\n") for i, item in enumerate(checklist["items"]): item_status = "✅" if i in part_data["completed_items"] else "⭕" f.write(f"- {item_status} {item}\n") f.write("\n") overall_progress = (completed_items / total_items) * 100 f.write(f"## 📊 전체 요약\n\n") f.write(f"전체 진도: {completed_items}/{total_items} ({overall_progress:.1f}%)\n") print(f"📄 진도 리포트가 {filename}에 저장되었습니다.") def main(): """메인 함수""" checker = ProgressChecker() if len(sys.argv) < 2: print("사용법:") print(" python progress_checker.py show [part_id] - 진도 현황 표시") print(" python progress_checker.py complete part_id item_index - 항목 완료") print(" python progress_checker.py incomplete part_id item_index - 항목 미완료") print(" python progress_checker.py reset [part_id] - 진도 초기화") print(" python progress_checker.py export [filename] - 진도 리포트 생성") print("\n예시:") print(" python progress_checker.py show") print(" python progress_checker.py show part_2") print(" python progress_checker.py complete part_2 0") print(" python progress_checker.py export my_progress.md") return command = sys.argv[1] if command == "show": part_id = sys.argv[2] if len(sys.argv) > 2 else None checker.show_progress(part_id) elif command == "complete": if len(sys.argv) < 4: print("❌ 파트 ID와 항목 인덱스를 지정해주세요.") return part_id = sys.argv[2] item_index = int(sys.argv[3]) checker.mark_completed(part_id, item_index) elif command == "incomplete": if len(sys.argv) < 4: print("❌ 파트 ID와 항목 인덱스를 지정해주세요.") return part_id = sys.argv[2] item_index = int(sys.argv[3]) checker.mark_incomplete(part_id, item_index) elif command == "reset": part_id = sys.argv[2] if len(sys.argv) > 2 else None checker.reset_progress(part_id) elif command == "export": filename = sys.argv[2] if len(sys.argv) > 2 else "progress_report.md" checker.export_progress(filename) else: print(f"❌ 알 수 없는 명령어: {command}") if __name__ == "__main__": main()