File: range.py

package info (click to toggle)
thuban 1.2.2-14
  • links: PTS, VCS
  • area: main
  • in suites: buster
  • size: 9,176 kB
  • sloc: python: 30,410; ansic: 6,181; xml: 4,234; cpp: 1,595; makefile: 145
file content (146 lines) | stat: -rw-r--r-- 4,678 bytes parent folder | download | duplicates (6)
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
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
# Copyright (C) 2002, 2003 by Intevation GmbH
# Authors:
# Thomas Koester <tkoester@intevation.de>
#
# This program is free software under the GPL (>=v2)
# Read the file COPYING coming with the software for details.

"""
Range class for Scientific Parameter
"""

__version__ = "$Revision: 1480 $"
# $Source$
# $Id: range.py 1480 2003-07-24 17:52:48Z bh $

import re
import types

_inf = float('1e1000')   # FIXME: hack for infinite

class Range:

    number_re = '(?P<%s>-?(\d*\.?\d*([eE][\-+]?\d+)?|oo))'
    brace_re = '(?P<%s>[][])'
    range_re = '^' + brace_re % 'left' + number_re % 'begin' + \
               ';' + number_re % 'end' + brace_re % 'right' + '$'
    parse_range = re.compile(range_re)

    def __init__(self, range=None):
        self._SetRange(range)

    def _SetRange(self, range):
        if isinstance(range, Range):
            self._SetRange(range.GetRange())
        elif range in [None, '']:
            self._SetRange(']-oo;oo[')
        elif type(range) == types.TupleType:
            if (len(range) == 4 and range[0] in ['[', ']']
                and range[3] in ['[', ']']):
                self._left = range[0]
                self._begin = self.float(range[1])
                self._end = self.float(range[2])
                self._right = range[3]
                if (self._begin > self._end or
                    (self._begin == self._end and
                     (self._left != '[' or self._right != ']'))):
                    raise ValueError("illegal range: %s" % (range,))
            else:
                raise ValueError("can't parse range: %r" % (range,))
        else:
            self._range = range
            match = self.parse_range.match(self._range)
            if match:
                self._SetRange((match.group('left'),
                              match.group('begin'),
                              match.group('end'),
                              match.group('right')))
            else:
                raise ValueError("can't parse range: %s" % (range,))

    def GetRange(self):
        """return internal representation of range

        4-tuple ('[' or ']', begin(float), end(float), '[' or ']')

        """
        return (self._left, self._begin, self._end, self._right)

    def float(self, value):
        """convert string or number to float"""
        if value == 'oo':
            return _inf
        elif value == '-oo':
            return -_inf
        else:
            return float(value)

    def _float2string(self, value):
        """convert float value to string

        (minus) infinity will be converted to (-)oo,
        scientific notation will be used if necessary.

        """
        if value == _inf:
            return 'oo'
        elif value == -_inf:
            return '-oo'
        else:
            return "%g" % (value,)

    def string(self, range):
        """convert internal representation to string"""
        left, begin, end, right = range
        return "%s%s;%s%s" % (left, self._float2string(begin),
                              self._float2string(end), right)

    def __contains__(self, value):
        if self._left == ']':
            contains = value > self._begin
        else:
            contains = value >= self._begin
        if self._right == '[':
            contains = contains and (value < self._end)
        else:
            contains = contains and (value <= self._end)
        return contains

    def __eq__(self, other):
        return (self.GetRange() == other.GetRange())

    def __ne__(self, other):
        return not self.__eq__(other)

    def __str__(self):
        return self.string(self.GetRange())


def _test():
    range1 = Range(']0;99]')
    print 'range1 =', range1, range1.GetRange()
    for i in [-0.1, 0, 0.1, 9.9, 99, 99.9]:
        print '%4.1f in range1 =' % i, i in range1
    range2 = Range(']-oo;10[')
    print 'range2 =', range2, range2.GetRange()
    for i in [-0.1, 0, 0.1, 9.9, 10, 10.1]:
        print '%4.1f not in range2 =' % i, i not in range2
    range3 = Range(']1e-1;1E2]')
    print 'range3 =', range3, range3.GetRange()
    for i in [0, 0.1, 0.11, 10, 100, 101]:
        print '%4.1f not in range3 =' % i, i not in range3
    print 'range3 != range2 =', range3 != range2
    print 'range3 != Range("]1e-1;1E2]") =', range3 != Range("]1e-1;1E2]")

    range4 = Range('')
    print 'range4 =', range4, range4.GetRange()

    range5 = Range(']0;99E+00]')
    print 'range5 =', range5, range5.GetRange()
    range6 = Range(']0;99E+01]')
    print 'range6 =', range6, range6.GetRange()
    range7 = Range(']0;99E-01]')
    print 'range7 =', range7, range7.GetRange()

if __name__ == "__main__":
    _test()