aboutsummaryrefslogtreecommitdiff
path: root/src/philo
diff options
context:
space:
mode:
authorCharles Cabergs <me@cacharle.xyz>2020-10-01 16:39:47 +0200
committerCharles Cabergs <me@cacharle.xyz>2020-10-01 16:39:47 +0200
commit8a351c6d267c55445de7b7b40b1de3b16305bd02 (patch)
tree17e59ab15e809868acdcd14353521a3f11fffce5 /src/philo
parent1f18e740539aed751865ecff9d0f3cba44230e54 (diff)
downloadphilosophers_test-8a351c6d267c55445de7b7b40b1de3b16305bd02.tar.gz
philosophers_test-8a351c6d267c55445de7b7b40b1de3b16305bd02.tar.bz2
philosophers_test-8a351c6d267c55445de7b7b40b1de3b16305bd02.zip
Readded some check
Diffstat (limited to 'src/philo')
-rw-r--r--src/philo/log.py4
-rw-r--r--src/philo/philo.py114
-rw-r--r--src/philo/table.py8
3 files changed, 76 insertions, 50 deletions
diff --git a/src/philo/log.py b/src/philo/log.py
index f5817d0..14bdd75 100644
--- a/src/philo/log.py
+++ b/src/philo/log.py
@@ -6,7 +6,7 @@
# By: cacharle <me@cacharle.xyz> +#+ +:+ +#+ #
# +#+#+#+#+#+ +#+ #
# Created: 2020/10/01 10:51:39 by cacharle #+# #+# #
-# Updated: 2020/10/01 11:30:53 by cacharle ### ########.fr #
+# Updated: 2020/10/01 14:19:29 by cacharle ### ########.fr #
# #
# ############################################################################ #
@@ -44,4 +44,4 @@ class Log:
return value
def __repr__(self):
- return "{}ms #{} {}".format(self.timestamp, self.id, self.event)
+ return "{} {} {}".format(self.timestamp, self.id, Event.to_string(self.event))
diff --git a/src/philo/philo.py b/src/philo/philo.py
index afb6362..0f75589 100644
--- a/src/philo/philo.py
+++ b/src/philo/philo.py
@@ -6,7 +6,7 @@
# By: cacharle <me@cacharle.xyz> +#+ +:+ +#+ #
# +#+#+#+#+#+ +#+ #
# Created: 2020/10/01 10:52:56 by cacharle #+# #+# #
-# Updated: 2020/10/01 11:19:23 by cacharle ### ########.fr #
+# Updated: 2020/10/01 16:39:30 by cacharle ### ########.fr #
# #
# ############################################################################ #
@@ -54,54 +54,80 @@ class Philo:
- State switch should be
thinking -> take fork -> take fork -> eat * meal_num -> sleep -> repeat
- Should die when starving: last log timestamp - timeout_death > last_time_eat
+ - Should eat n times, Should take fork 2 times, The other event should happend 1 time
"""
if len(self.logs) == 0:
return
- # def _check_fork_taking(self):
- # for l1, l2, l3 in zip(self.logs, self.logs[1:], self.logs[2:]):
- # if l1.event is Event.FORK and (l2.event is not Event.FORK or l2.event is not Event.EAT):
- # self._raise("should take 2 forks then eat")
- #
- # def _check_meal(self):
- # grouped = [(e, list(g)) for e, g in itertools.groupby(self.logs, (lambda x: x.event))]
- # for e, g in grouped:
- # if e is Event.EATING:
- # if len(g) != self._meal_num:
- # raise error.Log(self.logs, "should eat {} times".format(self._meal_num))
- # else:
- # if len(g) != 1:
- # raise error.Log(self.logs, "event {} should occur 1 time".format(Event.to_string(e)))
- #
- # def _check_order(self):
- # for l1, l2 in zip(self.logs, self.logs[1:]):
- # if l2.event is Event.DIED:
- # break
- # if l1.event is Event.EATING and l2.event is Event.EATING:
- # if l2.timestamp - l1.timestamp > self._timeout_eat:
- # raise ValueError
- # second, timeout = {
- # Event.THINKING: (Event.EATING, None),
- # Event.EATING: (Event.SLEEPING, self._timeout_eat),
- # Event.SLEEPING: (Event.THINKING, self._timeout_sleep)
- # }[l1.event]
- # if l2.event is not second:
- # raise error.Log(self.logs, "invalid switch {} -> {}".format(l1.event, l2.event))
- # if timeout is not None and l2.timestamp - l1.timestamp > timeout:
- # raise ValueError
- #
- # def _check_death_timeout(self):
- # last_eat = None
- # for log in reversed(self.logs):
- # if log.event is Event.EATING:
- # last_eat = log
- # break
- # last = self.logs[-1]
- # if last_eat is not None and last_eat is not last:
- # if last.timestamp - last_eat.timestamp > self._timeout_die + 10:
- # raise error.Log(self.logs, "{} should be dead {} - {} > {}".format(
- # self.id, last.timestamp, last_eat.timestamp, self._timeout_die + 10))
+ # check 2 forks before eating
+ for l1, l2, l3 in zip(self.logs, self.logs[1:], self.logs[2:]):
+ if (l3.event is Event.EAT
+ and (l1.event is not Event.FORK
+ or l2.event is not Event.FORK)):
+ self._raise("should take 2 forks then eat")
+
+ # check log event number
+ grouped = [(e, list(g)) for e, g in itertools.groupby(self.logs, (lambda x: x.event))]
+ for e, g in grouped[:-1]:
+ if e is Event.EAT:
+ if len(g) != self._meal_num:
+ self._raise("Should eat {} times".format(self._meal_num))
+ elif e is Event.FORK:
+ if len(g) != 2:
+ self._raise("Should take fork 2 times")
+ elif len(g) != 1:
+ self._raise("Event `{}` should occur 1 time".format(Event.to_string(e)))
+
+ # check state switch order
+ events = [e for e, _ in grouped]
+ for e1, e2 in zip(events, events[1:]):
+ second = {
+ Event.THINK: Event.FORK,
+ Event.FORK: Event.EAT,
+ Event.EAT: Event.SLEEP,
+ Event.SLEEP: Event.THINK
+ }[e1]
+ if e2 is not second:
+ self._raise("invalid state switch `{}` -> `{}`".format(
+ Event.to_string(e1), Event.to_string(e2)))
+
+ # check timeouts
+ for l1, l2 in zip(self.logs, self.logs[1:]):
+ e1, e2 = l1.event, l2.event
+ t1, t2 = l1.timestamp, l2.timestamp
+ if e1 is Event.FORK and e2 is Event.EAT:
+ if t2 - t1 > 10:
+ self._raise("Delay between taking second fork and eat > 10")
+ if e1 is Event.SLEEP:
+ self._check_time_range(t1, t2, self._timeout_sleep, "Slept")
+ if e1 is Event.EAT:
+ self._check_time_range(t1, t2, self._timeout_eat, "Ate")
+
+
+ # if l1.event is Event.EATING and l2.event is Event.EATING:
+ # if l2.timestamp - l1.timestamp > self._timeout_eat:
+ # raise ValueError
+ # if timeout is not None and l2.timestamp - l1.timestamp > timeout:
+ # raise ValueError
+
+ # check if should be dead
+ # last_eat = None
+ # for log in reversed(self.logs):
+ # if log.event is Event.EATING:
+ # last_eat = log
+ # break
+ # last = self.logs[-1]
+ # if last_eat is not None and last_eat is not last:
+ # if last.timestamp - last_eat.timestamp > self._timeout_die + 10:
+ # self._raise("{} should be dead {} - {} > {}".format(self.id, last.timestamp, last_eat.timestamp, self._timeout_die + 10))
+
+ def _check_time_range(self, t1, t2, timeout, verb):
+ lo = timeout - 10
+ hi = timeout + 10
+ if not (lo <= t2 - t1 <= hi):
+ self._raise("{} {}ms expected {}-{}ms".format(verb, t2 - t1, lo, hi))
+
def _raise(self, msg):
""" Helper to raise Log errrors"""
diff --git a/src/philo/table.py b/src/philo/table.py
index ea93391..56ed331 100644
--- a/src/philo/table.py
+++ b/src/philo/table.py
@@ -6,7 +6,7 @@
# By: cacharle <me@cacharle.xyz> +#+ +:+ +#+ #
# +#+#+#+#+#+ +#+ #
# Created: 2020/10/01 10:53:29 by cacharle #+# #+# #
-# Updated: 2020/10/01 11:31:44 by cacharle ### ########.fr #
+# Updated: 2020/10/01 14:15:09 by cacharle ### ########.fr #
# #
# ############################################################################ #
@@ -41,7 +41,7 @@ class Table:
philo.logs.append(log)
# move
if self.dead:
- raise error.Log(self._logs, "should not output after death")
+ raise error.Log(self._logs, "Output after death")
if log.event is Event.DIE:
self.dead = True
@@ -61,7 +61,7 @@ class Table:
fork_used = sum([p.used_forks for p in self._philos])
if fork_used > self._philo_num:
- raise error.Log(self._logs, "using nonexistant forks")
+ raise error.Log(self._logs, "Using nonexistant forks")
for l1, l2 in zip(self._logs, self._logs[1:]):
if l1.timestamp > l2.timestamp:
- raise error.Log(self._logs, "timestamps not in ordered")
+ raise error.Log(self._logs, "Timestamps not in ordered")