실제 제작 소스에서 찾은 질문을 독립 합성 코드로 다시 만들었다. 전체 구현과 실행 예제, 테스트를 함께 공개하며 원래 업체의 프로그램과 자료는 연결하지 않는다.

숫자를 단위 없이 비교하지 않는다

normalized는 제한된 양의 소수 문자열과 per_1k·per_1m을 받는다. 천 단위 값은 1000배해 백만 단위로 맞추고 Decimal로 계산한다. 알 수 없는 단위와 지수 표현, 숫자형과 참·거짓 입력은 거절한다. 실제 제공자의 현재 가격과 이름을 가져오지 않았다.

표시 문자열의 2와 2.000은 Decimal 값으로 비교한다. 문자열이 다르다는 이유로 가격 변경을 만들지 않기 위해서다. 단위가 확실하지 않은 자료는 추정해 변환하지 않고 검토가 필요하다고 실패한다. 통화 변환과 할인 조건 해석은 없다.

한 필드의 근거가 전체 행을 보장하지 않는다

coverage는 input과 output 같은 각 필드의 값·단위를 근거 행과 비교한다. 참조와 확인 날짜가 있어도 값이 맞지 않으면 그 필드는 missing이다. 한쪽 근거만 맞으면 다른 쪽은 빈 상태로 남는다. 행 하나에 출처 배지를 붙여 모든 필드가 확인됐다고 보이지 않게 하는 구조다.

근거 행은 호출자가 준비한 구조화 값이며 원문을 자동 읽거나 공식 기관의 진위를 확인하지 않는다. 맞는 숫자를 복사해 넣는다고 근거가 진짜가 되는 것도 아니다. 원본 확인과 어떤 문장이 필드를 뒷받침하는지는 별도의 검토 책임으로 남긴다.

사전으로 바꾸기 전에 중복을 막는다

index는 provider·model 조합이 이미 있는지 확인한 뒤 저장한다. before와 after 모두 같은 검사를 받아야 하며 한쪽만 중복이어도 diff는 실패한다. 기존 비교 코드에서 사전 생성으로 같은 키가 사라질 수 있는 질문을 찾고 새 계약에서 명시적으로 막았다.

diff는 실제 값이 바뀐 필드와 checked·reference·note 변경, 원시 단위 표현 변경을 각각 남긴다. 확인일만 바뀌어도 기록은 보존하지만 가격 변경이라고 부르지 않는다. 기존 소스의 무시 필드를 그대로 버리지 않은 것이 새 예제의 차이다.

코드와 구현 살펴보기

독립 합성 전체 구현

"""Synthetic price normalization and evidence-aware diff. No provider fetch."""
from decimal import Decimal,InvalidOperation
from datetime import date
import re
def normalized(value,unit):
 if not isinstance(value,str) or not re.fullmatch(r'\d{1,9}(?:\.\d{1,6})?',value):raise ValueError('bounded unsigned decimal text')
 if unit not in ('per_1k','per_1m'):raise ValueError('unit needs review')
 return format(Decimal(value)*(1000 if unit=='per_1k' else 1),'f')
def coverage(fields,evidence):
 if not isinstance(fields,dict) or not isinstance(evidence,list):raise ValueError('explicit fields and evidence')
 matched={k:[] for k in fields}
 for e in evidence:
  if set(e)!={'field','value','unit','reference','checked'} or not isinstance(e['reference'],str) or not e['reference'].strip():raise ValueError('evidence contract')
  date.fromisoformat(e['checked'])
  if e['field'] not in fields:raise ValueError('unknown field')
  row=fields[e['field']]
  if Decimal(normalized(row['value'],row['unit']))==Decimal(normalized(e['value'],e['unit'])):matched[e['field']].append(e['reference'])
 return dict(matches=matched,missing=sorted(k for k,v in matched.items() if not v),automatic_source_authentication=False)
def index(rows):
 result={}
 for r in rows:
  if set(r)!={'provider','model','input','output','checked','reference','note'}:raise ValueError('snapshot contract')
  if any(not isinstance(r[k],str) or not r[k].strip() for k in ('provider','model','reference')):raise ValueError('identifier/reference')
  key=(r['provider'],r['model'])
  if key in result:raise ValueError('duplicate composite identity')
  date.fromisoformat(r['checked'])
  for k in ('input','output'):normalized(r[k]['value'],r[k]['unit'])
  result[key]=r
 return result
def diff(before,after):
 a,b=index(before),index(after);changes=[]
 for key in sorted(a.keys()|b.keys()):
  if key not in a or key not in b:changes.append(dict(identity=list(key),kind='added' if key in b else 'removed'));continue
  values=[k for k in ('input','output') if Decimal(normalized(a[key][k]['value'],a[key][k]['unit']))!=Decimal(normalized(b[key][k]['value'],b[key][k]['unit']))]
  metadata=[k for k in ('checked','reference','note') if a[key][k]!=b[key][k]]
  representation=[k for k in ('input','output') if a[key][k]!=b[key][k]]
  if values or metadata or representation:changes.append(dict(identity=list(key),kind='value_changed' if values else 'verification_or_representation_only',value_fields=values,metadata_fields=metadata,representation_fields=representation))
 return changes

값이 같은 표현 변경을 보존한다

0.002 per_1k와 2 per_1m은 같은 기준값이지만 원문 표현은 다르다. 새 diff는 value_fields는 비우고 representation_fields를 남긴다. 확인일만 바뀌면 metadata_fields에 남는다. 가격 변경을 만들지 않으면서 근거와 표기 변화의 기록도 잃지 않는 반례다.

이 반례는 실행 기록과 테스트로 다시 확인할 수 있다. 다른 업무에 적용할 때는 이름만 바꾸지 말고 입력의 의미와 실패 정책이 같은지 먼저 확인해야 한다. 작은 독립 함수는 운영 프로그램 전체를 대신하지 않는다.

공개 코드와 ZIP은 같은 검토 파일을 사용한다. 실제 업체의 자료를 가져오거나 외부 시스템을 실행하지 않은 상태에서도 핵심 판단을 확인할 수 있도록 만들었다. 새로운 연결을 추가하면 그 연결의 결과는 별도로 기록해야 한다.

직접 확인한 실행과 남겨 둔 경계

소스 폴더와 ZIP을 새로 푼 폴더에서 각각 12개 테스트가 통과했다. 실행 예제의 실제 반환값도 records.json으로 남겼다. 공개 페이지의 코드는 내려받기 구현과 대조할 수 있다. 과거 프로젝트의 완료 보고와 테스트 수치를 이번 실행의 증거로 가져오지 않았다.

아래 선택기는 실제 로컬 실행에서 저장한 결과를 읽는다. Python이나 서버를 브라우저에서 실행하는 기능은 아니다. 이 검수는 실제 브라우저의 렌더링과 물리적 기기 조작을 포함하지 않는다. 실서비스 통합의 결과는 별도 근거로 확인해야 한다.

저장된 실행 기록을 읽는 뷰어입니다. Python이나 서버를 브라우저에서 실행하지 않습니다.

내려받아 적용하기 전에

ZIP에는 전체 코어와 테스트, 실행기, 저장된 결과와 사용 안내가 있다. 라이브 예제는 두 언어 HTML도 포함한다. 수정과 재사용이 가능한 새 합성 코드이며 고객 원본 이미지, 실데이터와 계정 정보는 없다. 실제 프로그램을 실행하는 지시와 외부 전송도 넣지 않았다.

적용할 때는 먼저 단위와 입력 출처, 실패한 경우의 안내를 실제 업무에 맞춰 정해야 한다. 테스트 통과가 모든 입력 사실과 운영 권한을 보장하지는 않는다. 필요한 인증·저장·전송과 화면 검수는 작은 계약 바깥의 일로 남긴다. 나는 재사용할 코드와 함께 어떤 판단을 다시 해야 하는지도 읽을 수 있게 공개한다.

구현·테스트·실행 예제 ZIP 받기
독립 합성 코드, 수정·재사용 가능