GitHub 제출물을 수집하고 C/Python 실습을 채점하는 PyQt6 데스크톱 앱입니다. Windows + Docker에서 검증했습니다. Linux와 WSL 실행 모드도 제공하며, 시스템 프로그래밍은 기본값인 Docker를 사용하세요.
AI 케이스 생성 → 기준 코드 검증 또는 직접 검토 → 채점에 추가 → 학생 선택 → 일괄 채점 → 결과 자동 저장 순서로 사용합니다.
메인 화면 오른쪽 위 화면 모드에서 시스템 설정 / 라이트 모드 / 다크 모드를 선택합니다. 선택 즉시 열린 창과 팝업에 적용되며 재실행 후에도 유지됩니다. 기본값은 시스템 설정이며 Windows의 모드 변경을 따라갑니다. 바로 옆에서 글자 크기도 조절할 수 있습니다.
AI 창에서 활성 저장한 케이스는 testcase/<과목>/<장>/<문제>/에 추가됩니다.
메인 화면이 같은 문제를 보고 있으면 케이스 경로와 활성 개수가 즉시 갱신됩니다.
초안 저장한 케이스는 제외합니다. 저장 자체가 학생 코드 실행을 시작하지는 않습니다.
선택 N명 일괄 채점은 선택 학생의 코드를 케이스별로 실행해 출력·파일·종료 코드 등을 비교합니다. 기본 결과는 케이스별 통과/실패와 학생별 통과 수입니다. 배점이 없는 케이스에 임의로 100점 점수를 붙이지 않습니다.
모든 결과는 SQLite 파일 data/swlab.db 한 곳에 영속됩니다. 학생 명단(학번·이름), 채점 실행과 케이스별 결과, 중간고사 점수 조정 이력이 여기에 들어가며 학생 한 명이 끝날 때마다 기록됩니다.
채점 결과 탭은 기본으로 최신 점수표를 보여 줍니다. 분반·장·문제를 고르면 학생·문제별 최근 실행 결과와 정성평가, 수동 점수 조정을 DB에서 자동으로 모읍니다. 전체 채점 후 일부 학생이나 한 문제만 다시 채점해도 나머지 학생·문제의 결과는 유지합니다. 실행 결과는 실행 시작 시각으로 비교하며, 과거 실행의 점수를 나중에 조정해도 그 실행의 자동 채점 결과가 최신 실행을 덮지 않습니다. 수동 조정이 있으면 가장 최근 조정 점수를 적용하며 새 실행 후에도 유지합니다. 각 학생에게 실제 사용한 케이스와 필수 통과 비율로 점수를 계산합니다.
목록의 최신 점수표 (기본) 아래에는 과거 실행이 있습니다. 과거 실행 선택은 당시 결과·근거·조정을 조회하는 선택 기능입니다. 최신 점수표 (기본) 항목을 다시 고르거나 최신값 새로고침을 누르면 최신 점수표로 돌아옵니다. 기본 표에서도 점수를 조정할 수 있고, 해당 학생·문제의 실행 기록에 저장되며 다음 실행에도 반영됩니다. 상세 근거에서 점수에 사용된 실행 ID·시각과 조정 사유를 확인합니다. 최신 점수표의 CSV/JSON 내보내기도 현재 모인 결과를 사용하며, JSON에는 출처 실행과 정성평가를 함께 보관합니다.
메인 화면의 CSV 내보내기는 항상 현재 분반·장·문제의 최신 점수표를 학생당 한 행으로 저장합니다. 저장 직전에 DB를 다시 읽으므로 과거 실행 조회 중이거나 창을 연 뒤 새 평가·승인이 저장된 경우에도 최신값을 내보냅니다. 명단의 미평가 학생과 정성평가만 있는 학생도 포함하며, 미평가·검토 필요 점수는 빈칸으로, 실제 0점은 0으로 저장합니다. 평가 사유·검토 의견의 줄바꿈은 공백으로 바꿔 물리적인 데이터 행 수도 학생 수와 같습니다. Excel 호환 UTF-8 BOM과 수식 방지 처리를 적용합니다.
| CSV 열 | 내용 |
|---|---|
student, student_name |
학번, 이름 |
auto_score, final_score, max_score |
실행 자동 총점, 수동 조정을 반영한 최종 총점, 배점 |
copy.c_auto, copy.c_final, copy.c_max, copy.c_adjusted 등 |
문제별 자동 점수, 조정 반영 최종 점수, 배점, 수동 조정 점수(조정이 없으면 빈칸) |
copy.c_qualitative_status, _overall, _suggested_score, _final_score 등 |
문제별 정성 상태, 종합 품질, AI 제안, 교수자 확정 점수 |
copy.c_qualitative_correctness_score, _resource_files_score 등 |
정성평가 항목별 점수. 각 항목의 _applicable 열에 적용 여부를 저장하며 제외 점수는 빈칸 |
copy.c_adjustment_reason, _reviewer, _at 등 |
조정 사유, 교수자, 조정 시각 |
중간고사 전체를 선택하면 7개 문제를 각각 열로 구분합니다. 전체 문제를 한 번에 정성평가한 기록은 별도 exam_qualitative_* 열에 저장합니다. 정성평가 제안·확정 점수는 실행 점수와 구분하며 임의로 합산하거나 최종 총점을 대체하지 않습니다. 배점이 없는 일반 실습에서는 통과 수·전체 케이스 수를 저장하고 실행 점수를 빈칸으로 둡니다. 기존 실행 폴더의 cases.csv·summary.csv는 해당 실행의 기록으로 유지합니다.
DB 파일은 Git에 포함하지 않으므로 다른 PC로 옮길 때는 data/swlab.db를 복사하세요.
같은 내용을 reports/case-grading/<실행시각_식별자>/에도 내보냅니다. Excel로 보거나 다른 사람에게 전달할 때 사용합니다.
run.json: 실행 상태, 대상 학생, 사용한 케이스 설정, 실제 출력과 판정 근거.cases.csv: 학생·케이스별 상세 결과.summary.csv: 학생별 통과 수와 전체 케이스 수. 채점 불가·미실행은 통과 수를 비웁니다.
화면 아래에서 DB 또는 조회 중인 실행의 저장 위치를 확인합니다. 과거 실행 조회에서는 결과 폴더 열기로 내보낸 파일에 접근할 수 있습니다.
이전 결과 열기는 다른 PC에서 가져온 run.json을 여는 용도이며, 연 기록은 DB에도 저장됩니다.
DB를 만들기 전에 쌓인 reports/case-grading 폴더와 reports/qualitative_*.json은 도구 / 고급 → 이전 채점·정성평가 기록을 DB로 가져오기를 한 번 실행하면 전부 들어갑니다. 명령행에서는 .\.venv\Scripts\python src\db.py import, 목록 확인은 src\db.py runs(채점)와 src\db.py reviews(정성평가)입니다.
도구 / 고급 → CSV / JSON 내보내기은 자동 저장과 별도로 원하는 위치에 추가 내보내는 기능입니다.
채점 결과 화면 아래의 장 골라 CSV 내보내기(같은 항목이 도구 / 고급 메뉴에도 있음)는 현재 분반에서 기록이 있는 장 가운데 원하는 장만 골라 최신 점수표를 CSV 하나로 저장합니다. 중간고사는 전체 문제 보기(정성 총점 포함)로, 다른 장은 기록된 문제마다 학생당 한 행씩 들어가며 각 행의 chapter·problem 열로 구분합니다.
도구 / 고급 → 명세 파일로 배점 채점… 메뉴는 교수자가 problem.yaml로 케이스별 배점을 정의했을 때 사용하는 선택 기능입니다.
AI 케이스를 실행하는 데 이 화면을 거칠 필요가 없습니다. 명세 채점 기록은 별도 records/<문제ID>/<실행ID>/에 저장합니다.
명세 작성·매핑·기록 사용법 · 현재 구현 계획
새 컴퓨터에 처음 설치할 때는 프로그램 설치·명단·Qwen 설정·기록 이전까지 정리한 처음 설치하기를 따르세요. 요약하면 다음과 같습니다.
Python 3.10 이상, Git, 실행 중인 Docker Desktop이 필요합니다.
python -m venv .venv
.\.venv\Scripts\python -m pip install -r requirements.txt
docker compose build grader
.\.venv\Scripts\python src\main.py매번 명령을 입력하지 않으려면 바로가기를 한 번 만들어 두세요. 바탕화면에 SWLAB 실습 채점 아이콘이 생기고, 두 번 클릭하면 콘솔 창 없이 앱이 열립니다. 작업 표시줄이나 시작 메뉴에 고정해도 됩니다.
powershell -ExecutionPolicy Bypass -File scripts\create_shortcut.ps1상주 컨테이너를 켤 필요는 없습니다. 매 실행마다 grader-image에서 컨테이너를 만들고 정리합니다. 프로젝트 전체를 컨테이너에 마운트하지 않습니다.
- 저장소 동기화에서 학생 명단 CSV를 선택하면 저장소를 처음 다운로드하거나 최신 커밋으로 업데이트합니다. 완료 창에는 성공·실패 인원과 실패한 학생의 이름·학번·사유가 표시됩니다. 이미 수집한 경우 연도와 분반만 선택합니다.
- 장·문제를 선택하고 활성 케이스 개수를 확인합니다. 케이스가 없으면 AI 케이스 생성에서 검증 또는 수동 검토 후 저장합니다.
- 분반의 로컬 학생 폴더 전체가 기본 선택됩니다. 왼쪽 전체 선택 / 선택 해제와 학생 클릭으로 대상을 바꿉니다. Ctrl/Shift를 누를 필요가 없습니다.
- 아래 학생 N명 × 케이스 M개를 확인하고 파란색 선택 N명 일괄 채점 버튼을 누릅니다.
- 진행 인원과 학생별 결과가 표에 갱신됩니다. 중지를 누르면 현재 학생을 저장한 뒤 멈추며, 나머지는 미실행으로 남습니다.
- 결과 표에서 학생을 선택하고 상세 근거 보기를 누릅니다. 결과 폴더 열기 / 이전 결과 열기로 자동 저장 기록을 확인합니다.
오른쪽 위 글자 크기에서 12pt·14pt·16pt를 선택할 수 있고, 다음 실행에도 설정이 유지됩니다. 제출 코드, 직접 실행, 실행 로그는 별도 탭에 있습니다. 직접 실행은 학생 한 명만 선택해야 합니다. 실행 환경, 실습 자료, 배점 명세, 추가 내보내기는 도구 / 고급 메뉴에 있습니다. 왼쪽 Qwen 정성평가도 현재 선택한 학생들을 대상으로 합니다.
CSV는 UTF-8 또는 UTF-8 BOM, 학번,이름,GitHub URL 형식입니다. 헤더는 선택 사항이며 빈 행은 무시합니다. 잘못된 행과 중복 학번은 가져오기 전에 보고합니다. 학번은 숫자로 처리합니다. 복제 위치는 실행 디렉터리와 무관하게 src/origin/<과목>_<분반>_<연도>/<학번>입니다. 기존 제출물에 로컬 변경이 있으면 pull을 건너뜁니다.
학번 · 이름 표시: 명단의 이름은 동기화 시 src/origin/<분반>/.student_names.json에 저장되며(저장소 URL은 저장하지 않음),
없으면 testdata/<연도>/<과목>_<분반>.csv를 읽습니다. 메인 학생 선택 목록은 학번 · 이름으로 표시하고,
정성평가 표와 채점 결과 표는 학번·이름을 별도 열로 표시합니다. 폴더 이름·경로·학번 검색은 학번만 사용합니다. 채점 결과(run.json, cases.csv, summary.csv)와 정성평가 결과(JSON, CSV)에는
student_name 열이 함께 저장되고, 이름이 없는 학번은 빈 값으로 남습니다.
정성평가 표와 채점 결과 표의 열 제목을 클릭하면 오름차순·내림차순 정렬이 전환됩니다. 학번·점수·통과 수는 숫자 기준으로 정렬합니다. 정렬 후에도 선택한 학생과 현재 검토 중인 학생을 유지하며, 평가 결과가 갱신되어도 정렬 기준·방향을 유지합니다. 정렬된 행에서 검색·상세 보기·점수 조정·일괄 평가·승인을 해도 원래 학생 식별자를 기준으로 처리합니다.
직접 실행에서는 선택한 소스 파일에 인자와 표준입력을 전달합니다. 경로는 제출물 폴더 기준입니다. 공백을 포함한 인자는 "file name.txt"처럼 입력합니다. 수동 실행과 명시적인 파일 추가/삭제는 선택한 제출물에서 수행됩니다. 자동 채점은 케이스마다 복사본에서 실행되어 제출물을 수정하지 않습니다.
2026 중간고사는 학생의 midterm/ 안에 문제별 C 파일을 두는 구조입니다.
중간고사 테스트 사용법에 복사·도서 관리 36개 케이스와 파일별 실행 방법을 정리했습니다.
GUI에서 midterm을 선택하면 C 파일별 문제와 전체 문제(36개) 항목을 선택해 일괄 채점할 수 있습니다.
중간고사는 문제 배점 × 필수 케이스 통과 비율로 부분점수를 계산해 75점 만점으로 합산합니다.
진단용 추가 8개는 점수에서 제외하며, 문제별 자동·최종 점수와 조정 이력을 저장합니다.
전체 실행: python src/midterm.py src/origin/system_3_2026 --batch (기본 28개, --include-extra 사용 시 36개).
공통 위치는 testcase/<과목>/<장>/<문제>/<케이스>입니다. 기존처럼 문제 폴더에 직접 output.txt를 놓아도 됩니다. 각 케이스에는 다음 파일을 둘 수 있습니다.
output.txt: 기대 표준출력. 기본은 줄바꿈 통일 후 앞뒤 공백을 제거해 비교합니다.input.txt: 표준입력. 없으면 빈 입력으로 EOF를 전달합니다.args.txt: 공백으로 구분한 인자. 따옴표를 지원합니다.case.json: 파일 결과, 종료 코드, 비교 방식 등 확장 설정.- 나머지 파일/폴더: 실행 전에 복사할 보조 자료.
{
"args": ["source.txt", "destination.txt"],
"files": {"destination.txt": "Hello\n"},
"file_comparison": "exact",
"exit_code": 0,
"timeout": 10,
"target_file": "main.c",
"sources": ["main.c", "copy.c"],
"cflags": ["-Wall", "-Wextra"],
"enabled": true
}output.txt 없이 files만 지정하면 파일 내용을 검사합니다. expected로 JSON 안에 기대 출력을 직접 지정할 수도 있습니다. stderr와 stderr_comparison으로 오류 출력을 검사할 수 있습니다. 비교 방식은 exact, trim, tokens, regex이며 regex는 전체 출력과 일치해야 합니다. exit_code 기본값은 0입니다. enabled: false인 케이스는 제외합니다. 검사 항목이 없는 케이스는 합격 처리하지 않습니다.
C 기본 빌드는 같은 소스 디렉터리의 모든 .c 파일을 링크합니다. 독립 실행 프로그램 여러 개가 한 폴더에 있으면 target_file과 sources를 명시하세요. 수동 실행의 파일 선택은 진입 소스를 선택하고, 복수 C 파일 링크 방식은 같습니다.
Test Case Generator는 기준 소스를 복사본에서 실행해 동일한 테스트 경로에 출력·입력·인자·소스명을 저장합니다. 기존 케이스는 덮어쓰지 않습니다. 외부 입력 파일이 필요한 경우 생성한 케이스에 보조 파일을 추가하세요. 파일 상태·바이너리 레코드·사용 API 사용 여부는 텍스트 출력 비교만으로 증명되지 않습니다.
python src/cli.py examples/cat --cases testcase/system/chap4/prob1 --output reports/cat.json
python src/cli.py examples/copy --cases testcase/system/chap4/prob2 --output reports/copy.csv
python src/cli.py src/origin/system_3_2026 --batch --chapter chap5 --problem prob3 --cases testcase/system/chap5/prob3 --output reports/class.json종료 코드는 전체 합격 0, 채점 실패 1, 설정 오류 2입니다. --mode, --timeout, --source, --image로 실행 설정을 변경할 수 있습니다. CSV는 Excel 호환 BOM을 포함하며 학생 출력이 수식으로 실행되지 않도록 처리합니다. JSON은 원문을 보존합니다. 수동 평가 기록으로 선택한 학생의 판정과 검토 근거를 추가할 수 있습니다. 자동 채점과 구분되는 manual_passed / manual_failed 상태로 내보냅니다. 새 자동 채점을 시작하면 화면은 새 결과로 바뀌지만 이전 실행의 자동 저장 파일은 보존됩니다.
- 요구사항 및 수용 기준: 기존 구현과 제공 자료에서 정리한 개발 기준.
- 실습별 채점 범위: 자동 채점과 수동 검토의 구분, 판본 충돌.
- 자료 색인: 25개 PPT, 519쪽의 출처·페이지·텍스트.
python src/materials.py로 재생성합니다. examples/: 채점기 검증용 최소 C 구현. 전체 실습 정답 모음은 아닙니다.
python -m unittest discover -s tests -v
$env:SWLAB_TEST_DOCKER = '1'
python -m unittest discover -s tests -vDocker 실행은 네트워크 차단, 메모리 256MB, CPU 1개, 프로세스 64개, 파일 크기 8MB 제한을 사용합니다. 기본 시간 제한은 컴파일·컨테이너 시작을 포함해 10초이며 최대 300초입니다. stdout/stderr는 각각 1MB까지만 보관합니다. Docker 컨테이너 종료 시 자식 프로세스도 정리합니다. Windows/Linux 직접 실행은 호스트 권한으로 실행되므로 신뢰하는 코드의 디버깅에 사용하세요. WSL/네이티브 Linux 실행은 이 Windows 환경에서 통합 검증하지 않았습니다.
메인 화면의 AI 케이스 생성을 누릅니다.
- 슬라이드 목록에서 문제 선택… 버튼을 누릅니다. 장·PPT 판본을 고른 뒤 제목·본문 검색과 페이지 클릭으로 선택합니다. 같은 문제 페이지 모두 선택으로 설명·코드 여러 쪽을 함께 가져올 수 있습니다. 오른쪽 미리보기에서 확인하고 선택한 페이지 사용을 누릅니다. 문제를 직접 입력해도 됩니다.
- 상단 생성·저장 대상에서 장·문제 번호와 실제 저장 폴더를 확인하고 케이스 수(1–10개)를 지정합니다. 슬라이드에 명시된 번호는 자동 반영하며, 번호가 없는 페이지는 직접 확인합니다. 장과 문제에 숫자만 입력하면
chapN,probN으로 바뀝니다. 기존prod1같은 제출 폴더명은 유지합니다. - 올바른 기준 코드를 선택합니다. 오답 예제 선택으로 잘못된 구현도 추가하면 해당 오류를 케이스가 탐지하는지 검사합니다. 독립된 프로그램은 각각 별도 폴더에 둡니다.
- Qwen으로 테스트 케이스 생성을 누르면 입력·인자·보조 파일·기대 결과를 생성합니다. 기준 코드가 있으면 Docker 복사본에서 두 번 실행해 AI 기대값을 교정하고 반복 결과를 비교합니다. 잘못된 종료 코드, 반복 결과 불일치, 모든 케이스를 통과하는 오답 예제는 검증 실패로 처리합니다.
- 검증된 결과는 검증된 케이스 · 채점에 추가로 저장합니다. 기준 코드가 없으면 미검증 상태로 표시하고, 기대값을 직접 확인한 뒤 수동 검토 체크를 해야 추가할 수 있습니다. 초안 저장 · 채점 제외는 검토 전에도 사용할 수 있습니다. 검증 실패한 케이스는 수정 후 재검증해야 합니다.
기대값과 입력은 JSON 편집 탭에서 수정합니다. 편집하면 기존 검증 상태가 해제됩니다. 생성 후 기준 코드로 정답·오답 탐지 검증을 눌러도 됩니다. 검증 근거와 기대값 수정 내역은 case.json의 generation.verification에 기록합니다. 동일 입력·기대값·보조 파일을 다시 저장하면 기존 케이스를 재사용합니다. 활성 저장한 파일은 메인 화면의 선택 N명 일괄 채점과 CLI에서 바로 사용할 수 있습니다.
생성 후 장·문제·설명·원본 슬라이드가 바뀌면 이전 결과를 다른 문제에 저장할 수 없으며 다시 생성해야 합니다. 기준 코드 파일을 바꾸면 검증 상태가 해제됩니다. 선택한 장·문제와 슬라이드 페이지는 생성 기록에도 저장됩니다. 선택 케이스 상세 보기에서 입력·기대 출력·보조 파일의 전체 내용을 확인할 수 있습니다.
메인 문제 목록은 활성 케이스 있음 → 초안만 있음 → 케이스 없음 순서이며 케이스 개수를 함께 표시합니다. 학생 제출 폴더가 아직 없어도 케이스가 있는 문제를 표시합니다. 활성 저장하면 새 문제를 목록에 추가하고 해당 문제를 선택합니다. 정성평가에서도 같은 슬라이드 선택 창을 사용합니다.
3장 최장 줄 예제는 examples/longest_line/에 기준 코드와 10개 케이스를 제공합니다. testcase/system/chap3/prod1/의 기존 중복 4개를 비활성화하고, 기준 코드 2회 실행과 오답 예제 3종 탐지를 확인한 10개를 활성화했습니다. 원본은 reports/testcase-repair-*/original_cases/에 보존했습니다. 오답 탐지 기록은 선택한 오답 예제에 대한 결과이며 전체 오류에 대한 완전한 보장은 아닙니다.
서버 주소와 모델명은 코드에 기본값으로 포함하지 않습니다. settings.example.json을 settings.local.json으로 복사한 뒤 llm.url, llm.model을 설정하거나 화면에서 입력하세요. 로컬 설정 파일과 .env 파일은 Git 및 Docker 빌드에서 제외됩니다. .env는 자동으로 읽지 않으므로 환경 변수를 사용하려면 실행할 셸에 설정하세요.
Copy-Item settings.example.json settings.local.json
# 환경 변수로 지정하는 경우: 실제 서버 주소와 제공 모델명으로 변경
$env:SWLAB_LLM_URL = 'https://llm.example.com/v1'
$env:SWLAB_LLM_MODEL = 'your-model-id'
# 인증이 필요한 서버에서만 지정
$env:SWLAB_LLM_API_KEY = 'your-key'두 LLM 화면은 환경 변수 → 화면에서 저장한 설정 → 로컬 설정 파일 순서로 URL과 모델명을 읽습니다. 화면에 직접 입력한 값은 해당 요청에 사용합니다. SWLAB_CONFIG로 로컬 설정 JSON 경로를 지정할 수도 있습니다. API 키는 환경 변수 또는 로컬 설정에서만 읽으며 화면 설정이나 생성 케이스에는 기록하지 않습니다.
서버 연결 확인은 모델명을 입력하기 전에도 /models 목록을 조회합니다. 케이스 생성과 정성평가는 URL·모델명이 모두 필요하고, 누락하면 안내를 표시합니다. 별도 SDK 없이 OpenAI 호환 /models, /chat/completions API를 사용합니다.
LLM에 보내는 것은 선택한 문제 설명과 케이스 생성 지시뿐입니다. 학생 명단·학생 소스·교수자 기준 소스는 자동으로 전송하지 않습니다. 생성된 케이스에는 모델명, 서버 주소, 출처 페이지, 문제 설명 해시, 생성 시각, 기대값 출처를 기록합니다.
기준 코드가 없을 때의 기대값은 LLM의 제안입니다. 기준 코드 실행값도 해당 코드가 올바르다는 전제를 가지며, PID·현재 시각·주소처럼 매번 바뀌는 값은 그대로 고정 정답으로 사용하면 안 됩니다. 생성은 데이터에 한정하며 LLM이 만든 프로그램을 실행하지 않습니다. 불명확한 문제는 검토 메모로 표시하고 기대 결과가 없는 케이스는 활성 저장을 막습니다. PPT 이미지 속 코드·실행 결과는 자동으로 읽지 않으므로 필요한 조건은 문제 설명에 보충합니다.
요청당 네트워크 대기 제한은 300초(5분)입니다. 응답이 잘리거나 지연되면 케이스 수 또는 문제 범위를 줄여 다시 생성할 수 있습니다. 기존 케이스는 덮어쓰지 않고 ai_<시각>_<식별자>_<이름> 폴더로 추가됩니다. 모델 목록 조회·추론은 서버가 실행 중일 때 사용할 수 있으며 기존 채점 기능은 LLM 연결 없이도 동작합니다.
Cannot reach LLM server ... WinError 10053은 호스트 소프트웨어가 통신 연결을 중단했다는 뜻이며, 전송 시간 초과·프로토콜 오류 등이 가능한 원인입니다(Microsoft 설명). 오류 문구만으로 방화벽·백신 등 특정 원인을 확정할 수 없습니다. 모델 목록 조회가 성공해도 실제 평가 요청 성공까지 확인되는 것은 아닙니다. 현재 자동 재시도는 없으므로 정성평가에서 미평가·실패 선택 → 선택 N명 일괄 정성평가로 재시도할 수 있습니다. 계속 발생하면 실패까지 걸린 시간과 같은 시점의 LLM 서버 로그를 확인하세요.
동일한 문제를 여러 학생에게 같은 기준으로 평가할 수 있습니다.
- 메인 화면에서 분반·장·문제를 선택하고 평가할 학생을 선택합니다. 학생 목록에서 Ctrl+A로 전체를 선택합니다.
- Qwen 정성평가를 엽니다. PPT의 문제 페이지를 불러오거나 요구사항을 직접 입력합니다.
- 평가 기준 / 배점에서 DCUCode의 정확성·알고리즘·가독성·문제 이해도와 자원 관리 3문항(파일·동적 메모리·프로세스)을 확인합니다. 각 항목은 0–10점 정수이며, 항목명·설명은 수정할 수 있습니다. 문제 배점 / 자원 적용 탭에서 시험 배점과 자원별 자동/포함/제외를 설정합니다.
- 정성평가 창의 학생 표에서 평가할 학생을 선택하고 선택 N명 일괄 정성평가를 누릅니다. 처음에는 메인 화면에서 가져온 학생이 모두 선택되어 있으며, 학생 클릭 또는 전체 선택 / 선택 해제로 대상을 바꿀 수 있습니다. 버튼에 표시된 N명만 서버에 요청하고, 아무도 선택하지 않으면 실행하지 않습니다. 진행률도 이번 선택 인원 기준입니다. 재평가할 때 선택하지 않은 학생의 기존 평가·확정 점수는 유지합니다.
- 학생을 선택하면 종합 품질(100점), 시험 제안 부분점수, 항목별 현재 상태 평가·개선 의견·근거 파일/줄/코드, 총평을 볼 수 있습니다. 비적용 자원은 제외 사유와 함께 표시합니다.
- 필요하면 교수자 확정 점수를 조정하고 검토 의견을 작성한 뒤 현재 학생 점수 확정을 누릅니다. AI 제안 점수는 원래 값으로 남습니다.
- 여러 학생의 제안 점수를 그대로 승인하려면 결과 표에서 학생을 클릭해 선택하고 선택 학생 일괄 승인을 누릅니다. 전체 선택 / 선택 해제 버튼도 사용할 수 있습니다. 공통 검토 의견은 버튼 옆에서 수정하며, 선택한 미확정 AI 제안만 각자의 제안 점수로 확정합니다. 기존 확정 점수와 평가 실패는 건너뛰고 자동 저장합니다.
정성평가 결과도 data/swlab.db에 저장됩니다. 학생 한 명이 끝날 때마다, 그리고 점수를 확정할 때마다 기록되며 같은 내용을 reports/qualitative_<시각>.json으로 내보냅니다. 창 아래의 저장된 평가 선택… 목록은 같은 분반·문제의 지난 평가를 최신순으로 보여 주고, 고르면 제안·확정 점수와 근거를 그대로 불러옵니다. JSON 파일 열기는 다른 PC에서 가져온 파일용이며 연 기록은 DB에도 저장됩니다.
메인 채점 결과 표도 분반·장·문제를 선택하면 DB에 저장된 정성평가를 자동으로 불러옵니다. 정성 점수는 확정 점수가 있으면 그 값을, 없으면 AI 제안 점수를 숫자로만 표시합니다. 전체 보기에서는 평가 기록이 있는 문제를 정성 1번, 정성 2-(2)처럼 별도 열로 표시하며 전체 정성평가는 정성 전체로 구분합니다. 문제별 열 뒤의 정성 총점은 학생의 문제별 정성 점수(확정 우선, 미확정은 AI 제안)를 더한 값과, 정성평가 기록이 있는 문제들의 배점 합계를 12 / 45처럼 표시합니다. 정성 전체 평가는 문제별 점수와 겹치므로 총점에 더하지 않으며, 미평가·실패 문제는 0점이 아니라 합계에서 빠집니다. 정성 사유에는 파일 없음, 빈 파일, 폴더 없음, 평가 실패 · 응답 형식 오류 등을 한 줄로 표시합니다. 미확정 점수는 사유에 AI 제안을 표시하고 미평가·실패 점수는 —, 자동 0점은 0으로 구분합니다. 긴 사유는 줄바꿈 없이 줄여 표시하며, 셀에 마우스를 올리거나 상세 근거 보기를 열면 종합 품질·제안/확정 점수·배점·전체 사유·항목별 평가·검토 의견을 확인할 수 있습니다.
정성평가 기록만 있는 화면은 학번·이름·정성 점수·사유만 표시하며, 실행 채점 결과가 있으면 실행 점수 열을 함께 표시합니다. 평가 완료·교수자 승인 직후 자동 갱신하며, 다른 창에서 저장한 기록은 최신값 새로고침으로 다시 읽습니다. 학생·문제별 평가/확정 시각이 가장 최근인 기록을 사용하며, 재평가 실패나 미평가 행은 기존 점수를 덮어 표시하지 않습니다. 실행 점수와 정성 점수는 각각 표시하며, AI 제안을 자동 확정하지 않으며, 여러 문제의 정성 점수는 전체 보기의 정성 총점 열에서만 합산합니다. 메인 표의 간단한 표시는 저장된 점수나 CSV·JSON의 상세 내용을 바꾸지 않습니다.
아직 실행하지 않은 학생은 미평가(not_reviewed)로 표시하고 점수를 비웁니다. 평가 중 선택을 바꿔도 진행 중인 요청 대상은 시작 시점의 선택으로 유지합니다. 중지하면 현재 학생까지 저장하고, 나머지는 이전 결과 또는 미평가 상태로 남습니다. 메인 화면에서 학생 선택을 바꾼 뒤 같은 문제의 정성평가를 다시 열면 열린 창의 선택도 갱신됩니다.
미평가·실패 선택은 AI 제안 점수가 없는 학생을 한 번에 선택합니다. 평가 실패 학생도 포함하며, 0점 제안과 교수자 확정 학생은 제외합니다. 해당 학생이 없으면 선택을 해제하고 평가 버튼을 비활성화합니다. 표에 초점을 두고 ↑/↓ 방향키로 이동하면 현재 학생의 평가 내용·확정 점수·검토 의견이 바로 표시됩니다. 방향키 이동은 일괄 평가·승인에 사용할 학생 선택을 바꾸지 않습니다.
학생 표 위의 학번 검색에 학번 전체나 일부를 입력하면 해당 학생으로 이동하고 평가 내용을 표시합니다. 전체 학번이 정확히 일치하면 우선 이동하며, 여러 명이 일치하면 Enter / 다음 찾기로 순환합니다. 일치 인원과 현재 위치를 표시하고 검색 결과가 없으면 안내합니다. 검색·이동은 일괄 평가·승인 대상 선택을 유지합니다.
정성평가 창의 학생 표와 아래 평가 내용 사이 경계를 위아래로 드래그하면 각각의 높이를 조절할 수 있습니다. 좌우 설정·결과 영역의 경계와 표의 열 제목 사이 경계도 드래그해 너비를 조절합니다. 조절한 크기는 다음 실행에도 유지되며, 검색창 옆 배치 초기화로 기본 크기를 복원할 수 있습니다. 배치를 바꿔도 학생 선택·정렬·평가 결과는 유지합니다.
중간고사(midterm)도 같은 창에서 평가합니다. 문제 목록에서 C 파일 또는 전체 문제를 고르고 Qwen 정성평가를 열면
시험지 문제 본문(assignments/system/2026/midterm/problems.json)이 요구사항에 미리 채워지고,
문제 배점(1번 10점, 전체 75점 등)이 제안 부분점수의 만점으로 설정됩니다. DCUCode 평가축은 각 10점으로 유지합니다. 도서 대출 상태는 사용자 보정(True/1=대출 가능)을 시험지의 상충하는 예시보다 우선 적용합니다. 전송 소스는 학생 midterm/ 폴더 전체가 아니라 선택한 문제의 C 파일과 .h 헤더로 제한하며,
시험지 파일명과 다른 파일(Copy.c, bookcreate1.c 등)은 보내지 않습니다. 지정 파일·폴더가 없거나 대상 파일이 비어 있으면 제출 상태 0점으로 기록됩니다.
자세한 내용은 중간고사 테스트 사용법의 정성평가 절을 참고하세요.
자원 관리와 점수 계산: 파일 열기 성공/실패 확인과 닫기, 동적 할당과 해제, 프로세스 생성·종료와 wait/waitpid 자식 회수를 각각 평가합니다. 자동 모드는 문제 요구사항 또는 제출 코드의 실제 API 사용으로 적용 여부를 정합니다. 문자열·주석의 API 이름은 사용으로 세지 않습니다. 자동 판정은 정적 휴리스틱이므로 문제의 표현이나 사용자 정의 래퍼에 따라 놓칠 수 있으며, 탭에서 포함/제외를 지정해 보정할 수 있습니다. 필요한 자원을 학생이 구현하지 않았다는 이유로 제외하지 않습니다.
적용되는 자원 문항 점수만 평균 낸 뒤 정수로 올림하여 자원 관리 점수 R(0–10)을 만듭니다. 비적용 항목에는 0점이나 만점을 부여하지 않습니다.
| 계산 | 자원 관리 적용 | 자원 관리 모두 비적용 (DCUCode 원식) |
|---|---|---|
| 종합 품질 | ceil((정확성+알고리즘+가독성+문제이해도+R)/50*100) |
ceil((정확성+알고리즘+가독성+문제이해도)/40*100) |
| 시험 제안 부분점수 | ceil(문제배점*(정확성+문제이해도+R)/30) |
ceil(문제배점*(정확성+문제이해도)/20) |
알고리즘·가독성은 종합 품질에만 반영합니다. 소수점이 생기면 모두 올림하며, 부동소수 오차 없이 정수 나눗셈으로 계산합니다. 예: 배점 100점, 정확성 8·문제 이해도 7·파일 관리 7점이고 나머지 자원이 비적용이면 제안 부분점수는 ceil(100*22/30)=74점입니다. 올림 기준(dcucode_resources_v2) 이전에 저장된 평가(dcucode_resources_v1)는 당시 규칙인 Python round(정확한 중간값은 짝수 쪽)로 검증해 그대로 열립니다. 기존 기록을 올림 기준으로 바꾸려면 .\.venv\Scripts\python src\db.py rescore를 실행하세요(--dry-run은 바뀔 점수만 출력). 확정 점수가 당시 제안 점수와 같았던 학생은 확정 점수도 새 제안 점수로 바뀌고, 교수자가 다르게 정한 확정 점수는 유지되며, 이전 값은 각 행의 score_migration에 남습니다.
정성평가는 학생 코드 자체를 검토하므로 선택한 문제 폴더의 소스 코드, 요구사항, 평가 기준을 지정 Qwen 서버로 전송합니다. 학생별 학번·분반 매핑과 명단 이름은 요청에 별도 포함하지 않고 로컬 결과에 연결합니다(목록은 학번 · 이름, CSV/JSON은 student_name). 소스 자체에 작성된 이름·주석은 소스 내용에 포함됩니다. 기존 AI 테스트 케이스 생성은 계속 문제 설명만 전송합니다.
대상 확장자는 .c, .h, .py, .cpp, .hpp이며 숨김 폴더·빌드 산출물은 제외합니다. 한 학생당 40개 파일 또는 총 120KB를 초과하면 일부를 조용히 누락하지 않고 평가 실패로 표시합니다. 모델의 항목 수/ID, 정수 점수 범위, 현재 상태 평가와 개선 의견, 코드 근거 파일과 줄 번호를 검증하며 총점은 앱에서 위 식으로 계산합니다.
미제출·빈 제출은 0점, 평가 처리 실패는 점수 없음으로 구분합니다. 선택한 문제의 폴더나 파일이 없거나 파일 내용이 빈 문자열·공백·개행·UTF-8 BOM뿐이면 AI를 호출하지 않고 제출 상태 0점(submission_zero)으로 저장합니다. 제안·최종 점수와 종합 품질은 0이며, 빈 파일의 줄 번호를 근거로 만들지 않습니다. 자원 관리 비적용 항목은 기존처럼 계산에서 제외합니다. 별도 일괄 승인은 필요 없고, 교수자가 필요하면 사유와 함께 점수를 조정할 수 있습니다. 모든 선택 학생이 이 상태이면 LLM 설정 없이도 처리합니다.
헤더 파일만 있거나 시험지와 다른 파일명만 있으면 해당 문제는 미제출입니다. 전체 문제 정성평가에서는 모든 대상 소스가 없거나 비었을 때 전체를 0점 처리하며, 일부 문제의 풀이가 있으면 그 소스를 평가합니다. 빈 보조 파일은 AI 전송에서 제외합니다. 중간고사 실행 채점도 폴더 없음·파일 없음·빈 파일을 케이스별 미통과로 기록해 해당 문제의 자동 점수를 0점으로 계산합니다.
서버 연결·JSON 형식·잘못된 코드 근거·파일 읽기 권한·인코딩·설정·크기 제한 문제는 평가 실패(error)이며 점수는 비워 둡니다. 최신 점수표와 CSV는 제출 상태 0점을 실제 점수로 반영하며, 이후 서버 평가가 실패해도 기존 0점을 유지합니다. 예전에 실패로 기록한 학생은 미평가·실패 선택 → 일괄 정성평가로 다시 처리하면 제출 상태를 재확인해 새 결과를 DB에 저장합니다. 이전 실행 기록은 보존합니다.
자동 저장: 시작 시와 각 학생 완료 시 reports/qualitative_<시각>_<식별자>.json에 문제·평가 기준·완료 결과를 저장합니다. 중지하면 현재 학생 요청이 끝난 뒤 멈추고 완료된 결과를 보존합니다. 저장된 평가 열기로 JSON 보고서를 다시 열어 검토·확정할 수 있습니다. 불러온 보고서의 문제와 배점도 복원합니다.
정성평가 CSV/JSON에도 이름(student_name)을 함께 보관합니다. 예전 보고서에 이름이 없으면 로컬 명단에서 보충하며, 기존에 저장된 이름은 유지합니다. 이름 매핑은 LLM 요청에 별도로 포함하지 않습니다.
메인 표의 최신 점수표 CSV에는 문제별로 1번 정성 점수, 1번 정성 사유, 1번 정성 상태 같은 요약 열도 추가됩니다. 점수는 메인 표처럼 확정 점수 우선, 확정 전에는 AI 제안 점수이며 미평가·실패는 빈칸입니다. 중간고사 전체 보기의 CSV에는 메인 표와 같은 합계인 정성 총점과 그 만점인 정성 총점 만점 열도 들어갑니다. 사유는 파일 없음, 빈 파일처럼 한 줄로 저장하고 기존 상세 열은 유지합니다. 정성평가 창의 상태는 자동 0점의 원인을 대상파일없음, 제출폴더없음, 빈파일로 구분합니다. 실제 평가 오류는 계속 평가 실패로 표시합니다.
내보내기: 기본 학생별 요약 CSV는 현재 평가 결과의 학생 한 명당 한 행입니다. 배점·AI 제안 부분점수(suggested_score)·교수자 확정 점수(final_score)·종합 품질(overall), 항목별 점수와 적용 여부를 열로 저장합니다. 실패 학생도 한 행을 유지하고 점수는 비웁니다. 총평·검토 의견의 개행은 공백으로 합쳐 학생 수만큼 데이터 행이 생깁니다. 저장 창에서 항목별 상세 CSV를 선택하면 기존처럼 학생·항목별 한 행으로 평가 의견과 코드 근거를 저장합니다(7항목이면 학생당 7행). JSON은 문제/평가 기준, 개행을 포함한 전체 상세, 모델·서버·평가 시각과 파일별 SHA-256을 보관하며 다시 열어 검토할 수 있습니다. AI 제안 상태는 ai_proposed, 교수자 확정은 confirmed, 실패는 error이며 확정 전 final_score는 비어 있습니다. 제안 상태에서도 결과를 내보낼 수 있습니다.
새 보고서는 계산 버전, 문제 배점, 자원 적용 설정·판정 사유, 종합 품질과 부분점수를 보관합니다. 다시 열 때 계산 결과를 검증하며, 제외 문항은 JSON score: null/CSV 빈 점수로 저장합니다. 이전 평가 기준의 보고서는 당시 점수 그대로 열어 검토할 수 있고 새 기준으로 자동 변경하지 않습니다. 이전 보고서에서 새 평가를 시작하려면 DCUCode 기준으로 복원을 누릅니다.
정성평가와 실행 기반 자동 채점은 별도 결과입니다. 정성평가에서 코드를 실행하지 않으며, 실제 실행 성공이나 표절 여부를 확정하지 않습니다. 코드 근거의 파일/줄 존재를 검증해도 설명의 타당성까지 보장하지는 않으므로 점수는 교수자 검토용 제안으로 표시합니다. API 요청 제한 시간은 기본 300초(5분)입니다.
강의 원본 PPTX/PDF는 로컬 강의자료/ 폴더에 보관합니다. 원본과 자동 생성된 docs/practice_catalog.json은 Git에서 제외되며, 다른 PC에서는 원본 자료를 해당 폴더에 추가하면 슬라이드 선택 목록이 구성됩니다.