mirror of
https://github.com/donnemartin/system-design-primer.git
synced 2025-09-17 09:30:39 +03:00
poriting to noat.cards
This commit is contained in:
@@ -4,7 +4,7 @@
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"This notebook was prepared by [Donne Martin](https://github.com/donnemartin). Source and license info is on [GitHub](https://github.com/donnemartin/system-design-primer)."
|
||||
"This notebook was prepared by [Donne Martin](https://github.com/donnemartin) . Source and license info is on [GitHub](https://github.com/donnemartin/system-design-primer) ."
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -67,118 +67,118 @@
|
||||
"from enum import Enum\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"class Rank(Enum):\n",
|
||||
"class Rank(Enum) :\n",
|
||||
"\n",
|
||||
" OPERATOR = 0\n",
|
||||
" SUPERVISOR = 1\n",
|
||||
" DIRECTOR = 2\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"class Employee(metaclass=ABCMeta):\n",
|
||||
"class Employee(metaclass=ABCMeta) :\n",
|
||||
"\n",
|
||||
" def __init__(self, employee_id, name, rank, call_center):\n",
|
||||
" def __init__(self, employee_id, name, rank, call_center) :\n",
|
||||
" self.employee_id = employee_id\n",
|
||||
" self.name = name\n",
|
||||
" self.rank = rank\n",
|
||||
" self.call = None\n",
|
||||
" self.call_center = call_center\n",
|
||||
"\n",
|
||||
" def take_call(self, call):\n",
|
||||
" def take_call(self, call) :\n",
|
||||
" \"\"\"Assume the employee will always successfully take the call.\"\"\"\n",
|
||||
" self.call = call\n",
|
||||
" self.call.employee = self\n",
|
||||
" self.call.state = CallState.IN_PROGRESS\n",
|
||||
"\n",
|
||||
" def complete_call(self):\n",
|
||||
" def complete_call(self) :\n",
|
||||
" self.call.state = CallState.COMPLETE\n",
|
||||
" self.call_center.notify_call_completed(self.call)\n",
|
||||
" self.call_center.notify_call_completed(self.call) \n",
|
||||
"\n",
|
||||
" @abstractmethod\n",
|
||||
" def escalate_call(self):\n",
|
||||
" def escalate_call(self) :\n",
|
||||
" pass\n",
|
||||
"\n",
|
||||
" def _escalate_call(self):\n",
|
||||
" def _escalate_call(self) :\n",
|
||||
" self.call.state = CallState.READY\n",
|
||||
" call = self.call\n",
|
||||
" self.call = None\n",
|
||||
" self.call_center.notify_call_escalated(call)\n",
|
||||
" self.call_center.notify_call_escalated(call) \n",
|
||||
"\n",
|
||||
"\n",
|
||||
"class Operator(Employee):\n",
|
||||
"class Operator(Employee) :\n",
|
||||
"\n",
|
||||
" def __init__(self, employee_id, name):\n",
|
||||
" super(Operator, self).__init__(employee_id, name, Rank.OPERATOR)\n",
|
||||
" def __init__(self, employee_id, name) :\n",
|
||||
" super(Operator, self) .__init__(employee_id, name, Rank.OPERATOR) \n",
|
||||
"\n",
|
||||
" def escalate_call(self):\n",
|
||||
" def escalate_call(self) :\n",
|
||||
" self.call.level = Rank.SUPERVISOR\n",
|
||||
" self._escalate_call()\n",
|
||||
" self._escalate_call() \n",
|
||||
"\n",
|
||||
"\n",
|
||||
"class Supervisor(Employee):\n",
|
||||
"class Supervisor(Employee) :\n",
|
||||
"\n",
|
||||
" def __init__(self, employee_id, name):\n",
|
||||
" super(Operator, self).__init__(employee_id, name, Rank.SUPERVISOR)\n",
|
||||
" def __init__(self, employee_id, name) :\n",
|
||||
" super(Operator, self) .__init__(employee_id, name, Rank.SUPERVISOR) \n",
|
||||
"\n",
|
||||
" def escalate_call(self):\n",
|
||||
" def escalate_call(self) :\n",
|
||||
" self.call.level = Rank.DIRECTOR\n",
|
||||
" self._escalate_call()\n",
|
||||
" self._escalate_call() \n",
|
||||
"\n",
|
||||
"\n",
|
||||
"class Director(Employee):\n",
|
||||
"class Director(Employee) :\n",
|
||||
"\n",
|
||||
" def __init__(self, employee_id, name):\n",
|
||||
" super(Operator, self).__init__(employee_id, name, Rank.DIRECTOR)\n",
|
||||
" def __init__(self, employee_id, name) :\n",
|
||||
" super(Operator, self) .__init__(employee_id, name, Rank.DIRECTOR) \n",
|
||||
"\n",
|
||||
" def escalate_call(self):\n",
|
||||
" raise NotImplemented('Directors must be able to handle any call')\n",
|
||||
" def escalate_call(self) :\n",
|
||||
" raise NotImplemented('Directors must be able to handle any call') \n",
|
||||
"\n",
|
||||
"\n",
|
||||
"class CallState(Enum):\n",
|
||||
"class CallState(Enum) :\n",
|
||||
"\n",
|
||||
" READY = 0\n",
|
||||
" IN_PROGRESS = 1\n",
|
||||
" COMPLETE = 2\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"class Call(object):\n",
|
||||
"class Call(object) :\n",
|
||||
"\n",
|
||||
" def __init__(self, rank):\n",
|
||||
" def __init__(self, rank) :\n",
|
||||
" self.state = CallState.READY\n",
|
||||
" self.rank = rank\n",
|
||||
" self.employee = None\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"class CallCenter(object):\n",
|
||||
"class CallCenter(object) :\n",
|
||||
"\n",
|
||||
" def __init__(self, operators, supervisors, directors):\n",
|
||||
" def __init__(self, operators, supervisors, directors) :\n",
|
||||
" self.operators = operators\n",
|
||||
" self.supervisors = supervisors\n",
|
||||
" self.directors = directors\n",
|
||||
" self.queued_calls = deque()\n",
|
||||
" self.queued_calls = deque() \n",
|
||||
"\n",
|
||||
" def dispatch_call(self, call):\n",
|
||||
" if call.rank not in (Rank.OPERATOR, Rank.SUPERVISOR, Rank.DIRECTOR):\n",
|
||||
" def dispatch_call(self, call) :\n",
|
||||
" if call.rank not in (Rank.OPERATOR, Rank.SUPERVISOR, Rank.DIRECTOR) :\n",
|
||||
" raise ValueError('Invalid call rank: {}'.format(call.rank))\n",
|
||||
" employee = None\n",
|
||||
" if call.rank == Rank.OPERATOR:\n",
|
||||
" employee = self._dispatch_call(call, self.operators)\n",
|
||||
" employee = self._dispatch_call(call, self.operators) \n",
|
||||
" if call.rank == Rank.SUPERVISOR or employee is None:\n",
|
||||
" employee = self._dispatch_call(call, self.supervisors)\n",
|
||||
" employee = self._dispatch_call(call, self.supervisors) \n",
|
||||
" if call.rank == Rank.DIRECTOR or employee is None:\n",
|
||||
" employee = self._dispatch_call(call, self.directors)\n",
|
||||
" employee = self._dispatch_call(call, self.directors) \n",
|
||||
" if employee is None:\n",
|
||||
" self.queued_calls.append(call)\n",
|
||||
" self.queued_calls.append(call) \n",
|
||||
"\n",
|
||||
" def _dispatch_call(self, call, employees):\n",
|
||||
" def _dispatch_call(self, call, employees) :\n",
|
||||
" for employee in employees:\n",
|
||||
" if employee.call is None:\n",
|
||||
" employee.take_call(call)\n",
|
||||
" employee.take_call(call) \n",
|
||||
" return employee\n",
|
||||
" return None\n",
|
||||
"\n",
|
||||
" def notify_call_escalated(self, call): # ...\n",
|
||||
" def notify_call_completed(self, call): # ...\n",
|
||||
" def dispatch_queued_call_to_newly_freed_employee(self, call, employee): # ..."
|
||||
" def notify_call_escalated(self, call) : # ...\n",
|
||||
" def notify_call_completed(self, call) : # ...\n",
|
||||
" def dispatch_queued_call_to_newly_freed_employee(self, call, employee) : # ..."
|
||||
]
|
||||
}
|
||||
],
|
||||
|
@@ -3,120 +3,120 @@ from collections import deque
|
||||
from enum import Enum
|
||||
|
||||
|
||||
class Rank(Enum):
|
||||
class Rank(Enum) :
|
||||
|
||||
OPERATOR = 0
|
||||
SUPERVISOR = 1
|
||||
DIRECTOR = 2
|
||||
|
||||
|
||||
class Employee(metaclass=ABCMeta):
|
||||
class Employee(metaclass=ABCMeta) :
|
||||
|
||||
def __init__(self, employee_id, name, rank, call_center):
|
||||
def __init__(self, employee_id, name, rank, call_center) :
|
||||
self.employee_id = employee_id
|
||||
self.name = name
|
||||
self.rank = rank
|
||||
self.call = None
|
||||
self.call_center = call_center
|
||||
|
||||
def take_call(self, call):
|
||||
def take_call(self, call) :
|
||||
"""Assume the employee will always successfully take the call."""
|
||||
self.call = call
|
||||
self.call.employee = self
|
||||
self.call.state = CallState.IN_PROGRESS
|
||||
|
||||
def complete_call(self):
|
||||
def complete_call(self) :
|
||||
self.call.state = CallState.COMPLETE
|
||||
self.call_center.notify_call_completed(self.call)
|
||||
self.call_center.notify_call_completed(self.call)
|
||||
|
||||
@abstractmethod
|
||||
def escalate_call(self):
|
||||
def escalate_call(self) :
|
||||
pass
|
||||
|
||||
def _escalate_call(self):
|
||||
def _escalate_call(self) :
|
||||
self.call.state = CallState.READY
|
||||
call = self.call
|
||||
self.call = None
|
||||
self.call_center.notify_call_escalated(call)
|
||||
self.call_center.notify_call_escalated(call)
|
||||
|
||||
|
||||
class Operator(Employee):
|
||||
class Operator(Employee) :
|
||||
|
||||
def __init__(self, employee_id, name):
|
||||
super(Operator, self).__init__(employee_id, name, Rank.OPERATOR)
|
||||
def __init__(self, employee_id, name) :
|
||||
super(Operator, self) .__init__(employee_id, name, Rank.OPERATOR)
|
||||
|
||||
def escalate_call(self):
|
||||
def escalate_call(self) :
|
||||
self.call.level = Rank.SUPERVISOR
|
||||
self._escalate_call()
|
||||
self._escalate_call()
|
||||
|
||||
|
||||
class Supervisor(Employee):
|
||||
class Supervisor(Employee) :
|
||||
|
||||
def __init__(self, employee_id, name):
|
||||
super(Operator, self).__init__(employee_id, name, Rank.SUPERVISOR)
|
||||
def __init__(self, employee_id, name) :
|
||||
super(Operator, self) .__init__(employee_id, name, Rank.SUPERVISOR)
|
||||
|
||||
def escalate_call(self):
|
||||
def escalate_call(self) :
|
||||
self.call.level = Rank.DIRECTOR
|
||||
self._escalate_call()
|
||||
self._escalate_call()
|
||||
|
||||
|
||||
class Director(Employee):
|
||||
class Director(Employee) :
|
||||
|
||||
def __init__(self, employee_id, name):
|
||||
super(Operator, self).__init__(employee_id, name, Rank.DIRECTOR)
|
||||
def __init__(self, employee_id, name) :
|
||||
super(Operator, self) .__init__(employee_id, name, Rank.DIRECTOR)
|
||||
|
||||
def escalate_call(self):
|
||||
raise NotImplementedError('Directors must be able to handle any call')
|
||||
def escalate_call(self) :
|
||||
raise NotImplementedError('Directors must be able to handle any call')
|
||||
|
||||
|
||||
class CallState(Enum):
|
||||
class CallState(Enum) :
|
||||
|
||||
READY = 0
|
||||
IN_PROGRESS = 1
|
||||
COMPLETE = 2
|
||||
|
||||
|
||||
class Call(object):
|
||||
class Call(object) :
|
||||
|
||||
def __init__(self, rank):
|
||||
def __init__(self, rank) :
|
||||
self.state = CallState.READY
|
||||
self.rank = rank
|
||||
self.employee = None
|
||||
|
||||
|
||||
class CallCenter(object):
|
||||
class CallCenter(object) :
|
||||
|
||||
def __init__(self, operators, supervisors, directors):
|
||||
def __init__(self, operators, supervisors, directors) :
|
||||
self.operators = operators
|
||||
self.supervisors = supervisors
|
||||
self.directors = directors
|
||||
self.queued_calls = deque()
|
||||
self.queued_calls = deque()
|
||||
|
||||
def dispatch_call(self, call):
|
||||
if call.rank not in (Rank.OPERATOR, Rank.SUPERVISOR, Rank.DIRECTOR):
|
||||
def dispatch_call(self, call) :
|
||||
if call.rank not in (Rank.OPERATOR, Rank.SUPERVISOR, Rank.DIRECTOR) :
|
||||
raise ValueError('Invalid call rank: {}'.format(call.rank))
|
||||
employee = None
|
||||
if call.rank == Rank.OPERATOR:
|
||||
employee = self._dispatch_call(call, self.operators)
|
||||
employee = self._dispatch_call(call, self.operators)
|
||||
if call.rank == Rank.SUPERVISOR or employee is None:
|
||||
employee = self._dispatch_call(call, self.supervisors)
|
||||
employee = self._dispatch_call(call, self.supervisors)
|
||||
if call.rank == Rank.DIRECTOR or employee is None:
|
||||
employee = self._dispatch_call(call, self.directors)
|
||||
employee = self._dispatch_call(call, self.directors)
|
||||
if employee is None:
|
||||
self.queued_calls.append(call)
|
||||
self.queued_calls.append(call)
|
||||
|
||||
def _dispatch_call(self, call, employees):
|
||||
def _dispatch_call(self, call, employees) :
|
||||
for employee in employees:
|
||||
if employee.call is None:
|
||||
employee.take_call(call)
|
||||
employee.take_call(call)
|
||||
return employee
|
||||
return None
|
||||
|
||||
def notify_call_escalated(self, call):
|
||||
def notify_call_escalated(self, call) :
|
||||
pass
|
||||
|
||||
def notify_call_completed(self, call):
|
||||
def notify_call_completed(self, call) :
|
||||
pass
|
||||
|
||||
def dispatch_queued_call_to_newly_freed_employee(self, call, employee):
|
||||
def dispatch_queued_call_to_newly_freed_employee(self, call, employee) :
|
||||
pass
|
||||
|
@@ -4,7 +4,7 @@
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"This notebook was prepared by [Donne Martin](https://github.com/donnemartin). Source and license info is on [GitHub](https://github.com/donnemartin/system-design-primer)."
|
||||
"This notebook was prepared by [Donne Martin](https://github.com/donnemartin) . Source and license info is on [GitHub](https://github.com/donnemartin/system-design-primer) ."
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -57,7 +57,7 @@
|
||||
"import sys\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"class Suit(Enum):\n",
|
||||
"class Suit(Enum) :\n",
|
||||
"\n",
|
||||
" HEART = 0\n",
|
||||
" DIAMOND = 1\n",
|
||||
@@ -65,100 +65,100 @@
|
||||
" SPADE = 3\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"class Card(metaclass=ABCMeta):\n",
|
||||
"class Card(metaclass=ABCMeta) :\n",
|
||||
"\n",
|
||||
" def __init__(self, value, suit):\n",
|
||||
" def __init__(self, value, suit) :\n",
|
||||
" self.value = value\n",
|
||||
" self.suit = suit\n",
|
||||
" self.is_available = True\n",
|
||||
"\n",
|
||||
" @property\n",
|
||||
" @abstractmethod\n",
|
||||
" def value(self):\n",
|
||||
" def value(self) :\n",
|
||||
" pass\n",
|
||||
"\n",
|
||||
" @value.setter\n",
|
||||
" @abstractmethod\n",
|
||||
" def value(self, other):\n",
|
||||
" def value(self, other) :\n",
|
||||
" pass\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"class BlackJackCard(Card):\n",
|
||||
"class BlackJackCard(Card) :\n",
|
||||
"\n",
|
||||
" def __init__(self, value, suit):\n",
|
||||
" super(BlackJackCard, self).__init__(value, suit)\n",
|
||||
" def __init__(self, value, suit) :\n",
|
||||
" super(BlackJackCard, self) .__init__(value, suit) \n",
|
||||
"\n",
|
||||
" def is_ace(self):\n",
|
||||
" def is_ace(self) :\n",
|
||||
" return self._value == 1\n",
|
||||
"\n",
|
||||
" def is_face_card(self):\n",
|
||||
" def is_face_card(self) :\n",
|
||||
" \"\"\"Jack = 11, Queen = 12, King = 13\"\"\"\n",
|
||||
" return 10 < self._value <= 13\n",
|
||||
"\n",
|
||||
" @property\n",
|
||||
" def value(self):\n",
|
||||
" def value(self) :\n",
|
||||
" if self.is_ace() == 1:\n",
|
||||
" return 1\n",
|
||||
" elif self.is_face_card():\n",
|
||||
" elif self.is_face_card() :\n",
|
||||
" return 10\n",
|
||||
" else:\n",
|
||||
" return self._value\n",
|
||||
"\n",
|
||||
" @value.setter\n",
|
||||
" def value(self, new_value):\n",
|
||||
" def value(self, new_value) :\n",
|
||||
" if 1 <= new_value <= 13:\n",
|
||||
" self._value = new_value\n",
|
||||
" else:\n",
|
||||
" raise ValueError('Invalid card value: {}'.format(new_value))\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"class Hand(object):\n",
|
||||
"class Hand(object) :\n",
|
||||
"\n",
|
||||
" def __init__(self, cards):\n",
|
||||
" def __init__(self, cards) :\n",
|
||||
" self.cards = cards\n",
|
||||
"\n",
|
||||
" def add_card(self, card):\n",
|
||||
" self.cards.append(card)\n",
|
||||
" def add_card(self, card) :\n",
|
||||
" self.cards.append(card) \n",
|
||||
"\n",
|
||||
" def score(self):\n",
|
||||
" def score(self) :\n",
|
||||
" total_value = 0\n",
|
||||
" for card in self.cards:\n",
|
||||
" total_value += card.value\n",
|
||||
" return total_value\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"class BlackJackHand(Hand):\n",
|
||||
"class BlackJackHand(Hand) :\n",
|
||||
"\n",
|
||||
" BLACKJACK = 21\n",
|
||||
"\n",
|
||||
" def __init__(self, cards):\n",
|
||||
" super(BlackJackHand, self).__init__(cards)\n",
|
||||
" def __init__(self, cards) :\n",
|
||||
" super(BlackJackHand, self) .__init__(cards) \n",
|
||||
"\n",
|
||||
" def score(self):\n",
|
||||
" def score(self) :\n",
|
||||
" min_over = sys.MAXSIZE\n",
|
||||
" max_under = -sys.MAXSIZE\n",
|
||||
" for score in self.possible_scores():\n",
|
||||
" for score in self.possible_scores() :\n",
|
||||
" if self.BLACKJACK < score < min_over:\n",
|
||||
" min_over = score\n",
|
||||
" elif max_under < score <= self.BLACKJACK:\n",
|
||||
" max_under = score\n",
|
||||
" return max_under if max_under != -sys.MAXSIZE else min_over\n",
|
||||
"\n",
|
||||
" def possible_scores(self):\n",
|
||||
" def possible_scores(self) :\n",
|
||||
" \"\"\"Return a list of possible scores, taking Aces into account.\"\"\"\n",
|
||||
" # ...\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"class Deck(object):\n",
|
||||
"class Deck(object) :\n",
|
||||
"\n",
|
||||
" def __init__(self, cards):\n",
|
||||
" def __init__(self, cards) :\n",
|
||||
" self.cards = cards\n",
|
||||
" self.deal_index = 0\n",
|
||||
"\n",
|
||||
" def remaining_cards(self):\n",
|
||||
" def remaining_cards(self) :\n",
|
||||
" return len(self.cards) - deal_index\n",
|
||||
"\n",
|
||||
" def deal_card():\n",
|
||||
" def deal_card() :\n",
|
||||
" try:\n",
|
||||
" card = self.cards[self.deal_index]\n",
|
||||
" card.is_available = False\n",
|
||||
@@ -167,7 +167,7 @@
|
||||
" return None\n",
|
||||
" return card\n",
|
||||
"\n",
|
||||
" def shuffle(self): # ..."
|
||||
" def shuffle(self) : # ..."
|
||||
]
|
||||
}
|
||||
],
|
||||
|
@@ -3,7 +3,7 @@ from enum import Enum
|
||||
import sys
|
||||
|
||||
|
||||
class Suit(Enum):
|
||||
class Suit(Enum) :
|
||||
|
||||
HEART = 0
|
||||
DIAMOND = 1
|
||||
@@ -11,100 +11,100 @@ class Suit(Enum):
|
||||
SPADE = 3
|
||||
|
||||
|
||||
class Card(metaclass=ABCMeta):
|
||||
class Card(metaclass=ABCMeta) :
|
||||
|
||||
def __init__(self, value, suit):
|
||||
def __init__(self, value, suit) :
|
||||
self.value = value
|
||||
self.suit = suit
|
||||
self.is_available = True
|
||||
|
||||
@property
|
||||
@abstractmethod
|
||||
def value(self):
|
||||
def value(self) :
|
||||
pass
|
||||
|
||||
@value.setter
|
||||
@abstractmethod
|
||||
def value(self, other):
|
||||
def value(self, other) :
|
||||
pass
|
||||
|
||||
|
||||
class BlackJackCard(Card):
|
||||
class BlackJackCard(Card) :
|
||||
|
||||
def __init__(self, value, suit):
|
||||
super(BlackJackCard, self).__init__(value, suit)
|
||||
def __init__(self, value, suit) :
|
||||
super(BlackJackCard, self) .__init__(value, suit)
|
||||
|
||||
def is_ace(self):
|
||||
def is_ace(self) :
|
||||
return True if self._value == 1 else False
|
||||
|
||||
def is_face_card(self):
|
||||
def is_face_card(self) :
|
||||
"""Jack = 11, Queen = 12, King = 13"""
|
||||
return True if 10 < self._value <= 13 else False
|
||||
|
||||
@property
|
||||
def value(self):
|
||||
def value(self) :
|
||||
if self.is_ace() == 1:
|
||||
return 1
|
||||
elif self.is_face_card():
|
||||
elif self.is_face_card() :
|
||||
return 10
|
||||
else:
|
||||
return self._value
|
||||
|
||||
@value.setter
|
||||
def value(self, new_value):
|
||||
def value(self, new_value) :
|
||||
if 1 <= new_value <= 13:
|
||||
self._value = new_value
|
||||
else:
|
||||
raise ValueError('Invalid card value: {}'.format(new_value))
|
||||
|
||||
|
||||
class Hand(object):
|
||||
class Hand(object) :
|
||||
|
||||
def __init__(self, cards):
|
||||
def __init__(self, cards) :
|
||||
self.cards = cards
|
||||
|
||||
def add_card(self, card):
|
||||
self.cards.append(card)
|
||||
def add_card(self, card) :
|
||||
self.cards.append(card)
|
||||
|
||||
def score(self):
|
||||
def score(self) :
|
||||
total_value = 0
|
||||
for card in self.cards:
|
||||
total_value += card.value
|
||||
return total_value
|
||||
|
||||
|
||||
class BlackJackHand(Hand):
|
||||
class BlackJackHand(Hand) :
|
||||
|
||||
BLACKJACK = 21
|
||||
|
||||
def __init__(self, cards):
|
||||
super(BlackJackHand, self).__init__(cards)
|
||||
def __init__(self, cards) :
|
||||
super(BlackJackHand, self) .__init__(cards)
|
||||
|
||||
def score(self):
|
||||
def score(self) :
|
||||
min_over = sys.MAXSIZE
|
||||
max_under = -sys.MAXSIZE
|
||||
for score in self.possible_scores():
|
||||
for score in self.possible_scores() :
|
||||
if self.BLACKJACK < score < min_over:
|
||||
min_over = score
|
||||
elif max_under < score <= self.BLACKJACK:
|
||||
max_under = score
|
||||
return max_under if max_under != -sys.MAXSIZE else min_over
|
||||
|
||||
def possible_scores(self):
|
||||
def possible_scores(self) :
|
||||
"""Return a list of possible scores, taking Aces into account."""
|
||||
pass
|
||||
|
||||
|
||||
class Deck(object):
|
||||
class Deck(object) :
|
||||
|
||||
def __init__(self, cards):
|
||||
def __init__(self, cards) :
|
||||
self.cards = cards
|
||||
self.deal_index = 0
|
||||
|
||||
def remaining_cards(self):
|
||||
def remaining_cards(self) :
|
||||
return len(self.cards) - self.deal_index
|
||||
|
||||
def deal_card(self):
|
||||
def deal_card(self) :
|
||||
try:
|
||||
card = self.cards[self.deal_index]
|
||||
card.is_available = False
|
||||
@@ -113,5 +113,5 @@ class Deck(object):
|
||||
return None
|
||||
return card
|
||||
|
||||
def shuffle(self):
|
||||
def shuffle(self) :
|
||||
pass
|
||||
|
@@ -4,7 +4,7 @@
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"This notebook was prepared by [Donne Martin](https://github.com/donnemartin). Source and license info is on [GitHub](https://github.com/donnemartin/system-design-primer)."
|
||||
"This notebook was prepared by [Donne Martin](https://github.com/donnemartin) . Source and license info is on [GitHub](https://github.com/donnemartin/system-design-primer) ."
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -56,44 +56,44 @@
|
||||
],
|
||||
"source": [
|
||||
"%%writefile hash_map.py\n",
|
||||
"class Item(object):\n",
|
||||
"class Item(object) :\n",
|
||||
"\n",
|
||||
" def __init__(self, key, value):\n",
|
||||
" def __init__(self, key, value) :\n",
|
||||
" self.key = key\n",
|
||||
" self.value = value\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"class HashTable(object):\n",
|
||||
"class HashTable(object) :\n",
|
||||
"\n",
|
||||
" def __init__(self, size):\n",
|
||||
" def __init__(self, size) :\n",
|
||||
" self.size = size\n",
|
||||
" self.table = [[] for _ in range(self.size)]\n",
|
||||
" self.table = [[] for _ in range(self.size) ]\n",
|
||||
"\n",
|
||||
" def _hash_function(self, key):\n",
|
||||
" def _hash_function(self, key) :\n",
|
||||
" return key % self.size\n",
|
||||
"\n",
|
||||
" def set(self, key, value):\n",
|
||||
" hash_index = self._hash_function(key)\n",
|
||||
" def set(self, key, value) :\n",
|
||||
" hash_index = self._hash_function(key) \n",
|
||||
" for item in self.table[hash_index]:\n",
|
||||
" if item.key == key:\n",
|
||||
" item.value = value\n",
|
||||
" return\n",
|
||||
" self.table[hash_index].append(Item(key, value))\n",
|
||||
"\n",
|
||||
" def get(self, key):\n",
|
||||
" hash_index = self._hash_function(key)\n",
|
||||
" def get(self, key) :\n",
|
||||
" hash_index = self._hash_function(key) \n",
|
||||
" for item in self.table[hash_index]:\n",
|
||||
" if item.key == key:\n",
|
||||
" return item.value\n",
|
||||
" raise KeyError('Key not found')\n",
|
||||
" raise KeyError('Key not found') \n",
|
||||
"\n",
|
||||
" def remove(self, key):\n",
|
||||
" hash_index = self._hash_function(key)\n",
|
||||
" for index, item in enumerate(self.table[hash_index]):\n",
|
||||
" def remove(self, key) :\n",
|
||||
" hash_index = self._hash_function(key) \n",
|
||||
" for index, item in enumerate(self.table[hash_index]) :\n",
|
||||
" if item.key == key:\n",
|
||||
" del self.table[hash_index][index]\n",
|
||||
" return\n",
|
||||
" raise KeyError('Key not found')"
|
||||
" raise KeyError('Key not found') "
|
||||
]
|
||||
}
|
||||
],
|
||||
|
@@ -1,38 +1,38 @@
|
||||
class Item(object):
|
||||
class Item(object) :
|
||||
|
||||
def __init__(self, key, value):
|
||||
def __init__(self, key, value) :
|
||||
self.key = key
|
||||
self.value = value
|
||||
|
||||
|
||||
class HashTable(object):
|
||||
class HashTable(object) :
|
||||
|
||||
def __init__(self, size):
|
||||
def __init__(self, size) :
|
||||
self.size = size
|
||||
self.table = [[] for _ in range(self.size)]
|
||||
self.table = [[] for _ in range(self.size) ]
|
||||
|
||||
def _hash_function(self, key):
|
||||
def _hash_function(self, key) :
|
||||
return key % self.size
|
||||
|
||||
def set(self, key, value):
|
||||
hash_index = self._hash_function(key)
|
||||
def set(self, key, value) :
|
||||
hash_index = self._hash_function(key)
|
||||
for item in self.table[hash_index]:
|
||||
if item.key == key:
|
||||
item.value = value
|
||||
return
|
||||
self.table[hash_index].append(Item(key, value))
|
||||
|
||||
def get(self, key):
|
||||
hash_index = self._hash_function(key)
|
||||
def get(self, key) :
|
||||
hash_index = self._hash_function(key)
|
||||
for item in self.table[hash_index]:
|
||||
if item.key == key:
|
||||
return item.value
|
||||
raise KeyError('Key not found')
|
||||
raise KeyError('Key not found')
|
||||
|
||||
def remove(self, key):
|
||||
hash_index = self._hash_function(key)
|
||||
for index, item in enumerate(self.table[hash_index]):
|
||||
def remove(self, key) :
|
||||
hash_index = self._hash_function(key)
|
||||
for index, item in enumerate(self.table[hash_index]) :
|
||||
if item.key == key:
|
||||
del self.table[hash_index][index]
|
||||
return
|
||||
raise KeyError('Key not found')
|
||||
raise KeyError('Key not found')
|
||||
|
@@ -4,7 +4,7 @@
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"This notebook was prepared by [Donne Martin](https://github.com/donnemartin). Source and license info is on [GitHub](https://github.com/donnemartin/system-design-primer)."
|
||||
"This notebook was prepared by [Donne Martin](https://github.com/donnemartin) . Source and license info is on [GitHub](https://github.com/donnemartin/system-design-primer) ."
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -52,67 +52,67 @@
|
||||
],
|
||||
"source": [
|
||||
"%%writefile lru_cache.py\n",
|
||||
"class Node(object):\n",
|
||||
"class Node(object) :\n",
|
||||
"\n",
|
||||
" def __init__(self, results):\n",
|
||||
" def __init__(self, results) :\n",
|
||||
" self.results = results\n",
|
||||
" self.prev = None\n",
|
||||
" self.next = None\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"class LinkedList(object):\n",
|
||||
"class LinkedList(object) :\n",
|
||||
"\n",
|
||||
" def __init__(self):\n",
|
||||
" def __init__(self) :\n",
|
||||
" self.head = None\n",
|
||||
" self.tail = None\n",
|
||||
"\n",
|
||||
" def move_to_front(self, node): # ...\n",
|
||||
" def append_to_front(self, node): # ...\n",
|
||||
" def remove_from_tail(self): # ...\n",
|
||||
" def move_to_front(self, node) : # ...\n",
|
||||
" def append_to_front(self, node) : # ...\n",
|
||||
" def remove_from_tail(self) : # ...\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"class Cache(object):\n",
|
||||
"class Cache(object) :\n",
|
||||
"\n",
|
||||
" def __init__(self, MAX_SIZE):\n",
|
||||
" def __init__(self, MAX_SIZE) :\n",
|
||||
" self.MAX_SIZE = MAX_SIZE\n",
|
||||
" self.size = 0\n",
|
||||
" self.lookup = {} # key: query, value: node\n",
|
||||
" self.linked_list = LinkedList()\n",
|
||||
" self.linked_list = LinkedList() \n",
|
||||
"\n",
|
||||
" def get(self, query)\n",
|
||||
" def get(self, query) \n",
|
||||
" \"\"\"Get the stored query result from the cache.\n",
|
||||
" \n",
|
||||
" Accessing a node updates its position to the front of the LRU list.\n",
|
||||
" \"\"\"\n",
|
||||
" node = self.lookup.get(query)\n",
|
||||
" node = self.lookup.get(query) \n",
|
||||
" if node is None:\n",
|
||||
" return None\n",
|
||||
" self.linked_list.move_to_front(node)\n",
|
||||
" self.linked_list.move_to_front(node) \n",
|
||||
" return node.results\n",
|
||||
"\n",
|
||||
" def set(self, results, query):\n",
|
||||
" def set(self, results, query) :\n",
|
||||
" \"\"\"Set the result for the given query key in the cache.\n",
|
||||
" \n",
|
||||
" When updating an entry, updates its position to the front of the LRU list.\n",
|
||||
" If the entry is new and the cache is at capacity, removes the oldest entry\n",
|
||||
" before the new entry is added.\n",
|
||||
" \"\"\"\n",
|
||||
" node = self.lookup.get(query)\n",
|
||||
" node = self.lookup.get(query) \n",
|
||||
" if node is not None:\n",
|
||||
" # Key exists in cache, update the value\n",
|
||||
" node.results = results\n",
|
||||
" self.linked_list.move_to_front(node)\n",
|
||||
" self.linked_list.move_to_front(node) \n",
|
||||
" else:\n",
|
||||
" # Key does not exist in cache\n",
|
||||
" if self.size == self.MAX_SIZE:\n",
|
||||
" # Remove the oldest entry from the linked list and lookup\n",
|
||||
" self.lookup.pop(self.linked_list.tail.query, None)\n",
|
||||
" self.linked_list.remove_from_tail()\n",
|
||||
" self.lookup.pop(self.linked_list.tail.query, None) \n",
|
||||
" self.linked_list.remove_from_tail() \n",
|
||||
" else:\n",
|
||||
" self.size += 1\n",
|
||||
" # Add the new key and value\n",
|
||||
" new_node = Node(results)\n",
|
||||
" self.linked_list.append_to_front(new_node)\n",
|
||||
" new_node = Node(results) \n",
|
||||
" self.linked_list.append_to_front(new_node) \n",
|
||||
" self.lookup[query] = new_node"
|
||||
]
|
||||
}
|
||||
|
@@ -1,66 +1,66 @@
|
||||
class Node(object):
|
||||
class Node(object) :
|
||||
|
||||
def __init__(self, results):
|
||||
def __init__(self, results) :
|
||||
self.results = results
|
||||
self.next = next
|
||||
|
||||
|
||||
class LinkedList(object):
|
||||
class LinkedList(object) :
|
||||
|
||||
def __init__(self):
|
||||
def __init__(self) :
|
||||
self.head = None
|
||||
self.tail = None
|
||||
|
||||
def move_to_front(self, node):
|
||||
def move_to_front(self, node) :
|
||||
pass
|
||||
|
||||
def append_to_front(self, node):
|
||||
def append_to_front(self, node) :
|
||||
pass
|
||||
|
||||
def remove_from_tail(self):
|
||||
def remove_from_tail(self) :
|
||||
pass
|
||||
|
||||
|
||||
class Cache(object):
|
||||
class Cache(object) :
|
||||
|
||||
def __init__(self, MAX_SIZE):
|
||||
def __init__(self, MAX_SIZE) :
|
||||
self.MAX_SIZE = MAX_SIZE
|
||||
self.size = 0
|
||||
self.lookup = {} # key: query, value: node
|
||||
self.linked_list = LinkedList()
|
||||
self.linked_list = LinkedList()
|
||||
|
||||
def get(self, query):
|
||||
def get(self, query) :
|
||||
"""Get the stored query result from the cache.
|
||||
|
||||
Accessing a node updates its position to the front of the LRU list.
|
||||
"""
|
||||
node = self.lookup.get(query)
|
||||
node = self.lookup.get(query)
|
||||
if node is None:
|
||||
return None
|
||||
self.linked_list.move_to_front(node)
|
||||
self.linked_list.move_to_front(node)
|
||||
return node.results
|
||||
|
||||
def set(self, results, query):
|
||||
def set(self, results, query) :
|
||||
"""Set the result for the given query key in the cache.
|
||||
|
||||
When updating an entry, updates its position to the front of the LRU list.
|
||||
If the entry is new and the cache is at capacity, removes the oldest entry
|
||||
before the new entry is added.
|
||||
"""
|
||||
node = self.lookup.get(query)
|
||||
node = self.lookup.get(query)
|
||||
if node is not None:
|
||||
# Key exists in cache, update the value
|
||||
node.results = results
|
||||
self.linked_list.move_to_front(node)
|
||||
self.linked_list.move_to_front(node)
|
||||
else:
|
||||
# Key does not exist in cache
|
||||
if self.size == self.MAX_SIZE:
|
||||
# Remove the oldest entry from the linked list and lookup
|
||||
self.lookup.pop(self.linked_list.tail.query, None)
|
||||
self.linked_list.remove_from_tail()
|
||||
self.lookup.pop(self.linked_list.tail.query, None)
|
||||
self.linked_list.remove_from_tail()
|
||||
else:
|
||||
self.size += 1
|
||||
# Add the new key and value
|
||||
new_node = Node(results)
|
||||
self.linked_list.append_to_front(new_node)
|
||||
new_node = Node(results)
|
||||
self.linked_list.append_to_front(new_node)
|
||||
self.lookup[query] = new_node
|
||||
|
@@ -4,7 +4,7 @@
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"This notebook was prepared by [Donne Martin](https://github.com/donnemartin). Source and license info is on [GitHub](https://github.com/donnemartin/system-design-primer)."
|
||||
"This notebook was prepared by [Donne Martin](https://github.com/donnemartin) . Source and license info is on [GitHub](https://github.com/donnemartin/system-design-primer) ."
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -67,21 +67,21 @@
|
||||
"from abc import ABCMeta\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"class UserService(object):\n",
|
||||
"class UserService(object) :\n",
|
||||
"\n",
|
||||
" def __init__(self):\n",
|
||||
" def __init__(self) :\n",
|
||||
" self.users_by_id = {} # key: user id, value: User\n",
|
||||
"\n",
|
||||
" def add_user(self, user_id, name, pass_hash): # ...\n",
|
||||
" def remove_user(self, user_id): # ...\n",
|
||||
" def add_friend_request(self, from_user_id, to_user_id): # ...\n",
|
||||
" def approve_friend_request(self, from_user_id, to_user_id): # ...\n",
|
||||
" def reject_friend_request(self, from_user_id, to_user_id): # ...\n",
|
||||
" def add_user(self, user_id, name, pass_hash) : # ...\n",
|
||||
" def remove_user(self, user_id) : # ...\n",
|
||||
" def add_friend_request(self, from_user_id, to_user_id) : # ...\n",
|
||||
" def approve_friend_request(self, from_user_id, to_user_id) : # ...\n",
|
||||
" def reject_friend_request(self, from_user_id, to_user_id) : # ...\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"class User(object):\n",
|
||||
"class User(object) :\n",
|
||||
"\n",
|
||||
" def __init__(self, user_id, name, pass_hash):\n",
|
||||
" def __init__(self, user_id, name, pass_hash) :\n",
|
||||
" self.user_id = user_id\n",
|
||||
" self.name = name\n",
|
||||
" self.pass_hash = pass_hash\n",
|
||||
@@ -91,54 +91,54 @@
|
||||
" self.received_friend_requests_by_friend_id = {} # key: friend id, value: AddRequest\n",
|
||||
" self.sent_friend_requests_by_friend_id = {} # key: friend id, value: AddRequest\n",
|
||||
"\n",
|
||||
" def message_user(self, friend_id, message): # ...\n",
|
||||
" def message_group(self, group_id, message): # ...\n",
|
||||
" def send_friend_request(self, friend_id): # ...\n",
|
||||
" def receive_friend_request(self, friend_id): # ...\n",
|
||||
" def approve_friend_request(self, friend_id): # ...\n",
|
||||
" def reject_friend_request(self, friend_id): # ...\n",
|
||||
" def message_user(self, friend_id, message) : # ...\n",
|
||||
" def message_group(self, group_id, message) : # ...\n",
|
||||
" def send_friend_request(self, friend_id) : # ...\n",
|
||||
" def receive_friend_request(self, friend_id) : # ...\n",
|
||||
" def approve_friend_request(self, friend_id) : # ...\n",
|
||||
" def reject_friend_request(self, friend_id) : # ...\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"class Chat(metaclass=ABCMeta):\n",
|
||||
"class Chat(metaclass=ABCMeta) :\n",
|
||||
"\n",
|
||||
" def __init__(self, chat_id):\n",
|
||||
" def __init__(self, chat_id) :\n",
|
||||
" self.chat_id = chat_id\n",
|
||||
" self.users = []\n",
|
||||
" self.messages = []\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"class PrivateChat(Chat):\n",
|
||||
"class PrivateChat(Chat) :\n",
|
||||
"\n",
|
||||
" def __init__(self, first_user, second_user):\n",
|
||||
" super(PrivateChat, self).__init__()\n",
|
||||
" self.users.append(first_user)\n",
|
||||
" self.users.append(second_user)\n",
|
||||
" def __init__(self, first_user, second_user) :\n",
|
||||
" super(PrivateChat, self) .__init__() \n",
|
||||
" self.users.append(first_user) \n",
|
||||
" self.users.append(second_user) \n",
|
||||
"\n",
|
||||
"\n",
|
||||
"class GroupChat(Chat):\n",
|
||||
"class GroupChat(Chat) :\n",
|
||||
"\n",
|
||||
" def add_user(self, user): # ...\n",
|
||||
" def remove_user(self, user): # ... \n",
|
||||
" def add_user(self, user) : # ...\n",
|
||||
" def remove_user(self, user) : # ... \n",
|
||||
"\n",
|
||||
"\n",
|
||||
"class Message(object):\n",
|
||||
"class Message(object) :\n",
|
||||
"\n",
|
||||
" def __init__(self, message_id, message, timestamp):\n",
|
||||
" def __init__(self, message_id, message, timestamp) :\n",
|
||||
" self.message_id = message_id\n",
|
||||
" self.message = message\n",
|
||||
" self.timestamp = timestamp\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"class AddRequest(object):\n",
|
||||
"class AddRequest(object) :\n",
|
||||
"\n",
|
||||
" def __init__(self, from_user_id, to_user_id, request_status, timestamp):\n",
|
||||
" def __init__(self, from_user_id, to_user_id, request_status, timestamp) :\n",
|
||||
" self.from_user_id = from_user_id\n",
|
||||
" self.to_user_id = to_user_id\n",
|
||||
" self.request_status = request_status\n",
|
||||
" self.timestamp = timestamp\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"class RequestStatus(Enum):\n",
|
||||
"class RequestStatus(Enum) :\n",
|
||||
"\n",
|
||||
" UNREAD = 0\n",
|
||||
" READ = 1\n",
|
||||
|
@@ -2,30 +2,30 @@ from abc import ABCMeta
|
||||
from enum import Enum
|
||||
|
||||
|
||||
class UserService(object):
|
||||
class UserService(object) :
|
||||
|
||||
def __init__(self):
|
||||
def __init__(self) :
|
||||
self.users_by_id = {} # key: user id, value: User
|
||||
|
||||
def add_user(self, user_id, name, pass_hash):
|
||||
def add_user(self, user_id, name, pass_hash) :
|
||||
pass
|
||||
|
||||
def remove_user(self, user_id):
|
||||
def remove_user(self, user_id) :
|
||||
pass
|
||||
|
||||
def add_friend_request(self, from_user_id, to_user_id):
|
||||
def add_friend_request(self, from_user_id, to_user_id) :
|
||||
pass
|
||||
|
||||
def approve_friend_request(self, from_user_id, to_user_id):
|
||||
def approve_friend_request(self, from_user_id, to_user_id) :
|
||||
pass
|
||||
|
||||
def reject_friend_request(self, from_user_id, to_user_id):
|
||||
def reject_friend_request(self, from_user_id, to_user_id) :
|
||||
pass
|
||||
|
||||
|
||||
class User(object):
|
||||
class User(object) :
|
||||
|
||||
def __init__(self, user_id, name, pass_hash):
|
||||
def __init__(self, user_id, name, pass_hash) :
|
||||
self.user_id = user_id
|
||||
self.name = name
|
||||
self.pass_hash = pass_hash
|
||||
@@ -35,68 +35,68 @@ class User(object):
|
||||
self.received_friend_requests_by_friend_id = {} # key: friend id, value: AddRequest
|
||||
self.sent_friend_requests_by_friend_id = {} # key: friend id, value: AddRequest
|
||||
|
||||
def message_user(self, friend_id, message):
|
||||
def message_user(self, friend_id, message) :
|
||||
pass
|
||||
|
||||
def message_group(self, group_id, message):
|
||||
def message_group(self, group_id, message) :
|
||||
pass
|
||||
|
||||
def send_friend_request(self, friend_id):
|
||||
def send_friend_request(self, friend_id) :
|
||||
pass
|
||||
|
||||
def receive_friend_request(self, friend_id):
|
||||
def receive_friend_request(self, friend_id) :
|
||||
pass
|
||||
|
||||
def approve_friend_request(self, friend_id):
|
||||
def approve_friend_request(self, friend_id) :
|
||||
pass
|
||||
|
||||
def reject_friend_request(self, friend_id):
|
||||
def reject_friend_request(self, friend_id) :
|
||||
pass
|
||||
|
||||
|
||||
class Chat(metaclass=ABCMeta):
|
||||
class Chat(metaclass=ABCMeta) :
|
||||
|
||||
def __init__(self, chat_id):
|
||||
def __init__(self, chat_id) :
|
||||
self.chat_id = chat_id
|
||||
self.users = []
|
||||
self.messages = []
|
||||
|
||||
|
||||
class PrivateChat(Chat):
|
||||
class PrivateChat(Chat) :
|
||||
|
||||
def __init__(self, first_user, second_user):
|
||||
super(PrivateChat, self).__init__()
|
||||
self.users.append(first_user)
|
||||
self.users.append(second_user)
|
||||
def __init__(self, first_user, second_user) :
|
||||
super(PrivateChat, self) .__init__()
|
||||
self.users.append(first_user)
|
||||
self.users.append(second_user)
|
||||
|
||||
|
||||
class GroupChat(Chat):
|
||||
class GroupChat(Chat) :
|
||||
|
||||
def add_user(self, user):
|
||||
def add_user(self, user) :
|
||||
pass
|
||||
|
||||
def remove_user(self, user):
|
||||
def remove_user(self, user) :
|
||||
pass
|
||||
|
||||
|
||||
class Message(object):
|
||||
class Message(object) :
|
||||
|
||||
def __init__(self, message_id, message, timestamp):
|
||||
def __init__(self, message_id, message, timestamp) :
|
||||
self.message_id = message_id
|
||||
self.message = message
|
||||
self.timestamp = timestamp
|
||||
|
||||
|
||||
class AddRequest(object):
|
||||
class AddRequest(object) :
|
||||
|
||||
def __init__(self, from_user_id, to_user_id, request_status, timestamp):
|
||||
def __init__(self, from_user_id, to_user_id, request_status, timestamp) :
|
||||
self.from_user_id = from_user_id
|
||||
self.to_user_id = to_user_id
|
||||
self.request_status = request_status
|
||||
self.timestamp = timestamp
|
||||
|
||||
|
||||
class RequestStatus(Enum):
|
||||
class RequestStatus(Enum) :
|
||||
|
||||
UNREAD = 0
|
||||
READ = 1
|
||||
|
@@ -4,7 +4,7 @@
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"This notebook was prepared by [Donne Martin](https://github.com/donnemartin). Source and license info is on [GitHub](https://github.com/donnemartin/system-design-primer)."
|
||||
"This notebook was prepared by [Donne Martin](https://github.com/donnemartin) . Source and license info is on [GitHub](https://github.com/donnemartin/system-design-primer) ."
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -59,107 +59,107 @@
|
||||
"from abc import ABCMeta, abstractmethod\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"class VehicleSize(Enum):\n",
|
||||
"class VehicleSize(Enum) :\n",
|
||||
"\n",
|
||||
" MOTORCYCLE = 0\n",
|
||||
" COMPACT = 1\n",
|
||||
" LARGE = 2\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"class Vehicle(metaclass=ABCMeta):\n",
|
||||
"class Vehicle(metaclass=ABCMeta) :\n",
|
||||
"\n",
|
||||
" def __init__(self, vehicle_size, license_plate, spot_size):\n",
|
||||
" def __init__(self, vehicle_size, license_plate, spot_size) :\n",
|
||||
" self.vehicle_size = vehicle_size\n",
|
||||
" self.license_plate = license_plate\n",
|
||||
" self.spot_size = spot_size\n",
|
||||
" self.spots_taken = []\n",
|
||||
"\n",
|
||||
" def clear_spots(self):\n",
|
||||
" def clear_spots(self) :\n",
|
||||
" for spot in self.spots_taken:\n",
|
||||
" spot.remove_vehicle(self)\n",
|
||||
" spot.remove_vehicle(self) \n",
|
||||
" self.spots_taken = []\n",
|
||||
"\n",
|
||||
" def take_spot(self, spot):\n",
|
||||
" self.spots_taken.append(spot)\n",
|
||||
" def take_spot(self, spot) :\n",
|
||||
" self.spots_taken.append(spot) \n",
|
||||
"\n",
|
||||
" @abstractmethod\n",
|
||||
" def can_fit_in_spot(self, spot):\n",
|
||||
" def can_fit_in_spot(self, spot) :\n",
|
||||
" pass\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"class Motorcycle(Vehicle):\n",
|
||||
"class Motorcycle(Vehicle) :\n",
|
||||
"\n",
|
||||
" def __init__(self, license_plate):\n",
|
||||
" super(Motorcycle, self).__init__(VehicleSize.MOTORCYCLE, license_plate, spot_size=1)\n",
|
||||
" def __init__(self, license_plate) :\n",
|
||||
" super(Motorcycle, self) .__init__(VehicleSize.MOTORCYCLE, license_plate, spot_size=1) \n",
|
||||
"\n",
|
||||
" def can_fit_in_spot(self, spot):\n",
|
||||
" def can_fit_in_spot(self, spot) :\n",
|
||||
" return True\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"class Car(Vehicle):\n",
|
||||
"class Car(Vehicle) :\n",
|
||||
"\n",
|
||||
" def __init__(self, license_plate):\n",
|
||||
" super(Car, self).__init__(VehicleSize.COMPACT, license_plate, spot_size=1)\n",
|
||||
" def __init__(self, license_plate) :\n",
|
||||
" super(Car, self) .__init__(VehicleSize.COMPACT, license_plate, spot_size=1) \n",
|
||||
"\n",
|
||||
" def can_fit_in_spot(self, spot):\n",
|
||||
" def can_fit_in_spot(self, spot) :\n",
|
||||
" return True if (spot.size == LARGE or spot.size == COMPACT) else False\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"class Bus(Vehicle):\n",
|
||||
"class Bus(Vehicle) :\n",
|
||||
"\n",
|
||||
" def __init__(self, license_plate):\n",
|
||||
" super(Bus, self).__init__(VehicleSize.LARGE, license_plate, spot_size=5)\n",
|
||||
" def __init__(self, license_plate) :\n",
|
||||
" super(Bus, self) .__init__(VehicleSize.LARGE, license_plate, spot_size=5) \n",
|
||||
"\n",
|
||||
" def can_fit_in_spot(self, spot):\n",
|
||||
" def can_fit_in_spot(self, spot) :\n",
|
||||
" return True if spot.size == LARGE else False\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"class ParkingLot(object):\n",
|
||||
"class ParkingLot(object) :\n",
|
||||
"\n",
|
||||
" def __init__(self, num_levels):\n",
|
||||
" def __init__(self, num_levels) :\n",
|
||||
" self.num_levels = num_levels\n",
|
||||
" self.levels = []\n",
|
||||
"\n",
|
||||
" def park_vehicle(self, vehicle):\n",
|
||||
" def park_vehicle(self, vehicle) :\n",
|
||||
" for level in levels:\n",
|
||||
" if level.park_vehicle(vehicle):\n",
|
||||
" if level.park_vehicle(vehicle) :\n",
|
||||
" return True\n",
|
||||
" return False\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"class Level(object):\n",
|
||||
"class Level(object) :\n",
|
||||
"\n",
|
||||
" SPOTS_PER_ROW = 10\n",
|
||||
"\n",
|
||||
" def __init__(self, floor, total_spots):\n",
|
||||
" def __init__(self, floor, total_spots) :\n",
|
||||
" self.floor = floor\n",
|
||||
" self.num_spots = total_spots\n",
|
||||
" self.available_spots = 0\n",
|
||||
" self.parking_spots = []\n",
|
||||
"\n",
|
||||
" def spot_freed(self):\n",
|
||||
" def spot_freed(self) :\n",
|
||||
" self.available_spots += 1\n",
|
||||
"\n",
|
||||
" def park_vehicle(self, vehicle):\n",
|
||||
" spot = self._find_available_spot(vehicle)\n",
|
||||
" def park_vehicle(self, vehicle) :\n",
|
||||
" spot = self._find_available_spot(vehicle) \n",
|
||||
" if spot is None:\n",
|
||||
" return None\n",
|
||||
" else:\n",
|
||||
" spot.park_vehicle(vehicle)\n",
|
||||
" spot.park_vehicle(vehicle) \n",
|
||||
" return spot\n",
|
||||
"\n",
|
||||
" def _find_available_spot(self, vehicle):\n",
|
||||
" def _find_available_spot(self, vehicle) :\n",
|
||||
" \"\"\"Find an available spot where vehicle can fit, or return None\"\"\"\n",
|
||||
" # ...\n",
|
||||
"\n",
|
||||
" def _park_starting_at_spot(self, spot, vehicle):\n",
|
||||
" def _park_starting_at_spot(self, spot, vehicle) :\n",
|
||||
" \"\"\"Occupy starting at spot.spot_number to vehicle.spot_size.\"\"\"\n",
|
||||
" # ...\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"class ParkingSpot(object):\n",
|
||||
"class ParkingSpot(object) :\n",
|
||||
"\n",
|
||||
" def __init__(self, level, row, spot_number, spot_size, vehicle_size):\n",
|
||||
" def __init__(self, level, row, spot_number, spot_size, vehicle_size) :\n",
|
||||
" self.level = level\n",
|
||||
" self.row = row\n",
|
||||
" self.spot_number = spot_number\n",
|
||||
@@ -167,16 +167,16 @@
|
||||
" self.vehicle_size = vehicle_size\n",
|
||||
" self.vehicle = None\n",
|
||||
"\n",
|
||||
" def is_available(self):\n",
|
||||
" def is_available(self) :\n",
|
||||
" return True if self.vehicle is None else False\n",
|
||||
"\n",
|
||||
" def can_fit_vehicle(self, vehicle):\n",
|
||||
" def can_fit_vehicle(self, vehicle) :\n",
|
||||
" if self.vehicle is not None:\n",
|
||||
" return False\n",
|
||||
" return vehicle.can_fit_in_spot(self)\n",
|
||||
" return vehicle.can_fit_in_spot(self) \n",
|
||||
"\n",
|
||||
" def park_vehicle(self, vehicle): # ...\n",
|
||||
" def remove_vehicle(self): # ..."
|
||||
" def park_vehicle(self, vehicle) : # ...\n",
|
||||
" def remove_vehicle(self) : # ..."
|
||||
]
|
||||
}
|
||||
],
|
||||
|
@@ -2,107 +2,107 @@ from abc import ABCMeta, abstractmethod
|
||||
from enum import Enum
|
||||
|
||||
|
||||
class VehicleSize(Enum):
|
||||
class VehicleSize(Enum) :
|
||||
|
||||
MOTORCYCLE = 0
|
||||
COMPACT = 1
|
||||
LARGE = 2
|
||||
|
||||
|
||||
class Vehicle(metaclass=ABCMeta):
|
||||
class Vehicle(metaclass=ABCMeta) :
|
||||
|
||||
def __init__(self, vehicle_size, license_plate, spot_size):
|
||||
def __init__(self, vehicle_size, license_plate, spot_size) :
|
||||
self.vehicle_size = vehicle_size
|
||||
self.license_plate = license_plate
|
||||
self.spot_size
|
||||
self.spots_taken = []
|
||||
|
||||
def clear_spots(self):
|
||||
def clear_spots(self) :
|
||||
for spot in self.spots_taken:
|
||||
spot.remove_vehicle(self)
|
||||
spot.remove_vehicle(self)
|
||||
self.spots_taken = []
|
||||
|
||||
def take_spot(self, spot):
|
||||
self.spots_taken.append(spot)
|
||||
def take_spot(self, spot) :
|
||||
self.spots_taken.append(spot)
|
||||
|
||||
@abstractmethod
|
||||
def can_fit_in_spot(self, spot):
|
||||
def can_fit_in_spot(self, spot) :
|
||||
pass
|
||||
|
||||
|
||||
class Motorcycle(Vehicle):
|
||||
class Motorcycle(Vehicle) :
|
||||
|
||||
def __init__(self, license_plate):
|
||||
super(Motorcycle, self).__init__(VehicleSize.MOTORCYCLE, license_plate, spot_size=1)
|
||||
def __init__(self, license_plate) :
|
||||
super(Motorcycle, self) .__init__(VehicleSize.MOTORCYCLE, license_plate, spot_size=1)
|
||||
|
||||
def can_fit_in_spot(self, spot):
|
||||
def can_fit_in_spot(self, spot) :
|
||||
return True
|
||||
|
||||
|
||||
class Car(Vehicle):
|
||||
class Car(Vehicle) :
|
||||
|
||||
def __init__(self, license_plate):
|
||||
super(Car, self).__init__(VehicleSize.COMPACT, license_plate, spot_size=1)
|
||||
def __init__(self, license_plate) :
|
||||
super(Car, self) .__init__(VehicleSize.COMPACT, license_plate, spot_size=1)
|
||||
|
||||
def can_fit_in_spot(self, spot):
|
||||
return spot.size in (VehicleSize.LARGE, VehicleSize.COMPACT)
|
||||
def can_fit_in_spot(self, spot) :
|
||||
return spot.size in (VehicleSize.LARGE, VehicleSize.COMPACT)
|
||||
|
||||
|
||||
class Bus(Vehicle):
|
||||
class Bus(Vehicle) :
|
||||
|
||||
def __init__(self, license_plate):
|
||||
super(Bus, self).__init__(VehicleSize.LARGE, license_plate, spot_size=5)
|
||||
def __init__(self, license_plate) :
|
||||
super(Bus, self) .__init__(VehicleSize.LARGE, license_plate, spot_size=5)
|
||||
|
||||
def can_fit_in_spot(self, spot):
|
||||
def can_fit_in_spot(self, spot) :
|
||||
return spot.size == VehicleSize.LARGE
|
||||
|
||||
|
||||
class ParkingLot(object):
|
||||
class ParkingLot(object) :
|
||||
|
||||
def __init__(self, num_levels):
|
||||
def __init__(self, num_levels) :
|
||||
self.num_levels = num_levels
|
||||
self.levels = [] # List of Levels
|
||||
|
||||
def park_vehicle(self, vehicle):
|
||||
def park_vehicle(self, vehicle) :
|
||||
for level in self.levels:
|
||||
if level.park_vehicle(vehicle):
|
||||
if level.park_vehicle(vehicle) :
|
||||
return True
|
||||
return False
|
||||
|
||||
|
||||
class Level(object):
|
||||
class Level(object) :
|
||||
|
||||
SPOTS_PER_ROW = 10
|
||||
|
||||
def __init__(self, floor, total_spots):
|
||||
def __init__(self, floor, total_spots) :
|
||||
self.floor = floor
|
||||
self.num_spots = total_spots
|
||||
self.available_spots = 0
|
||||
self.spots = [] # List of ParkingSpots
|
||||
|
||||
def spot_freed(self):
|
||||
def spot_freed(self) :
|
||||
self.available_spots += 1
|
||||
|
||||
def park_vehicle(self, vehicle):
|
||||
spot = self._find_available_spot(vehicle)
|
||||
def park_vehicle(self, vehicle) :
|
||||
spot = self._find_available_spot(vehicle)
|
||||
if spot is None:
|
||||
return None
|
||||
else:
|
||||
spot.park_vehicle(vehicle)
|
||||
spot.park_vehicle(vehicle)
|
||||
return spot
|
||||
|
||||
def _find_available_spot(self, vehicle):
|
||||
def _find_available_spot(self, vehicle) :
|
||||
"""Find an available spot where vehicle can fit, or return None"""
|
||||
pass
|
||||
|
||||
def _park_starting_at_spot(self, spot, vehicle):
|
||||
def _park_starting_at_spot(self, spot, vehicle) :
|
||||
"""Occupy starting at spot.spot_number to vehicle.spot_size."""
|
||||
pass
|
||||
|
||||
|
||||
class ParkingSpot(object):
|
||||
class ParkingSpot(object) :
|
||||
|
||||
def __init__(self, level, row, spot_number, spot_size, vehicle_size):
|
||||
def __init__(self, level, row, spot_number, spot_size, vehicle_size) :
|
||||
self.level = level
|
||||
self.row = row
|
||||
self.spot_number = spot_number
|
||||
@@ -110,16 +110,16 @@ class ParkingSpot(object):
|
||||
self.vehicle_size = vehicle_size
|
||||
self.vehicle = None
|
||||
|
||||
def is_available(self):
|
||||
def is_available(self) :
|
||||
return True if self.vehicle is None else False
|
||||
|
||||
def can_fit_vehicle(self, vehicle):
|
||||
def can_fit_vehicle(self, vehicle) :
|
||||
if self.vehicle is not None:
|
||||
return False
|
||||
return vehicle.can_fit_in_spot(self)
|
||||
return vehicle.can_fit_in_spot(self)
|
||||
|
||||
def park_vehicle(self, vehicle):
|
||||
def park_vehicle(self, vehicle) :
|
||||
pass
|
||||
|
||||
def remove_vehicle(self):
|
||||
def remove_vehicle(self) :
|
||||
pass
|
||||
|
Reference in New Issue
Block a user