24
24
SCOPE_SEPARATOR ,
25
25
csv_column ,
26
26
csv_column_or_none ,
27
- csv_read ,
28
27
csv_scope ,
29
28
csv_str_or_none ,
30
29
csv_val_or_none ,
31
- csv_write ,
32
30
pycommons_footer_bottom_comments ,
33
31
)
32
+ from pycommons .io .csv import CsvReader as CsvReaderBase
33
+ from pycommons .io .csv import CsvWriter as CsvWriterBase
34
34
from pycommons .io .path import Path , file_path , line_writer
35
35
from pycommons .strings .string_conv import (
36
36
int_or_none_to_str ,
@@ -553,14 +553,7 @@ def to_csv(results: Iterable[EndResult], file: str) -> Path:
553
553
path .ensure_parent_dir_exists ()
554
554
with path .open_for_write () as wt :
555
555
consumer : Final [Callable [[str ], None ]] = line_writer (wt )
556
- for r in csv_write (
557
- data = sorted (results ),
558
- setup = CsvWriter ().setup ,
559
- column_titles = CsvWriter .get_column_titles ,
560
- get_row = CsvWriter .get_row ,
561
- header_comments = CsvWriter .get_header_comments ,
562
- footer_comments = CsvWriter .get_footer_comments ,
563
- footer_bottom_comments = CsvWriter .get_footer_bottom_comments ):
556
+ for r in CsvWriter .write (results ):
564
557
consumer (r )
565
558
logger (f"Done writing end results to CSV file { path !r} ." )
566
559
return path
@@ -580,50 +573,24 @@ def from_csv(file: str,
580
573
path : Final [Path ] = file_path (file )
581
574
logger (f"Now reading CSV file { path !r} ." )
582
575
with path .open_for_read () as rd :
583
- for r in csv_read (rows = rd ,
584
- setup = CsvReader ,
585
- parse_row = CsvReader .parse_row ):
576
+ for r in CsvReader .read (rd ):
586
577
if filterer (r ):
587
578
yield r
588
579
logger (f"Done reading CSV file { path !r} ." )
589
580
590
581
591
- class CsvWriter :
582
+ class CsvWriter ( CsvWriterBase ) :
592
583
"""A class for CSV writing of :class:`EndResult`."""
593
584
594
- def __init__ (self , scope : str | None = None ) -> None :
585
+ def __init__ (self , data : Iterable [EndResult ],
586
+ scope : str | None = None ) -> None :
595
587
"""
596
588
Initialize the csv writer.
597
589
590
+ :param data: the data
598
591
:param scope: the prefix to be pre-pended to all columns
599
592
"""
600
- #: an optional scope
601
- self .scope : Final [str | None ] = (
602
- str .strip (scope )) if scope is not None else None
603
-
604
- #: has this writer been set up?
605
- self .__setup : bool = False
606
- #: do we need the encoding?
607
- self .__needs_encoding : bool = False
608
- #: do we need the max FEs?
609
- self .__needs_max_fes : bool = False
610
- #: do we need the max millis?
611
- self .__needs_max_ms : bool = False
612
- #: do we need the goal F?
613
- self .__needs_goal_f : bool = False
614
-
615
- def setup (self , data : Iterable [EndResult ]) -> "CsvWriter" :
616
- """
617
- Set up this csv writer based on existing data.
618
-
619
- :param data: the data to setup with
620
- :returns: this writer
621
- """
622
- if self .__setup :
623
- raise ValueError (
624
- "EndResults CsvWriter has already been set up." )
625
- self .__setup = True
626
-
593
+ super ().__init__ (data , scope )
627
594
no_encoding : bool = True
628
595
no_max_fes : bool = True
629
596
no_max_ms : bool = True
@@ -632,30 +599,33 @@ def setup(self, data: Iterable[EndResult]) -> "CsvWriter":
632
599
for er in data :
633
600
if no_encoding and (er .encoding is not None ):
634
601
no_encoding = False
635
- self .__needs_encoding = True
636
602
check -= 1
637
603
if check <= 0 :
638
- return self
604
+ break
639
605
if no_max_fes and (er .max_fes is not None ):
640
- self .__needs_max_fes = True
641
606
no_max_fes = False
642
607
check -= 1
643
608
if check <= 0 :
644
- return self
609
+ break
645
610
if no_max_ms and (er .max_time_millis is not None ):
646
- self .__needs_max_ms = True
647
611
no_max_ms = False
648
612
check -= 1
649
613
if check <= 0 :
650
- return self
614
+ break
651
615
if no_goal_f and (er .goal_f is not None ) and (
652
616
isfinite (er .goal_f )):
653
- self .__needs_goal_f = True
654
617
no_goal_f = False
655
618
check -= 1
656
619
if check <= 0 :
657
- return self
658
- return self
620
+ break
621
+ #: do we need the encoding?
622
+ self .__needs_encoding : Final [bool ] = not no_encoding
623
+ #: do we need the max FEs?
624
+ self .__needs_max_fes : Final [bool ] = not no_max_fes
625
+ #: do we need the max millis?
626
+ self .__needs_max_ms : Final [bool ] = not no_max_ms
627
+ #: do we need the goal F?
628
+ self .__needs_goal_f : Final [bool ] = not no_goal_f
659
629
660
630
def get_column_titles (self ) -> Iterable [str ]:
661
631
"""
@@ -768,7 +738,7 @@ def get_footer_bottom_comments(self) -> Iterable[str]:
768
738
yield from pycommons_footer_bottom_comments (self )
769
739
770
740
771
- class CsvReader :
741
+ class CsvReader ( CsvReaderBase ) :
772
742
"""A csv parser for end results."""
773
743
774
744
def __init__ (self , columns : dict [str , int ]) -> None :
@@ -777,9 +747,7 @@ def __init__(self, columns: dict[str, int]) -> None:
777
747
778
748
:param columns: the columns
779
749
"""
780
- super ().__init__ ()
781
- if not isinstance (columns , dict ):
782
- raise type_error (columns , "columns" , dict )
750
+ super ().__init__ (columns )
783
751
#: the index of the algorithm column, if any
784
752
self .__idx_algorithm : Final [int ] = csv_column (columns , KEY_ALGORITHM )
785
753
#: the index of the instance column, if any
0 commit comments