symbian-qemu-0.9.1-12/python-2.6.1/Demo/classes/Range.py
changeset 1 2fb8b9db1c86
equal deleted inserted replaced
0:ffa851df0825 1:2fb8b9db1c86
       
     1 """Example of a generator: re-implement the built-in range function
       
     2 without actually constructing the list of values.
       
     3 
       
     4 OldStyleRange is coded in the way required to work in a 'for' loop before
       
     5 iterators were introduced into the language; using __getitem__ and __len__ .
       
     6 
       
     7 """
       
     8 def handleargs(arglist):
       
     9     """Take list of arguments and extract/create proper start, stop, and step
       
    10     values and return in a tuple"""
       
    11     try:
       
    12         if len(arglist) == 1:
       
    13             return 0, int(arglist[0]), 1
       
    14         elif len(arglist) == 2:
       
    15             return int(arglist[0]), int(arglist[1]), 1
       
    16         elif len(arglist) == 3:
       
    17             if arglist[2] == 0:
       
    18                 raise ValueError("step argument must not be zero")
       
    19             return tuple(int(x) for x in arglist)
       
    20         else:
       
    21             raise TypeError("range() accepts 1-3 arguments, given", len(arglist))
       
    22     except TypeError:
       
    23         raise TypeError("range() arguments must be numbers or strings "
       
    24         "representing numbers")
       
    25 
       
    26 def genrange(*a):
       
    27     """Function to implement 'range' as a generator"""
       
    28     start, stop, step = handleargs(a)
       
    29     value = start
       
    30     while value < stop:
       
    31         yield value
       
    32         value += step
       
    33 
       
    34 class oldrange:
       
    35     """Class implementing a range object.
       
    36     To the user the instances feel like immutable sequences
       
    37     (and you can't concatenate or slice them)
       
    38 
       
    39     Done using the old way (pre-iterators; __len__ and __getitem__) to have an
       
    40     object be used by a 'for' loop.
       
    41 
       
    42     """
       
    43 
       
    44     def __init__(self, *a):
       
    45         """ Initialize start, stop, and step values along with calculating the
       
    46         nubmer of values (what __len__ will return) in the range"""
       
    47         self.start, self.stop, self.step = handleargs(a)
       
    48         self.len = max(0, (self.stop - self.start) // self.step)
       
    49 
       
    50     def __repr__(self):
       
    51         """implement repr(x) which is also used by print"""
       
    52         return 'range(%r, %r, %r)' % (self.start, self.stop, self.step)
       
    53 
       
    54     def __len__(self):
       
    55         """implement len(x)"""
       
    56         return self.len
       
    57 
       
    58     def __getitem__(self, i):
       
    59         """implement x[i]"""
       
    60         if 0 <= i <= self.len:
       
    61             return self.start + self.step * i
       
    62         else:
       
    63             raise IndexError, 'range[i] index out of range'
       
    64 
       
    65 
       
    66 def test():
       
    67     import time, __builtin__
       
    68     #Just a quick sanity check
       
    69     correct_result = __builtin__.range(5, 100, 3)
       
    70     oldrange_result = list(oldrange(5, 100, 3))
       
    71     genrange_result = list(genrange(5, 100, 3))
       
    72     if genrange_result != correct_result or oldrange_result != correct_result:
       
    73         raise Exception("error in implementation:\ncorrect   = %s"
       
    74                          "\nold-style = %s\ngenerator = %s" %
       
    75                          (correct_result, oldrange_result, genrange_result))
       
    76     print "Timings for range(1000):"
       
    77     t1 = time.time()
       
    78     for i in oldrange(1000):
       
    79         pass
       
    80     t2 = time.time()
       
    81     for i in genrange(1000):
       
    82         pass
       
    83     t3 = time.time()
       
    84     for i in __builtin__.range(1000):
       
    85         pass
       
    86     t4 = time.time()
       
    87     print t2-t1, 'sec (old-style class)'
       
    88     print t3-t2, 'sec (generator)'
       
    89     print t4-t3, 'sec (built-in)'
       
    90 
       
    91 
       
    92 if __name__ == '__main__':
       
    93     test()