Marthee commited on
Commit
2691864
·
verified ·
1 Parent(s): 553d55b

Update google_sheet_Legend.py

Browse files
Files changed (1) hide show
  1. google_sheet_Legend.py +164 -166
google_sheet_Legend.py CHANGED
@@ -16,7 +16,9 @@ import pandas as pd
16
  from google.oauth2 import service_account
17
  from googleapiclient.discovery import build
18
  import pygsheets
19
- import re
 
 
20
 
21
 
22
  def authorizeLegend():
@@ -465,172 +467,114 @@ def getguessnames(gc,ws):
465
  return guessednamesfinal
466
 
467
  ################################################################
468
-
469
- def deletefromlegend(deletedrows,SimilarAreaDictionarycopy,section, areaPermArr=[]):
470
- items=[]
471
- print('dletefromlegend')
472
- idx=0
473
- if section.startswith('1.0'):
474
- areaPermArr=ast.literal_eval(areaPermArr)
475
- myDict=eval(SimilarAreaDictionarycopy)
476
- SimilarAreaDictionarycopy=pd.DataFrame(myDict)
477
- # deletedrows=eval(deletedrows)
478
- strings=deletedrows['content']
479
- areastodelete = []
480
- perimstodelete=[]
481
- lengthstodelete=[]
482
-
483
- for item in strings:
484
- newitem=str(item).split('\n \n')
485
- input_str = " ".join(str(newitem).split())
486
- # Search for the Area value
487
- matchA = re.search(r"Area=(\d+\.\d+)", input_str)
488
- matchL = re.search(r"Length=(\d+\.\d+)", input_str)
489
- matchP = re.search(r"Perimeter=(\d+\.\d+)", input_str)
490
-
491
- if matchA:
492
- areastodelete.append(float(matchA.group(1)))
493
- if matchP:
494
- perimstodelete.append(float(matchP.group(1)))
495
- if matchL:
496
- lengthstodelete.append(float(matchL.group(1)))
497
- print('Areas to delete:', areastodelete)
498
- print('Perimeters to delete:', perimstodelete)
499
- print('Lengths to delete:', lengthstodelete)
500
-
501
- for i in range(len(areastodelete)):#item in areastodelete:
502
- if section.startswith('1.0'):
503
- tol=0.3
504
- elif section.startswith('3.2'):
505
- tol=1
506
- areamin=round(areastodelete[i],1)- tol
507
- areamax=round(areastodelete[i],1)+ tol
508
- if section.startswith('1.0'):
509
- for p in range(len(areaPermArr)):
510
- if areastodelete[i] in areaPermArr[p]:
511
- width= areaPermArr[p][1]
512
- height= areaPermArr[p][2]
513
- break
514
- widthMin= width -10
515
- widthMax= width +10
516
- heightMin = height-10
517
- heightMax=height+10
518
- if len(areastodelete)>0:
519
- found=SimilarAreaDictionarycopy.loc[SimilarAreaDictionarycopy.index[((SimilarAreaDictionarycopy['Rounded'] >=areamin) & (SimilarAreaDictionarycopy['Rounded']<=areamax) ) & ( ((SimilarAreaDictionarycopy['Width']>=widthMin) & (SimilarAreaDictionarycopy['Width']<=widthMax) & (SimilarAreaDictionarycopy['Height']>=heightMin) & (SimilarAreaDictionarycopy['Height']<=heightMax) ) | ((SimilarAreaDictionarycopy['Width']>=heightMin) & (SimilarAreaDictionarycopy['Width']<=heightMax) & (SimilarAreaDictionarycopy['Height']>=widthMin) & (SimilarAreaDictionarycopy['Height']<=widthMax) )) ]]
520
- elif section.startswith('3.2'):
521
- found=SimilarAreaDictionarycopy.loc[SimilarAreaDictionarycopy.index[((SimilarAreaDictionarycopy['Area'] >=areamin) & (SimilarAreaDictionarycopy['Area']<=areamax) )]]
522
- if len(found.index.values) >0:
523
- occ=SimilarAreaDictionarycopy.loc[found.index.values[0],'Occurences']
524
- if occ== 1: #drop row
525
- SimilarAreaDictionarycopy= SimilarAreaDictionarycopy.drop(found.index.values[0])
526
- else: #occ minus 1 , total area - areavalue , total perim - perimvalue
527
- print('occ>1')
528
- if section.startswith('1.0'):
529
- if len(areastodelete)>0:
530
- idx=SimilarAreaDictionarycopy.index[((SimilarAreaDictionarycopy['Rounded'] >=areamin) & (SimilarAreaDictionarycopy['Rounded']<=areamax) ) & ( ((SimilarAreaDictionarycopy['Width']>=widthMin) & (SimilarAreaDictionarycopy['Width']<=widthMax) & (SimilarAreaDictionarycopy['Height']>=heightMin) & (SimilarAreaDictionarycopy['Height']<=heightMax) ) | ((SimilarAreaDictionarycopy['Width']>=heightMin) & (SimilarAreaDictionarycopy['Width']<=heightMax) & (SimilarAreaDictionarycopy['Height']>=widthMin) & (SimilarAreaDictionarycopy['Height']<=widthMax) )) ]
531
- elif section.startswith('3.2'):
532
- idx=SimilarAreaDictionarycopy.index[((SimilarAreaDictionarycopy['Area'] >=areamin) & (SimilarAreaDictionarycopy['Area']<=areamax) )]
533
- if len(areastodelete)>0:
534
- comment = SimilarAreaDictionarycopy.loc[idx, 'Comments']
535
- if pd.notna(comment.iloc[0]) and 'Area' in str(comment.iloc[0]):
536
- matches = re.findall(r'\b\d+\b', str(SimilarAreaDictionarycopy.loc[idx, 'Comments']))
537
- area_occurrences = int(matches[1]) -1
538
- perimeter_occurrences = int(matches[2])
539
- print(area_occurrences, perimeter_occurrences)
540
- SimilarAreaDictionarycopy.loc[idx, 'Comments'] = f'Area occurrences: {area_occurrences}, Perimeter occurrences: {perimeter_occurrences}'
541
- if area_occurrences > perimeter_occurrences:
542
- SimilarAreaDictionarycopy.loc[idx,'Occurences'] = area_occurrences
543
- elif perimeter_occurrences> area_occurrences:
544
- SimilarAreaDictionarycopy.loc[idx,'Occurences'] = perimeter_occurrences
545
- elif int(area_occurrences)==int(perimeter_occurrences):
546
- SimilarAreaDictionarycopy.loc[idx,'Occurences'] = int(SimilarAreaDictionarycopy.loc[idx,'Occurences']) - 1
547
- if section.startswith('1.0'):
548
- SimilarAreaDictionarycopy.loc[idx,'Total Length'] = SimilarAreaDictionarycopy.loc[idx,'Total Length'] - lengthstodelete[i]
549
-
550
- else:
551
- print('not yet')
552
- area_occurrences = SimilarAreaDictionarycopy.loc[idx, 'Occurences'].iloc[0] -1
553
- perimeter_occurrences = SimilarAreaDictionarycopy.loc[idx, 'Occurences'].iloc[0]
554
- print(area_occurrences,perimeter_occurrences)
555
- SimilarAreaDictionarycopy.loc[idx, 'Comments'] = f'Area occurrences: {area_occurrences}, Perimeter occurrences: {perimeter_occurrences}'
556
- SimilarAreaDictionarycopy.loc[idx,'Total Area'] = SimilarAreaDictionarycopy.loc[idx,'Total Area'] - areastodelete[i]
557
-
558
-
559
- for i in range(len(perimstodelete)):#item in areastodelete:
560
- if section.startswith('1.0'):
561
- tol=0.3
562
- elif section.startswith('3.2'):
563
- tol=10
564
 
565
- if len(perimstodelete)>0:
566
- print(perimstodelete[i])
567
- perimmin=round(perimstodelete[i],1)- 0.3
568
- perimmax=round(perimstodelete[i],1)+ 0.3
569
- print('perimmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmm')
570
- if section.startswith('1.0'):
571
- for p in range(len(areaPermArr)):
572
- if areastodelete[i] in areaPermArr[p]:
573
- print('AAA',areaPermArr[p])
574
- area= areaPermArr[p][0]
575
- width= areaPermArr[p][1]
576
- height= areaPermArr[p][2]
577
- break
578
- widthMin= width -10
579
- widthMax= width +10
580
- heightMin = height-10
581
- heightMax=height+10
582
- found=SimilarAreaDictionarycopy.loc[SimilarAreaDictionarycopy.index[( (SimilarAreaDictionarycopy['Perimeter'] >=perimmin) & (SimilarAreaDictionarycopy['Perimeter']<=perimmax) ) & ( ((SimilarAreaDictionarycopy['Width']>=widthMin) & (SimilarAreaDictionarycopy['Width']<=widthMax) & (SimilarAreaDictionarycopy['Height']>=heightMin) & (SimilarAreaDictionarycopy['Height']<=heightMax) ) | ((SimilarAreaDictionarycopy['Width']>=heightMin) & (SimilarAreaDictionarycopy['Width']<=heightMax) & (SimilarAreaDictionarycopy['Height']>=widthMin) & (SimilarAreaDictionarycopy['Height']<=widthMax) )) ]]
583
- elif section.startswith('3.2'):
584
- found=SimilarAreaDictionarycopy.loc[SimilarAreaDictionarycopy.index[( (SimilarAreaDictionarycopy['Perimeter'] >=perimmin) & (SimilarAreaDictionarycopy['Perimeter']<=perimmax) )]]
585
-
586
- if len(found.index.values) >0:
587
- occ=SimilarAreaDictionarycopy.loc[found.index.values[0],'Occurences']
588
- if occ== 1: #drop row
589
- print('occ=1')
590
- print(found)
591
- SimilarAreaDictionarycopy= SimilarAreaDictionarycopy.drop(found.index.values[0])
592
-
593
- else: #occ minus 1 , total area - areavalue , total perim - perimvalue
594
- print('occ>1')
595
- if section.startswith('1.0'):
596
- if len(perimstodelete)>0:
597
- idx=SimilarAreaDictionarycopy.index[((SimilarAreaDictionarycopy['Perimeter'] >=perimmin) & (SimilarAreaDictionarycopy['Perimeter']<=perimmax) ) & ( ((SimilarAreaDictionarycopy['Width']>=widthMin) & (SimilarAreaDictionarycopy['Width']<=widthMax) & (SimilarAreaDictionarycopy['Height']>=heightMin) & (SimilarAreaDictionarycopy['Height']<=heightMax) ) | ((SimilarAreaDictionarycopy['Width']>=heightMin) & (SimilarAreaDictionarycopy['Width']<=heightMax) & (SimilarAreaDictionarycopy['Height']>=widthMin) & (SimilarAreaDictionarycopy['Height']<=widthMax) )) ]
598
- elif section.startswith('3.2'):
599
- if len(perimstodelete)>0:
600
- perimmin=round(perimstodelete[i],1)- 1
601
- perimmax=round(perimstodelete[i],1)+ 1
602
- idx=SimilarAreaDictionarycopy.index[((SimilarAreaDictionarycopy['Perimeter'] >=perimmin) & (SimilarAreaDictionarycopy['Perimeter']<=perimmax) )]
603
 
604
-
605
- if len(perimstodelete)>0:
606
- comment = SimilarAreaDictionarycopy.loc[idx, 'Comments']
607
- if pd.notna(comment.iloc[0]) and 'Area' in str(comment.iloc[0]):
608
- matches = re.findall(r'\b\d+\b', str(SimilarAreaDictionarycopy.loc[idx, 'Comments']))
609
- area_occurrences = int(matches[1])
610
- perimeter_occurrences = int(matches[2])-1
611
- print(area_occurrences, perimeter_occurrences)
612
- SimilarAreaDictionarycopy.loc[idx, 'Comments'] = f'Area occurrences: {area_occurrences}, Perimeter occurrences: {perimeter_occurrences}'
613
- if area_occurrences > perimeter_occurrences:
614
- SimilarAreaDictionarycopy.loc[idx,'Occurences'] = area_occurrences
615
- elif perimeter_occurrences> area_occurrences:
616
- SimilarAreaDictionarycopy.loc[idx,'Occurences'] = perimeter_occurrences
617
- elif int(area_occurrences)==int(perimeter_occurrences):
618
- SimilarAreaDictionarycopy.loc[idx,'Occurences'] = int(SimilarAreaDictionarycopy.loc[idx,'Occurences']) - 1
619
- if section.startswith('1.0'):
620
- SimilarAreaDictionarycopy.loc[idx,'Total Length'] = SimilarAreaDictionarycopy.loc[idx,'Total Length'] - lengthstodelete[i]
621
-
622
- else:
623
- print('not yet')
624
- area_occurrences = SimilarAreaDictionarycopy.loc[idx, 'Occurences'].iloc[0]
625
- perimeter_occurrences = SimilarAreaDictionarycopy.loc[idx, 'Occurences'].iloc[0] -1
626
-
627
- SimilarAreaDictionarycopy.loc[idx, 'Comments'] = f'Area occurrences: {area_occurrences}, Perimeter occurrences: {perimeter_occurrences}'
628
- area_occurrences = SimilarAreaDictionarycopy.loc[idx, 'Occurences'].iloc[0] -1
629
- perimeter_occurrences = SimilarAreaDictionarycopy.loc[idx, 'Occurences'].iloc[0]
630
-
631
-
632
- SimilarAreaDictionarycopy.loc[idx,'Total Perimeter'] = SimilarAreaDictionarycopy.loc[idx,'Total Perimeter'] - perimstodelete[i]
633
- return SimilarAreaDictionarycopy
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
634
 
635
 
636
  def DoorsLegend(Dictionary,spreadsheetId,worksheet):
@@ -762,4 +706,58 @@ def delete3_2(deletedrows,dictionary):
762
  df_doors = df_doors[['Type', 'Quantity']]
763
  return df_doors
764
 
765
- ######################
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
16
  from google.oauth2 import service_account
17
  from googleapiclient.discovery import build
18
  import pygsheets
19
+ import tsadropboxretrieval
20
+ import fitz
21
+ import numpy as np
22
 
23
 
24
  def authorizeLegend():
 
467
  return guessednamesfinal
468
 
469
  ################################################################
470
+ def is_color_within_tolerance(color1, color2, tolerance):
471
+ # Ensure both colors are tuples of integers
472
+ color1 = tuple(map(int, color1))
473
+ color2 = tuple(map(int, color2))
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
474
 
475
+ return all(abs(c1 - c2) <= tolerance for c1, c2 in zip(color1, color2))
476
+
477
+ def deletefromlegend(deletedrows, SimilarAreaDictionarycopy, section, areaPermArr=[]):
478
+ items = []
479
+ print('deletefromlegend',deletedrows)
480
+ idx = 0
481
+ if section.startswith('1.0') or section.startswith('3.2'):
482
+ areaPermArr = ast.literal_eval(areaPermArr)
483
+ myDict = eval(SimilarAreaDictionarycopy)
484
+ SimilarAreaDictionarycopy = pd.DataFrame(myDict)
485
+ strings = deletedrows['content']
486
+ colors = deletedrows['color']
487
+ indicies_toDelete=[]
488
+ print(colors)
489
+ # Define your tolerance value
490
+ tolerance = 2 # Allowable tolerance for RGB differences
491
+ print(SimilarAreaDictionarycopy)
492
+ color_list = list(SimilarAreaDictionarycopy['Color']) # Convert Index/Series to list
493
+ if section.startswith('1.0'):
494
+ color_list = [ast.literal_eval(color) for color in color_list]
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
495
 
496
+ for j in range(len(colors)):
497
+ # newitem=str(colors[j]).split('\n \n')
498
+ # input_str = " ".join(str(newitem).split())
499
+ color = tuple(colors[j]) # Ensure 'color' is in tuple format
500
+ found = False
501
+
502
+ for idx, existing_color in enumerate(color_list):
503
+ existing_color = tuple(existing_color) # Ensure it's a tuple for comparison
504
+
505
+
506
+ print('eee',existing_color,color)
507
+ if is_color_within_tolerance(existing_color, color, tolerance):
508
+ print(f'Color {color} found close to {existing_color} at index {idx}')
509
+ found = True
510
+ print(strings[j])
511
+ matchA = re.search(r"Area=(\d+\.\d+)", strings[j])
512
+ matchP = re.search(r"Perimeter=(\d+\.\d+)", strings[j])
513
+ matchL = re.search(r"Length=(\d+\.\d+)", strings[j])
514
+ comment = SimilarAreaDictionarycopy.iloc[int(idx), SimilarAreaDictionarycopy.columns.get_loc('Comments')]
515
+ occ = SimilarAreaDictionarycopy.iloc[int(idx), SimilarAreaDictionarycopy.columns.get_loc('Occurences')]
516
+
517
+ # Only subtract area if the area value is found
518
+ if matchA:
519
+ SimilarAreaDictionarycopy.iloc[int(idx), SimilarAreaDictionarycopy.columns.get_loc('Total Area')] =SimilarAreaDictionarycopy.iloc[int(idx), SimilarAreaDictionarycopy.columns.get_loc('Total Area')] - float(matchA.group(1))
520
+ # Update area occurrences
521
+ if pd.notna(comment) and 'Area' in str(comment):
522
+ matches = re.findall(r'\b\d+\b', str(comment))
523
+ area_occurrences = int(matches[0]) - 1
524
+ perimeter_occurrences = int(matches[1])
525
+ else:
526
+ area_occurrences = int(SimilarAreaDictionarycopy.iloc[int(idx), SimilarAreaDictionarycopy.columns.get_loc('Occurences')]) - 1
527
+ perimeter_occurrences = SimilarAreaDictionarycopy.iloc[int(idx), SimilarAreaDictionarycopy.columns.get_loc('Occurences')]
528
+
529
+ SimilarAreaDictionarycopy.iloc[int(idx), SimilarAreaDictionarycopy.columns.get_loc('Comments')] = f'Area occurrences: {area_occurrences}, Perimeter occurrences: {perimeter_occurrences}'
530
+ if matchP:
531
+
532
+ SimilarAreaDictionarycopy.iloc[int(idx), SimilarAreaDictionarycopy.columns.get_loc('Total Perimeter')] =SimilarAreaDictionarycopy.iloc[int(idx), SimilarAreaDictionarycopy.columns.get_loc('Total Perimeter')] - float(matchP.group(1))# Replace 'Area' with the actual column name
533
+ if pd.notna(comment) and 'Perimeter' in str(comment):
534
+ matches = re.findall(r'\b\d+\b', str(comment))
535
+ area_occurrences = int(matches[0])
536
+ perimeter_occurrences = int(matches[1]) -1
537
+ else:
538
+ area_occurrences = int(SimilarAreaDictionarycopy.iloc[int(idx), SimilarAreaDictionarycopy.columns.get_loc('Occurences')])
539
+ perimeter_occurrences = SimilarAreaDictionarycopy.iloc[int(idx), SimilarAreaDictionarycopy.columns.get_loc('Occurences')]-1
540
+ # print(area_occurrences,perimeter_occurrences)
541
+ SimilarAreaDictionarycopy.iloc[int(idx), SimilarAreaDictionarycopy.columns.get_loc('Comments')] = f'Area occurrences: {area_occurrences}, Perimeter occurrences: {perimeter_occurrences}'
542
+
543
+
544
+
545
+
546
+ # Handle occurrences and row deletion
547
+ if area_occurrences==0 and perimeter_occurrences==0:
548
+ # if area_occurrences ==0 and perimeter_occurrences==0:
549
+ if str(idx) not in indicies_toDelete:
550
+ indicies_toDelete.append(str(idx))
551
+ # print(SimilarAreaDictionarycopy.index[idx],idx)
552
+
553
+
554
+ else:
555
+ SimilarAreaDictionarycopy.iloc[int(idx), SimilarAreaDictionarycopy.columns.get_loc('Comments')] = f'Area occurrences: {area_occurrences}, Perimeter occurrences: {perimeter_occurrences}'
556
+ if area_occurrences > perimeter_occurrences:
557
+ SimilarAreaDictionarycopy.iloc[int(idx), SimilarAreaDictionarycopy.columns.get_loc('Occurences')] = area_occurrences
558
+ elif perimeter_occurrences > area_occurrences:
559
+ SimilarAreaDictionarycopy.iloc[int(idx), SimilarAreaDictionarycopy.columns.get_loc('Occurences')] = perimeter_occurrences
560
+ else:
561
+ SimilarAreaDictionarycopy.iloc[int(idx), SimilarAreaDictionarycopy.columns.get_loc('Occurences')] = area_occurrences
562
+ if area_occurrences==1:
563
+ SimilarAreaDictionarycopy.iloc[int(idx), SimilarAreaDictionarycopy.columns.get_loc('Area')]= SimilarAreaDictionarycopy.iloc[int(idx), SimilarAreaDictionarycopy.columns.get_loc('Total Area')]
564
+ if perimeter_occurrences==1:
565
+ SimilarAreaDictionarycopy.iloc[int(idx), SimilarAreaDictionarycopy.columns.get_loc('Perimeter')]= SimilarAreaDictionarycopy.iloc[int(idx), SimilarAreaDictionarycopy.columns.get_loc('Total Perimeter')]
566
+ if area_occurrences==perimeter_occurrences:
567
+ if section.startswith('1.0'):
568
+ SimilarAreaDictionarycopy.iloc[int(idx), SimilarAreaDictionarycopy.columns.get_loc('Total Length')] =SimilarAreaDictionarycopy.iloc[int(idx), SimilarAreaDictionarycopy.columns.get_loc('Total Length')] - float(matchL.group(1))# Replace 'Area' with the actual column name
569
+ break
570
+
571
+ if not found:
572
+ print(f'Color {color} not found within tolerance')
573
+ print('indicies_toDelete',indicies_toDelete)
574
+ SimilarAreaDictionarycopy.drop(index=indicies_toDelete, axis=0, inplace=True)
575
+ print('SimilarAreaDictionarycopy',SimilarAreaDictionarycopy)
576
+ return SimilarAreaDictionarycopy
577
+
578
 
579
 
580
  def DoorsLegend(Dictionary,spreadsheetId,worksheet):
 
706
  df_doors = df_doors[['Type', 'Quantity']]
707
  return df_doors
708
 
709
+ ######################
710
+
711
+
712
+ def deletemarkups(list1, dbPath, path):
713
+ '''list1 : original markup pdf
714
+ list2 : deleted markup pdf
715
+ deletedrows : deleted markups - difference between both dfs
716
+ '''
717
+
718
+ myDict1 = eval(list1)
719
+ list1 = pd.DataFrame(myDict1)
720
+
721
+ dbxTeam = tsadropboxretrieval.ADR_Access_DropboxTeam('user')
722
+ md, res = dbxTeam.files_download(path=dbPath + path)
723
+ data = res.content
724
+ doc = fitz.open("pdf", data)
725
+
726
+ # Prepare a DataFrame for the annotations in the new PDF
727
+ list2 = pd.DataFrame(columns=['content', 'id', 'subject', 'color'])
728
+
729
+ for page in doc:
730
+ # Iterate through annotations on the page
731
+ for annot in page.annots():
732
+ # Get the color of the annotation
733
+ annot_color = annot.colors
734
+ if annot_color is not None:
735
+ # Check for fill or stroke color
736
+ stroke_color = annot_color.get('stroke')
737
+ fill_color = annot_color.get('fill')
738
+
739
+ v = 'stroke' if stroke_color else 'fill'
740
+ color = annot_color.get(v)
741
+ if color:
742
+ # Convert color to tuple and multiply by 255 to get RGB values
743
+ color_tuple = (int(color[0] * 255), int(color[1] * 255), int(color[2] * 255))
744
+ # Append annotation data to list2
745
+ list2.loc[len(list2)] = [annot.info['content'], annot.info['id'], annot.info['subject'], color_tuple]
746
+
747
+ # Ensure that colors are stored as tuples (which are hashable)
748
+ list1['color'] = list1['color'].apply(lambda x: tuple(x) if isinstance(x, list) else x)
749
+
750
+ # Find the deleted rows by checking the difference between original and current annotations
751
+ deletedrows = pd.concat([list1, list2]).drop_duplicates(keep=False)
752
+
753
+ print(deletedrows, len(deletedrows))
754
+ flag = 0
755
+ if len(deletedrows) != 0:
756
+ flag = 1
757
+ deletedrows = deletedrows[['content', 'id', 'subject', 'color']]
758
+ # Drop rows where 'content' starts with 'Scale'
759
+ deletedrows = deletedrows.drop(deletedrows.index[deletedrows['content'].str.startswith('Scale')])
760
+ else:
761
+ flag = 0
762
+
763
+ return deletedrows