kestrel256 commited on
Commit
39fd1e1
·
verified ·
1 Parent(s): 862e551

Updated handling of Explanation when cards are renamed

Browse files

After a set of cards is generated, the previous logic included a check for card names that have already been used by pre-existing MTG cards. If this situation was detected, the card's name is re-generated (keeping all other card information unchanged). The card name is re-generated until a name is generated that has not been used already.

Unfortunately, the previous logic did not also update the Explanation with the newly regenerated card name(s). This commit implements code that also updates the Explanation with the newly regenerated card name(s).

Files changed (1) hide show
  1. app.py +95 -42
app.py CHANGED
@@ -377,62 +377,115 @@ def CreateCard(msg: str, card_model: str, extract_model: str, temp: float):
377
  parsed_list: MTGCardList = completion.choices[0].message.parsed
378
  cards = parsed_list.cards
379
  set_name = parsed_list.Name
380
- # Clean the explanation to remove quotes around card names
381
- explanation = clean_explanation_quotes(parsed_list, card_model)
382
 
383
  # Track names in the current batch to ensure uniqueness within the batch
384
  batch_names = set()
 
 
385
 
386
  # Check if any generated card names are duplicates and regenerate them
387
  for i, card in enumerate(cards):
 
388
  # Check if name is duplicate in existing card database
389
  if card.Name in card_names:
390
- try:
391
- # Combine existing names and current batch names to avoid duplicates
392
- all_used_names = card_names | batch_names
393
- new_name = generate_unique_name_for_card(
394
- parsed_card=card,
395
- used_names=all_used_names,
396
- extract_model=extract_model,
397
- )
398
- # Verify the regenerated name is actually unique
399
- if new_name in card_names:
400
- print(f"⚠ Regenerated name '{new_name}' is still a duplicate in card_names")
401
- raise ValueError("Regenerated name is still a duplicate")
402
- if new_name in batch_names:
403
- print(f"⚠ Regenerated name '{new_name}' conflicts with another card in this batch")
404
- raise ValueError("Regenerated name conflicts with batch")
405
- card.Name = new_name
406
- except Exception as e:
407
- print(f"⚠ Failed to generate replacement name: {e}")
408
- # Continue to next attempt
409
- raise ValueError("Failed to generate unique name")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
410
 
411
  # Check if name is duplicate within the current batch
412
  if card.Name in batch_names:
413
- try:
414
- # Combine existing names and current batch names to avoid duplicates
415
- all_used_names = card_names | batch_names
416
- new_name = generate_unique_name_for_card(
417
- parsed_card=card,
418
- used_names=all_used_names,
419
- extract_model=extract_model,
420
- )
421
- # Verify the regenerated name is actually unique
422
- if new_name in card_names:
423
- print(f"⚠ Regenerated name '{new_name}' is still a duplicate in card_names")
424
- raise ValueError("Regenerated name is still a duplicate")
425
- if new_name in batch_names:
426
- print(f"⚠ Regenerated name '{new_name}' conflicts with another card in this batch")
427
- raise ValueError("Regenerated name conflicts with batch")
428
- card.Name = new_name
429
- except Exception as e:
430
- print(f"⚠ Failed to generate replacement name for batch duplicate: {e}")
431
- # Continue to next attempt
432
- raise ValueError("Failed to generate unique name")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
433
 
434
  # Add the (now unique) name to batch tracking
435
  batch_names.add(card.Name)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
436
 
437
  # Success - format all cards (without explanation)
438
  formatted_cards = []
 
377
  parsed_list: MTGCardList = completion.choices[0].message.parsed
378
  cards = parsed_list.cards
379
  set_name = parsed_list.Name
380
+ # Get original explanation before any renaming
381
+ original_explanation = parsed_list.explanation
382
 
383
  # Track names in the current batch to ensure uniqueness within the batch
384
  batch_names = set()
385
+ # Track name mappings for updating explanation (old_name -> new_name)
386
+ name_mappings = {}
387
 
388
  # Check if any generated card names are duplicates and regenerate them
389
  for i, card in enumerate(cards):
390
+ original_name = card.Name
391
  # Check if name is duplicate in existing card database
392
  if card.Name in card_names:
393
+ # Keep trying to generate a unique name until one is found
394
+ max_name_attempts = 10 # Try up to 10 times to generate a unique name
395
+ name_found = False
396
+ for name_attempt in range(max_name_attempts):
397
+ try:
398
+ # Combine existing names and current batch names to avoid duplicates
399
+ all_used_names = card_names | batch_names
400
+ new_name = generate_unique_name_for_card(
401
+ parsed_card=card,
402
+ used_names=all_used_names,
403
+ extract_model=extract_model,
404
+ )
405
+ # Verify the regenerated name is actually unique
406
+ if new_name in card_names:
407
+ print(f"Regenerated name '{new_name}' (attempt {name_attempt + 1}) is still a duplicate in card_names, retrying...")
408
+ continue # Try again
409
+ if new_name in batch_names:
410
+ print(f"⚠ Regenerated name '{new_name}' (attempt {name_attempt + 1}) conflicts with another card in this batch, retrying...")
411
+ continue # Try again
412
+ # Unique name found!
413
+ card.Name = new_name
414
+ # Track the name change
415
+ if original_name != new_name:
416
+ name_mappings[original_name] = new_name
417
+ name_found = True
418
+ break
419
+ except Exception as e:
420
+ print(f"⚠ Failed to generate replacement name (attempt {name_attempt + 1}): {e}")
421
+ if name_attempt == max_name_attempts - 1:
422
+ # Last attempt failed, give up and retry entire card generation
423
+ raise ValueError("Failed to generate unique name after multiple attempts")
424
+ continue # Try again
425
+
426
+ if not name_found:
427
+ raise ValueError("Failed to generate unique name after multiple attempts")
428
 
429
  # Check if name is duplicate within the current batch
430
  if card.Name in batch_names:
431
+ # Keep trying to generate a unique name until one is found
432
+ max_name_attempts = 10 # Try up to 10 times to generate a unique name
433
+ name_found = False
434
+ for name_attempt in range(max_name_attempts):
435
+ try:
436
+ # Combine existing names and current batch names to avoid duplicates
437
+ all_used_names = card_names | batch_names
438
+ new_name = generate_unique_name_for_card(
439
+ parsed_card=card,
440
+ used_names=all_used_names,
441
+ extract_model=extract_model,
442
+ )
443
+ # Verify the regenerated name is actually unique
444
+ if new_name in card_names:
445
+ print(f"Regenerated name '{new_name}' (attempt {name_attempt + 1}) is still a duplicate in card_names, retrying...")
446
+ continue # Try again
447
+ if new_name in batch_names:
448
+ print(f"⚠ Regenerated name '{new_name}' (attempt {name_attempt + 1}) conflicts with another card in this batch, retrying...")
449
+ continue # Try again
450
+ # Unique name found!
451
+ card.Name = new_name
452
+ # Track the name change
453
+ if original_name != new_name:
454
+ name_mappings[original_name] = new_name
455
+ name_found = True
456
+ break
457
+ except Exception as e:
458
+ print(f"⚠ Failed to generate replacement name for batch duplicate (attempt {name_attempt + 1}): {e}")
459
+ if name_attempt == max_name_attempts - 1:
460
+ # Last attempt failed, give up and retry entire card generation
461
+ raise ValueError("Failed to generate unique name after multiple attempts")
462
+ continue # Try again
463
+
464
+ if not name_found:
465
+ raise ValueError("Failed to generate unique name after multiple attempts")
466
 
467
  # Add the (now unique) name to batch tracking
468
  batch_names.add(card.Name)
469
+
470
+ # Update explanation with new card names if any cards were renamed
471
+ if name_mappings:
472
+ explanation = original_explanation
473
+ # Replace old names with new names in the explanation
474
+ # Sort by length (longest first) to handle cases where one name contains another
475
+ sorted_mappings = sorted(name_mappings.items(), key=lambda x: len(x[0]), reverse=True)
476
+ for old_name, new_name in sorted_mappings:
477
+ # Use word boundaries to replace whole words only
478
+ escaped_old_name = re.escape(old_name)
479
+ pattern = r'\b' + escaped_old_name + r'\b'
480
+ explanation = re.sub(pattern, new_name, explanation)
481
+ # Update parsed_list.explanation so clean_explanation_quotes uses the updated version
482
+ parsed_list.explanation = explanation
483
+ else:
484
+ explanation = original_explanation
485
+
486
+ # Clean the explanation to remove quotes around card names (after updating names)
487
+ # Note: parsed_list.cards already have the updated names since they're the same objects
488
+ explanation = clean_explanation_quotes(parsed_list, card_model)
489
 
490
  # Success - format all cards (without explanation)
491
  formatted_cards = []