Recording an intermediate state

Tue, 07 May 2013 21:53:15 +0200

author
Andy Buckley <andy@insectnation.org>
date
Tue, 07 May 2013 21:53:15 +0200
changeset 218
dc6b80cfe4ac
parent 217
ba574a129967
child 219
99ab72d8a77e

Recording an intermediate state

pyslha.py file | annotate | diff | comparison | revisions
     1.1 --- a/pyslha.py	Mon Apr 29 15:27:14 2013 +0200
     1.2 +++ b/pyslha.py	Tue May 07 21:53:15 2013 +0200
     1.3 @@ -36,11 +36,13 @@
     1.4  TODOs:
     1.5  
     1.6    For 2.1.0:
     1.7 +   * Only allow integers to be used as block entry indices, to allow multiple
     1.8 +     values (request, if possible, from Anders & Are).
     1.9 +
    1.10 +  For 2.2.0:
    1.11     * Preserve comments from read -> write (needs full-line/inline comment
    1.12       separation?). Can use separate comment dicts in Block and Decay, and
    1.13       attach a multiline .comment attr to the returned/written dicts.
    1.14 -   * Only allow integers to be used as block entry indices, to allow multiple
    1.15 -     values (request, if possible, from Anders & Are).
    1.16  
    1.17    Later/maybe:
    1.18     * Identify HERWIG decay matrix element to use in ISAWIG
    1.19 @@ -48,7 +50,7 @@
    1.20  """
    1.21  
    1.22  __author__ = "Andy Buckley <andy.buckley@cern.ch"
    1.23 -__version__ = "2.0.0"
    1.24 +__version__ = "2.1.0"
    1.25  
    1.26  
    1.27  def _mkdict():
    1.28 @@ -137,9 +139,6 @@
    1.29          """Add an entry to the block from an iterable (i.e. list or tuple) or
    1.30          whitespace-separated string.
    1.31  
    1.32 -        Indexing will be determined automatically such that there is always a
    1.33 -        single-element value: multi-value or None indices may be constructed
    1.34 -        implicitly.
    1.35          """
    1.36          ## If the argument is a single string, split it and proceed
    1.37          if type(entry) is str:
    1.38 @@ -150,12 +149,7 @@
    1.39          ## Auto-convert the types in the list
    1.40          entry = map(_autotype, entry)
    1.41          ## Add the entry to the map, with appropriate indices
    1.42 -        if len(entry) == 1:
    1.43 -            self.entries[None] = entry[0]
    1.44 -        elif len(entry) == 2:
    1.45 -            self.entries[entry[0]] = entry[1]
    1.46 -        else:
    1.47 -            self.entries[tuple(entry[:-1])] = entry[-1]
    1.48 +        self.set_value(entry)
    1.49  
    1.50      def is_single_valued(self):
    1.51          """Return true if there is only one entry, and it has no index: the
    1.52 @@ -176,6 +170,13 @@
    1.53          """Set a value in the block with supplied key, val args (or just val for
    1.54          an unindexed block).
    1.55  
    1.56 +        Indexing is determined automatically: any leading integers will be
    1.57 +        treated as a multi-dimensional index, with the remaining entries being a
    1.58 +        multi-dimensional value. If all N values in the entry iterable are ints,
    1.59 +        then the first N-1 are treated as the index and the Nth as the value. If
    1.60 +        there is only one value it will be treated as the value of a
    1.61 +        single-valued block.
    1.62 +
    1.63          If no key is given, then the block must contain only one non-indexed
    1.64          value otherwise an AccessError exception will be raised.\
    1.65          """
    1.66 @@ -185,8 +186,23 @@
    1.67              if len(self.entries) > 0 and not self.is_single_valued():
    1.68                  raise AccessError("Tried to set a unique value on a multi-value block")
    1.69              self.entries[None] = args[0]
    1.70 +        elif len(entry) == 2:
    1.71 +            if type(entry[0]) is not int:
    1.72 +                raise AccessError("Attempted to set a block entry with a non-integer(s) index")
    1.73 +            self.entries[entry[0]] = entry[1]
    1.74          else:
    1.75 -            self.entries[tuple(args[:-1])] = args[-1]
    1.76 +            ## Find the first non-integer -- all previous items are indices
    1.77 +            i_first_nonint = -1
    1.78 +            for i, x in enumerate(entry):
    1.79 +                if type(x) is not int:
    1.80 +                    i_first_nonint = i
    1.81 +                    break
    1.82 +            if i_first_nonint == 0:
    1.83 +                raise AccessError("No valid integer indices found when setting a multi-index/multi-value block entry")
    1.84 +            elif i_first_nonint == 1:
    1.85 +                self.entries[args[0]] = args[1:]
    1.86 +            else:
    1.87 +                self.entries[tuple(args[:i_first_nonint])] = entry[i_first_nonint:]
    1.88  
    1.89      def has_key(self, key):
    1.90          """Does the block have the given key?"""
    1.91 @@ -214,6 +230,8 @@
    1.92          return self.entries[key]
    1.93  
    1.94      def __setitem__(self, key, value):
    1.95 +        if type(key) is not int and not all(type(x) is int for x in key):
    1.96 +            raise AccessError("Attempted to set a block entry with a non-integer(s) index")
    1.97          self.entries[key] = value
    1.98  
    1.99      def __cmp__(self, other):

mercurial