OpenCV 비전 실무20장 · 교육 콘텐츠 설계와 종합 실습14 / 21← 이전목차다음 →MetaContents

20장. 교육 콘텐츠 설계와 종합 실습

실습 1 — 수업 계획표 만들기

학습목표, 행동 동사, 확인 방법, 시간을 한 표에 적은 수업 계획표를 pandas 로 만듭니다. 목표 문장을 프로그램으로 점검하고, 시간 배분을 그래프로 본 뒤 out_ch20_plan.csv 로 저장합니다.

1단계. 계획표 만들기

Python
import pandas as pd
import matplotlib.pyplot as plt

plt.rcParams["font.family"] = "Malgun Gothic"
plt.rcParams["axes.unicode_minus"] = False

# 한 차시(필터 수업)의 활동을 줄마다 적는다. 시간은 분
plan = pd.DataFrame([
    {"활동": "도입", "학습목표": "노이즈 낀 그림과 깨끗한 그림의 차이를 PSNR 로 견줄 수 있다",
     "확인 방법": "PSNR 두 값을 찍은 출력", "시간": 10},
    {"활동": "실습 1", "학습목표": "Median 필터로 잡티를 지워 PSNR 을 3dB 이상 올릴 수 있다",
     "확인 방법": "전후 PSNR 차이", "시간": 20},
    {"활동": "실습 2", "학습목표": "필터 세 가지를 같은 그림에 걸어 결과를 표로 견줄 수 있다",
     "확인 방법": "필터별 PSNR 표", "시간": 25},
    {"활동": "실습 3", "학습목표": "필터를 이해한다",
     "확인 방법": "", "시간": 15},
    {"활동": "정리", "학습목표": "전후 비교 격자를 만들어 저장할 수 있다",
     "확인 방법": "저장된 out_ 그림", "시간": 10},
])
print(plan[["활동", "시간"]].to_string(index=False))
print("총 시간:", int(plan["시간"].sum()), "분")
출력
  활동  시간
  도입  10
실습 1  20
실습 2  25
실습 3  15
  정리  10
총 시간: 80 분

2단계. 학습목표 문장 점검하기

Python
VERBS = ["견줄", "올릴", "만들어", "찾을", "셀", "고칠", "저장할"]   # 이 계획표에서 쓰는 행동 동사
VAGUE = ["이해", "안다", "익힌다"]                                  # 덜 알맞은 말

def review(row):
    """학습목표 한 줄을 점검해 고칠 점을 글자로 돌려준다. 문제가 없으면 '통과'."""
    goal = row["학습목표"]
    notes = []
    if not goal.endswith("수 있다"):
        notes.append("'~할 수 있다'로 끝내기")
    if any(word in goal for word in VAGUE):
        notes.append("행동 동사로 바꾸기")
    if not any(verb in goal for verb in VERBS):
        notes.append("행동 동사 넣기")
    if not row["확인 방법"]:
        notes.append("확인 방법 적기")
    return "통과" if not notes else ", ".join(notes)

# apply(함수, axis=1): 표의 줄마다 함수를 불러 결과를 새 칸에 담는다
plan["점검"] = plan.apply(review, axis=1)
print(plan[["활동", "점검"]].to_string(index=False))
출력
  활동                                             점검
  도입                                             통과
실습 1                                             통과
실습 2                                             통과
실습 3 '~할 수 있다'로 끝내기, 행동 동사로 바꾸기, 행동 동사 넣기, 확인 방법 적기
  정리                                             통과

3단계. 고치고 시간 배분 보기

Python
# 점검에 걸린 줄을 고쳐 적는다
plan.loc[plan["활동"] == "실습 3", "학습목표"] = "윤곽선으로 잡티를 지운 그림의 부품 수를 셀 수 있다"
plan.loc[plan["활동"] == "실습 3", "확인 방법"] = "정답 개수와 같은지"
plan["점검"] = plan.apply(review, axis=1)
print("통과한 줄:", int((plan["점검"] == "통과").sum()), "/", len(plan))

# 활동마다 시간을 가로 막대로 그린다. barh = bar horizontal(가로 막대)
fig, ax = plt.subplots(figsize=(7, 3))
ax.barh(plan["활동"], plan["시간"])
ax.invert_yaxis()                      # 위에서부터 수업 순서대로 보이게 뒤집는다
ax.set_xlabel("시간(분)")
ax.set_title(f"한 차시 {int(plan['시간'].sum())}분의 시간 배분")
plt.tight_layout()
plt.show()
출력
통과한 줄: 5 / 5
도입, 실습 1, 실습 2, 실습 3, 정리의 시간을 가로 막대로 그린 그래프

4단계. 저장하고 다시 읽어 확인하기

Python
# utf-8-sig: 엑셀에서 열어도 한글이 깨지지 않게 맨 앞에 표시(BOM)를 붙여 저장한다
plan.to_csv("out_ch20_plan.csv", index=False, encoding="utf-8-sig")

back = pd.read_csv("out_ch20_plan.csv", encoding="utf-8-sig")
print("저장한 줄과 칸:", back.shape)
print("칸 이름:", list(back.columns))
print("실습 비중:", round(float(back.loc[back["활동"].str.startswith("실습"), "시간"].sum() / back["시간"].sum()), 3))
출력
저장한 줄과 칸: (5, 5)
칸 이름: ['활동', '학습목표', '확인 방법', '시간', '점검']
실습 비중: 0.75

코드 설명

  • pd.DataFrame([{...}, {...}]) 은 사전 하나를 한 줄로 삼아 표를 만듭니다. 계획표의 칸(활동, 학습목표, 확인 방법, 시간)이 사전의 키입니다.
  • plan.apply(review, axis=1) 은 줄마다 review 함수를 부릅니다. axis=1 은 "줄 방향으로 하나씩"이라는 뜻입니다. 학습목표 점검을 사람이 아니라 함수가 하므로, 계획표가 길어져도 같은 기준으로 봅니다.
  • plan.loc[조건, "칸"] = 값 은 조건에 맞는 줄의 그 칸만 고칩니다. loc 은 location(자리)의 줄임입니다.
  • ax.barh 는 가로 막대, ax.invert_yaxis() 는 위아래를 뒤집어 첫 활동이 맨 위에 오게 합니다.
  • encoding="utf-8-sig" 로 저장하면 엑셀에서 열어도 한글이 깨지지 않습니다. 17장의 mistakes.csv 도 이 방식입니다.
← 이전 절20장 · 실습 지도다음 절 →20장 · 실습 2 — 난이도 손잡이가 있는 연습 그림 생성기