py2ls 0.1.10.23__py3-none-any.whl → 0.1.10.24__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
py2ls/ips.py CHANGED
@@ -1443,10 +1443,21 @@ def fappend(fpath, content=None):
1443
1443
  file.write(content)
1444
1444
 
1445
1445
 
1446
+ def filter_kwargs(kws, valid_kwargs):
1447
+ if isinstance(valid_kwargs, dict):
1448
+ kwargs_filtered = {
1449
+ key: value for key, value in kws.items() if key in valid_kwargs.keys()
1450
+ }
1451
+ elif isinstance(valid_kwargs, list):
1452
+ kwargs_filtered = {
1453
+ key: value for key, value in kws.items() if key in valid_kwargs
1454
+ }
1455
+ return kwargs_filtered
1456
+
1457
+
1446
1458
  def fsave(
1447
1459
  fpath,
1448
1460
  content,
1449
- mode="w",
1450
1461
  how="overwrite",
1451
1462
  kind=None,
1452
1463
  font_name="Times",
@@ -1468,7 +1479,7 @@ def fsave(
1468
1479
  None
1469
1480
  """
1470
1481
 
1471
- def save_content(fpath, content, mode=mode, how="overwrite"):
1482
+ def save_content(fpath, content, mode="w", how="overwrite"):
1472
1483
  if "wri" in how.lower():
1473
1484
  with open(fpath, mode, encoding="utf-8") as file:
1474
1485
  file.write(content)
@@ -1515,13 +1526,36 @@ def fsave(
1515
1526
  pdf.output(fpath, "F")
1516
1527
 
1517
1528
  def save_csv(fpath, data, **kwargs):
1529
+ # https://pandas.pydata.org/docs/reference/api/pandas.DataFrame.to_csv.html
1530
+ kwargs_csv = dict(
1531
+ path_or_buf=None,
1532
+ sep=",",
1533
+ na_rep="",
1534
+ float_format=None,
1535
+ columns=None,
1536
+ header=True,
1537
+ index=True,
1538
+ index_label=None,
1539
+ mode="w",
1540
+ encoding=None,
1541
+ compression="infer",
1542
+ quoting=None,
1543
+ quotechar='"',
1544
+ lineterminator=None,
1545
+ chunksize=None,
1546
+ date_format=None,
1547
+ doublequote=True,
1548
+ escapechar=None,
1549
+ decimal=".",
1550
+ errors="strict",
1551
+ storage_options=None,
1552
+ )
1553
+ kwargs_valid = filter_kwargs(kwargs, kwargs_csv)
1518
1554
  df = pd.DataFrame(data)
1519
- df.to_csv(fpath, **kwargs)
1555
+ df.to_csv(fpath, **kwargs_valid)
1520
1556
 
1521
1557
  def save_xlsx(fpath, data, **kwargs):
1522
- format = kwargs.get("format", None)
1523
- if format:
1524
- kwargs.pop("format", None)
1558
+ if any(kwargs):
1525
1559
  format_excel(df=data, filename=fpath, **kwargs)
1526
1560
  else:
1527
1561
  kwargs.pop("format", None)
@@ -1618,7 +1652,7 @@ def fsave(
1618
1652
  print(
1619
1653
  f"Warning:\n{kind} is not in the supported list ['docx', 'txt', 'md', 'html', 'pdf', 'csv', 'xlsx', 'json', 'xml', 'yaml']"
1620
1654
  )
1621
-
1655
+ mode = kwargs.get("mode", "w")
1622
1656
  if kind == "docx" or kind == "doc":
1623
1657
  save_docx(fpath, content, font_name, font_size, spacing)
1624
1658
  elif kind == "txt":
@@ -3186,7 +3220,13 @@ def hex2argb(hex_color):
3186
3220
  # Otherwise, assume it's in RRGGBB format and prepend FF for opaque
3187
3221
  if len(hex_color) == 6:
3188
3222
  return f"FF{hex_color}"
3189
-
3223
+ if len(hex_color) == 7:
3224
+ return f"F{hex_color}"
3225
+ else:
3226
+ if len(hex_color) > 8:
3227
+ return hex_color[-9:]
3228
+ else:
3229
+ return "F" * (9 - len(hex_color)) + hex_color
3190
3230
  raise ValueError(
3191
3231
  "Invalid hex color format. Use RRGGBB, #RRGGBB, or aARRGGBB format."
3192
3232
  )
@@ -3540,7 +3580,6 @@ def format_excel(
3540
3580
  number_format=None, # dict: e.g., {1:"0.00", 2:"#,##0",3:"0%",4:"$#,##0.00"}
3541
3581
  data_validation=None, # dict
3542
3582
  conditional_format=None, # dict
3543
- index_default=False,
3544
3583
  **kwargs,
3545
3584
  ):
3546
3585
  if not isinstance(df, pd.DataFrame):
@@ -3711,15 +3750,29 @@ format_excel(
3711
3750
  print(func_xample)
3712
3751
  return None
3713
3752
  kwargs.pop("format", None) # 更好地跟fsave结合使用
3753
+ kwargs.pop("sheet_name", None) # 更好地跟df.to_excel结合使用
3754
+ sheet_name_corr = (
3755
+ sheet_name if isinstance(sheet_name, str) else f"Sheet_{sheet_name}"
3756
+ )
3714
3757
 
3715
- # Save DataFrame to Excel file
3716
- if not index_default:
3717
- df.to_excel(filename, index=False, **kwargs)
3718
- else:
3719
- df.to_excel(filename, **kwargs)
3758
+ # 只有openpyxl才支持 append
3759
+ mode = strcmp(kwargs.get("mode", "w"), ["a", "w"])[0]
3760
+ kwargs.pop("mode", None)
3761
+ engine = strcmp(kwargs.get("engine", "openpyxl"), ["xlsxwriter", "openpyxl"])[0]
3762
+ # 通常是不需要保存index的
3763
+ index = kwargs.get("index", False)
3764
+ kwargs.pop("index", None)
3765
+ # save file
3766
+ with pd.ExcelWriter(filename, mode=mode, engine=engine) as writer:
3767
+ df.to_excel(writer, sheet_name=sheet_name_corr, index=index, **kwargs)
3720
3768
 
3721
3769
  wb = load_workbook(filename)
3722
- ws = wb.worksheets[sheet_name]
3770
+ if isinstance(sheet_name, str):
3771
+ ws = wb[sheet_name]
3772
+ elif isinstance(sheet_name, int):
3773
+ ws = wb.worksheets[sheet_name]
3774
+ else:
3775
+ ws = wb.worksheets[sheet_name] # the index of worksheets
3723
3776
 
3724
3777
  # !Apply cell formatting
3725
3778
  if cell:
@@ -3812,7 +3865,9 @@ format_excel(
3812
3865
  comment = [comment]
3813
3866
  for comment_ in comment:
3814
3867
  for (row, col), comment_str in comment_.items():
3815
- ws.cell(row=row, column=col).comment = Comment(comment_str, "Author")
3868
+ ws.cell(row=row + 1, column=col + 1).comment = Comment(
3869
+ comment_str, "Author"
3870
+ )
3816
3871
 
3817
3872
  # !Add link
3818
3873
  if link:
@@ -3820,7 +3875,7 @@ format_excel(
3820
3875
  link = [link]
3821
3876
  for link_ in link:
3822
3877
  for (row, col), link_str in link_.items():
3823
- ws.cell(row=row, column=col).hyperlink = link_str
3878
+ ws.cell(row=row + 1, column=col + 1).hyperlink = link_str
3824
3879
 
3825
3880
  # !Apply data validation
3826
3881
  if data_validation:
py2ls/netfinder.py CHANGED
@@ -582,7 +582,7 @@ def find_links(url, driver="request", booster=False):
582
582
  if all(exclusion not in link_href for exclusion in cond_ex):
583
583
  links_href.append(link_href)
584
584
 
585
- unique_links = list(set(links_href)) # Remove duplicates
585
+ unique_links = ips.unique(links_href) # Remove duplicates
586
586
 
587
587
  if booster:
588
588
  for link in unique_links:
@@ -590,7 +590,7 @@ def find_links(url, driver="request", booster=False):
590
590
  sub_links = find_links(link, driver=driver, booster=False)
591
591
  if sub_links:
592
592
  links_href.extend(sub_links)
593
- links_href = list(set(links_href)) # Remove duplicates again
593
+ links_href = ips.unique(links_href) # Remove duplicates again
594
594
 
595
595
  return links_href
596
596
 
py2ls/ocr.py CHANGED
@@ -286,14 +286,16 @@ def add_text_pil(
286
286
  text,
287
287
  position,
288
288
  font_size=12,
289
- color=(255, 0, 0),
290
- bg_color=(173, 216, 230, 120),
289
+ color=(0, 0, 0),
290
+ bg_color=(133, 203, 245, 100),
291
291
  ):
292
292
  # Convert the image to PIL format
293
- pil_image = Image.fromarray(cv2.cvtColor(image, cv2.COLOR_BGR2RGB))
294
- # Create a drawing context
295
- draw = ImageDraw.Draw(pil_image)
293
+ pil_image = Image.fromarray(cv2.cvtColor(image, cv2.COLOR_BGR2RGB)).convert("RGBA")
296
294
  # Define the font (make sure to use a font that supports Chinese characters)
295
+ overlay = Image.new("RGBA", pil_image.size, (255, 255, 255, 0))
296
+ # Create a drawing context
297
+ draw = ImageDraw.Draw(overlay)
298
+
297
299
  try:
298
300
  font = ImageFont.truetype(
299
301
  "/System/Library/Fonts/Supplemental/Songti.ttc", font_size
@@ -328,8 +330,14 @@ def add_text_pil(
328
330
  draw.rectangle(background_rect, fill=bg_color)
329
331
  # Add text to the image
330
332
  draw.text(adjusted_position, text, font=font, fill=color)
333
+ # Ensure both images are in RGBA mode for alpha compositing
334
+ if pil_image.mode != "RGBA":
335
+ pil_image = pil_image.convert("RGBA")
336
+ if overlay.mode != "RGBA":
337
+ overlay = overlay.convert("RGBA")
338
+ combined = Image.alpha_composite(pil_image, overlay)
331
339
  # Convert the image back to OpenCV format
332
- image = cv2.cvtColor(np.array(pil_image), cv2.COLOR_RGBA2BGR)
340
+ image = cv2.cvtColor(np.array(combined), cv2.COLOR_RGBA2BGR)
333
341
  return image
334
342
 
335
343
 
@@ -382,12 +390,15 @@ def preprocess_img(
382
390
  image = cv2.imread(image)
383
391
  if not isinstance(image, np.ndarray):
384
392
  image = np.array(image)
385
- if image.shape[1] == 4: # Check if it has an alpha channel
386
- # Drop the alpha channel (if needed), or handle it as required
387
- image = cv2.cvtColor(image, cv2.COLOR_RGBA2RGB)
388
- else:
389
- # Convert RGB to BGR for OpenCV compatibility
390
- image = cv2.cvtColor(image, cv2.COLOR_RGB2BGR)
393
+ try:
394
+ if image.shape[1] == 4: # Check if it has an alpha channel
395
+ # Drop the alpha channel (if needed), or handle it as required
396
+ image = cv2.cvtColor(image, cv2.COLOR_RGBA2RGB)
397
+ else:
398
+ # Convert RGB to BGR for OpenCV compatibility
399
+ image = cv2.cvtColor(image, cv2.COLOR_RGB2BGR)
400
+ except:
401
+ pass
391
402
 
392
403
  # Rotate image
393
404
  if rotate == "auto":
@@ -532,7 +543,7 @@ def get_text(
532
543
  thr=0.1,
533
544
  gpu=True,
534
545
  decoder="wordbeamsearch", #'greedy', 'beamsearch' and 'wordbeamsearch'(hightly accurate)
535
- output="all",
546
+ output="txt",
536
547
  preprocess=None,
537
548
  postprocess="not ready",
538
549
  show=True,
@@ -541,9 +552,9 @@ def get_text(
541
552
  font=cv2.FONT_HERSHEY_SIMPLEX,
542
553
  font_scale=0.8,
543
554
  thickness_text=2, # Line thickness of 2 px
544
- color_box=(0, 255, 0), # draw_box
545
- color_text=(203, 44, 57), # draw_box
546
- bg_color=(173, 216, 230, 128),
555
+ box_color=(0, 255, 0), # draw_box
556
+ font_color=(0, 0, 0),
557
+ bg_color=(133, 203, 245, 100),
547
558
  usage=False,
548
559
  **kwargs,
549
560
  ):
@@ -559,8 +570,8 @@ def get_text(
559
570
  show: 是否显示结果图像。
560
571
  ax: 用于显示图像的 Matplotlib 子图。
561
572
  cmap: 用于显示图像的颜色映射。
562
- color_box: 边界框的颜色。
563
- color_text: 文本的颜色。
573
+ box_color: 边界框的颜色。
574
+ font_color: 文本的颜色。
564
575
  kwargs: 传递给 EasyOCR readtext 函数的其他参数。
565
576
 
566
577
  # Uage
@@ -632,19 +643,19 @@ def get_text(
632
643
  if score > thr:
633
644
  top_left = tuple(map(int, bbox[0]))
634
645
  bottom_right = tuple(map(int, bbox[2]))
635
- image = cv2.rectangle(image, top_left, bottom_right, color_box, 2)
646
+ image = cv2.rectangle(image, top_left, bottom_right, box_color, 2)
636
647
  # image = cv2.putText(
637
- # image, text, top_left, font, font_scale, color_text, thickness_text
648
+ # image, text, top_left, font, font_scale, font_color, thickness_text
638
649
  # )
639
650
  image = add_text_pil(
640
651
  image,
641
652
  text,
642
653
  top_left,
643
654
  font_size=font_scale * 32,
644
- color=color_text,
655
+ color=font_color,
645
656
  )
646
- img_cmp = cv2.cvtColor(image, cmap)
647
- ax.imshow(img_cmp)
657
+ # img_cmp = cv2.cvtColor(image, cmap)
658
+ ax.imshow(image)
648
659
  ax.axis("off")
649
660
  # plt.show()
650
661
  # 根据输出类型返回相应的结果
@@ -720,20 +731,20 @@ def get_text(
720
731
  map(int, bbox[1])
721
732
  ) # Bottom-left for more accurate placement
722
733
  bottom_right = tuple(map(int, bbox[2]))
723
- image = cv2.rectangle(image, top_left, bottom_right, color_box, 2)
734
+ image = cv2.rectangle(image, top_left, bottom_right, box_color, 2)
724
735
  # image = cv2.putText(
725
- # image, text, top_left, font, font_scale, color_text, thickness_text
736
+ # image, text, top_left, font, font_scale, font_color, thickness_text
726
737
  # )
727
738
  image = add_text_pil(
728
739
  image,
729
740
  text,
730
741
  top_left,
731
742
  font_size=font_scale * 32,
732
- color=color_text,
743
+ color=font_color,
733
744
  bg_color=bg_color,
734
745
  )
735
746
  img_cmp = cv2.cvtColor(image, cmap)
736
- ax.imshow(img_cmp)
747
+ ax.imshow(image)
737
748
  ax.axis("off")
738
749
  # plt.show()
739
750
  # 根据输出类型返回相应的结果
@@ -797,13 +808,13 @@ def get_text(
797
808
  bottom_right = (right, h - bottom)
798
809
 
799
810
  # Draw the bounding box
800
- image = cv2.rectangle(image, top_left, bottom_right, color_box, 2)
811
+ image = cv2.rectangle(image, top_left, bottom_right, box_color, 2)
801
812
  image = add_text_pil(
802
813
  image,
803
814
  char,
804
815
  left,
805
816
  font_size=font_scale * 32,
806
- color=color_text,
817
+ color=font_color,
807
818
  )
808
819
  img_cmp = cv2.cvtColor(image, cmap)
809
820
  ax.imshow(img_cmp)
@@ -838,8 +849,8 @@ def draw_box(
838
849
  detections=None,
839
850
  thr=0.25,
840
851
  cmap=cv2.COLOR_BGR2RGB,
841
- color_box=(0, 255, 0), # draw_box
842
- color_text=(0, 0, 255), # draw_box
852
+ box_color=(0, 255, 0), # draw_box
853
+ font_color=(0, 0, 255), # draw_box
843
854
  font_scale=0.8,
844
855
  show=True,
845
856
  ax=None,
@@ -857,12 +868,12 @@ def draw_box(
857
868
  if score > thr:
858
869
  top_left = tuple(map(int, bbox[0]))
859
870
  bottom_right = tuple(map(int, bbox[2]))
860
- image = cv2.rectangle(image, top_left, bottom_right, color_box, 2)
871
+ image = cv2.rectangle(image, top_left, bottom_right, box_color, 2)
861
872
  # image = cv2.putText(
862
- # image, text, top_left, font, font_scale, color_text, thickness_text
873
+ # image, text, top_left, font, font_scale, font_color, thickness_text
863
874
  # )
864
875
  image = add_text_pil(
865
- image, text, top_left, font_size=font_scale * 32, color=color_text
876
+ image, text, top_left, font_size=font_scale * 32, color=font_color
866
877
  )
867
878
 
868
879
  img_cmp = cv2.cvtColor(image, cmap)
py2ls/plot.py CHANGED
@@ -2391,3 +2391,49 @@ def style_examples(
2391
2391
  dir_save,
2392
2392
  f"{f.name[i]}.pdf",
2393
2393
  )
2394
+
2395
+
2396
+ import matplotlib.pyplot as plt
2397
+ from PIL import Image
2398
+
2399
+
2400
+ def thumbnail(dir_img_list: list, figsize=(10, 10), dpi=100, show=False, usage=False):
2401
+ """
2402
+ Display a thumbnail figure of all images in the specified directory.
2403
+
2404
+ Args:
2405
+ dir_img_list (list): List of image file paths to display.
2406
+ figsize (tuple): Size of the figure (width, height) in inches.
2407
+ dpi (int): Dots per inch for the figure.
2408
+ """
2409
+ if usage:
2410
+ print(
2411
+ 'thumbnail(listdir("./img-innere-medizin-ii", ["jpeg", "jpg", "png"]).fpath.tolist(),figsize=[5,5],dpi=200)'
2412
+ )
2413
+ num_images = len(dir_img_list)
2414
+ if num_images == 0:
2415
+ print("No images found to display.")
2416
+ return None
2417
+
2418
+ # Calculate the number of rows and columns for the grid
2419
+ cols = int(num_images**0.5)
2420
+ rows = (num_images // cols) + (num_images % cols > 0)
2421
+
2422
+ fig, axs = plt.subplots(rows, cols, figsize=figsize, dpi=dpi)
2423
+ axs = axs.flatten() # Flatten the grid for easy iteration
2424
+
2425
+ for ax, image_file in zip(axs, dir_img_list):
2426
+ try:
2427
+ img = Image.open(image_file)
2428
+ ax.imshow(img)
2429
+ ax.axis("off") # Hide axes
2430
+ except (IOError, FileNotFoundError) as e:
2431
+ ax.axis("off") # Still hide axes if image can't be loaded
2432
+
2433
+ # Hide any remaining unused axes
2434
+ for ax in axs[len(dir_img_list) :]:
2435
+ ax.axis("off")
2436
+
2437
+ plt.tight_layout()
2438
+ if show:
2439
+ plt.show()
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: py2ls
3
- Version: 0.1.10.23
3
+ Version: 0.1.10.24
4
4
  Summary: py(thon)2(too)ls
5
5
  Author: Jianfeng
6
6
  Author-email: Jianfeng.Liu0413@gmail.com
@@ -206,15 +206,15 @@ py2ls/doc.py,sha256=xN3g1OWfoaGUhikbJ0NqbN5eKy1VZVvWwRlhHMgyVEc,4243
206
206
  py2ls/export_requirements.py,sha256=x2WgUF0jYKz9GfA1MVKN-MdsM-oQ8yUeC6Ua8oCymio,2325
207
207
  py2ls/freqanalysis.py,sha256=F4218VSPbgL5tnngh6xNCYuNnfR-F_QjECUUxrPYZss,32594
208
208
  py2ls/ich2ls.py,sha256=3E9R8oVpyYZXH5PiIQgT3CN5NxLe4Dwtm2LwaeacE6I,21381
209
- py2ls/ips.py,sha256=c152TEz1X3huntbr_QySp0rqEZVf3TkFZeOHUr1m7H0,141806
210
- py2ls/netfinder.py,sha256=_stenzqRZsB4m5FDE7YsSkC2jvkmrUOsq48BRQB2mPM,55369
211
- py2ls/ocr.py,sha256=T1C589yPF07lJ6EFpGgKq5Dw0vLIZ_-ffH_WZZVIz5o,31026
212
- py2ls/plot.py,sha256=J8hRKLpQXHQRG_xE_nmT0mQvc1IxCMJ21tJmKsUKFl4,96155
209
+ py2ls/ips.py,sha256=rbQPUX0Hh_PZET7uBPzZtq93w35zqI5lp_HHLBWT6QI,143812
210
+ py2ls/netfinder.py,sha256=vgOOMhzwbjRuLWMAPyf_kh3HoOhsJ9dlA-tCkMf7kNU,55371
211
+ py2ls/ocr.py,sha256=5lhUbJufIKRSOL6wAWVLEo8TqMYSjoI_Q-IO-_4u3DE,31419
212
+ py2ls/plot.py,sha256=yj-AfnYNr1ha_Y5EimTsUVSooFc36nE0KCQ8cP9_Trs,97601
213
213
  py2ls/setuptools-70.1.0-py3-none-any.whl,sha256=2bi3cUVal8ip86s0SOvgspteEF8SKLukECi-EWmFomc,882588
214
214
  py2ls/sleep_events_detectors.py,sha256=bQA3HJqv5qnYKJJEIhCyhlDtkXQfIzqksnD0YRXso68,52145
215
215
  py2ls/stats.py,sha256=fJmXQ9Lq460StOn-kfEljE97cySq7876HUPTnpB5hLs,38123
216
216
  py2ls/translator.py,sha256=zBeq4pYZeroqw3DT-5g7uHfVqKd-EQptT6LJ-Adi8JY,34244
217
217
  py2ls/wb_detector.py,sha256=7y6TmBUj9exCZeIgBAJ_9hwuhkDh1x_-yg4dvNY1_GQ,6284
218
- py2ls-0.1.10.23.dist-info/METADATA,sha256=VIi88HkNs4dmmv3pLfKQOq0OGT-x0ktBoBmnIn1yVHY,19791
219
- py2ls-0.1.10.23.dist-info/WHEEL,sha256=FMvqSimYX_P7y0a7UY-_Mc83r5zkBZsCYPm7Lr0Bsq4,88
220
- py2ls-0.1.10.23.dist-info/RECORD,,
218
+ py2ls-0.1.10.24.dist-info/METADATA,sha256=dbf8zXh56f8wJo2XZxxPbN37Y9FdRMlTbRuBjqR8zPE,19791
219
+ py2ls-0.1.10.24.dist-info/WHEEL,sha256=FMvqSimYX_P7y0a7UY-_Mc83r5zkBZsCYPm7Lr0Bsq4,88
220
+ py2ls-0.1.10.24.dist-info/RECORD,,