system-design-primer/solutions/object_oriented_design/circular_array/Circular array.ipynb

106 lines
3.2 KiB
Python
Raw Blame History

This file contains invisible Unicode characters!

This file contains invisible Unicode characters that may be processed differently from what appears below. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to reveal hidden characters.

{
"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
}