-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathsimple_outputs.py
106 lines (81 loc) · 2.98 KB
/
simple_outputs.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
"""Contains the output classes for the logger.
Each class is sent logger data and handles it itself.
"""
import abc
import datetime
import os
import sys
import dateutil.tz
from dowel import LogOutput
from dowel.tabular_input import TabularInput
from dowel.utils import mkdir_p
class StdOutput(LogOutput):
"""Standard console output for the logger.
:param with_timestamp: Whether to log a timestamp before non-tabular data.
"""
def __init__(self, with_timestamp=True):
self._with_timestamp = with_timestamp
@property
def types_accepted(self):
"""Accept str and TabularInput objects."""
return (str, TabularInput)
def record(self, data, prefix=""):
"""Log data to console."""
if isinstance(data, str):
out = prefix + data
if self._with_timestamp:
now = datetime.datetime.now(dateutil.tz.tzlocal())
timestamp = now.strftime("%Y-%m-%d %H:%M:%S")
out = "%s | %s" % (timestamp, out)
elif isinstance(data, TabularInput):
out = str(data)
data.mark_str()
else:
raise ValueError("Unacceptable type")
print(out)
def dump(self, step=None):
"""Flush data to standard output stream."""
sys.stdout.flush()
class FileOutput(LogOutput, metaclass=abc.ABCMeta):
"""File output abstract class for logger.
:param file_name: The file this output should log to.
:param mode: File open mode ('a', 'w', etc).
"""
def __init__(self, file_name, mode="w"):
mkdir_p(os.path.dirname(file_name))
# Open the log file in child class
self._log_file = open(file_name, mode)
def close(self):
"""Close any files used by the output."""
if self._log_file and not self._log_file.closed:
self._log_file.close()
def dump(self, step=None):
"""Flush data to log file."""
self._log_file.flush()
class TextOutput(FileOutput):
"""Text file output for logger.
:param file_name: The file this output should log to.
:param with_timestamp: Whether to log a timestamp before the data.
"""
def __init__(self, file_name, with_timestamp=True):
super().__init__(file_name, "a")
self._with_timestamp = with_timestamp
self._delimiter = " | "
@property
def types_accepted(self):
"""Accept str objects only."""
return (str, TabularInput)
def record(self, data, prefix=""):
"""Log data to text file."""
if isinstance(data, str):
out = prefix + data
if self._with_timestamp:
now = datetime.datetime.now(dateutil.tz.tzlocal())
timestamp = now.strftime("%Y-%m-%d %H:%M:%S")
out = "%s | %s" % (timestamp, out)
elif isinstance(data, TabularInput):
out = str(data)
data.mark_str()
else:
raise ValueError("Unacceptable type.")
self._log_file.write(out + "\n")