Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
Administrator
geumdo_docs
Commits
f0a52c6a
Commit
f0a52c6a
authored
Jun 24, 2025
by
insun park
Browse files
docs: README, TODO, Makefile 및 진도 체크 시스템(progress_checker.py) 개선 및 추가
parent
978c6ed6
Changes
21
Show whitespace changes
Inline
Side-by-side
ai_lecture/scripts/progress_checker.py
0 → 100644
View file @
f0a52c6a
#!/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
:.
1
f
}
%)"
)
print
()
for
i
,
item
in
enumerate
(
checklist
[
"items"
]):
status
=
"✅"
if
i
in
part_data
[
"completed_items"
]
else
"⭕"
print
(
f
"
{
status
}
{
i
+
1
:
2
d
}
.
{
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
:
2
d
}
/
{
part_total
:
2
d
}
(
{
progress_percent
:
5.1
f
}
%)"
)
overall_progress
=
(
completed_items
/
total_items
)
*
100
print
(
"
\n
"
+
"="
*
60
)
print
(
f
"📊 전체 진도:
{
completed_parts
}
/
{
total_parts
}
파트 완료 (
{
overall_progress
:.
1
f
}
%)"
)
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
:.
1
f
}
%)
\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
:.
1
f
}
%)
\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
()
\ No newline at end of file
Prev
1
2
Next
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment