10dcbc4b1714260820fd4b8d6536fbb05e139cc0fAhmad Sharif# Copyright 2011 Google Inc. All Rights Reserved.
2742ed2c8cd29f8f2d1ff28f3e3aea48307c71839Yunlian Jiang"""Module to represent a Field in an experiment file."""
30dcbc4b1714260820fd4b8d6536fbb05e139cc0fAhmad Sharif
4f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano
50dcbc4b1714260820fd4b8d6536fbb05e139cc0fAhmad Sharifclass Field(object):
60dcbc4b1714260820fd4b8d6536fbb05e139cc0fAhmad Sharif  """Class representing a Field in an experiment file."""
70dcbc4b1714260820fd4b8d6536fbb05e139cc0fAhmad Sharif
80dcbc4b1714260820fd4b8d6536fbb05e139cc0fAhmad Sharif  def __init__(self, name, required, default, inheritable, description):
90dcbc4b1714260820fd4b8d6536fbb05e139cc0fAhmad Sharif    self.name = name
100dcbc4b1714260820fd4b8d6536fbb05e139cc0fAhmad Sharif    self.required = required
110dcbc4b1714260820fd4b8d6536fbb05e139cc0fAhmad Sharif    self.assigned = False
120dcbc4b1714260820fd4b8d6536fbb05e139cc0fAhmad Sharif    self.default = default
130dcbc4b1714260820fd4b8d6536fbb05e139cc0fAhmad Sharif    self._value = default
140dcbc4b1714260820fd4b8d6536fbb05e139cc0fAhmad Sharif    self.inheritable = inheritable
150dcbc4b1714260820fd4b8d6536fbb05e139cc0fAhmad Sharif    self.description = description
160dcbc4b1714260820fd4b8d6536fbb05e139cc0fAhmad Sharif
170dcbc4b1714260820fd4b8d6536fbb05e139cc0fAhmad Sharif  def Set(self, value, parse=True):
180dcbc4b1714260820fd4b8d6536fbb05e139cc0fAhmad Sharif    if parse:
190dcbc4b1714260820fd4b8d6536fbb05e139cc0fAhmad Sharif      self._value = self._Parse(value)
200dcbc4b1714260820fd4b8d6536fbb05e139cc0fAhmad Sharif    else:
210dcbc4b1714260820fd4b8d6536fbb05e139cc0fAhmad Sharif      self._value = value
220dcbc4b1714260820fd4b8d6536fbb05e139cc0fAhmad Sharif    self.assigned = True
230dcbc4b1714260820fd4b8d6536fbb05e139cc0fAhmad Sharif
240dcbc4b1714260820fd4b8d6536fbb05e139cc0fAhmad Sharif  def Append(self, value):
250dcbc4b1714260820fd4b8d6536fbb05e139cc0fAhmad Sharif    self._value += self._Parse(value)
260dcbc4b1714260820fd4b8d6536fbb05e139cc0fAhmad Sharif    self.assigned = True
270dcbc4b1714260820fd4b8d6536fbb05e139cc0fAhmad Sharif
280dcbc4b1714260820fd4b8d6536fbb05e139cc0fAhmad Sharif  def _Parse(self, value):
290dcbc4b1714260820fd4b8d6536fbb05e139cc0fAhmad Sharif    return value
300dcbc4b1714260820fd4b8d6536fbb05e139cc0fAhmad Sharif
310dcbc4b1714260820fd4b8d6536fbb05e139cc0fAhmad Sharif  def Get(self):
320dcbc4b1714260820fd4b8d6536fbb05e139cc0fAhmad Sharif    return self._value
330dcbc4b1714260820fd4b8d6536fbb05e139cc0fAhmad Sharif
340dcbc4b1714260820fd4b8d6536fbb05e139cc0fAhmad Sharif  def GetString(self):
350dcbc4b1714260820fd4b8d6536fbb05e139cc0fAhmad Sharif    return str(self._value)
360dcbc4b1714260820fd4b8d6536fbb05e139cc0fAhmad Sharif
370dcbc4b1714260820fd4b8d6536fbb05e139cc0fAhmad Sharif
380dcbc4b1714260820fd4b8d6536fbb05e139cc0fAhmad Sharifclass TextField(Field):
39742ed2c8cd29f8f2d1ff28f3e3aea48307c71839Yunlian Jiang  """Class of text field."""
40f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano
41f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano  def __init__(self,
42f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano               name,
43f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano               required=False,
44f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano               default='',
45f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano               inheritable=False,
46f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano               description=''):
470dcbc4b1714260820fd4b8d6536fbb05e139cc0fAhmad Sharif    super(TextField, self).__init__(name, required, default, inheritable,
480dcbc4b1714260820fd4b8d6536fbb05e139cc0fAhmad Sharif                                    description)
490dcbc4b1714260820fd4b8d6536fbb05e139cc0fAhmad Sharif
500dcbc4b1714260820fd4b8d6536fbb05e139cc0fAhmad Sharif  def _Parse(self, value):
510dcbc4b1714260820fd4b8d6536fbb05e139cc0fAhmad Sharif    return str(value)
520dcbc4b1714260820fd4b8d6536fbb05e139cc0fAhmad Sharif
530dcbc4b1714260820fd4b8d6536fbb05e139cc0fAhmad Sharif
540dcbc4b1714260820fd4b8d6536fbb05e139cc0fAhmad Sharifclass BooleanField(Field):
55742ed2c8cd29f8f2d1ff28f3e3aea48307c71839Yunlian Jiang  """Class of boolean field."""
56f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano
57f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano  def __init__(self,
58f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano               name,
59f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano               required=False,
60f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano               default=False,
61f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano               inheritable=False,
62f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano               description=''):
630dcbc4b1714260820fd4b8d6536fbb05e139cc0fAhmad Sharif    super(BooleanField, self).__init__(name, required, default, inheritable,
640dcbc4b1714260820fd4b8d6536fbb05e139cc0fAhmad Sharif                                       description)
650dcbc4b1714260820fd4b8d6536fbb05e139cc0fAhmad Sharif
660dcbc4b1714260820fd4b8d6536fbb05e139cc0fAhmad Sharif  def _Parse(self, value):
67f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano    if value.lower() == 'true':
680dcbc4b1714260820fd4b8d6536fbb05e139cc0fAhmad Sharif      return True
69f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano    elif value.lower() == 'false':
700dcbc4b1714260820fd4b8d6536fbb05e139cc0fAhmad Sharif      return False
719099a788cd7124024559c064e425ed9caef6e0acCaroline Tice    raise TypeError("Invalid value for '%s'. Must be true or false." %
720dcbc4b1714260820fd4b8d6536fbb05e139cc0fAhmad Sharif                    self.name)
730dcbc4b1714260820fd4b8d6536fbb05e139cc0fAhmad Sharif
740dcbc4b1714260820fd4b8d6536fbb05e139cc0fAhmad Sharif
750dcbc4b1714260820fd4b8d6536fbb05e139cc0fAhmad Sharifclass IntegerField(Field):
76742ed2c8cd29f8f2d1ff28f3e3aea48307c71839Yunlian Jiang  """Class of integer field."""
77f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano
78f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano  def __init__(self,
79f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano               name,
80f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano               required=False,
81f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano               default=0,
82f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano               inheritable=False,
83f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano               description=''):
840dcbc4b1714260820fd4b8d6536fbb05e139cc0fAhmad Sharif    super(IntegerField, self).__init__(name, required, default, inheritable,
850dcbc4b1714260820fd4b8d6536fbb05e139cc0fAhmad Sharif                                       description)
860dcbc4b1714260820fd4b8d6536fbb05e139cc0fAhmad Sharif
870dcbc4b1714260820fd4b8d6536fbb05e139cc0fAhmad Sharif  def _Parse(self, value):
880dcbc4b1714260820fd4b8d6536fbb05e139cc0fAhmad Sharif    return int(value)
890dcbc4b1714260820fd4b8d6536fbb05e139cc0fAhmad Sharif
900dcbc4b1714260820fd4b8d6536fbb05e139cc0fAhmad Sharif
910dcbc4b1714260820fd4b8d6536fbb05e139cc0fAhmad Sharifclass FloatField(Field):
92742ed2c8cd29f8f2d1ff28f3e3aea48307c71839Yunlian Jiang  """Class of float field."""
93f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano
94f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano  def __init__(self,
95f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano               name,
96f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano               required=False,
97f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano               default=0,
98f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano               inheritable=False,
99f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano               description=''):
1000dcbc4b1714260820fd4b8d6536fbb05e139cc0fAhmad Sharif    super(FloatField, self).__init__(name, required, default, inheritable,
1010dcbc4b1714260820fd4b8d6536fbb05e139cc0fAhmad Sharif                                     description)
1020dcbc4b1714260820fd4b8d6536fbb05e139cc0fAhmad Sharif
1030dcbc4b1714260820fd4b8d6536fbb05e139cc0fAhmad Sharif  def _Parse(self, value):
1040dcbc4b1714260820fd4b8d6536fbb05e139cc0fAhmad Sharif    return float(value)
1050dcbc4b1714260820fd4b8d6536fbb05e139cc0fAhmad Sharif
1060dcbc4b1714260820fd4b8d6536fbb05e139cc0fAhmad Sharif
1070dcbc4b1714260820fd4b8d6536fbb05e139cc0fAhmad Sharifclass ListField(Field):
108742ed2c8cd29f8f2d1ff28f3e3aea48307c71839Yunlian Jiang  """Class of list field."""
109f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano
110f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano  def __init__(self,
111f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano               name,
112f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano               required=False,
113f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano               default=None,
114f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano               inheritable=False,
115f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano               description=''):
1160dcbc4b1714260820fd4b8d6536fbb05e139cc0fAhmad Sharif    super(ListField, self).__init__(name, required, default, inheritable,
1170dcbc4b1714260820fd4b8d6536fbb05e139cc0fAhmad Sharif                                    description)
1180dcbc4b1714260820fd4b8d6536fbb05e139cc0fAhmad Sharif
1190dcbc4b1714260820fd4b8d6536fbb05e139cc0fAhmad Sharif  def _Parse(self, value):
1200dcbc4b1714260820fd4b8d6536fbb05e139cc0fAhmad Sharif    return value.split()
1210dcbc4b1714260820fd4b8d6536fbb05e139cc0fAhmad Sharif
1220dcbc4b1714260820fd4b8d6536fbb05e139cc0fAhmad Sharif  def GetString(self):
123f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano    return ' '.join(self._value)
1240dcbc4b1714260820fd4b8d6536fbb05e139cc0fAhmad Sharif
12575e1ccc6513c4529e47007105b7c523755f8e0c0Caroline Tice  def Append(self, value):
12675e1ccc6513c4529e47007105b7c523755f8e0c0Caroline Tice    v = self._Parse(value)
12775e1ccc6513c4529e47007105b7c523755f8e0c0Caroline Tice    if not self._value:
12875e1ccc6513c4529e47007105b7c523755f8e0c0Caroline Tice      self._value = v
12975e1ccc6513c4529e47007105b7c523755f8e0c0Caroline Tice    else:
13075e1ccc6513c4529e47007105b7c523755f8e0c0Caroline Tice      self._value += v
13175e1ccc6513c4529e47007105b7c523755f8e0c0Caroline Tice    self.assigned = True
1320dcbc4b1714260820fd4b8d6536fbb05e139cc0fAhmad Sharif
133f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano
1340dcbc4b1714260820fd4b8d6536fbb05e139cc0fAhmad Sharifclass EnumField(Field):
135742ed2c8cd29f8f2d1ff28f3e3aea48307c71839Yunlian Jiang  """Class of enum field."""
136f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano
137f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano  def __init__(self,
138f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano               name,
139f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano               options,
140f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano               required=False,
141f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano               default='',
142f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano               inheritable=False,
143f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano               description=''):
1440dcbc4b1714260820fd4b8d6536fbb05e139cc0fAhmad Sharif    super(EnumField, self).__init__(name, required, default, inheritable,
1450dcbc4b1714260820fd4b8d6536fbb05e139cc0fAhmad Sharif                                    description)
1460dcbc4b1714260820fd4b8d6536fbb05e139cc0fAhmad Sharif    self.options = options
1470dcbc4b1714260820fd4b8d6536fbb05e139cc0fAhmad Sharif
1480dcbc4b1714260820fd4b8d6536fbb05e139cc0fAhmad Sharif  def _Parse(self, value):
1490dcbc4b1714260820fd4b8d6536fbb05e139cc0fAhmad Sharif    if value not in self.options:
1509099a788cd7124024559c064e425ed9caef6e0acCaroline Tice      raise TypeError("Invalid enum value for field '%s'. Must be one of (%s)" %
151f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano                      (self.name, ', '.join(self.options)))
1520dcbc4b1714260820fd4b8d6536fbb05e139cc0fAhmad Sharif    return str(value)
153