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