added circular array implementation in Python

pull/178/head
Bertalan Körmendy 2018-07-18 11:34:11 +02:00
parent 17530912ac
commit cda699ef9f
3 changed files with 156 additions and 0 deletions

View File

@ -0,0 +1,105 @@
{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Constraints and Assumptions\n",
"> Can we assume the list fits in memory?\n",
"\n",
"Yes\n",
"\n",
"> Do we have to worry about load factors?\n",
"\n",
"No\n",
"\n",
"> Can we assume inputs are valid or do we have to validate them?\n",
"\n",
"Assume they are valid"
]
},
{
"cell_type": "code",
"execution_count": 1,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"class CircularArray:\n",
" \"\"\"\n",
" Python class implementing a circular array.\n",
" \"\"\"\n",
" def __init__(self, size):\n",
" \"\"\"\n",
" Constructor. Refer to `full()` for explanation for `size+1`.\n",
" \"\"\"\n",
" self._size = size + 1\n",
" self._items = [None for _ in range(self._size)]\n",
" self._read = 0 # read pointer\n",
" self._write = 0 # write pointer\n",
" \n",
" @property\n",
" def empty(self):\n",
" \"\"\"\n",
" Returns whether the queue is empty.\n",
" \"\"\"\n",
" return self._read == self._write\n",
" \n",
" @property\n",
" def full(self):\n",
" \"\"\"\n",
" Return wheter the queue is full.\n",
" In a naive implementation, full and empty are both indicated by read == write, which introduces an\n",
" ambiguity. Thus, to break this, a circular array is assumed to be full if the write pointer is one\n",
" position behind the read pointer. To preserve the inituitiveness of the class interface, the internal\n",
" size property is incremented by 1, a sentinel element (so this way the user won't be surprised that their\n",
" array that supposedly fits 10 elements only accomodates 9).\n",
" \"\"\"\n",
" return self._read == (self._write + 1) % self._size\n",
" \n",
" def queue(self, item):\n",
" \"\"\"\n",
" Enqueues an item in the circular buffer.\n",
" \"\"\"\n",
" if self.full:\n",
" raise BufferError('Queue is full')\n",
" self._items[self._write] = item\n",
" self._write = (self._write + 1) % self._size\n",
" \n",
" def dequeue(self):\n",
" \"\"\"\n",
" Dequeues an item from the buffer.\n",
" \"\"\"\n",
" if self.empty:\n",
" raise BufferError('Queue is empty')\n",
" item = self._items[self._read]\n",
" self._items[self._read] = None\n",
" self._read = (self._read + 1) % self._size\n",
" return item"
]
}
],
"metadata": {
"anaconda-cloud": {},
"kernelspec": {
"display_name": "Python [py35]",
"language": "python",
"name": "Python [py35]"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.5.1"
}
},
"nbformat": 4,
"nbformat_minor": 0
}

View File

@ -0,0 +1,51 @@
class CircularArray:
"""
Python class implementing a circular array.
"""
def __init__(self, size):
"""
Constructor. Refer to `full()` for explanation for `size+1`.
"""
self._size = size + 1
self._items = [None for _ in range(self._size)]
self._read = 0 # read pointer
self._write = 0 # write pointer
@property
def empty(self):
"""
Returns whether the queue is empty.
"""
return self._read == self._write
@property
def full(self):
"""
Return wheter the queue is full.
In a naive implementation, full and empty are both indicated by read == write, which introduces an
ambiguity. Thus, to break this, a circular array is assumed to be full if the write pointer is one
position behind the read pointer. To preserve the inituitiveness of the class interface, the internal
size property is incremented by 1, a sentinel element (so this way the user won't be surprised that their
array that supposedly fits 10 elements only accomodates 9).
"""
return self._read == (self._write + 1) % self._size
def queue(self, item):
"""
Enqueues an item in the circular buffer.
"""
if self.full:
raise BufferError('Queue is full')
self._items[self._write] = item
self._write = (self._write + 1) % self._size
def dequeue(self):
"""
Dequeues an item from the buffer.
"""
if self.empty:
raise BufferError('Queue is empty')
item = self._items[self._read]
self._items[self._read] = None
self._read = (self._read + 1) % self._size
return item