That's my implementation of the dynamic array in python with types:
import ctypes
class DynamicArray:
def __init__(self,):
self.n = 0 # the current number of elements added to the array
self.capacity = 1 # Initial capacity of the dynamic array is one
self.array = self.make_array(self.capacity)
def add_element(self,element):
# First check whether the array is full or not
if self.n == self.capacity:
self.resize(2*self.capacity)
self.array[self.n] = element
self.n +=1
return
def resize(self,new_capacity):
new_array = self.make_array(new_capacity)
for i in range(self.n):
new_array[i] = self.array[i]
self.array = new_array
self.capacity = new_capacity
return
def make_array(self,capacity):
return (capacity * ctypes.py_object)()
def get_array(self):
return list(self.array)
After running the following test cases:
dynamic_r = DynamicArray()
dynamic_r.add_element(4)
dynamic_r.get_array()
dynamic_r.add_element(9)
dynamic_r.get_array()
dynamic_r.add_element(10)
dynamic_r.get_array()
I get this
ValueError: PyObject is NULL
It should be noted that I don't get this error every time I run the code
At the point of failure in your test case, self.capacity == 4
but self.n == 3
. list(self.array)
converts all the elements to a list, but only the first n
elements are initialized. Use list(self.array[:self.n])
to only convert the initialized elements.
By the way, ctypes.py_object()
doesn't need to be used. You could use
def make_array(self,capacity):
return [None] * capacity
or perhaps a special sentinal object like:
class Empty:
def __repr__(self):
return '<empty>'
and then:
def make_array(self,capacity):
return [Empty()] * capacity
If you print the result of dynamic_r.get_array())
, you'll see the uninitialized element as None
or <empty>
and catch the error that way:
[4]
[4, 9]
[4, 9, 10, <empty>]