mirror of
				https://github.com/donnemartin/system-design-primer.git
				synced 2025-11-04 10:12:32 +03:00 
			
		
		
		
	added some edge cases and dunder methods
This commit is contained in:
		@@ -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 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 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 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) |
 | 
					| Add an object-oriented design question | [Contribute](#contributing) |
 | 
				
			||||||
 | 
					
 | 
				
			||||||
## System design topics: start here
 | 
					## System design topics: start here
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -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
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
		Reference in New Issue
	
	Block a user