-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathcircular.py
156 lines (138 loc) · 4.85 KB
/
circular.py
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
147
148
149
150
151
152
153
154
155
#!/usr/bin/python3
"""A circular list-like object for non-integral modulo arithmetic."""
class Circular():
def __init__(self, array):
if not hasattr(array, '__len__'):
raise InitError("arg1 must be a list-like object (list, tuple, string).")
self.array = []
return
self.array = array
def __len__(self):
return len(self.array)
def __getitem__(self, index):
if isinstance(index, int) or isinstance(index, float):
index = self._internalIndex(index)
return self.array[index]
def __setitem__(self, key, value):
if isinstance(key, int) or isinstance(key, float):
key = self._internalIndex(key)
self.array[key] = value
def __iter__(self):
yield from self.array
def _internalIndex(self, index):
"""Get the internal index (ranging from 0 to len(self) - 1) corresponding to
outward-facing index 'index' (which can range from -inf to +inf)."""
index = int(index)
l = len(self)
while index > l - 1:
index -= l
while index < 0:
index += l
return index
def __repr__(self):
return repr(self.array)
def getArray(self):
return self.array
def index(self, val):
"""Return the index of the first value matching 'val' if found.
Return None if 'val' not found in self."""
for n in range(len(self.array)):
if self.array[n] == val:
return n
return None
def rindex(self, val):
"""Return the index of the first value matching 'val' if found, starting
from the end and counting backwards.
Return None if 'val' not found in self."""
for n in range(len(self.array)-1, -1, -1):
if self.array[n] == val:
return n
return None
def rotate(self, n):
"""Rotate the underlying array by 'n' units (positive or negative)."""
self.array = rotate(self.array, n)
def rotate(l, n):
"""Return a copy of list/yuple 'l' as a list rotated by increment 'n'
Negative 'n' shifts everything to the right (0 -> 1, 1 -> 2, etc..., last -> 0)
Positive 'n' shifts values left."""
length = len(l)
return [l[(n + m) % length] for m in range(length)]
def _testInternalIndex(argv):
USAGE = "python3 {} length index"
if len(argv) > 2:
l = int(argv[1])
n = int(argv[2])
crc = Circular([0]*l)
print("len(Circular) = {}; index {} yields {}".format(len(crc), n, crc._internalIndex(n)))
else:
print(USAGE)
def _testCircular(argv):
if len(argv) > 1:
array = [x.strip(',') for x in argv[1:]]
else:
array = []
while True:
try:
query = input("Add item to Circular: ")
if query == "":
break
else:
array.append(query)
except KeyboardInterrupt:
print("Exiting...")
return
circ = Circular(array)
while True:
try:
query = input("Get [g], set [s], print [p], or rotate [r]? ")
if query == '':
raise KeyboardInterrupt()
if query.lower()[0] == 's':
index = input("Index to set: ")
if index == "":
index = 0
else:
try:
index = int(index)
except TypeError:
print("Type Error!")
continue
toSet = input("Set at {}: ".format(index))
circ[index] = toSet
print("Circular[{}] = {}".format(index, toSet))
elif query.lower()[0] == 'g':
index = input("Index to get: ")
if index == "":
index = 0
else:
try:
index = int(index)
except TypeError:
print("Type Error!")
continue
print("Circular[{}] = {}".format(index, circ[index]))
elif query.lower()[0] == 'p':
print(circ)
elif query.lower()[0] == 'r':
amount = input("Rotate by: ")
try:
amount = int(amount)
except TypeError:
print("Type Error!")
continue
circ.rotate(amount)
print("Rotated by {}")
print(circ)
except KeyboardInterrupt:
print("Exiting...")
break
def _testIter(argv):
circ = Circular(('a', 'b', 'c', 'd', 'e'))
for x in circ:
print(x)
if __name__ == '__main__':
import sys
argv = sys.argv
#_testInternalIndex(argv)
#_testIter(argv)
_testCircular(argv)