added some edge cases and dunder methods

pull/178/head
Bertalan Körmendy 2018-07-19 15:43:40 +02:00
parent cda699ef9f
commit fc9de925a1
2 changed files with 129 additions and 1 deletions

View File

@ -362,7 +362,7 @@ Check out the following links to get a better idea of what to expect:
| Design a deck of cards | [Solution](solutions/object_oriented_design/deck_of_cards/deck_of_cards.ipynb) |
| Design a parking lot | [Solution](solutions/object_oriented_design/parking_lot/parking_lot.ipynb) |
| Design a chat server | [Solution](solutions/object_oriented_design/online_chat/online_chat.ipynb) |
| Design a circular array | [Contribute](#contributing) |
| Design a circular array | [Solution](solutions/object_oriented_design/circular_array/circular_array.ipynb) |
| Add an object-oriented design question | [Contribute](#contributing) |
## System design topics: start here

View File

@ -0,0 +1,128 @@
{
"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"
]
},
{
"cell_type": "code",
"execution_count": 131,
"metadata": {
"collapsed": false
},
"outputs": [],
"source": [
"class CircularArray:\n",
" \"\"\"\n",
" Python class implementing a circular array.\n",
" Credits to Sarath S. Pillai for some edge cases (https://github.com/sarathsp06)\n",
" \"\"\"\n",
" def __init__(self, size):\n",
" \"\"\"\n",
" Constructor. Refer to `full()` for explanation for `size+1`.\n",
" \"\"\"\n",
" if (size < 0):\n",
" raise RuntimeError(\"Invalid size (smaller than zero)\")\n",
" self._size = size + 1\n",
" self._items = [None for _ in range(self._size)]\n",
" self._read = 0 # read pointer (head of list)\n",
" self._write = 0 # write pointer (tail of list)\n",
" \n",
" def __len__(self):\n",
" '''\n",
" Returns how many elements are in the array.\n",
" '''\n",
" return (self._write - self._read) % (self._size - 1)\n",
" \n",
" def __getitem__(self, index):\n",
" if index < 0:\n",
" raise IndexError(\"Key must be a positive interger\")\n",
" if index > len(self):\n",
" raise IndexError(\"Index out of range\")\n",
" return self._items[((self._read + key) % self._size)]\n",
" \n",
" def __repr__(self):\n",
" if self.empty:\n",
" return \"<CircularArray []>\"\n",
" if self._read < self._write:\n",
" return \"<CircularArray {}>\".format(self._items[self._read:self._write])\n",
" return \"<CircularArray {}>\".format(self._items[self._read:] + self._items[:self._write])\n",
" \n",
" @property\n",
" def capacity(self):\n",
" return self._size - 1\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",
" Returns 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
}