워크노트 예제: 설문 CSV 집계 전 응답 수, 누락, 중복 점검하기

준비: Python 3.12 이상. 표준 라이브러리만 사용하며 계정과 외부 패키지는 필요하지 않습니다.
ZIP을 새 폴더에 압축 해제하고 example.py가 보이는 폴더에서 실행합니다.
  python example.py
Windows의 다른 실행기: py example.py / macOS·Linux의 다른 실행기: python3 example.py

입력: responses.csv, respondent_id와 answer 두 열
연습 문항: 다시 이용할 의향이 있나요?
응답: 예 / 아니오 / 잘 모르겠음 / 빈 칸
ID: 개인정보가 없는 직접 작성한 합성 ID R001~R009
같은 ID가 두 번 이상 나오면 그 ID의 모든 행을 제외합니다. 첫 응답을 임의로 선택하지 않습니다.
ID와 답변의 앞뒤 공백은 제거한 뒤 검사합니다.
빈 ID, 규칙을 벗어난 ID, 알 수 없는 응답, 잘못된 열 수는 결과 작성 전에 중지합니다.

예상 결과:
  원시 행 10 / 고유 ID 9 / 중복 ID 1개(R005) / 중복으로 제외되는 행 2
  중복 제외 후 고유 응답자 8 / 그중 빈 응답 2 / 유효 응답 6
  유효 응답 비율: 6/8 = 75.00%
  선택지 비율의 분모: 유효 응답 6
  예 3/6 = 50.00% / 아니오 2/6 = 33.33% / 잘 모르겠음 1/6 = 16.67%

출력:
  outputs/summary.json: 분모와 제외 사유가 포함된 요약
  outputs/choices.csv: 선택지별 개수, 분모, 백분율
  outputs/audit_rows.csv: 원본 데이터 행 순서별 valid/blank_answer/duplicate_id 판정
원본은 변경하지 않습니다. outputs가 있으면 덮어쓰지 않고 종료 코드 2로 중지합니다.
재실행하려면 결과를 다른 이름으로 옮기거나 ZIP을 새 폴더에 풀어 주세요.
분모가 0이면 비율을 계산하지 않고 JSON에는 null, CSV에는 빈 칸을 기록합니다.
비율은 소수점 둘째 자리 반올림이며 합계가 항상 100.00은 아닐 수 있습니다.
빈 물리적 줄은 csv 모듈에서 건너뜁니다. 빈 답변은 R004,처럼 ID가 있는 데이터 행입니다.
연습용 기술 예제이며 표본의 대표성·가중치·통계적 유의성은 판단하지 않습니다.
