Imagine a row of numbered drawers. An array works much like that row: each element has a position called an index, and you use the index to reach the element. Unlike a separate variable for every drawer, an array lets a program choose which element to access while it runs. section 2.1 section 2.2
In Python, indexes start at 0. For an array of size n, the last valid index is n-1; index n is out of bounds. Not every language starts at 0, so check the convention before translating a real-world position into an array index. Equal-sized elements also let a static array compute an element’s memory location from its index. section 2.4
Count die rolls
Use six counters, all initialized to 0, for die results 1 through 6. A roll of 4 increments counters[3]. In general, a roll of k increments counters[k-1]: the result starts at 1, but its array position starts at 0. To find the most frequent result, traverse the counters and keep the index of the largest value seen so far. section 2.16
Indexes also matter when an array grows. If k entries are in use, the next entry goes at index k—but only if capacity remains. Otherwise, insertion must report that the array is full. Searching a collection can work the other way around: find an entry first, then use its index to locate the position to free. section 2.11 section 2.17
Direct access by index is a strength of arrays. Binary search relies on reaching a middle element in constant time; a linked list must traverse preceding elements to reach it. Indexes can also describe relationships: in an array-backed heap, a node at index i has children at 2*i+1 and 2*i+2, when those children exist. section 6.13 section 10.15
def insert(self, new_entry):
if self._size >= len(self._array):
raise ValueError('The array is already full')
else:
self._array[self._size] = new_entry
self._size += 1
The insertion method shows how the current size supplies the next index, while a capacity check prevents an out-of-bounds write. section 2.11














