summaryrefslogtreecommitdiffstats
path: root/Demo/classes/Range.py
diff options
context:
space:
mode:
Diffstat (limited to 'Demo/classes/Range.py')
-rwxr-xr-xDemo/classes/Range.py72
1 files changed, 72 insertions, 0 deletions
diff --git a/Demo/classes/Range.py b/Demo/classes/Range.py
new file mode 100755
index 0000000..b8bc9be
--- /dev/null
+++ b/Demo/classes/Range.py
@@ -0,0 +1,72 @@
+# Example of a generator: re-implement the built-in range function
+# without actually constructing the list of values. (It turns out
+# that the built-in function is about 20 times faster -- that's why
+# it's built-in. :-)
+
+
+# Wrapper function to emulate the complicated range() arguments
+
+def range(*a):
+ if len(a) == 1:
+ start, stop, step = 0, a[0], 1
+ elif len(a) == 2:
+ start, stop = a
+ step = 1
+ elif len(a) == 3:
+ start, stop, step = a
+ else:
+ raise TypeError, 'range() needs 1-3 arguments'
+ return Range().init(start, stop, step)
+
+
+# Class implementing a range object.
+# To the user the instances feel like immutable sequences
+# (and you can't concatenate or slice them)
+
+class Range:
+
+ # initialization -- should be called only by range() above
+ def init(self, start, stop, step):
+ if step == 0:
+ raise ValueError, 'range() called with zero step'
+ self.start = start
+ self.stop = stop
+ self.step = step
+ self.len = max(0, int((self.stop - self.start) / self.step))
+ return self
+
+ # implement `x` and is also used by print x
+ def __repr__(self):
+ return 'range' + `self.start, self.stop, self.step`
+
+ # implement len(x)
+ def __len__(self):
+ return self.len
+
+ # implement x[i]
+ def __getitem__(self, i):
+ if 0 <= i < self.len:
+ return self.start + self.step * i
+ else:
+ raise IndexError, 'range[i] index out of range'
+
+
+# Small test program
+
+def test():
+ import time, builtin
+ print range(10), range(-10, 10), range(0, 10, 2)
+ for i in range(100, -100, -10): print i,
+ print
+ t1 = time.millitimer()
+ for i in range(1000):
+ pass
+ t2 = time.millitimer()
+ for i in builtin.range(1000):
+ pass
+ t3 = time.millitimer()
+ print t2-t1, 'msec (class)'
+ print t3-t2, 'msec (built-in)'
+
+
+test()