annotate Demo/classes/Range.py @ 80661:94de77bd0b4b 2.7

Issue #16194: document imp.load_dynamic problems when read several extension modules from the same binary object file.
author Andrew Svetlov <andrew.svetlov@gmail.com>
date Thu, 29 Nov 2012 19:51:28 +0200
parents e371183d0e19
children 7d16b42fcdbd
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
32425
e371183d0e19 Add code for a range function that uses generators.
Brett Cannon <bcannon@gmail.com>
parents: 31515
diff changeset
1 """Example of a generator: re-implement the built-in range function
e371183d0e19 Add code for a range function that uses generators.
Brett Cannon <bcannon@gmail.com>
parents: 31515
diff changeset
2 without actually constructing the list of values.
e371183d0e19 Add code for a range function that uses generators.
Brett Cannon <bcannon@gmail.com>
parents: 31515
diff changeset
3
e371183d0e19 Add code for a range function that uses generators.
Brett Cannon <bcannon@gmail.com>
parents: 31515
diff changeset
4 OldStyleRange is coded in the way required to work in a 'for' loop before
e371183d0e19 Add code for a range function that uses generators.
Brett Cannon <bcannon@gmail.com>
parents: 31515
diff changeset
5 iterators were introduced into the language; using __getitem__ and __len__ .
945
465b9841770e Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
6
32425
e371183d0e19 Add code for a range function that uses generators.
Brett Cannon <bcannon@gmail.com>
parents: 31515
diff changeset
7 """
e371183d0e19 Add code for a range function that uses generators.
Brett Cannon <bcannon@gmail.com>
parents: 31515
diff changeset
8 def handleargs(arglist):
e371183d0e19 Add code for a range function that uses generators.
Brett Cannon <bcannon@gmail.com>
parents: 31515
diff changeset
9 """Take list of arguments and extract/create proper start, stop, and step
e371183d0e19 Add code for a range function that uses generators.
Brett Cannon <bcannon@gmail.com>
parents: 31515
diff changeset
10 values and return in a tuple"""
e371183d0e19 Add code for a range function that uses generators.
Brett Cannon <bcannon@gmail.com>
parents: 31515
diff changeset
11 try:
e371183d0e19 Add code for a range function that uses generators.
Brett Cannon <bcannon@gmail.com>
parents: 31515
diff changeset
12 if len(arglist) == 1:
e371183d0e19 Add code for a range function that uses generators.
Brett Cannon <bcannon@gmail.com>
parents: 31515
diff changeset
13 return 0, int(arglist[0]), 1
e371183d0e19 Add code for a range function that uses generators.
Brett Cannon <bcannon@gmail.com>
parents: 31515
diff changeset
14 elif len(arglist) == 2:
e371183d0e19 Add code for a range function that uses generators.
Brett Cannon <bcannon@gmail.com>
parents: 31515
diff changeset
15 return int(arglist[0]), int(arglist[1]), 1
e371183d0e19 Add code for a range function that uses generators.
Brett Cannon <bcannon@gmail.com>
parents: 31515
diff changeset
16 elif len(arglist) == 3:
e371183d0e19 Add code for a range function that uses generators.
Brett Cannon <bcannon@gmail.com>
parents: 31515
diff changeset
17 if arglist[2] == 0:
e371183d0e19 Add code for a range function that uses generators.
Brett Cannon <bcannon@gmail.com>
parents: 31515
diff changeset
18 raise ValueError("step argument must not be zero")
e371183d0e19 Add code for a range function that uses generators.
Brett Cannon <bcannon@gmail.com>
parents: 31515
diff changeset
19 return tuple(int(x) for x in arglist)
e371183d0e19 Add code for a range function that uses generators.
Brett Cannon <bcannon@gmail.com>
parents: 31515
diff changeset
20 else:
e371183d0e19 Add code for a range function that uses generators.
Brett Cannon <bcannon@gmail.com>
parents: 31515
diff changeset
21 raise TypeError("range() accepts 1-3 arguments, given", len(arglist))
e371183d0e19 Add code for a range function that uses generators.
Brett Cannon <bcannon@gmail.com>
parents: 31515
diff changeset
22 except TypeError:
e371183d0e19 Add code for a range function that uses generators.
Brett Cannon <bcannon@gmail.com>
parents: 31515
diff changeset
23 raise TypeError("range() arguments must be numbers or strings "
e371183d0e19 Add code for a range function that uses generators.
Brett Cannon <bcannon@gmail.com>
parents: 31515
diff changeset
24 "representing numbers")
945
465b9841770e Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
25
32425
e371183d0e19 Add code for a range function that uses generators.
Brett Cannon <bcannon@gmail.com>
parents: 31515
diff changeset
26 def genrange(*a):
e371183d0e19 Add code for a range function that uses generators.
Brett Cannon <bcannon@gmail.com>
parents: 31515
diff changeset
27 """Function to implement 'range' as a generator"""
e371183d0e19 Add code for a range function that uses generators.
Brett Cannon <bcannon@gmail.com>
parents: 31515
diff changeset
28 start, stop, step = handleargs(a)
e371183d0e19 Add code for a range function that uses generators.
Brett Cannon <bcannon@gmail.com>
parents: 31515
diff changeset
29 value = start
e371183d0e19 Add code for a range function that uses generators.
Brett Cannon <bcannon@gmail.com>
parents: 31515
diff changeset
30 while value < stop:
e371183d0e19 Add code for a range function that uses generators.
Brett Cannon <bcannon@gmail.com>
parents: 31515
diff changeset
31 yield value
e371183d0e19 Add code for a range function that uses generators.
Brett Cannon <bcannon@gmail.com>
parents: 31515
diff changeset
32 value += step
28788
558689b6d7f0 Run these demo scripts through reindent.py to give them 4-space indents. I've verified that their output is unchanged.
Andrew M. Kuchling <amk@amk.ca>
parents: 1553
diff changeset
33
32425
e371183d0e19 Add code for a range function that uses generators.
Brett Cannon <bcannon@gmail.com>
parents: 31515
diff changeset
34 class oldrange:
e371183d0e19 Add code for a range function that uses generators.
Brett Cannon <bcannon@gmail.com>
parents: 31515
diff changeset
35 """Class implementing a range object.
e371183d0e19 Add code for a range function that uses generators.
Brett Cannon <bcannon@gmail.com>
parents: 31515
diff changeset
36 To the user the instances feel like immutable sequences
e371183d0e19 Add code for a range function that uses generators.
Brett Cannon <bcannon@gmail.com>
parents: 31515
diff changeset
37 (and you can't concatenate or slice them)
945
465b9841770e Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
38
32425
e371183d0e19 Add code for a range function that uses generators.
Brett Cannon <bcannon@gmail.com>
parents: 31515
diff changeset
39 Done using the old way (pre-iterators; __len__ and __getitem__) to have an
e371183d0e19 Add code for a range function that uses generators.
Brett Cannon <bcannon@gmail.com>
parents: 31515
diff changeset
40 object be used by a 'for' loop.
945
465b9841770e Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
41
32425
e371183d0e19 Add code for a range function that uses generators.
Brett Cannon <bcannon@gmail.com>
parents: 31515
diff changeset
42 """
945
465b9841770e Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
43
32425
e371183d0e19 Add code for a range function that uses generators.
Brett Cannon <bcannon@gmail.com>
parents: 31515
diff changeset
44 def __init__(self, *a):
e371183d0e19 Add code for a range function that uses generators.
Brett Cannon <bcannon@gmail.com>
parents: 31515
diff changeset
45 """ Initialize start, stop, and step values along with calculating the
e371183d0e19 Add code for a range function that uses generators.
Brett Cannon <bcannon@gmail.com>
parents: 31515
diff changeset
46 nubmer of values (what __len__ will return) in the range"""
e371183d0e19 Add code for a range function that uses generators.
Brett Cannon <bcannon@gmail.com>
parents: 31515
diff changeset
47 self.start, self.stop, self.step = handleargs(a)
e371183d0e19 Add code for a range function that uses generators.
Brett Cannon <bcannon@gmail.com>
parents: 31515
diff changeset
48 self.len = max(0, (self.stop - self.start) // self.step)
945
465b9841770e Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
49
28788
558689b6d7f0 Run these demo scripts through reindent.py to give them 4-space indents. I've verified that their output is unchanged.
Andrew M. Kuchling <amk@amk.ca>
parents: 1553
diff changeset
50 def __repr__(self):
32425
e371183d0e19 Add code for a range function that uses generators.
Brett Cannon <bcannon@gmail.com>
parents: 31515
diff changeset
51 """implement repr(x) which is also used by print"""
31515
71a294bd7950 Replace backticks with repr() or "%r"
Walter Dörwald <walter@livinglogic.de>
parents: 28788
diff changeset
52 return 'range(%r, %r, %r)' % (self.start, self.stop, self.step)
945
465b9841770e Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
53
28788
558689b6d7f0 Run these demo scripts through reindent.py to give them 4-space indents. I've verified that their output is unchanged.
Andrew M. Kuchling <amk@amk.ca>
parents: 1553
diff changeset
54 def __len__(self):
32425
e371183d0e19 Add code for a range function that uses generators.
Brett Cannon <bcannon@gmail.com>
parents: 31515
diff changeset
55 """implement len(x)"""
28788
558689b6d7f0 Run these demo scripts through reindent.py to give them 4-space indents. I've verified that their output is unchanged.
Andrew M. Kuchling <amk@amk.ca>
parents: 1553
diff changeset
56 return self.len
945
465b9841770e Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
57
28788
558689b6d7f0 Run these demo scripts through reindent.py to give them 4-space indents. I've verified that their output is unchanged.
Andrew M. Kuchling <amk@amk.ca>
parents: 1553
diff changeset
58 def __getitem__(self, i):
32425
e371183d0e19 Add code for a range function that uses generators.
Brett Cannon <bcannon@gmail.com>
parents: 31515
diff changeset
59 """implement x[i]"""
e371183d0e19 Add code for a range function that uses generators.
Brett Cannon <bcannon@gmail.com>
parents: 31515
diff changeset
60 if 0 <= i <= self.len:
28788
558689b6d7f0 Run these demo scripts through reindent.py to give them 4-space indents. I've verified that their output is unchanged.
Andrew M. Kuchling <amk@amk.ca>
parents: 1553
diff changeset
61 return self.start + self.step * i
558689b6d7f0 Run these demo scripts through reindent.py to give them 4-space indents. I've verified that their output is unchanged.
Andrew M. Kuchling <amk@amk.ca>
parents: 1553
diff changeset
62 else:
558689b6d7f0 Run these demo scripts through reindent.py to give them 4-space indents. I've verified that their output is unchanged.
Andrew M. Kuchling <amk@amk.ca>
parents: 1553
diff changeset
63 raise IndexError, 'range[i] index out of range'
945
465b9841770e Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
64
465b9841770e Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
65
465b9841770e Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
66 def test():
28788
558689b6d7f0 Run these demo scripts through reindent.py to give them 4-space indents. I've verified that their output is unchanged.
Andrew M. Kuchling <amk@amk.ca>
parents: 1553
diff changeset
67 import time, __builtin__
32425
e371183d0e19 Add code for a range function that uses generators.
Brett Cannon <bcannon@gmail.com>
parents: 31515
diff changeset
68 #Just a quick sanity check
e371183d0e19 Add code for a range function that uses generators.
Brett Cannon <bcannon@gmail.com>
parents: 31515
diff changeset
69 correct_result = __builtin__.range(5, 100, 3)
e371183d0e19 Add code for a range function that uses generators.
Brett Cannon <bcannon@gmail.com>
parents: 31515
diff changeset
70 oldrange_result = list(oldrange(5, 100, 3))
e371183d0e19 Add code for a range function that uses generators.
Brett Cannon <bcannon@gmail.com>
parents: 31515
diff changeset
71 genrange_result = list(genrange(5, 100, 3))
e371183d0e19 Add code for a range function that uses generators.
Brett Cannon <bcannon@gmail.com>
parents: 31515
diff changeset
72 if genrange_result != correct_result or oldrange_result != correct_result:
e371183d0e19 Add code for a range function that uses generators.
Brett Cannon <bcannon@gmail.com>
parents: 31515
diff changeset
73 raise Exception("error in implementation:\ncorrect = %s"
e371183d0e19 Add code for a range function that uses generators.
Brett Cannon <bcannon@gmail.com>
parents: 31515
diff changeset
74 "\nold-style = %s\ngenerator = %s" %
e371183d0e19 Add code for a range function that uses generators.
Brett Cannon <bcannon@gmail.com>
parents: 31515
diff changeset
75 (correct_result, oldrange_result, genrange_result))
e371183d0e19 Add code for a range function that uses generators.
Brett Cannon <bcannon@gmail.com>
parents: 31515
diff changeset
76 print "Timings for range(1000):"
28788
558689b6d7f0 Run these demo scripts through reindent.py to give them 4-space indents. I've verified that their output is unchanged.
Andrew M. Kuchling <amk@amk.ca>
parents: 1553
diff changeset
77 t1 = time.time()
32425
e371183d0e19 Add code for a range function that uses generators.
Brett Cannon <bcannon@gmail.com>
parents: 31515
diff changeset
78 for i in oldrange(1000):
28788
558689b6d7f0 Run these demo scripts through reindent.py to give them 4-space indents. I've verified that their output is unchanged.
Andrew M. Kuchling <amk@amk.ca>
parents: 1553
diff changeset
79 pass
558689b6d7f0 Run these demo scripts through reindent.py to give them 4-space indents. I've verified that their output is unchanged.
Andrew M. Kuchling <amk@amk.ca>
parents: 1553
diff changeset
80 t2 = time.time()
32425
e371183d0e19 Add code for a range function that uses generators.
Brett Cannon <bcannon@gmail.com>
parents: 31515
diff changeset
81 for i in genrange(1000):
28788
558689b6d7f0 Run these demo scripts through reindent.py to give them 4-space indents. I've verified that their output is unchanged.
Andrew M. Kuchling <amk@amk.ca>
parents: 1553
diff changeset
82 pass
558689b6d7f0 Run these demo scripts through reindent.py to give them 4-space indents. I've verified that their output is unchanged.
Andrew M. Kuchling <amk@amk.ca>
parents: 1553
diff changeset
83 t3 = time.time()
32425
e371183d0e19 Add code for a range function that uses generators.
Brett Cannon <bcannon@gmail.com>
parents: 31515
diff changeset
84 for i in __builtin__.range(1000):
e371183d0e19 Add code for a range function that uses generators.
Brett Cannon <bcannon@gmail.com>
parents: 31515
diff changeset
85 pass
e371183d0e19 Add code for a range function that uses generators.
Brett Cannon <bcannon@gmail.com>
parents: 31515
diff changeset
86 t4 = time.time()
e371183d0e19 Add code for a range function that uses generators.
Brett Cannon <bcannon@gmail.com>
parents: 31515
diff changeset
87 print t2-t1, 'sec (old-style class)'
e371183d0e19 Add code for a range function that uses generators.
Brett Cannon <bcannon@gmail.com>
parents: 31515
diff changeset
88 print t3-t2, 'sec (generator)'
e371183d0e19 Add code for a range function that uses generators.
Brett Cannon <bcannon@gmail.com>
parents: 31515
diff changeset
89 print t4-t3, 'sec (built-in)'
945
465b9841770e Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
90
465b9841770e Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
91
32425
e371183d0e19 Add code for a range function that uses generators.
Brett Cannon <bcannon@gmail.com>
parents: 31515
diff changeset
92 if __name__ == '__main__':
e371183d0e19 Add code for a range function that uses generators.
Brett Cannon <bcannon@gmail.com>
parents: 31515
diff changeset
93 test()