Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 16 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -224,3 +224,19 @@ __marimo__/

# Streamlit
.streamlit/secrets.toml

# --- ๏ฟฝรนฤท๏ฟฝ๏ฟฝฬผ๏ฟฝ/๏ฟฝ๏ฟฝ ๏ฟฝ๏ฟฝ๏ฟฝ๏ฟฝ ๏ฟฝ๏ฟฝ๏ฟฝ๏ฟฝ๏ฟฝ (comparison_test.py๏ฟฝ๏ฟฝ ๏ฟฝ๏ฟฝ๏ฟฝ๏ฟฝ) ---
results/

# --- Python ฤณ๏ฟฝ๏ฟฝ ---
__pycache__/
*.pyc

# --- ๏ฟฝ๏ฟฝ๏ฟฝ๏ฟฝศฏ๏ฟฝ๏ฟฝ ---
.venv/

# --- ๏ฟฝ๏ฟฝ๏ฟฝ๏ฟฝ ๏ฟฝ๏ฟฝ๏ฟฝ๏ฟฝฬบ๏ฟฝ API ๏ฟฝ๏ฟฝ๏ฟฝ ๏ฟฝ๏ฟฝ ๏ฟฝ๏ฟฝ๏ฟฝ (OAuth ๏ฟฝ๏ฟฝ๏ฟฝ๏ฟฝ๏ฟฝ๏ฟฝ๏ฟฝ๏ฟฝ - ๏ฟฝ๏ฟฝ๏ฟฝ๏ฟฝ ฤฟ๏ฟฝ๏ฟฝ ๏ฟฝ๏ฟฝ๏ฟฝ๏ฟฝ) ---
.claude/scripts/gdrive_credentials.json
.claude/scripts/gdrive_token.json
algorithm/scripts/gdrive_credentials.json
algorithm/scripts/gdrive_token.json
3 changes: 3 additions & 0 deletions algorithm/feature/features.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,10 @@ def feature_remove_nine(ctx: FeatureContext) -> float:
nine_count = int((area==9).sum()) #area์•ˆ์— 9๊ฐ€ ์žˆ๋Š” ์ˆ˜์˜ ๊ฐœ์ˆ˜
if not _has_nine_one_pair(ctx): #9์™€ ์ง ์ง€์–ด์ง€๋Š” ๊ฒฝ์šฐ์˜ ์ˆ˜๊ฐ€ ํŒ ๋‚ด์— ์กด์žฌํ•˜๋Š”์ง€
return 0.0
<<<<<<< Updated upstream
return sigmoid(nine_count, k = 0.5, x0 = 3.0) #์ถ”ํ›„ ์ด ๊ฐ’์„ ์กฐ์ •ํ•˜๋ฉด์„œ k ๊ฐ’๊ณผ x0 ๊ฐ’์„ ์ฐพ์•„๋„ ๋จ
=======
>>>>>>> Stashed changes

def feature_remove_eight(ctx: FeatureContext) -> float:
area = ctx.board_array
Expand Down
140 changes: 140 additions & 0 deletions algorithm/scripts/check_changes.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,140 @@
"""
comparison_test.py๊ฐ€ ๋งŒ๋“  ๋‘ ๊ฒฐ๊ณผ JSON์„ ๋น„๊ตํ•ด์„œ:
1. feature ํ•จ์ˆ˜ ์ฝ”๋“œ๊ฐ€ ๋ฐ”๋€ ํ•จ์ˆ˜๋งŒ diff๋กœ ๋ณด์—ฌ์ฃผ๊ณ 
2. run๋ณ„ weight ๊ฐ’์ด ๋ฐ”๋€ ๊ฒƒ๋งŒ ๋ณด์—ฌ์ค€๋‹ค

comparison_test.py์˜ ์ž๋™ ์‹คํ–‰ ๋กœ์ง๊ณผ ๋ฌด๊ด€ํ•˜๊ฒŒ, ์ˆœ์ˆ˜ํ•˜๊ฒŒ ํŒŒ์ผ ๋‘ ๊ฐœ๋งŒ ์žˆ์œผ๋ฉด ๋™์ž‘ํ•œ๋‹ค.

์‚ฌ์šฉ๋ฒ•:
python check_changes.py old.json new.json
"""
import difflib
import json
import sys
from pathlib import Path


def load(path: str) -> dict:
data = json.loads(Path(path).read_text(encoding="utf-8"))
if "feature_snapshot" not in data:
print(f"โš ๏ธ ๊ฒฝ๊ณ : {path} ์— 'feature_snapshot' ํ•„๋“œ๊ฐ€ ์—†์Œ โ€” "
f"comparison_test.py๋กœ ๋งŒ๋“  ํŒŒ์ผ์ด ๋งž๋Š”์ง€ ํ™•์ธ ํ•„์š”")
return data


def check_code_changes(old: dict, new: dict) -> bool:
"""feature ํ•จ์ˆ˜ ์ฝ”๋“œ๊ฐ€ ๋ฐ”๋€ ๊ฒƒ๋งŒ ๊ณจ๋ผ์„œ diff๋กœ ๋ณด์—ฌ์ค€๋‹ค. ํ•˜๋‚˜๋ผ๋„ ๋ฐ”๋€Œ์—ˆ์œผ๋ฉด True ๋ฐ˜ํ™˜."""
old_snap = old.get("feature_snapshot", {})
new_snap = new.get("feature_snapshot", {})

print("\n" + "=" * 60)
print("1. ํ•จ์ˆ˜ ์ฝ”๋“œ ๋ณ€๊ฒฝ ์ฒดํฌ")
print("=" * 60)

if not old_snap or not new_snap:
print("๋น„๊ตํ•  feature_snapshot์ด ๋น„์–ด์žˆ์Œ โ€” ๋‘ JSON ๋‹ค comparison_test.py๋กœ ๋งŒ๋“  ๊ฒŒ ๋งž๋Š”์ง€ ํ™•์ธ")
return False

all_names = sorted(set(old_snap) | set(new_snap))
any_changed = False

for name in all_names:
old_entry = old_snap.get(name)
new_entry = new_snap.get(name)

if old_entry is None:
print(f"\n[+ ์ƒˆ๋กœ ์ถ”๊ฐ€๋จ] {name}")
any_changed = True
continue
if new_entry is None:
print(f"\n[- ์‚ญ์ œ๋จ] {name}")
any_changed = True
continue

old_hash = old_entry.get("source_hash")
new_hash = new_entry.get("source_hash")

if old_hash == new_hash:
continue # ์•ˆ ๋ฐ”๋€ ๊ฑด ์กฐ์šฉํžˆ ๋„˜์–ด๊ฐ (๋ฐ”๋€ ๊ฒƒ๋งŒ ๋ณด์—ฌ์ฃผ๋Š” ๊ฒŒ ๋ชฉ์ )

any_changed = True
print(f"\n[์ฝ”๋“œ ๋ฐ”๋€œ] {name} (hash: {old_hash} โ†’ {new_hash})")
old_lines = (old_entry.get("source") or "").splitlines(keepends=True)
new_lines = (new_entry.get("source") or "").splitlines(keepends=True)
diff = list(difflib.unified_diff(old_lines, new_lines, fromfile="old", tofile="new"))
if diff:
print("".join(diff))
else:
print(" (hash๋Š” ๋‹ค๋ฅธ๋ฐ ํ…์ŠคํŠธ๊ฐ€ ๊ฐ™๊ฒŒ ๋ณด์ž„ โ€” ๊ณต๋ฐฑ/์ธ์ฝ”๋”ฉ ๋ฌธ์ œ ์˜์‹ฌ, source ํ•„๋“œ ์ง์ ‘ ํ™•์ธ ํ•„์š”)")

if not any_changed:
print("์ฝ”๋“œ๊ฐ€ ๋ฐ”๋€ feature ์—†์Œ")

return any_changed


def check_weight_changes(old: dict, new: dict) -> bool:
"""run๋ณ„ weight ๊ฐ’์ด ๋ฐ”๋€ ๊ฒƒ๋งŒ ๋ณด์—ฌ์ค€๋‹ค. ํ•˜๋‚˜๋ผ๋„ ๋ฐ”๋€Œ์—ˆ์œผ๋ฉด True ๋ฐ˜ํ™˜."""
old_runs = {r["name"]: r.get("weights", {}) for r in old.get("runs", [])}
new_runs = {r["name"]: r.get("weights", {}) for r in new.get("runs", [])}

print("\n" + "=" * 60)
print("2. weight ๋ณ€๊ฒฝ ์ฒดํฌ")
print("=" * 60)

if not old_runs or not new_runs:
print("๋น„๊ตํ•  runs๊ฐ€ ๋น„์–ด์žˆ์Œ โ€” ๋‘ JSON ๋‹ค ์‹ค์ œ๋กœ ์‹œ๋ฎฌ๋ ˆ์ด์…˜์„ ๋Œ๋ ค์„œ ๋งŒ๋“  ๊ฒŒ ๋งž๋Š”์ง€ ํ™•์ธ")
return False

all_names = sorted(set(old_runs) | set(new_runs))
any_changed = False

for name in all_names:
if name not in old_runs:
print(f"\n[+ ์ƒˆ๋กœ ์ถ”๊ฐ€๋œ run] {name}: {new_runs[name]}")
any_changed = True
continue
if name not in new_runs:
print(f"\n[- ์‚ญ์ œ๋œ run] {name}")
any_changed = True
continue

old_w, new_w = old_runs[name], new_runs[name]
if old_w == new_w:
continue # ์•ˆ ๋ฐ”๋€ run์€ ์กฐ์šฉํžˆ ๋„˜์–ด๊ฐ

any_changed = True
print(f"\n[weight ๋ฐ”๋€œ] {name}")
keys = sorted(set(old_w) | set(new_w))
for k in keys:
ov = old_w.get(k, "(๋ฏธ์ง€์ • โ†’ ๊ธฐ๋ณธ๊ฐ’)")
nv = new_w.get(k, "(๋ฏธ์ง€์ • โ†’ ๊ธฐ๋ณธ๊ฐ’)")
if ov != nv:
print(f" {k}: {ov} โ†’ {nv}")

if not any_changed:
print("weight๊ฐ€ ๋ฐ”๋€ run ์—†์Œ")

return any_changed


def main():
if len(sys.argv) != 3:
print("์‚ฌ์šฉ๋ฒ•: python check_changes.py <old.json> <new.json>")
sys.exit(1)

old_path, new_path = sys.argv[1], sys.argv[2]
old, new = load(old_path), load(new_path)

print(f"๋น„๊ต: {old_path} ({old.get('generated_at', '?')}) vs {new_path} ({new.get('generated_at', '?')})")

code_changed = check_code_changes(old, new)
weight_changed = check_weight_changes(old, new)

print("\n" + "=" * 60)
print(f"๊ฒฐ๊ณผ: ์ฝ”๋“œ ๋ณ€๊ฒฝ = {code_changed}, weight ๋ณ€๊ฒฝ = {weight_changed}")
print("=" * 60)


if __name__ == "__main__":
main()
Loading