Skip to content

Commit c2333e9

Browse files
Merge pull request #51 from dscsnu/algo-final
Algo final
2 parents d6b6425 + bf52e63 commit c2333e9

File tree

13 files changed

+175
-55
lines changed

13 files changed

+175
-55
lines changed

algorithm/app.py

Lines changed: 171 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@
33
import os
44
import shutil
55
import time
6-
76
import pygame
87

98
os.chdir(os.path.dirname(__file__))
@@ -339,6 +338,24 @@ def approve_current(now):
339338
f.close()
340339
print(f"{left_nodes} assigned to {right_name}")
341340

341+
# Save approved nodes to individual spell file
342+
SPELL_JSON_DIR = os.path.abspath("patterns_by_spell")
343+
os.makedirs(SPELL_JSON_DIR, exist_ok=True)
344+
345+
spell_json_path = os.path.join(SPELL_JSON_DIR, f"{right_name}.json")
346+
if os.path.exists(spell_json_path):
347+
with open(spell_json_path, "r") as sf:
348+
spell_data = json.load(sf)
349+
else:
350+
spell_data = []
351+
352+
if list(left_nodes) not in spell_data:
353+
spell_data.append(list(left_nodes))
354+
355+
with open(spell_json_path, "w") as sf:
356+
json.dump(spell_data, sf, indent=4)
357+
358+
342359
# Remember the current index before reloading
343360
current_index = left_index
344361

@@ -365,51 +382,91 @@ def reject_current(now):
365382

366383
left_filename = left_files[left_index]
367384
left_path = left_paths[left_index]
368-
target_path = os.path.join(REJECTED_FOLDER, left_filename)
369385
left_nodes = left_nodelist[left_index]
370386
left_nodelist.pop(0)
371387

372-
# Move instead of copy
388+
is_triangle = isinstance(left_nodes, tuple) and len(left_nodes) == 3
389+
triangle_key = "triangle"
390+
391+
# Folder routing
392+
if is_triangle:
393+
target_dir = os.path.join(OUTPUT_FOLDER, triangle_key)
394+
else:
395+
target_dir = REJECTED_FOLDER
396+
397+
os.makedirs(target_dir, exist_ok=True)
398+
target_path = os.path.join(target_dir, left_filename)
399+
373400
shutil.move(left_path, target_path)
374401
action_stack.append(("rejected", left_index, target_path, left_path))
375-
376-
# prints that the nodes were rejected
377402
node_stack.append(left_nodes)
378-
right_name = os.path.splitext(right_files[right_index % len(right_files)])[0]
379-
file_exists = False
403+
404+
print(f"{left_nodes} was rejected")
405+
406+
# --- spell_patterns.json ---
380407
try:
381-
with open("spell_patterns.json", "r"):
382-
file_exists = True
408+
with open("spell_patterns.json", "r") as f:
409+
data = json.load(f)
383410
except FileNotFoundError:
384-
pass
385-
if file_exists:
386-
f = open("spell_patterns.json", "r")
387-
data = json.load(f)
388-
f.close()
411+
data = {"valid_patterns": 0}
412+
413+
if is_triangle:
414+
if triangle_key not in data:
415+
data[triangle_key] = {"patterns": [], "valid_patterns": 0}
416+
if list(left_nodes) not in data[triangle_key]["patterns"]:
417+
data[triangle_key]["patterns"].append(list(left_nodes))
418+
data[triangle_key]["valid_patterns"] += 1
419+
data["valid_patterns"] += 1
420+
print(f"{left_nodes} saved to triangle")
421+
else:
422+
right_name = os.path.splitext(right_files[right_index % len(right_files)])[0]
389423
if right_name in data:
390424
if list(left_nodes) in data[right_name]["patterns"]:
391425
data[right_name]["patterns"].remove(list(left_nodes))
392-
if len(data[right_name]["patterns"]) == 0:
393-
data.pop(right_name, None)
394-
else:
395-
data[right_name]["valid_patterns"] -= 1
426+
data[right_name]["valid_patterns"] -= 1
396427
data["valid_patterns"] -= 1
397-
f = open("spell_patterns.json", "w+")
398-
f.write(json.dumps(data, indent=4))
399-
f.close()
428+
if data[right_name]["valid_patterns"] == 0:
429+
del data[right_name]
400430

401-
# Remember the current index before reloading
402-
current_index = left_index
431+
with open("spell_patterns.json", "w") as f:
432+
json.dump(data, f, indent=4)
403433

404-
# After moving, reload the image list
405-
reload_images()
434+
# --- patterns_by_spell/triangle.json ---
435+
if is_triangle:
436+
triangle_json_path = os.path.join("patterns_by_spell", f"{triangle_key}.json")
437+
os.makedirs("patterns_by_spell", exist_ok=True)
406438

407-
# Stay at the same index after removing, unless we're at the end
408-
if current_index >= len(left_paths):
409-
left_index = max(0, len(left_paths) - 1)
410-
else:
411-
left_index = current_index
439+
try:
440+
with open(triangle_json_path, "r") as tf:
441+
triangle_data = json.load(tf)
442+
except FileNotFoundError:
443+
triangle_data = []
444+
445+
if list(left_nodes) not in triangle_data:
446+
triangle_data.append(list(left_nodes))
447+
448+
with open(triangle_json_path, "w") as tf:
449+
json.dump(triangle_data, tf, indent=4)
412450

451+
# --- rejected.json (ONLY non-triangle patterns) ---
452+
if not is_triangle:
453+
rejected_json_path = os.path.join("rejected.json")
454+
try:
455+
with open(rejected_json_path, "r") as rj:
456+
rejected_data = json.load(rj)
457+
except FileNotFoundError:
458+
rejected_data = {"rejected_patterns": []}
459+
460+
if list(left_nodes) not in rejected_data["rejected_patterns"]:
461+
rejected_data["rejected_patterns"].append(list(left_nodes))
462+
463+
with open(rejected_json_path, "w") as rj:
464+
json.dump(rejected_data, rj, indent=4)
465+
466+
# --- Finalization ---
467+
current_index = left_index
468+
reload_images()
469+
left_index = max(0, len(left_paths) - 1) if current_index >= len(left_paths) else current_index
413470
approval_time = now
414471
message_text = "Rejected!"
415472
message_color = RED
@@ -420,33 +477,93 @@ def go_back(now):
420477
global left_index, approval_time, show_message, message_text, message_color
421478
if action_stack:
422479
action, index, target_path, original_path = action_stack.pop()
480+
node = node_stack.pop()
481+
left_nodelist.insert(0, node) # Restore the node
482+
print(f"{node} was retrieved")
423483

424-
# adds the nodes back to the original list
425-
left_nodelist.insert(0, node_stack.pop())
426-
427-
print(f"{left_nodelist[0]} was retrieved")
484+
# Restore the image file
428485
if os.path.exists(target_path):
429-
# Make sure the directory exists
430486
os.makedirs(os.path.dirname(original_path), exist_ok=True)
431-
# Move the file back to its original location
432487
shutil.move(target_path, original_path)
433-
434-
# Reload images after moving it back
435488
reload_images()
436489

437-
# Find the index of the restored file
438490
try:
439491
restored_filename = os.path.basename(original_path)
440492
restored_index = left_files.index(restored_filename)
441493
left_index = restored_index
442494
except ValueError:
443-
# If for some reason we can't find the file, just stay at current index
444495
pass
445496

446-
approval_time = now
447-
message_text = "Undone"
448-
message_color = GRAY
449-
show_message = True
497+
# Load spell_patterns.json
498+
try:
499+
with open("spell_patterns.json", "r") as f:
500+
data = json.load(f)
501+
except FileNotFoundError:
502+
data = {"valid_patterns": 0}
503+
504+
node_list = list(node)
505+
506+
if action == "approved":
507+
try:
508+
spell_name = os.path.basename(os.path.dirname(target_path))
509+
except IndexError:
510+
spell_name = None
511+
512+
if spell_name and spell_name in data:
513+
if node_list in data[spell_name]["patterns"]:
514+
data[spell_name]["patterns"].remove(node_list)
515+
data[spell_name]["valid_patterns"] -= 1
516+
data["valid_patterns"] -= 1
517+
if data[spell_name]["valid_patterns"] == 0:
518+
del data[spell_name]
519+
520+
spell_json_path = os.path.join("patterns_by_spell", f"{spell_name}.json")
521+
if os.path.exists(spell_json_path):
522+
with open(spell_json_path, "r") as sf:
523+
spell_data = json.load(sf)
524+
if node_list in spell_data:
525+
spell_data.remove(node_list)
526+
with open(spell_json_path, "w") as sf:
527+
json.dump(spell_data, sf, indent=4)
528+
529+
elif action == "rejected":
530+
is_triangle = isinstance(node, tuple) and len(node) == 3
531+
triangle_key = "triangle"
532+
533+
if is_triangle and triangle_key in data:
534+
if node_list in data[triangle_key]["patterns"]:
535+
data[triangle_key]["patterns"].remove(node_list)
536+
data[triangle_key]["valid_patterns"] -= 1
537+
data["valid_patterns"] -= 1
538+
if data[triangle_key]["valid_patterns"] == 0:
539+
del data[triangle_key]
540+
541+
triangle_json_path = os.path.join("patterns_by_spell", f"{triangle_key}.json")
542+
if os.path.exists(triangle_json_path):
543+
with open(triangle_json_path, "r") as tf:
544+
triangle_data = json.load(tf)
545+
if node_list in triangle_data:
546+
triangle_data.remove(node_list)
547+
with open(triangle_json_path, "w") as tf:
548+
json.dump(triangle_data, tf, indent=4)
549+
550+
# Remove from rejected.json
551+
rejected_json_path = os.path.join("rejected.json")
552+
if os.path.exists(rejected_json_path):
553+
with open(rejected_json_path, "r") as rj:
554+
rejected_data = json.load(rj)
555+
if node_list in rejected_data["rejected_patterns"]:
556+
rejected_data["rejected_patterns"].remove(node_list)
557+
with open(rejected_json_path, "w") as rj:
558+
json.dump(rejected_data, rj, indent=4)
559+
560+
with open("spell_patterns.json", "w") as f:
561+
json.dump(data, f, indent=4)
562+
563+
approval_time = now
564+
message_text = "Undone"
565+
message_color = GRAY
566+
show_message = True
450567

451568

452569
# --- Main Loop ---
@@ -478,12 +595,14 @@ def main():
478595
for event in pygame.event.get():
479596
if event.type == pygame.QUIT:
480597
running = False
598+
with open("patterns_nodes.txt", "w") as f:
599+
f.write(str(left_nodelist))
481600

482601
elif event.type == pygame.KEYDOWN:
483-
if event.key == pygame.K_ESCAPE:
484-
running = False
485-
elif event.key == pygame.K_RETURN:
602+
if event.key == pygame.K_RETURN or event.key == pygame.K_y:
486603
approve_current(now)
604+
elif event.key == pygame.K_n:
605+
reject_current(now)
487606
elif event.key == pygame.K_LEFT and right_paths:
488607
key_held_left = True
489608
next_hold_time = now
@@ -493,9 +612,10 @@ def main():
493612
elif event.key == pygame.K_f:
494613
fullscreen = not fullscreen
495614
pygame.display.set_mode(
496-
(WIDTH, HEIGHT),
497-
pygame.FULLSCREEN if fullscreen else pygame.RESIZABLE,
498-
)
615+
(WIDTH, HEIGHT),
616+
pygame.FULLSCREEN if fullscreen else pygame.RESIZABLE,
617+
)
618+
499619

500620
elif event.type == pygame.KEYUP:
501621
if event.key == pygame.K_LEFT:
@@ -530,4 +650,4 @@ def main():
530650

531651

532652
if __name__ == "__main__":
533-
main()
653+
main()

algorithm/main.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@
2626
"Arc": (28.52723498480195, 77.57292972432113),
2727
"SARC": (28.523582249548888, 77.57437275274097),
2828
"C1": (28.52440905859402, 77.57308311017349),
29-
"Dib": (28.5246012306206, 77.57226886728225),
29+
"Dib": (28.525235547619324, 77.57072373132858),
3030
"DH3": (28.52316003957018, 77.5696713403205),
3131
"ISC": (28.521496152454514, 77.5712575598366),
3232
}
@@ -52,16 +52,16 @@
5252
fig, ax = plt.subplots(figsize=(8, 8))
5353
ax.set_title(f"Nodes: {', '.join(combo)}", fontsize=8)
5454

55-
# Set map limits around campus
55+
# # Set map limits around campus
5656
buffer = 200
5757
bounds = pts.total_bounds
5858
ax.set_xlim(bounds[0] - buffer, bounds[2] + buffer)
5959
ax.set_ylim(bounds[1] - buffer, bounds[3] + buffer)
6060

61-
# Add basemap (with transparency)
61+
# # Add basemap (with transparency)
6262
cx.add_basemap(ax, source=cx.providers.OpenStreetMap.Mapnik, alpha=0.5)
6363

64-
# Plot only the selected nodes as red triangles
64+
# # Plot only the selected nodes as red triangles
6565
for name in combo:
6666
geom = pts[pts["name"] == name].geometry.values[0]
6767
ax.scatter(geom.x, geom.y, s=100, color='red', edgecolors='black', marker='^', zorder=3)

algorithm/spells/ArrowsCard.jpg

-14.8 KB
Binary file not shown.
-136 KB
Binary file not shown.
-13.3 KB
Binary file not shown.
-16.4 KB
Binary file not shown.

algorithm/spells/TheLogCard.jpg

-97.8 KB
Binary file not shown.

algorithm/spells/ZapCard.jpg

-16.4 KB
Binary file not shown.

algorithm/spells/collinear.png

5.33 KB
Loading

algorithm/spells/images.jpeg

-10.4 KB
Binary file not shown.

0 commit comments

Comments
 (0)