PHASE 01 · 상세판

Python 프로그래밍 입문

처음부터 시작하여 매일 무엇을 배우고, 어떻게 배우고, 무엇을 연습할지 모두 안내합니다

총 기간: 2~3주
매일 투자: 2~3시간
사전 요구사항: 제로 베이스

📋 학습 일정 목차

DAY1-2
환경 구축 + 첫 번째 프로그램
도구부터 먼저 준비합시다
⬇️ Python 설치 필수

python.org에서 최신 Python 3.12+를 다운로드하고, 설치 시 반드시 "Add Python to PATH"를 체크하세요(Windows). Mac 사용자는 Homebrew 사용을 권장합니다: brew install python.

TERMINAL — 설치 확인
# 터미널 / 명령줄을 열고 입력:
python --version     # Python 3.12.x가 표시되어야 함
pip --version        # pip 24.x.x가 표시되어야 함
📝 편집기 선택 필수

VS Code(무료, 풍부한 플러그인)를 추천합니다. 설치 후 Python 확장(Microsoft 제작)을 설치하면 코드 하이라이팅, 자동 완성, 원클릭 실행을 사용할 수 있습니다.

💡 초보자 팁

편집기 선택에 고민하지 마세요. VS Code가 현재 업계에서 가장 주류인 선택입니다. 일단 사용해 보세요.

👋 첫 번째 Python 프로그램 필수

hello.py라는 파일을 만들고 아래 코드를 작성한 다음, 터미널에서 python hello.py를 실행하세요

hello.py
# 나의 첫 번째 Python 프로그램
print("Hello, World!")
print("안녕하세요, 세계!")

# 간단한 계산을 해봅시다
print(1 + 1)          # 출력: 2
print(10 * 3)         # 출력: 30
print("AI" * 3)      # 출력: AIAIAI

# 사용자 입력 받기
name = input("이름이 뭐예요? ")
print(f"안녕하세요, {name}! Python 학습을 환영합니다")

📌 기억할 것

  • print() — 화면에 내용을 출력
  • input() — 사용자의 키보드 입력을 받음
  • f"...{변수}..." — f-string 포맷팅, 변수를 문자열에 삽입
  • # 주석 — #으로 시작하는 것은 주석이며, 실행되지 않음

🏋️ Day 1-2 연습

프로그램 작성: 사용자의 이름과 나이를 묻고 "XX님 안녕하세요, 내년이면 XX살이시네요!"를 출력
간단한 계산기 작성: 두 숫자를 입력받아 덧셈, 뺄셈, 곱셈, 나눗셈 결과를 출력
DAY3-4
변수와 데이터 타입
Python의 "빌딩 블록" — 모든 데이터의 기본 형태
📦 변수: 데이터에 이름 붙이기 필수

변수는 데이터를 가리키는 이름입니다. Python은 타입을 선언할 필요 없이 바로 값을 할당하면 됩니다.

variables.py
# ---- 기본 할당 ----
age = 25                   # 정수 int
price = 9.99               # 부동소수점 float
name = "철수"              # 문자열 str
is_student = True          # 불리언 bool

# ---- 타입 확인 ----
print(type(age))           # <class 'int'>
print(type(name))          # <class 'str'>

# ---- 타입 변환 ----
age_str = "25"             # 이것은 문자열 "25"
age_num = int(age_str)     # 숫자 25로 변환
price_str = str(price)     # 숫자를 문자열 "9.99"로 변환

# ---- 명명 규칙 ----
user_name = "좋음"           # ✅ 밑줄로 연결(권장)
userName = "비권장"         # ❌ 카멜 케이스(Python에서는 잘 사용하지 않음)
🔤 문자열 작업 (중요!) 필수

AI 개발에서 많은 시간을 텍스트 처리에 사용하므로, 문자열 작업은 가장 자주 쓰이는 기술 중 하나입니다.

strings.py
text = "Hello, Python World!"

# ---- 기본 작업 ----
print(len(text))             # 길이: 21
print(text.lower())          # 전부 소문자: hello, python world!
print(text.upper())          # 전부 대문자: HELLO, PYTHON WORLD!
print(text.replace("World", "AI"))  # 치환: Hello, Python AI!

# ---- 슬라이싱 (매우 자주 사용) ----
print(text[0])               # 첫 번째 문자: H
print(text[7:13])            # 추출: Python
print(text[-6:])             # 뒤에서 6개: orld!

# ---- 분할과 결합 ----
words = text.split(",")      # 쉼표로 분할: ['Hello', ' Python World!']
joined = " | ".join(["a", "b", "c"])  # 결합: a | b | c

# ---- 검색과 판단 ----
print("Python" in text)     # True (포함 여부)
print(text.startswith("Hello"))  # True
print(text.find("Python"))   # 7 (위치 반환)

# ---- f-string 포맷팅 (가장 권장) ----
name = "철수"
score = 95.6
print(f"{name}의 성적은 {score:.1f}점입니다")  # 철수의 성적은 95.6점입니다

📌 AI 개발에서 가장 자주 쓰는 문자열 작업

  • .strip() — 앞뒤 공백/줄바꿈 제거 (데이터 정리 필수)
  • .split() — 구분자로 문자열 분할
  • "".join() — 리스트를 문자열로 다시 결합
  • f"..." — 포맷 출력 (prompt 조합 시 매일 사용)
🔢 숫자와 연산 중요
numbers.py
# ---- 기본 연산 ----
print(10 + 3)     # 덧셈: 13
print(10 - 3)     # 뺄셈: 7
print(10 * 3)     # 곱셈: 30
print(10 / 3)     # 나눗셈: 3.3333 (결과는 부동소수점)
print(10 // 3)    # 정수 나눗셈: 3
print(10 % 3)     # 나머지: 1
print(2 ** 10)    # 거듭제곱: 1024

# ---- 자주 쓰는 내장 함수 ----
print(abs(-5))     # 절대값: 5
print(round(3.7))  # 반올림: 4
print(max(1,5,3))  # 최대값: 5
print(min(1,5,3))  # 최소값: 1

🏋️ Day 3-4 연습

프로그램 작성: 영어 문장을 입력받아 단어 수와 문자 수를 출력
온도 변환기 작성: 섭씨를 입력받아 화씨를 출력 (공식: F = C × 9/5 + 32)
f-string으로 자기소개를 작성하세요. 이름, 나이, 직업을 포함
DAY5-6
조건 판단과 반복문
프로그램에 "로직"을 부여 — 판단하고, 반복하기
🔀 if / elif / else 조건 판단 필수
conditions.py
score = 85

# ---- 기본 판단 ----
if score >= 90:
    print("우수")
elif score >= 60:
    print("합격")
else:
    print("불합격")

# ---- 비교 연산자 ----
# ==  같음     !=  다름
# >   크다     <   작다
# >=  크거나 같다  <=  작거나 같다

# ---- 논리 연산자 ----
age = 20
has_id = True

if age >= 18 and has_id:
    print("입장 가능")

if age < 12 or age > 65:
    print("할인 적용")

if not has_id:
    print("신분증을 제시해 주세요")

# ---- 문자열 내용 판단 (AI 개발에서 자주 사용) ----
user_input = "안녕하세요"
if "안녕" in user_input:
    print("인사말 감지됨")

⚠️ 자주 하는 실수

Python은 들여쓰기(4칸 공백)로 코드 블록을 구분합니다. 중괄호 {}가 아닙니다. 들여쓰기가 맞지 않으면 IndentationError가 발생하며, 이것이 초보자가 가장 자주 겪는 에러입니다.

🔁 for 반복문 필수
for_loop.py
# ---- 리스트 순회 ----
fruits = ["사과", "바나나", "귤"]
for fruit in fruits:
    print(f"저는 {fruit}를 좋아합니다")

# ---- range()로 숫자 시퀀스 생성 ----
for i in range(5):           # 0, 1, 2, 3, 4
    print(i)

for i in range(1, 11):      # 1부터 10까지
    print(i)

# ---- 인덱스와 함께 순회 (enumerate) ----
for index, fruit in enumerate(fruits):
    print(f"{index}: {fruit}")

# ---- 문자열 순회 ----
for char in "Python":
    print(char, end=" ")     # P y t h o n
🔄 while 반복문 + break / continue 중요
while_loop.py
# ---- 기본 while ----
count = 0
while count < 5:
    print(f"{count + 1}번째")
    count += 1

# ---- break: 즉시 반복문 탈출 ----
while True:
    cmd = input("명령을 입력하세요 (quit으로 종료): ")
    if cmd == "quit":
        break
    print(f"입력하신 내용: {cmd}")

# ---- continue: 현재 반복 건너뛰기 ----
for i in range(10):
    if i % 2 == 0:       # 짝수 건너뛰기
        continue
    print(i)              # 출력: 1, 3, 5, 7, 9

🏋️ Day 5-6 연습

숫자 맞추기 게임: 프로그램이 1-100 사이의 랜덤 숫자를 생성하고, 사용자가 반복적으로 추측하며 "크다/작다" 힌트를 주고 맞출 때까지 계속
구구단: 이중 for 반복문으로 출력
FizzBuzz: 1부터 50까지, 3의 배수는 Fizz, 5의 배수는 Buzz, 3과 5의 공배수는 FizzBuzz 출력
DAY7-8
리스트와 딕셔너리
가장 중요한 두 가지 데이터 구조, AI 개발에서 모든 코드에 사용됩니다
📋 리스트 (List) 필수

리스트는 순서가 있는 데이터 모음으로, []로 표현하며 어떤 타입의 데이터든 넣을 수 있습니다.

lists.py
# ---- 리스트 생성 ----
nums = [1, 2, 3, 4, 5]
names = ["철수", "영희", "민수"]
mixed = [1, "hello", True, 3.14]   # 여러 타입 혼합 가능

# ---- 추가, 삭제, 수정, 조회 ----
names.append("지훈")          # 끝에 추가
names.insert(0, "수진")       # 지정 위치에 삽입
names.remove("영희")          # 지정 요소 삭제
last = names.pop()            # 마지막 요소를 삭제하고 반환
names[0] = "대왕"            # 요소 수정

# ---- 슬라이싱 (문자열과 동일) ----
print(nums[1:3])              # [2, 3]
print(nums[-2:])              # [4, 5]

# ---- 자주 쓰는 작업 ----
print(len(nums))              # 길이: 5
print(sorted(nums, reverse=True))  # 내림차순 정렬
print(3 in nums)              # True (포함 여부)

# ---- 리스트 컴프리헨션 (매우 자주 사용!) ----
squares = [x**2 for x in range(10)]
# [0, 1, 4, 9, 16, 25, 36, 49, 64, 81]

even = [x for x in range(20) if x % 2 == 0]
# [0, 2, 4, 6, 8, 10, 12, 14, 16, 18]
🗂️ 딕셔너리 (Dict) — AI 개발의 핵심 데이터 구조 필수

딕셔너리는 키-값 쌍의 모음으로, {}로 표현합니다. API가 반환하는 JSON 데이터는 본질적으로 딕셔너리이므로, 반드시 능숙하게 다룰 수 있어야 합니다!

dicts.py
# ---- 딕셔너리 생성 ----
person = {
    "name": "철수",
    "age": 25,
    "skills": ["Python", "SQL"],
    "is_student": False
}

# ---- 접근과 수정 ----
print(person["name"])           # 철수
print(person.get("age"))       # 25 (권장, 키가 없으면 None 반환)
print(person.get("email", "없음")) # "없음" (키가 없으면 기본값 반환)

person["age"] = 26            # 수정
person["email"] = "[email protected]"  # 추가
del person["is_student"]       # 삭제

# ---- 딕셔너리 순회 ----
for key, value in person.items():
    print(f"{key}: {value}")

# ---- 중첩 딕셔너리 (API 반환값 시뮬레이션) ----
api_response = {
    "status": "success",
    "data": {
        "message": "안녕하세요, 세계",
        "tokens": 15
    }
}
# 중첩된 값 추출
msg = api_response["data"]["message"]
print(msg)  # 안녕하세요, 세계

📌 딕셔너리가 왜 이렇게 중요할까?

  • 대규모 언어 모델 API의 요청과 반환값은 전부 JSON 형식 = Python 딕셔너리
  • 설정 파일, Prompt 템플릿 관리에 모두 딕셔너리 사용
  • 이후 배울 Pandas의 각 행 데이터도 본질적으로 키-값 쌍

🏋️ Day 7-8 연습

연락처 딕셔너리 만들기: "연락처 추가, 연락처 검색, 연락처 삭제, 전체 표시" 기능 지원
텍스트에서 각 단어의 출현 횟수를 세어 딕셔너리에 저장하고 빈도순으로 정렬
API 반환값 시뮬레이션: 중첩 딕셔너리를 만들고 다층 접근으로 값 추출 연습
DAY9-10
함수
반복되는 코드를 "도구"로 패키징 — 유지보수 가능한 코드 작성의 핵심
🔧 함수 정의와 호출 필수
functions.py
# ---- 기본 함수 ----
def greet(name):
    """누군가에게 인사하기"""
    return f"안녕하세요, {name}!"

result = greet("철수")
print(result)   # 안녕하세요, 철수!

# ---- 기본 매개변수 ----
def call_api(prompt, model="gpt-4", temperature=0.7):
    print(f"모델: {model}, 온도: {temperature}")
    print(f"프롬프트: {prompt}")

call_api("안녕하세요")                          # 기본 매개변수 사용
call_api("안녕하세요", model="claude")           # 모델만 변경
call_api("안녕하세요", temperature=0.2)          # 온도만 변경

# ---- 여러 값 반환 ----
def analyze_text(text):
    word_count = len(text.split())
    char_count = len(text)
    return word_count, char_count

words, chars = analyze_text("Hello World Python")
print(f"단어 수: {words}, 문자 수: {chars}")

# ---- 딕셔너리 반환 (AI 개발에서 흔한 패턴) ----
def process_response(raw_text):
    return {
        "content": raw_text.strip(),
        "length": len(raw_text),
        "is_empty": len(raw_text.strip()) == 0
    }
Lambda와 자주 쓰는 내장 함수 중요
lambda_builtins.py
# ---- lambda: 한 줄로 만드는 간단한 함수 ----
double = lambda x: x * 2
print(double(5))     # 10

# ---- 정렬 시 규칙 지정 (매우 자주 사용) ----
students = [
    {"name": "철수", "score": 85},
    {"name": "영희", "score": 92},
    {"name": "민수", "score": 78},
]
# 점수 높은 순으로 정렬
ranked = sorted(students, key=lambda s: s["score"], reverse=True)

# ---- map / filter ----
nums = [1, 2, 3, 4, 5]
doubled = list(map(lambda x: x * 2, nums))    # [2, 4, 6, 8, 10]
evens = list(filter(lambda x: x % 2 == 0, nums)) # [2, 4]

# 하지만 리스트 컴프리헨션이 더 권장됩니다 (더 Pythonic)
doubled = [x * 2 for x in nums]
evens = [x for x in nums if x % 2 == 0]

🏋️ Day 9-10 연습

build_prompt(role, question) 함수 작성: 완전한 AI 프롬프트 템플릿 생성
학생 리스트(딕셔너리 리스트)를 받아 평균 점수와 최고 점수 학생 이름을 반환하는 함수 작성
"간이 비밀번호 강도 검사기" 함수 작성: 길이, 대소문자 포함 여부, 숫자 포함 여부 체크
DAY11-12
파일 작업과 모듈
파일 읽기/쓰기 + 코드 구조화 — "스크립트 작성"에서 "프로젝트 개발"로
📄 파일 읽기/쓰기 필수
file_io.py
# ---- 파일 쓰기 ----
with open("output.txt", "w", encoding="utf-8") as f:
    f.write("첫 번째 줄 내용\n")
    f.write("두 번째 줄 내용\n")

# ---- 파일 읽기 ----
with open("output.txt", "r", encoding="utf-8") as f:
    content = f.read()          # 전체 내용 읽기
    print(content)

with open("output.txt", "r", encoding="utf-8") as f:
    lines = f.readlines()       # 줄별로 읽기, 리스트 반환
    for line in lines:
        print(line.strip())     # strip()으로 줄바꿈 제거

# ---- 내용 추가 ----
with open("output.txt", "a", encoding="utf-8") as f:
    f.write("추가된 세 번째 줄\n")

📌 with 문의 의미

  • with open()은 코드 블록이 끝나면 자동으로 파일을 닫아줍니다. 수동으로 close()할 필요 없음
  • 항상 encoding="utf-8"을 추가하여 한글 깨짐 방지
  • "w" = 쓰기(덮어쓰기), "r" = 읽기, "a" = 추가
📦 모듈, 패키지와 pip 필수
modules.py
# ---- 표준 라이브러리 임포트 ----
import os
import random
from datetime import datetime
from pathlib import Path

# os 모듈: 파일 경로 작업
print(os.getcwd())              # 현재 작업 디렉토리
print(os.path.exists("output.txt"))  # 파일 존재 여부

# pathlib (더 현대적인 경로 처리 방법)
p = Path("data") / "output.txt"  # 자동으로 경로 구분자 처리

# random 모듈
print(random.randint(1, 100))  # 랜덤 정수
print(random.choice(["a", "b", "c"]))  # 랜덤 선택

# datetime 모듈
now = datetime.now()
print(now.strftime("%Y-%m-%d %H:%M"))  # 2026-03-30 14:30
TERMINAL — pip으로 서드파티 패키지 설치
# 서드파티 패키지 설치
pip install requests         # HTTP 요청 라이브러리
pip install pandas           # 데이터 처리 라이브러리
pip install python-dotenv    # 환경 변수 관리

# 설치된 패키지 확인
pip list

# 가상 환경 만들기 (프로젝트마다 하나씩 권장)
python -m venv myenv         # 생성
source myenv/bin/activate    # 활성화 (Mac/Linux)
myenv\Scripts\activate       # 활성화 (Windows)

🏋️ Day 11-12 연습

일기 프로그램 작성: 실행할 때마다 diary.txt에 당일 날짜와 내용을 추가
파일 일괄 처리: 폴더 내 모든 .txt 파일을 읽어 각 파일의 줄 수를 통계
새 가상 환경에 requests 라이브러리를 설치하고 정상적으로 import되는지 확인
DAY13-14
실용 서드파티 라이브러리
이 세 가지 라이브러리를 배우면 API 호출 + 데이터 처리가 가능합니다
🌐 requests — HTTP 요청 (API 호출 필수) 필수
use_requests.py
import requests

# ---- GET 요청 (데이터 가져오기) ----
response = requests.get("https://api.github.com/users/octocat")
print(response.status_code)    # 200 = 성공

data = response.json()          # JSON → Python 딕셔너리
print(data["name"])             # The Octocat
print(data["public_repos"])    # 8

# ---- POST 요청 (데이터 보내기, AI API 호출에 사용) ----
url = "https://api.example.com/chat"
headers = {
    "Authorization": "Bearer YOUR_API_KEY",
    "Content-Type": "application/json"
}
payload = {
    "model": "gpt-4",
    "messages": [
        {"role": "user", "content": "안녕하세요"}
    ]
}
response = requests.post(url, headers=headers, json=payload)
result = response.json()

# ---- 에러 처리 ----
if response.status_code == 200:
    print("성공!")
else:
    print(f"에러 발생: {response.status_code}")
📊 json — 데이터 교환 형식 필수
use_json.py
import json

# ---- 딕셔너리 → JSON 문자열 ----
data = {"name": "철수", "scores": [85, 92, 78]}
json_str = json.dumps(data, ensure_ascii=False, indent=2)
print(json_str)

# ---- JSON 문자열 → 딕셔너리 ----
parsed = json.loads(json_str)
print(parsed["name"])         # 철수

# ---- JSON 파일 읽기/쓰기 ----
with open("config.json", "w", encoding="utf-8") as f:
    json.dump(data, f, ensure_ascii=False, indent=2)

with open("config.json", "r", encoding="utf-8") as f:
    loaded = json.load(f)
    print(loaded)

💡 json과 dict의 관계

JSON은 텍스트 형식이고, Python 딕셔너리는 메모리 내 데이터 구조입니다. json.dumps()는 딕셔너리를 텍스트로 변환하고, json.loads()는 텍스트를 딕셔너리로 되돌립니다. API 통신은 이것들에 전적으로 의존합니다.

🔑 dotenv — API Key 관리 (보안 최우선) 중요
.env 파일 (GitHub에 업로드하지 마세요!)
OPENAI_API_KEY=sk-xxxxxxxxxxxxxxxxxxxxxxxx
MODEL_NAME=gpt-4
use_dotenv.py
import os
from dotenv import load_dotenv

load_dotenv()  # .env 파일 로드

api_key = os.getenv("OPENAI_API_KEY")
model = os.getenv("MODEL_NAME", "gpt-3.5-turbo")  # 기본값 설정 가능
print(f"사용 모델: {model}")

⚠️ 보안 경고

절대로 API Key를 코드에 직접 작성하지 마세요! .env 파일로 관리하고, .gitignore에서 .env를 제외하세요. 이것은 업무에서의 철칙입니다.

🏋️ Day 13-14 연습

requests로 공개 API(날씨 API, GitHub API 등) 호출하여 결과를 JSON 파일로 저장
설정 관리 도구 작성: JSON 설정 파일을 읽고 수정 및 저장 지원
.env 파일에 API Key를 저장하고 dotenv로 읽어 요청에서 사용
DAY15-17
디버깅 능력 + 종합 프로젝트
"코드를 작성할 수 있는 것"에서 "문제를 해결할 수 있는 것"으로 진화
🐛 에러 메시지 읽는 법 필수

디버깅을 못하면 영원히 다른 사람에게 의존하게 됩니다. 에러 메시지를 읽는 법을 배우는 것이 독립적인 개발의 분수령입니다.

자주 나오는 에러 타입
# ❌ SyntaxError — 문법 오류
# 에러가 가리키는 줄 번호를 확인하세요. 보통 콜론, 괄호, 따옴표가 빠져 있음
if x == 1     # 콜론 : 빠짐

# ❌ NameError — 변수명이 존재하지 않음
print(username)  # username을 정의한 적 없음

# ❌ TypeError — 타입 불일치
"age: " + 25    # 문자열과 숫자를 직접 결합할 수 없음, str(25)로 변환 필요

# ❌ KeyError — 딕셔너리에서 해당 key를 찾을 수 없음
data = {"name": "철수"}
data["age"]     # data.get("age")를 사용하는 것이 더 안전함

# ❌ IndexError — 리스트 인덱스 범위 초과
lst = [1, 2, 3]
lst[5]           # 인덱스 0, 1, 2만 존재

# ❌ FileNotFoundError — 파일을 찾을 수 없음
open("없는파일.txt")  # 경로와 파일명 확인

📌 디버깅 3단계 방법

  • 1단계: 에러 메시지의 마지막 줄을 보세요 — 에러 타입과 원인을 알려줍니다
  • 2단계: 에러 메시지의 줄 번호를 확인하세요 — 에러가 발생한 위치를 파악
  • 3단계: 에러 메시지를 ChatGPT / Claude에 복사하세요 — AI가 직접 찾는 것보다 10배 빠르게 설명해 줍니다
🛡️ try / except 예외 처리 필수
error_handling.py
# ---- 기본 예외 처리 ----
try:
    num = int(input("숫자를 입력하세요: "))
    result = 100 / num
    print(f"결과: {result}")
except ValueError:
    print("유효한 숫자를 입력해 주세요!")
except ZeroDivisionError:
    print("0으로 나눌 수 없습니다!")
except Exception as e:
    print(f"알 수 없는 에러 발생: {e}")

# ---- 실제 응용: 안전한 API 호출 ----
import requests

def safe_api_call(url):
    try:
        response = requests.get(url, timeout=10)
        response.raise_for_status()  # 200이 아니면 예외 발생
        return response.json()
    except requests.Timeout:
        print("요청 시간 초과")
    except requests.RequestException as e:
        print(f"요청 실패: {e}")
    return None
🏆 Phase 1 종합 프로젝트: CSV 데이터 처리기 필수

앞에서 배운 모든 지식을 하나로 엮어 완전한 작은 도구를 만듭니다. 이것이 Phase 1의 "졸업 작품"입니다.

project.py — CSV 데이터 처리기
import json
import os

def read_csv(filepath):
    """CSV 파일을 읽어 딕셔너리 리스트로 반환"""
    try:
        with open(filepath, "r", encoding="utf-8") as f:
            lines = f.readlines()
        headers = lines[0].strip().split(",")
        data = []
        for line in lines[1:]:
            values = line.strip().split(",")
            row = dict(zip(headers, values))
            data.append(row)
        return data
    except FileNotFoundError:
        print(f"파일이 존재하지 않습니다: {filepath}")
        return []

def filter_data(data, column, value):
    """조건에 따라 데이터 필터링"""
    return [row for row in data if row.get(column) == value]

def summarize(data, column):
    """숫자 열의 합계와 평균값 계산"""
    values = [float(row[column]) for row in data if column in row]
    return {
        "count": len(values),
        "sum": sum(values),
        "average": sum(values) / len(values) if values else 0
    }

def save_result(data, filepath):
    """결과를 JSON으로 저장"""
    with open(filepath, "w", encoding="utf-8") as f:
        json.dump(data, f, ensure_ascii=False, indent=2)
    print(f"결과가 {filepath}에 저장되었습니다")

# ---- 메인 로직 ----
if __name__ == "__main__":
    data = read_csv("students.csv")
    print(f"총 {len(data)}건의 데이터를 읽었습니다")

    # 필터링
    class_a = filter_data(data, "class", "A")
    print(f"A반 학생: {len(class_a)}명")

    # 통계
    stats = summarize(data, "score")
    print(f"평균 점수: {stats['average']:.1f}")

    # 저장
    save_result(stats, "result.json")

🏋️ 종합 프로젝트 확장 도전

CSV 처리기에 "정렬" 기능 추가: 특정 열 기준으로 오름차순/내림차순 정렬
명령줄 인터랙션 추가: 사용자가 실행할 작업을 선택 (필터링/통계/저장)
에러 처리 추가: 빈 파일, 데이터 누락, 타입 에러 등 경계 케이스 처리

🏁 Phase 1 통과 자가 점검 목록

아래 항목을 모두 완료할 수 있다면, Phase 2로 진입할 준비가 된 것입니다:

📚 추천 학습 자료

무료 강좌점프 투 파이썬 — wikidocs.net (한국어, 초보자 친화적)
무료 강좌파이썬 코딩 도장 — dojang.io (한국어, 설명이 자세함)
영상Python for Beginners — YouTube (Mosh) / 유튜브에서 "파이썬 기초" 검색
연습LeetCode 쉬운 문제 (매일 1문제, 논리적 사고력 훈련)
AI 도우미문제가 생기면 ChatGPT / Claude에게 직접 물어보세요. 에러 메시지를 붙여넣고 설명을 요청하세요

Phase 1 완료 후 → Phase 2: Pandas 데이터 처리로 진입

Python 기초를 마스터하신 것을 축하합니다! 다음으로 Pandas를 배우면, 앞서 배운 리스트, 딕셔너리, 파일 작업이 모두 활용됩니다.