Files
s-canvas/_unused/REF_BY_SEOK/seed_manager.py
HYUNJUNGLEE b9342f6726 Import S-CANVAS source + iter=1~7 lint cleanup
S-CANVAS (Saman Corp.) — DXF + DEM + AI 기반 3D 조감도 생성 엔진.
~24k LOC Python (scanvas_maker.py 7072 LOC GUI + 구조물 파서/빌더 다수).

이 커밋은 7-iter cleanup이 적용된 상태로 import:
- F821 8 + B023 6: 비동기 lambda + except/loop 변수 캡처 NameError
  (Py3.13에서 reproduce 확인된 진짜 버그)
- RUF012 4 + RUF013 1: ClassVar / implicit Optional 명시화
- F811/B905/B904/F401/F841/W293/F541/UP/SIM/RUF/PLR 700+ cleanup/modernization

신규 파일:
- ruff.toml: target=py313, Korean unicode/저자 스타일/도메인 복잡도 무력화
- requirements-py313.txt: pyproj>=3.7, scipy>=1.14, numpy>=2.0.2 (Py3.13 wheel)
- .gitignore: gcp-key.json, 캐시, 백업, 생성 이미지 제외

검증: ruff 0 errors, py_compile 0 errors, import 33/33 OK on Py3.13.13.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-08 10:29:08 +09:00

67 lines
1.9 KiB
Python

"""Seed 관리자 - 작업별 Seed 고정 및 추적."""
from __future__ import annotations
import hashlib
import random
from typing import Optional
from sqlalchemy.orm import Session
from harness.logger import JobRecord, get_db_session
class SeedManager:
"""DXF 파일 해시 기반 결정론적 seed를 생성하고 이력을 관리한다."""
MAX_SEED = 2**32 - 1
def get_seed(
self,
file_hash: str,
fixed_seed: Optional[int] = None,
deterministic: bool = True,
) -> int:
"""
Args:
file_hash: DXF 파일의 SHA256 해시 앞 16자
fixed_seed: 사용자가 직접 지정한 seed (None이면 자동)
deterministic: True면 파일 해시 기반, False면 랜덤
"""
if fixed_seed is not None:
return int(fixed_seed) % (self.MAX_SEED + 1)
if deterministic:
return self._hash_to_seed(file_hash)
return random.randint(0, self.MAX_SEED)
def get_or_create_seed(
self,
db: Session,
job_id: int,
file_hash: str,
fixed_seed: Optional[int] = None,
deterministic: bool = True,
) -> int:
"""DB에서 기존 seed를 조회하거나 새로 생성한다."""
existing = db.query(JobRecord).filter_by(id=job_id).first()
if existing and existing.seed is not None:
return existing.seed
seed = self.get_seed(file_hash, fixed_seed, deterministic)
if existing:
existing.seed = seed
db.commit()
return seed
@staticmethod
def _hash_to_seed(file_hash: str) -> int:
"""파일 해시를 정수 seed로 변환한다."""
digest = hashlib.sha256(file_hash.encode()).digest()
return int.from_bytes(digest[:4], "big")
@staticmethod
def describe(seed: int) -> str:
return f"seed={seed} (0x{seed:08X})"