aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.gitignore1
-rw-r--r--src/__pycache__/config.cpython-38.pycbin462 -> 0 bytes
-rw-r--r--src/__pycache__/test.cpython-38.pycbin980 -> 0 bytes
-rw-r--r--src/philo/__init__.py (renamed from src/test/table.py)21
-rw-r--r--src/philo/event.py (renamed from src/test/philo.py)22
-rw-r--r--src/philo/log.py53
-rw-r--r--src/philo/philo.py50
-rw-r--r--src/philo/table.py40
-rw-r--r--src/test/__pycache__/__init__.cpython-38.pycbin185 -> 0 bytes
-rw-r--r--src/test/__pycache__/test.cpython-38.pycbin1876 -> 0 bytes
-rw-r--r--src/test/test.py56
11 files changed, 184 insertions, 59 deletions
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..0d20b64
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1 @@
+*.pyc
diff --git a/src/__pycache__/config.cpython-38.pyc b/src/__pycache__/config.cpython-38.pyc
deleted file mode 100644
index 0dd6446..0000000
--- a/src/__pycache__/config.cpython-38.pyc
+++ /dev/null
Binary files differ
diff --git a/src/__pycache__/test.cpython-38.pyc b/src/__pycache__/test.cpython-38.pyc
deleted file mode 100644
index aec2223..0000000
--- a/src/__pycache__/test.cpython-38.pyc
+++ /dev/null
Binary files differ
diff --git a/src/test/table.py b/src/philo/__init__.py
index 6aa1b15..f8cb07f 100644
--- a/src/test/table.py
+++ b/src/philo/__init__.py
@@ -1,23 +1,16 @@
# ############################################################################ #
# #
# ::: :::::::: #
-# table.py :+: :+: :+: #
+# __init__.py :+: :+: :+: #
# +:+ +:+ +:+ #
# By: charles <me@cacharle.xyz> +#+ +:+ +#+ #
# +#+#+#+#+#+ +#+ #
-# Created: 2020/09/27 12:44:48 by charles #+# #+# #
-# Updated: 2020/09/27 12:54:01 by charles ### ########.fr #
+# Created: 2020/09/27 16:06:28 by charles #+# #+# #
+# Updated: 2020/09/27 16:11:04 by charles ### ########.fr #
# #
# ############################################################################ #
-class Table:
- def __init__(self, philo_num):
- self._philos = [Philo(id_) for id_ in range(1, philo_num + 1)]
-
- def update(self, match):
- philo = itertools.first_true(self._philos, pred = lambda x: x.id == match.id)
- philo.add_log(match)
-
- def check(self):
- return True
-
+from philo.table import Table
+from philo.philo import Philo
+from philo.log import Log
+from philo.event import Event
diff --git a/src/test/philo.py b/src/philo/event.py
index c103bec..62f7ca6 100644
--- a/src/test/philo.py
+++ b/src/philo/event.py
@@ -1,23 +1,21 @@
# ############################################################################ #
# #
# ::: :::::::: #
-# philo.py :+: :+: :+: #
+# event.py :+: :+: :+: #
# +:+ +:+ +:+ #
# By: charles <me@cacharle.xyz> +#+ +:+ +#+ #
# +#+#+#+#+#+ +#+ #
-# Created: 2020/09/27 12:54:12 by charles #+# #+# #
-# Updated: 2020/09/27 12:59:50 by charles ### ########.fr #
+# Created: 2020/09/27 16:04:04 by charles #+# #+# #
+# Updated: 2020/09/27 16:28:43 by charles ### ########.fr #
# #
# ############################################################################ #
-class Philo:
- def __init__(id_: int):
- self.id = id_
- self.last_event = None
- self.last_eat_date = None
+from enum import Enum
- def add_log(self, match):
- pass
- def check(self):
- return True
+class Event(Enum):
+ EATING = 1
+ SLEEPING = 2
+ THINKING = 3
+ DIED = 4
+ NONE = 5
diff --git a/src/philo/log.py b/src/philo/log.py
new file mode 100644
index 0000000..cc4347e
--- /dev/null
+++ b/src/philo/log.py
@@ -0,0 +1,53 @@
+# ############################################################################ #
+# #
+# ::: :::::::: #
+# log.py :+: :+: :+: #
+# +:+ +:+ +:+ #
+# By: charles <me@cacharle.xyz> +#+ +:+ +#+ #
+# +#+#+#+#+#+ +#+ #
+# Created: 2020/09/27 16:04:18 by charles #+# #+# #
+# Updated: 2020/09/27 16:05:21 by charles ### ########.fr #
+# #
+# ############################################################################ #
+
+import re
+import time
+
+import philo
+
+
+class Log:
+ def __init__(self, log, philo_num):
+ match = re.match(
+ "^(?P<timestamp>\d+) "
+ "(?P<id>\d+) "
+ "(?P<event>is thinking|is eating|is sleeping|died)$",
+ log
+ )
+ if match is None:
+ raise ValueError("Bad line format |{}|".format(log))
+
+ curr = int(time.time() * 1000)
+ self.timestamp = Log._parse_ranged_int(match.group("timestamp"), curr - 100, curr + 100)
+ self.id = Log._parse_ranged_int(match.group("id"), 1, philo_num)
+
+ self.event = {
+ "is thinking": philo.Event.THINKING,
+ "is eating": philo.Event.EATING,
+ "is sleeping": philo.Event.SLEEPING,
+ "died": philo.Event.DIED,
+ }[match.group('event')]
+
+ @staticmethod
+ def _parse_ranged_int(s, lo, hi):
+ try:
+ value = int(s)
+ if not (lo <= value <= hi):
+ raise ValueError("Invalid value range {}".format(s))
+ except ValueError:
+ raise ValueError("Invalid value {}".format(s))
+ return value
+
+
+ def __repr__(self):
+ return "{} {} {}".format(self.timestamp, self.id, self.event)
diff --git a/src/philo/philo.py b/src/philo/philo.py
new file mode 100644
index 0000000..e7e2e1d
--- /dev/null
+++ b/src/philo/philo.py
@@ -0,0 +1,50 @@
+# ############################################################################ #
+# #
+# ::: :::::::: #
+# philo.py :+: :+: :+: #
+# +:+ +:+ +:+ #
+# By: charles <me@cacharle.xyz> +#+ +:+ +#+ #
+# +#+#+#+#+#+ +#+ #
+# Created: 2020/09/27 12:54:12 by charles #+# #+# #
+# Updated: 2020/09/27 16:50:22 by charles ### ########.fr #
+# #
+# ############################################################################ #
+
+import itertools
+from philo.event import Event
+
+class Philo:
+ def __init__(self, id_: int, meal_num: int = 1):
+ self._logs = []
+ self.id = id_
+ self.meal_num = meal_num
+
+ def add_log(self, log):
+ self._logs.append(log)
+
+ def check(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 RuntimeError("lala")
+ else:
+ if len(g) != 1:
+ raise RuntimeError("1lala")
+
+ events = [e for e, _ in grouped]
+ for e1, e2 in zip(events, events[1:]):
+ if e2 is Event.DIED:
+ break
+ if e1 is Event.THINKING and e2 is not Event.EATING:
+ raise RuntimeError("2lala")
+ elif e1 is Event.EATING and e2 is not Event.SLEEPING:
+ raise RuntimeError("2lala")
+ elif e1 is Event.SLEEPING and e2 is not Event.EATING:
+ raise RuntimeError("2lala")
+
+ @property
+ def last_event(self):
+ if len(self._logs) == 0:
+ return Event.NONE
+ return self._logs[-1].event
diff --git a/src/philo/table.py b/src/philo/table.py
new file mode 100644
index 0000000..8214ffb
--- /dev/null
+++ b/src/philo/table.py
@@ -0,0 +1,40 @@
+# ############################################################################ #
+# #
+# ::: :::::::: #
+# table.py :+: :+: :+: #
+# +:+ +:+ +:+ #
+# By: charles <me@cacharle.xyz> +#+ +:+ +#+ #
+# +#+#+#+#+#+ +#+ #
+# Created: 2020/09/27 12:44:48 by charles #+# #+# #
+# Updated: 2020/09/27 16:54:52 by charles ### ########.fr #
+# #
+# ############################################################################ #
+
+from philo.philo import Philo
+from philo.event import Event
+
+
+class Table:
+ def __init__(self, philo_num):
+ self._philos = [Philo(id_) for id_ in range(1, philo_num + 1)]
+ self._logs = []
+ self._philo_num = philo_num
+
+ def add_log(self, log):
+ self._logs.append(log)
+ philo = next(p for p in self._philos if p.id == log.id)
+ philo.add_log(log)
+
+ def check(self):
+ died_count = len([p for p in self._philos if p.last_event == Event.DIED])
+ if died_count > 1:
+ raise RuntimeError("died")
+ fork_used = 2 * len([p for p in self._philos if p.last_event == Event.EATING])
+ if fork_used > self._philo_num:
+ raise RuntimeError("too much fork")
+ for p in self._philos:
+ p.check()
+ for l1, l2 in zip(self._logs, self._logs[1:]):
+ if l1.timestamp > l2.timestamp:
+ raise RuntimeError("timestamp not ordered")
+
diff --git a/src/test/__pycache__/__init__.cpython-38.pyc b/src/test/__pycache__/__init__.cpython-38.pyc
deleted file mode 100644
index 37cb896..0000000
--- a/src/test/__pycache__/__init__.cpython-38.pyc
+++ /dev/null
Binary files differ
diff --git a/src/test/__pycache__/test.cpython-38.pyc b/src/test/__pycache__/test.cpython-38.pyc
deleted file mode 100644
index ce4b3b7..0000000
--- a/src/test/__pycache__/test.cpython-38.pyc
+++ /dev/null
Binary files differ
diff --git a/src/test/test.py b/src/test/test.py
index 7be1d18..14ee097 100644
--- a/src/test/test.py
+++ b/src/test/test.py
@@ -6,16 +6,21 @@
# By: charles <me@cacharle.xyz> +#+ +:+ +#+ #
# +#+#+#+#+#+ +#+ #
# Created: 2020/09/27 11:36:32 by charles #+# #+# #
-# Updated: 2020/09/27 13:28:15 by charles ### ########.fr #
+# Updated: 2020/09/27 16:25:37 by charles ### ########.fr #
# #
# ############################################################################ #
import re
+import time
import subprocess
# import threading
# from result import Result
+import philo
+# from test.table import Table
+
+
class Test: #(threading.Thread):
_tests = []
@@ -59,44 +64,35 @@ class Test: #(threading.Thread):
if self._meal_num is not None:
argv.append(str(self._meal_num))
# try:
- process_result = subprocess.run(
+ process = subprocess.Popen(
argv,
stdout=subprocess.PIPE,
stderr=subprocess.STDOUT
)
- output = process_result.stdout.decode()
- print(output)
+ # output = process_result.stdout.decode()
+ # print(output)
# timeout=1,
# except subprocess.TimeoutExpered as err:
# return Result(err)
# except subprocess.CalledProcessError as err:
# return Result(err)
- self._check_output(output)
- # return Result()
+ self._check_output(process.stdout)
+ process.wait()
def _check_output(self, stream):
- # table = Table(self._philo_num)
-
- for line in stream.split('\n'):
- match = re.match(
- "^(?P<timestamp>\d+) "
- "(?P<id>\d+) "
- "(?P<event>is thinking|is eating|is sleeping|died)$",
- line
- )
- if match is None:
- print("Bad line format |{}|".format(line))
- return
-
- print(match.group('event'))
- try:
- timestamp = int(match.group("timestamp"))
- # if timestamp < 0
- except ValueError:
- print("Invalid timestamp value {}".format(match.group("timestamp")))
-
- table.add_log(match)
+ table = philo.Table(self._philo_num)
+
+ for line in stream:
+ line = line.decode()[:-1]
+ # print(">", line)
+ l = philo.Log(line, self._philo_num)
+ print(l)
+ table.add_log(l)
+ table.check()
+
+ # print(timestamp, id_, event)
+
# philo_states.append(Philo)
@@ -104,9 +100,3 @@ class Test: #(threading.Thread):
# Test._stdout_lock.aquire()
# print(*args)
# Test._stdout_lock.release()
-
-# from enum import Enum
-# class PhiloEvent(Enum):
-# EATING = 1
-# SLEEPING = 2
-# THINKING = 3