88import sys
99
1010import dateutil .tz
11+ import numpy as np
1112
1213from dowel import LogOutput
1314from dowel .tabular_input import TabularInput
1718class StdOutput (LogOutput ):
1819 """Standard console output for the logger.
1920
21+ :param keys_accepted: Regex for which keys this output should accept.
2022 :param with_timestamp: Whether to log a timestamp before non-tabular data.
2123 """
2224
23- def __init__ (self , with_timestamp = True ):
25+ def __init__ (self , keys_accepted = r'^' , with_timestamp = True ):
26+ super ().__init__ (keys_accepted = keys_accepted )
2427 self ._with_timestamp = with_timestamp
28+ self .tabular = TabularInput ()
2529
2630 @property
2731 def types_accepted (self ):
28- """Accept str and TabularInput objects."""
29- return (str , TabularInput )
32+ """Accept str and scalar objects."""
33+ return (str , ) + np . ScalarType
3034
31- def record (self , data , prefix = '' ):
35+ def record (self , key , value , prefix = '' ):
3236 """Log data to console."""
33- if isinstance (data , str ):
34- out = prefix + data
35- if self ._with_timestamp :
36- now = datetime .datetime .now (dateutil .tz .tzlocal ())
37- timestamp = now .strftime ('%Y-%m-%d %H:%M:%S' )
38- out = '%s | %s' % (timestamp , out )
39- elif isinstance (data , TabularInput ):
40- out = str (data )
41- data .mark_str ()
37+ if not key :
38+ if isinstance (value , str ):
39+ out = prefix + value
40+ if self ._with_timestamp :
41+ now = datetime .datetime .now (dateutil .tz .tzlocal ())
42+ timestamp = now .strftime ('%Y-%m-%d %H:%M:%S' )
43+ out = '%s | %s' % (timestamp , out )
44+ print (out )
45+ else :
46+ raise ValueError ('Unacceptable type' )
4247 else :
43- raise ValueError ('Unacceptable type' )
44-
45- print (out )
48+ self .tabular .record (key , value )
4649
4750 def dump (self , step = None ):
4851 """Flush data to standard output stream."""
52+ if not self .tabular .empty :
53+ print (str (self .tabular ))
54+ self .tabular .clear ()
4955 sys .stdout .flush ()
5056
5157
5258class FileOutput (LogOutput , metaclass = abc .ABCMeta ):
5359 """File output abstract class for logger.
5460
5561 :param file_name: The file this output should log to.
62+ :param keys_accepted: Regex for which keys this output should accept.
5663 :param mode: File open mode ('a', 'w', etc).
5764 """
5865
59- def __init__ (self , file_name , mode = 'w' ):
66+ def __init__ (self , file_name , keys_accepted = r'^' , mode = 'w' ):
67+ super ().__init__ (keys_accepted = keys_accepted )
6068 mkdir_p (os .path .dirname (file_name ))
6169 # Open the log file in child class
6270 self ._log_file = open (file_name , mode )
@@ -75,31 +83,38 @@ class TextOutput(FileOutput):
7583 """Text file output for logger.
7684
7785 :param file_name: The file this output should log to.
86+ :param keys_accepted: Regex for which keys this output should accept.
7887 :param with_timestamp: Whether to log a timestamp before the data.
7988 """
8089
81- def __init__ (self , file_name , with_timestamp = True ):
82- super ().__init__ (file_name , 'a' )
90+ def __init__ (self , file_name , keys_accepted = r'^' , with_timestamp = True ):
91+ super ().__init__ (file_name , keys_accepted = keys_accepted , mode = 'a' )
8392 self ._with_timestamp = with_timestamp
84- self ._delimiter = ' | '
93+ self .tabular = TabularInput ()
8594
8695 @property
8796 def types_accepted (self ):
88- """Accept str objects only ."""
89- return (str , TabularInput )
97+ """Accept str and scalar objects ."""
98+ return (str , ) + np . ScalarType
9099
91- def record (self , data , prefix = '' ):
100+ def record (self , key , value , prefix = '' ):
92101 """Log data to text file."""
93- if isinstance (data , str ):
94- out = prefix + data
95- if self ._with_timestamp :
96- now = datetime .datetime .now (dateutil .tz .tzlocal ())
97- timestamp = now .strftime ('%Y-%m-%d %H:%M:%S' )
98- out = '%s | %s' % (timestamp , out )
99- elif isinstance (data , TabularInput ):
100- out = str (data )
101- data .mark_str ()
102+ if not key :
103+ if isinstance (value , str ):
104+ out = prefix + value
105+ if self ._with_timestamp :
106+ now = datetime .datetime .now (dateutil .tz .tzlocal ())
107+ timestamp = now .strftime ('%Y-%m-%d %H:%M:%S' )
108+ out = '%s | %s' % (timestamp , out )
109+ self ._log_file .write (out + '\n ' )
110+ else :
111+ raise ValueError ('Unacceptable type' )
102112 else :
103- raise ValueError ( 'Unacceptable type.' )
113+ self . tabular . record ( key , value )
104114
105- self ._log_file .write (out + '\n ' )
115+ def dump (self , step = None ):
116+ """Flush data to log file."""
117+ if not self .tabular .empty :
118+ self ._log_file .write (str (self .tabular ) + '\n ' )
119+ self .tabular .clear ()
120+ self ._log_file .flush ()
0 commit comments