Update.
authorFrançois Fleuret <francois@fleuret.org>
Tue, 29 Oct 2024 07:06:43 +0000 (08:06 +0100)
committerFrançois Fleuret <francois@fleuret.org>
Tue, 29 Oct 2024 07:06:43 +0000 (08:06 +0100)
distributed.py
grid.py

index b5e98e9..6fe3f6b 100755 (executable)
@@ -56,73 +56,58 @@ class SocketConnection:
 ######################################################################
 
 
-class CultureServer:
-    def __init__(self, port):
-        s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
-        s.bind(("0.0.0.0", port))
-        s.listen(5)
-        self.nb_accepts = 0
+def create_server(port, reader, writer):
+    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
+    s.bind(("0.0.0.0", port))
+    s.listen(5)
+    self.nb_accepts = 0
 
-        while True:
-            client_socket, ip_and_port = s.accept()
-            link = SocketConnection(client_socket)
-
-            threading.Thread(
-                target=self.client_loop,
-                kwargs={"link": link, "client_nb": self.nb_accepts},
-                daemon=True,
-            ).start()
-
-            self.nb_accepts += 1
-
-    def client_loop(self, link, client_nb):
-        link.send(f"HELLO #{client_nb}")
+    def reading_loop(self, link, client_nb):
         try:
             while True:
-                r = link.receive()
-                print(f'from #{client_nb} receive "{r}"')
-                link.send(f"ACK {r}")
-                if r == "BYE":
-                    break
+                reader(link.receive())
         except EOFError:
             print(f"closing #{client_nb} on EOF")
 
+    while True:
+        client_socket, ip_and_port = s.accept()
+        link = SocketConnection(client_socket)
 
-######################################################################
+        threading.Thread(
+            target=writer,
+            kwargs={"link": link.send, "client_nb": self.nb_accepts},
+            daemon=True,
+        ).start()
 
+        threading.Thread(
+            target=reading_loop,
+            kwargs={"link": link, "client_nb": self.nb_accepts},
+            daemon=True,
+        ).start()
 
-class CultureClient:
-    def __init__(self, server_hostname, port):
-        server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
-        server_socket.connect((server_hostname, port))
-        self.link = SocketConnection(server_socket)
-        self.buffer = []
+        self.nb_accepts += 1
 
-        threading.Thread(target=self.receive, daemon=True).start()
-        self.loop()
 
-    def receive(self):
-        try:
-            while True:
-                self.buffer.append(self.link.receive())
-        except EOFError:
-            print(f"** closing connection on EOF **")
+######################################################################
 
-    def loop(self):
-        try:
-            while True:
-                self.link.send(f"PING {time.localtime().tm_sec}")
 
-                try:
-                    while True:
-                        print(self.buffer.pop(0))
-                except IndexError:
-                    pass
+def create_client(server_hostname, port, reader):
+    server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
+    server_socket.connect((server_hostname, port))
+    link = SocketConnection(server_socket)
+
+    def reader_thread(reader):
+        while True:
+            reader(link.receive())
+
+    def writer(x):
+        self.link.send(x)
 
-                time.sleep(1)
+    threading.Thread(
+        target=reader_thread, kwargs={"reader": reader}, daemon=True
+    ).start()
 
-        except BrokenPipeError:
-            print(f"** closing connection on broken pipe **")
+    return writer
 
 
 ######################################################################
diff --git a/grid.py b/grid.py
index 7168491..12ecba1 100755 (executable)
--- a/grid.py
+++ b/grid.py
@@ -61,59 +61,59 @@ class FormalGrid:
     ######################################################################
 
     def constraint_to_fun(self, constraint):
-        g = [None]
+        a, b, c = None, None, None
 
         def match(pattern):
+            nonlocal a, b, c
             r = re.search("^" + pattern + "$", constraint)
             if r:
-                g[0] = (int(x) - 1 for x in r.groups())
+                g = tuple(int(x) - 1 for x in r.groups())
+                a, b, c = g + (None,) * (3 - len(g))
                 return True
             else:
                 return False
 
         if match("([1-9]) is_in_top_half"):
-            (a,) = g[0]
             return self.row[:, a] < self.grid_height // 2
+
         elif match("([1-9]) is_in_bottom_half"):
-            (a,) = g[0]
             return self.row[:, a] >= self.grid_height // 2
+
         elif match("([1-9]) is_on_left_side"):
-            (a,) = g[0]
             return self.col[:, a] < self.grid_width // 2
+
         elif match("([1-9]) is_on_right_side"):
-            (a,) = g[0]
             return self.col[:, a] >= self.grid_width // 2
+
         elif match("([1-9]) next_to ([1-9])"):
-            a, b = g[0]
             return (self.row[:, a] - self.row[:, b]).abs() + (
                 self.col[:, a] - self.col[:, b]
             ).abs() <= 1
+
         elif match("([1-9]) is_below ([1-9])"):
-            a, b = g[0]
             return self.row[:, a] > self.row[:, b]
+
         elif match("([1-9]) is_above ([1-9])"):
-            a, b = g[0]
             return self.row[:, a] < self.row[:, b]
+
         elif match("([1-9]) is_left_of ([1-9])"):
-            a, b = g[0]
             return self.col[:, a] < self.col[:, b]
+
         elif match("([1-9]) is_right_of ([1-9])"):
-            a, b = g[0]
             return self.col[:, a] > self.col[:, b]
+
         elif match("([1-9]) ([1-9]) parallel_to_diagonal"):
-            a, b = g[0]
             return (self.col[:, a] - self.col[:, b]).abs() == (
                 self.row[:, a] - self.row[:, b]
             ).abs()
+
         elif match("([1-9]) ([1-9]) vertical"):
-            a, b = g[0]
             return self.col[:, a] == self.col[:, b]
+
         elif match("([1-9]) ([1-9]) horizontal"):
-            a, b = g[0]
             return self.row[:, a] == self.row[:, b]
 
         elif match("([1-9]) ([1-9]) ([1-9]) are_aligned"):
-            a, b, c = g[0]
             return (self.col[:, a] - self.col[:, b]) * (
                 self.row[:, a] - self.row[:, c]
             ) - (self.row[:, a] - self.row[:, b]) * (
@@ -121,7 +121,6 @@ class FormalGrid:
             ) == 0
 
         elif match("([1-9]) middle_of ([1-9]) ([1-9])"):
-            a, b, c = g[0]
             return (
                 grid_set
                 & (self.col[:, a] + self.col[:, c] == 2 * self.col[:, b])
@@ -129,7 +128,6 @@ class FormalGrid:
             )
 
         elif match("([1-9]) is_equidistant_from ([1-9]) and ([1-9])"):
-            a, b, c = g[0]
             return (self.col[:, a] - self.col[:, b]) ** 2 + (
                 self.row[:, a] - self.row[:, b]
             ) ** 2 == (self.col[:, a] - self.col[:, c]) ** 2 + (
@@ -137,15 +135,13 @@ class FormalGrid:
             ) ** 2
 
         elif match("([1-9]) is_further_away_from ([1-9]) than ([1-9])"):
-            a, b, c = g[0]
             return (self.col[:, a] - self.col[:, b]) ** 2 + (
                 self.row[:, a] - self.row[:, b]
             ) ** 2 > (self.col[:, a] - self.col[:, c]) ** 2 + (
                 self.row[:, a] - self.row[:, c]
             ) ** 2
 
-        elif match("([1-9]) ([1-9]) ([1-9]) make_right_angle"):
-            a, b, c = g[0]
+        elif match("([1-9]) ([1-9]) ([1-9]) form_a_right_angle"):
             return (self.col[:, a] - self.col[:, b]) * (
                 self.col[:, c] - self.col[:, b]
             ) + (self.row[:, a] - self.row[:, b]) * (
@@ -199,9 +195,9 @@ if __name__ == "__main__":
 
     grid_set = grid.new_grid_set(
         [
-            "1 2 3 make_right_angle",
-            "2 3 4 make_right_angle",
-            "3 4 1 make_right_angle",
+            "1 2 3 form_a_right_angle",
+            "2 3 4 form_a_right_angle",
+            "3 4 1 form_a_right_angle",
             "2 is_equidistant_from 1 and 3",
             "1 is_above 4",
         ],