ยปCore Development>Code coverage>Demo/classes/Range.py

Python code coverage for Demo/classes/Range.py

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