ESP32-S3 Bench Guide
ESP32‑S3 N16R8 벤치 가이드: 실시간 핀아웃, 강의, 시뮬레이터 및 벤치 로그
아직 감지된 업데이트가 없습니다. GitHub 릴리스가 나오면 여기에 보입니다.
개인 계정의 공개 저장소 소유자는 GitHub로 로그인해 운영자를 확인하고 소개를 직접 관리할 수 있습니다. 관리자 승인은 필요하지 않습니다.
로그인한 뒤 확인 파일을 만들어 이 저장소의 기본 브랜치에 30분 안에 커밋해 주세요. 다른 브랜치나 포크의 파일은 인정하지 않습니다. 파일을 올린 뒤 아래에서 확인하면 관리자 승인 없이 관리할 수 있습니다. 자격을 유지하려면 파일을 남겨 두세요.
로그인이 필요하면 로그인 화면으로 이동합니다. 로그인 후 이곳으로 돌아와 원하는 확인 버튼을 다시 눌러 주세요.
프로젝트 폴더에서 /nomorevibe verify를 실행하면 소유권을 확인하고 소개를 직접 관리할 수 있습니다.
1분 만에 확인하기README 전체를 불러오는 중입니다. 아래는 저장된 발췌입니다.
데이터분석 동아리 회귀 프로젝트(중고차 가격 예측) 자동 채점 사이트. 팀이 예측 결과 CSV(id,price)를 올리면 RMSE·R²를 바로 계산해 리더보드에 올린다. 첫 구현 완료(API·정적 페이지·테스트). Vercel/Neon 배포는 아직. 결정 사항은 아래 문서에 있다. • 제출: sample_submission.csv와 같은 id,price CSV. 코드 실행 없음. • 채점: 행 순서 기준. test.csv의 id는 0부터 매긴 행 번호이고, 제출 파일의 id가 같은 순서인지 확인한 뒤 같은 위치끼리 비교한다. RMSE가 순위 기준, R²는 보조. • 참가: 아이디·비밀번호로 가입하고, 가입 때 적은 팀 번호(숫자만, 앞자리 0 무시)로 팀이 묶인다. 제출만 로그인 필요. 팀당 하루 3회(KST 자정 초기화). • 리더보드: 팀별 최고 기록 1건 — 닉네임·팀 번호·RMSE·R². • 스택: Vercel Hobby + Python(FastAPI) + Neon Postgres Free + 정적 프론트. 비용 0원. • 페이지: 홈 / 채점 / 리더보드 / 미니게임(사과게임·테트리스·블록깨기, 게임별 팀 순위).README 전문 보기 ↗
부산대 데이터분석 동아리 IBA의 중고차 가격 예측 회귀 프로젝트를 자동으로 채점하는 사이트다. 팀이 예측 결과 CSV를 올리면 RMSE와 R²를 바로 계산해 리더보드에 올린다. Vercel Hobby와 Neon Postgres Free 무료 티어로 운영해서 비용이 들지 않는다.
/how-to-use.html)| 읽는 사람 | 먼저 볼 곳 |
|---|---|
| 대회에 참가하는 팀원 | 사이트의 사용법 페이지, 이 문서의 채점 규칙 |
| 이번 기수 대회를 여는 운영진 | 기수 운영, 문제 해결 |
| 사이트를 고치는 사람 | 기술 스택, 폴더 구조, 로컬 실행, 테스트, 작업 방식, 자주 고치는 곳 |
| 사이트를 처음부터 다시 세우는 사람 | 새로 배포하기 |
iba_dev가 있다. 이 계정으로 낸 제출과 게임 점수는 기록하지 않고, 리더보드와 게임 순위에는 실제 기록 대신 목데이터가 보인다.id,price CSV다. 39,085행 전부를 test.csv와 같은 순서로 내야 한다.public 점수와 최종 점수를 나누는 것은 과적합을 막기 위해서다. 보이는 점수만 보고 모델을 고르면 그 30% 구간에만 잘 맞는 모델이 나오기 쉬워서, 최종 순위에는 대회 중에 본 적 없는 행을 섞는다. Kaggle의 public과 private 리더보드와 같은 방식이다.
| 역할 | 도구 | 고른 이유 |
|---|---|---|
| 백엔드 | Python 3.12, FastAPI | 동아리원 대부분이 Python을 쓰고, 채점 로직을 pandas 없이 표준 라이브러리로 짤 수 있다 |
| 프론트엔드 | HTML, CSS, 바닐라 JavaScript | 빌드 단계가 없어서 파일을 고치면 그대로 반영된다 |
| 배포 | Vercel Hobby | main에 push하면 자동 배포되고, Python 함수와 정적 파일을 한 저장소에서 같이 올린다 |
| DB | Neon Postgres Free | 신용카드 없이 쓸 수 있는 무료 Postgres다 |
사이트는 PC 브라우저에서 쓰는 것을 전제로 만들었고 모바일 화면과 터치 입력은 지원하지 않는다. 미니게임도 마우스와 키보드로만 조작한다.
Vercel Hobby는 비상업 용도로만 쓸 수 있다. 광고나 유료 기능을 붙이면 요금제를 바꿔야 한다. 플랫폼을 고른 과정과 무료 티어 한도는 docs/tech-stack-research.md에 있다.
flowchart LR
B[브라우저] -->|HTML, CSS, JS, 데이터셋| CDN[Vercel CDN<br/>public/]
B -->|/api/*| F[Vercel Python 함수<br/>app.py]
F --> S[scoring/<br/>CSV 검증, RMSE, R²]
F --> DB[(Neon Postgres<br/>정답, 계정, 제출, 게임 점수, 설정)]
페이지와 데이터셋은 Vercel CDN이 public/에서 그대로 내려보내고, /api/로 시작하는 요청만 Python 함수가 처리한다. 정답은 Neon DB에만 있어서 브라우저에서는 정답을 받을 수 없고, 채점할 때 함수만 정답을 읽는다.
app.py # FastAPI 앱, /api/* 엔드포인트 (Vercel Python 런타임 진입점)
auth.py # 비밀번호 해시(PBKDF2), 서명 쿠키 세션
store.py # 저장소 계층: PostgresStore(Neon) / MemoryStore(테스트, 로컬)
scoring/ # 채점 로직
parse.py # 제출 CSV 검증
metrics.py # RMSE, R²
split.py # public 구간 선택 (30%)
teams.py # 팀 번호와 닉네임 정규화, 이번 기수 팀 목록
clock.py # 한국 시간 기준 일정과 제출 횟수 초기화 시각
public/ # 정적 사이트 (Vercel CDN이 그대로 서빙)
*.html # 홈, 채점, 리더보드, 사용법, 미니게임, 로그인, 관리자, About, Thanks
assets/ # 페이지별 CSS, JS, 이미지
games/ # 미니게임
data/ # 참가자 배포용 CSV 네 개와 baseline 노트북, 이 다섯 개를 묶은 dataset.zip,
# 구경용 계정이 쓰는 demo_submission.csv, 채점 화면이 읽는 lyrics-*.txt
scripts/ # schema.sql, load_answers.py(정답 적재), grant_admin.py(첫 관리자 지정)
tests/ # pytest (API 레벨)
docs/ # 개발 문서: 구현 스펙, 구현 전 결정 기록, 기술 스택 조사
.github/workflows/ # push와 PR마다 pytest를 돌리는 GitHub Actions
vercel.json # 배포 지역(싱가포르)과 함수 번들에서 뺄 폴더
Python 패키지 관리는 uv를 쓴다. uv가 없으면 https://docs.astral.sh/uv/ 에서 먼저 설치한다.
uv venv --python 3.12 .venv
source .venv/bin/activate # Windows PowerShell: .venv\Scripts\Activate.ps1
uv pip install -r requirements-dev.txt
DB 없이 돌리려면 정답 CSV 경로만 넘긴다. 제출 기록은 메모리에만 남고 재시작하면 사라진다.
# macOS, Linux
DEV_ANSWER_CSV=answer.csv SESSION_SECRET=dev uvicorn app:app --port 8765
# Windows PowerShell
$env:DEV_ANSWER_CSV="answer.csv"; $env:SESSION_SECRET="dev"; uvicorn app:app --port 8765
브라우저에서 http://localhost:8765 를 연다. 이 모드에서는 아무 아이디와 비밀번호로나 로그인되고, 아이디 admin으로 로그인하면 관리자 계정이 된다. 실제 배포에서는 이 기능이 꺼져 있다.
정답 파일 없이 화면만 보고 싶으면 public/을 8791 포트로 띄운다. 이 포트에서는 public/assets/local-preview.js가 API 응답을 흉내 내서 로그인한 화면을 볼 수 있다. 리더보드 기록은 흉내 내지 않으므로 리더보드는 8765 포트에서 확인한다.
python -m http.server 8791 -d public
pytest
실제 정답 파일로 기준값 테스트까지 하려면 ANSWER_CSV에 정답 경로를 넣고 pytest tests/test_real_data.py를 실행한다. sample_submission을 그대로 내면 전체 데이터 RMSE가 13,189.79로 나와야 한다. 채점 로직을 고쳤다면 push하기 전에 이 테스트까지 돌린다.
GitHub Actions도 main에 push하거나 PR을 올릴 때마다 pytest를 돌린다. 저장소에는 정답 파일이 없어서 Actions에서는 실제 정답 테스트를 건너뛰고 합성 정답으로 만든 테스트만 실행한다.
지금까지는 대부분의 수정을 main에 바로 push했고, 화면을 크게 바꾸는 작업 11건은 feat/나 fix/ 브랜치에서 PR로 올려 병합했다. main에 push하면 바로 실제 사이트에 배포되므로, 앞으로는 아래처럼 PR로 올리기를 권한다.
main에서 feat/나 fix/로 시작하는 브랜치를 만든다.pytest를 돌리고, 채점 로직을 고쳤다면 실제 정답 테스트까지 돌린다.main에 병합한다.미리보기 주소도 실제 사이트와 같은 DB를 쓴다. 미리보기에서 가입하거나 제출하면 실제 기록에 남으므로 화면 확인은 구경용 계정 iba_dev로 한다.
저장소는 GitHub 조직 pnu-iba의 https://github.com/pnu-iba/iba_scoring_machine 이다. Vercel 팀 pnu-iba와 Neon DB는 동아리 공용 구글 계정으로 관리하고, Vercel은 동아리 GitHub 계정 pnuiba와 연결되어 있다. 계정 정보는 운영진끼리 따로 전달한다.
main 브랜치에 push하면 Vercel이 자동으로 배포한다. 다른 브랜치에 push하면 미리보기 주소가 따로 만들어진다. 미리보기가 같은 DB를 쓴다는 점은 작업 방식 절에 적었다.
Vercel은 정적 파일을 Cache-Control: max-age=0, must-revalidate로 내려보내서 배포가 끝나면 CSS와 JS도 바로 반영된다. 그래도 옛 화면이 보이면 Ctrl+Shift+R로 강력 새로고침한다.
계정을 옮기거나 사이트를 처음부터 다시 세울 때만 필요한 절차다.
DATABASE로 정하면 코드가 읽는 DATABASE_URL이 자동으로 들어간다.SESSION_SECRET을 넣는다. 길고 무작위인 문자열이면 되고, 바꾸면 모든 사용자가 로그아웃된다.psql "$DATABASE_URL" -f scripts/schema.sql로 스키마를 만든다. 이미 만든 DB에 다시 실행해도 빠진 컬럼과 테이블만 추가한다.DATABASE_URL=... python scripts/load_answers.py answer.csv로 정답을 처음 한 번만 적재한다. 이때 public 구간이 무작위로 정해지므로, 다시 적재하면 구간이 바뀌어 기존 점수와 맞지 않는다.DATABASE_URL=... python scripts/grant_admin.py <아이디>로 첫 관리자를 지정한다. 가입할 때 적은 팀 번호는 그대로 남지만, 관리자는 리더보드와 가입자 집계에서 빠진다.iba_dev를 사이트에서 가입해 둔다. 이 아이디로 로그인하면 구경용으로 동작하고, 미리 만들어 두어야 다른 사람이 이 아이디를 가져가지 못한다./api/health가 {"ok": true}를 돌려주는지, 브라우저에서 /answer.csv를 열었을 때 파일이 내려받아지지 않는지 확인한다.관리자 계정으로 로그인하면 사이드바에 Admin 메뉴(/admin.html)가 보인다. 관리자 계정으로는 제출할 수 없고, 파일 점수만 확인할 때는 채점 확인 기능을 쓴다.
| 탭 | 하는 일 |
|---|---|
| 현황 | 대회 상태, 시작과 마감 시각, 정답 적재 여부, 제출 수와 가입자 수 |
| 대회 설정 | 시작일, 마지막 날, 하루 제출 횟수. 저장하면 바로 반영된다 |
| 제출 | 전체 제출 목록, 삭제와 복구 |
| 사용자 | 팀 번호 변경, 임시 비밀번호 발급, 관리자 지정과 해제 |
| 채점 확인과 초기화 | 기록이 남지 않는 채점, 결과 zip 내려받기, 기수 초기화 |
대회가 끝나면 이번 운영진이 아래 순서로 정리한다.
git tag 2026-2 다음에 git push origin 2026-2를 실행한다.기수 초기화는 이때 하지 않는다. 초기화하면 제출 기록이 지워져서 최종 리더보드도 사라지므로 다음 대회를 열 때까지 그대로 둔다.
다음 대회를 열 때는 새 운영진이 아래 순서로 준비한다.
기수 초기화를 입력해야 실행된다.scoring/teams.py의 TEAMS를 고쳐 push한다.초기화하면 제출 기록이 지워지고, 기본으로 체크된 두 항목에 따라 관리자가 아닌 계정과 미니게임 점수도 지워진다. 관리자 계정, 구경용 계정 iba_dev, 정답, 대회 설정은 남는다. 데이터셋과 정답은 기수가 바뀌어도 그대로 쓴다.
| 하고 싶은 일 | 고칠 곳 |
|---|---|
| 대회 일정, 하루 제출 횟수 변경 | 관리자 페이지 대회 설정 탭 (코드 수정 없음) |
| 팀 수 변경 | scoring/teams.py의 TEAMS |
| public 구간 비율 변경 | scoring/split.py의 PUBLIC_FRACTION, 바꾼 뒤 정답을 다시 적재해야 한다 |
| 제출 형식 검사 규칙 변경 | scoring/parse.py |
| 페이지 문구와 디자인 변경 | public/*.html, public/assets/ |
| 참가자에게 주는 데이터 교체 | public/data/, 정답이 바뀌면 answers 테이블도 다시 적재한다 |
| 미니게임 추가와 수정 | public/games/, 점수 저장은 app.py의 /api/games/* |
| 증상 | 확인할 것 |
|---|---|
| 첫 접속이나 첫 제출이 몇 초 걸린다 | Neon 무료 DB는 한동안 요청이 없으면 멈췄다가 다시 켜진다. 고장이 아니다 |
| 참가자가 비밀번호를 잊었다 | 관리자 페이지 사용자 탭에서 임시 비밀번호를 발급한다 |
| 팀 번호를 잘못 적고 가입했다 | 관리자 페이지 사용자 탭에서 팀 번호를 바꾼다 |
| 다른 팀 번호로 가입해 그 팀의 제출 횟수를 쓴 사람이 있다 | 가입할 때 팀을 확인하는 장치는 없다. 제출 탭에서 그 제출을 지우면 횟수가 돌아오고, 사용자 탭에서 계정의 팀을 옮긴다 |
| 실수로 낸 제출을 지우고 싶다 | 관리자 페이지 제출 탭에서 삭제한다. 삭제한 제출은 복구할 수 있다 |
| 모든 사용자가 갑자기 로그아웃됐다 | Vercel 환경변수 SESSION_SECRET이 바뀌었는지 확인한다 |
| 사이트 전체가 오류를 낸다 | Vercel 대시보드의 Logs에서 오류를 보고, DATABASE_URL이 맞는지 확인한다 |
이 저장소는 공개 저장소라서 answer.csv를 커밋하지 않는다. .gitignore와 .vercelignore가 막고 있고, 정답은 Neon DB의 answers 테이블에 둔다. 원본 answer.csv는 새로 배포할 때 다시 필요하므로 운영진끼리 따로 보관한다. DATABASE_URL과 SESSION_SECRET도 Vercel 환경변수에만 두고 코드나 문서에 적지 않는다.
코드는 MIT 라이선스를 따른다. public/data/의 중고차 데이터는 Kaggle의 100,000 UK Used Car Data set(adityadesai13)에서 가져왔고 원본의 CC0 라이선스를 따른다. 같은 폴더의 lyrics-*.txt는 노래 가사라서 이 라이선스들에 포함되지 않는다. public/assets/의 사진은 MIT 라이선스에 포함되지 않으며 따로 허락 없이 쓸 수 없다.
저장소는 공개로 둔다. Vercel Hobby는 GitHub 조직이 가진 비공개 저장소를 배포하지 않으므로 비공개로 바꾸면 자동 배포가 멈춘다.
docs/에는 사이트를 만들면서 쓴 설계 문서가 있다. 기능이 왜 지금처럼 동작하는지 알아야 할 때 docs/README.md부터 본다. 운영과 수정에 필요한 내용은 이 README에 모두 있다.