@@ -13,10 +13,10 @@ class BaseProperty(base.BaseObject):
1313 """An odML Property"""
1414 _format = frmt .Property
1515
16- def __init__ (self , name = None , value = None , parent = None , unit = None ,
16+ def __init__ (self , name = None , values = None , parent = None , unit = None ,
1717 uncertainty = None , reference = None , definition = None ,
1818 dependency = None , dependency_value = None , dtype = None ,
19- value_origin = None , oid = None ):
19+ value_origin = None , oid = None , value = None ):
2020 """
2121 Create a new Property. If a value without an explicitly stated dtype
2222 has been provided, the method will try to infer the value's dtype.
@@ -31,8 +31,8 @@ def __init__(self, name=None, value=None, parent=None, unit=None,
3131 >>> p.dtype
3232 >>> int
3333 :param name: The name of the property.
34- :param value : Some data value, it can be a single value or
35- a list of homogeneous values.
34+ :param values : Some data value, it can be a single value or
35+ a list of homogeneous values.
3636 :param unit: The unit of the stored data.
3737 :param uncertainty: The uncertainty (e.g. the standard deviation)
3838 associated with a measure value.
@@ -48,6 +48,8 @@ def __init__(self, name=None, value=None, parent=None, unit=None,
4848 :param oid: object id, UUID string as specified in RFC 4122. If no id is provided,
4949 an id will be generated and assigned. An id has to be unique
5050 within an odML Document.
51+ :param value: Legacy code to the 'values' attribute. If 'values' is provided,
52+ any data provided via 'value' will be ignored.
5153 """
5254 try :
5355 if oid is not None :
@@ -78,28 +80,33 @@ def __init__(self, name=None, value=None, parent=None, unit=None,
7880 else :
7981 print ("Warning: Unknown dtype '%s'." % dtype )
8082
81- self ._value = []
82- self .value = value
83+ self ._values = []
84+ self .values = values
85+ if not values and (value or isinstance (value , bool )):
86+ self .values = value
8387
8488 self .parent = parent
8589
8690 def __len__ (self ):
87- return len (self ._value )
91+ return len (self ._values )
8892
8993 def __getitem__ (self , key ):
90- return self ._value [key ]
94+ return self ._values [key ]
9195
9296 def __setitem__ (self , key , item ):
9397 if int (key ) < 0 or int (key ) > self .__len__ ():
9498 raise IndexError ("odml.Property.__setitem__: key %i invalid for "
9599 "array of length %i" % (int (key ), self .__len__ ()))
96100 try :
97101 val = dtypes .get (item , self .dtype )
98- self ._value [int (key )] = val
102+ self ._values [int (key )] = val
99103 except Exception :
100104 raise ValueError ("odml.Property.__setitem__: passed value cannot be "
101105 "converted to data type \' %s\' !" % self ._dtype )
102106
107+ def __repr__ (self ):
108+ return "Property: {name = %s}" % self ._name
109+
103110 @property
104111 def oid (self ):
105112 """
@@ -143,9 +150,6 @@ def name(self, new_name):
143150
144151 self ._name = new_name
145152
146- def __repr__ (self ):
147- return "<Property %s>" % self ._name
148-
149153 @property
150154 def dtype (self ):
151155 """
@@ -166,10 +170,10 @@ def dtype(self, new_type):
166170 raise AttributeError ("'%s' is not a valid type." % new_type )
167171 # we convert the value if possible
168172 old_type = self ._dtype
169- old_values = self ._value
173+ old_values = self ._values
170174 try :
171175 self ._dtype = new_type
172- self .value = old_values
176+ self .values = old_values
173177 except :
174178 self ._dtype = old_type # If conversion failed, restore old dtype
175179 raise ValueError ("cannot convert from '%s' to '%s'" %
@@ -209,42 +213,27 @@ def _validate_parent(new_parent):
209213 @property
210214 def value (self ):
211215 """
212- Returns the value(s) stored in this property. Method always returns a list
213- that is a copy (!) of the stored value. Changing this list will NOT change
214- the property.
215- For manipulation of the stored values use the append, extend, and direct
216- access methods (using brackets).
217-
218- For example:
219- >>> p = odml.Property("prop", value=[1, 2, 3])
220- >>> print(p.value)
221- [1, 2, 3]
222- >>> p.value.append(4)
223- >>> print(p.value)
224- [1, 2, 3]
216+ Deprecated alias of 'values'. Will be removed with the next minor release.
217+ """
218+ print ("The attribute 'value' is deprecated. Please use 'values' instead." )
219+ return self .values
225220
226- Individual values can be accessed and manipulated like this:
227- >>> print(p[0])
228- [1]
229- >>> p[0] = 4
230- >>> print(p[0])
231- [4]
221+ @value .setter
222+ def value (self , new_value ):
223+ """
224+ Deprecated alias of 'values'. Will be removed with the next minor release.
232225
233- The values can be iterated e.g. with a loop:
234- >>> for v in p.value:
235- >>> print(v)
236- 4
237- 2
238- 3
226+ :param new_value: a single value or list of values.
239227 """
240- return list (self ._value )
228+ print ("The attribute 'value' is deprecated. Please use 'values' instead." )
229+ self .values = new_value
241230
242231 def value_str (self , index = 0 ):
243232 """
244233 Used to access typed data of the value at a specific
245234 index position as a string.
246235 """
247- return dtypes .set (self ._value [index ], self ._dtype )
236+ return dtypes .set (self ._values [index ], self ._dtype )
248237
249238 def _validate_values (self , values ):
250239 """
@@ -285,19 +274,52 @@ def _convert_value_input(self, new_value):
285274 "unsupported data type for values: %s" % type (new_value ))
286275 return new_value
287276
288- @value . setter
289- def value (self , new_value ):
277+ @property
278+ def values (self ):
290279 """
291- Set the value of the property discarding any previous information.
280+ Returns the value(s) stored in this property. Method always returns a list
281+ that is a copy (!) of the stored value. Changing this list will NOT change
282+ the property.
283+ For manipulation of the stored values use the append, extend, and direct
284+ access methods (using brackets).
285+
286+ For example:
287+ >>> p = odml.Property("prop", values=[1, 2, 3])
288+ >>> print(p.values)
289+ [1, 2, 3]
290+ >>> p.values.append(4)
291+ >>> print(p.values)
292+ [1, 2, 3]
293+
294+ Individual values can be accessed and manipulated like this:
295+ >>> print(p[0])
296+ [1]
297+ >>> p[0] = 4
298+ >>> print(p[0])
299+ [4]
300+
301+ The values can be iterated e.g. with a loop:
302+ >>> for v in p.values:
303+ >>> print(v)
304+ 4
305+ 2
306+ 3
307+ """
308+ return list (self ._values )
309+
310+ @values .setter
311+ def values (self , new_value ):
312+ """
313+ Set the values of the property discarding any previous information.
292314 Method will try to convert the passed value to the dtype of
293- the property and raise an ValueError if not possible.
315+ the property and raise a ValueError if not possible.
294316
295317 :param new_value: a single value or list of values.
296318 """
297319 # Make sure boolean value 'False' gets through as well...
298320 if new_value is None or \
299321 (isinstance (new_value , (list , tuple , str )) and len (new_value ) == 0 ):
300- self ._value = []
322+ self ._values = []
301323 return
302324
303325 new_value = self ._convert_value_input (new_value )
@@ -306,9 +328,9 @@ def value(self, new_value):
306328 self ._dtype = dtypes .infer_dtype (new_value [0 ])
307329
308330 if not self ._validate_values (new_value ):
309- raise ValueError ("odml.Property.value : passed values are not of "
331+ raise ValueError ("odml.Property.values : passed values are not of "
310332 "consistent type!" )
311- self ._value = [dtypes .get (v , self .dtype ) for v in new_value ]
333+ self ._values = [dtypes .get (v , self .dtype ) for v in new_value ]
312334
313335 @property
314336 def value_origin (self ):
@@ -394,8 +416,8 @@ def remove(self, value):
394416 occurrence of the passed in value is removed from the properties
395417 list of values.
396418 """
397- if value in self ._value :
398- self ._value .remove (value )
419+ if value in self ._values :
420+ self ._values .remove (value )
399421
400422 def get_path (self ):
401423 """
@@ -417,7 +439,7 @@ def clone(self, keep_id=False):
417439 """
418440 obj = super (BaseProperty , self ).clone ()
419441 obj ._parent = None
420- obj .value = self ._value
442+ obj .values = self ._values
421443 if not keep_id :
422444 obj .new_id ()
423445
@@ -441,7 +463,7 @@ def merge_check(self, source, strict=True):
441463
442464 # Catch unmerge-able values at this point to avoid
443465 # failing Section tree merges which cannot easily be rolled back.
444- new_value = self ._convert_value_input (source .value )
466+ new_value = self ._convert_value_input (source .values )
445467 if not self ._validate_values (new_value ):
446468 raise ValueError ("odml.Property.merge: passed value(s) cannot "
447469 "be converted to data type '%s'!" % self ._dtype )
@@ -512,7 +534,7 @@ def merge(self, other, strict=True):
512534 if self .unit is None and other .unit is not None :
513535 self .unit = other .unit
514536
515- to_add = [v for v in other .value if v not in self ._value ]
537+ to_add = [v for v in other .values if v not in self ._values ]
516538 self .extend (to_add , strict = strict )
517539
518540 def unmerge (self , other ):
@@ -557,11 +579,11 @@ def extend(self, obj, strict=True):
557579 if obj .unit != self .unit :
558580 raise ValueError ("odml.Property.extend: src and dest units (%s, %s) "
559581 "do not match!" % (obj .unit , self .unit ))
560- self .extend (obj .value )
582+ self .extend (obj .values )
561583 return
562584
563585 if self .__len__ () == 0 :
564- self .value = obj
586+ self .values = obj
565587 return
566588
567589 new_value = self ._convert_value_input (obj )
@@ -572,7 +594,7 @@ def extend(self, obj, strict=True):
572594 if not self ._validate_values (new_value ):
573595 raise ValueError ("odml.Property.extend: passed value(s) cannot be converted "
574596 "to data type \' %s\' !" % self ._dtype )
575- self ._value .extend ([dtypes .get (v , self .dtype ) for v in new_value ])
597+ self ._values .extend ([dtypes .get (v , self .dtype ) for v in new_value ])
576598
577599 def append (self , obj , strict = True ):
578600 """
@@ -587,8 +609,8 @@ def append(self, obj, strict=True):
587609 if obj in [None , "" , [], {}]:
588610 return
589611
590- if not self .value :
591- self .value = obj
612+ if not self .values :
613+ self .values = obj
592614 return
593615
594616 new_value = self ._convert_value_input (obj )
@@ -603,4 +625,36 @@ def append(self, obj, strict=True):
603625 raise ValueError ("odml.Property.append: passed value(s) cannot be converted "
604626 "to data type \' %s\' !" % self ._dtype )
605627
606- self ._value .append (dtypes .get (new_value [0 ], self .dtype ))
628+ self ._values .append (dtypes .get (new_value [0 ], self .dtype ))
629+
630+ def pprint (self , indent = 2 , max_length = 80 , current_depth = - 1 ):
631+ """
632+ Pretty print method to visualize Properties and Section-Property trees.
633+
634+ :param indent: number of leading spaces for every child Property.
635+ :param max_length: maximum number of characters printed in one line.
636+ :param current_depth: number of hierarchical levels printed from the
637+ starting Section.
638+ """
639+ property_spaces = ""
640+ prefix = ""
641+ if current_depth >= 0 :
642+ property_spaces = " " * ((current_depth + 2 ) * indent )
643+ prefix = "|-"
644+
645+ if self .unit is None :
646+ value_string = str (self .values )
647+ else :
648+ value_string = "{}{}" .format (self .values , self .unit )
649+
650+ p_len = len (property_spaces ) + len (self .name ) + len (value_string )
651+ if p_len >= max_length - 4 :
652+ split_len = int ((max_length - len (property_spaces )
653+ + len (self .name ) - len (prefix ))/ 2 )
654+ str1 = value_string [0 : split_len ]
655+ str2 = value_string [- split_len :]
656+ print (("{}{} {}: {} ... {}" .format (property_spaces , prefix ,
657+ self .name , str1 , str2 )))
658+ else :
659+ print (("{}{} {}: {}" .format (property_spaces , prefix , self .name ,
660+ value_string )))
0 commit comments