summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Graph.pycbin12796 -> 0 bytes
-rw-r--r--data/dijkstra.test59
-rw-r--r--lib.py42
-rw-r--r--templates/user.html2
-rw-r--r--test_dijkstra.py46
5 files changed, 126 insertions, 23 deletions
diff --git a/Graph.pyc b/Graph.pyc
deleted file mode 100644
index 9e3b5d9..0000000
--- a/Graph.pyc
+++ /dev/null
Binary files differ
diff --git a/data/dijkstra.test b/data/dijkstra.test
new file mode 100644
index 0000000..22aba2d
--- /dev/null
+++ b/data/dijkstra.test
@@ -0,0 +1,59 @@
+# -- Answers for the shortest path of the given graphs --
+# The file consists of a number of test cases.
+# Feel free to provide your own test cases!
+# Each test case has this structure:
+# <number of nodes>
+# <space separated SOURCE and DESTINATION node indexes>
+# ... <space separated x y coordinates of each node>
+# <number of edges>
+# ... <space separated nodes edges> (NODE1 is connected to NODE2)
+# <distance of the shortest path>
+# ...<node ids of the shortest path in the order visited>
+# Test case 1:
+6
+0 5
+0 0
+2 2
+2 -2
+4 1
+4 -2
+6 1
+7
+0 1
+0 2
+2 3
+1 2
+3 5
+1 4
+0 5
+6.082762530298219
+0 5
+# Test case 2:
+4
+0 3
+0 0
+2 0
+2 2
+4 0
+4
+0 1
+0 2
+1 3
+2 3
+4.0
+0 1 3
+# Test case 3:
+5
+0 3
+1 3
+4 2
+-2 4
+1 5
+-1 4
+4
+0 1
+1 3
+4 3
+1 4
+7.404918347287664
+0 1 3 \ No newline at end of file
diff --git a/lib.py b/lib.py
index 499b791..7a10bf3 100644
--- a/lib.py
+++ b/lib.py
@@ -1,22 +1,31 @@
import os
import io
import re
+import sys
from http.server import HTTPServer, BaseHTTPRequestHandler
posts = {}
gets = {}
def find_get(path):
+ """ [Internal] - Used by the Handler class to try and
+ find the correct handler for a GET request.
+ """
try:
return gets[path]()
- except KeyError:
+ except Exception as e:
+ print(type(e), e)
return "404"
def find_post(path, request):
+ """ [Internal] - Used by the Handler class to try and
+ find the correct handler for a POST request.
+ """
try:
return posts[path](request)
- except KeyError:
+ except Exception as e:
+ print(type(e), e)
return "404"
def get_relative_path():
@@ -39,7 +48,7 @@ def read_html(relative_file_path):
return html_content
def inject_external_files(html_content):
- """ Replaces {{ 'file_path' }} with the file content of that file
+ """ [Internal] - Replaces {{ 'file_path' }} with the file content of that file
path. Useful for seperation of javascript and css files.
Uses regex to capture the pattern. Here is a link to see how it
works: https://regex101.com/r/v917NK/2
@@ -67,8 +76,8 @@ def inject_external_files(html_content):
def post(route = '/'):
""" A decorator that takes in the route path as argument, and then
puts the post handler in the dictionary, with the route as a key.
- The handler will receive one argument called 'body', where the body
- of the post request will exist. """
+ The handler will receive one `str` argument called 'body',
+ where the body of the post request will exist. """
def decorator(handler_function):
posts[route] = handler_function
@@ -89,19 +98,25 @@ def get(route = '/'):
# Explanation: https://blog.anvileight.com/posts/simple-python-http-server/
+
class Handler(BaseHTTPRequestHandler):
- """ The class responsible for handling all the
- different requests made to our server
+ """ [Internal] - The class responsible for handling all the
+ different requests made to our server.
"""
def _set_headers(self):
- """ Standard header stuff that has to be done """
+ """ Sets the headers for a response. This is to tell the browser
+ the status of the request that was sent. '200' means that everything
+ went fine.
+ """
self.send_response(200)
self.send_header("Content-type", "text/html")
self.end_headers()
def do_GET(self):
- """ Just serve up our one and only html page """
+ """ Tries to find the handler for this GET request. The handler can
+ return either `bytes` or `str`.
+ """
self._set_headers()
res = find_get(self.path)
if hasattr(res, 'encode'):
@@ -111,20 +126,21 @@ class Handler(BaseHTTPRequestHandler):
def do_POST(self):
- """ An async ajax request. Find the function from 'posts.py' to handle this
- particular request.
+ """ Tries to find the handler for this POST request. The handler
+ will get the 'body' of the request as the argument. The body
+ is a `str`, formatted in JSON.
"""
self.send_response(200)
self.end_headers()
content_length = int(self.headers['Content-Length'])
body = self.rfile.read(content_length)
- res = find_post(self.path, body)
+ res = find_post(self.path, body.decode('utf-8'))
self.wfile.write(res.encode())
def run_server (port = 8314):
server_adress = ('', port) # Should make the port a command line argument
server = HTTPServer(server_adress, Handler)
- print(f'Starting server on port: {port}.')
+ print('Starting server on port: {}.'.format(port))
server.serve_forever()
\ No newline at end of file
diff --git a/templates/user.html b/templates/user.html
index cde9267..9245e91 100644
--- a/templates/user.html
+++ b/templates/user.html
@@ -1,4 +1,4 @@
-
+<!--Template for the EXPANSION 'Allowing users to login and register 'securely' (2 points) ' -->
<div id="user-stuff">
<button id="login">Show Login</button>
<div id="login-info">
diff --git a/test_dijkstra.py b/test_dijkstra.py
index a0f315c..f906b59 100644
--- a/test_dijkstra.py
+++ b/test_dijkstra.py
@@ -1,21 +1,49 @@
-import notebooks.Graph as Graph
from collections import defaultdict
from heapq import heappush, heappop
import math
def dijkstra(adjacency_list, source_id, target_id):
- """ To be implemented by students. `adjacency_list` is a dictionary with structure:
+ """ To be implemented by students (optional exercise). `adjacency_list` is a dictionary with structure:
{node_id: [...(neighbor_id, weight)]}.
Function should return (distance, path). Path should be a list of the nodes in the shortest path
- **including** the source_id and target_id. If no shortest path is found, it should return (infinity, []) """
-
- return math.inf, [source_id]
+ **including** the source_id and target_id. If no shortest path is found, it should return (float('inf'), []) """
+ return float('inf'), []
if __name__ == '__main__':
+ file = open('data/dijkstra.test') # Feel free to add your own test cases to the file!
+ testcase = 0
try:
- Graph.test_dijkstra(dijkstra)
- print('Passed ALL tests!')
+ while True:
+ num_nodes = file.readline()
+ if num_nodes[0] == '#':
+ continue
+ testcase += 1
+ num_nodes = int(num_nodes)
+ source, target = map(int, file.readline().split())
+ nodes = []
+ for n in range(num_nodes):
+ x, y = map(float, file.readline().split())
+ nodes.append((x, y))
+ adjacency_list = defaultdict(list)
+ num_edges = int(file.readline())
+ for m in range(num_edges):
+ v1, v2 = map(int, file.readline().split())
+ x1, y1 = nodes[v1]
+ x2, y2 = nodes[v2]
+ weight = math.hypot(x2-x1, y2-y1) # Get distance between the nodes
+ adjacency_list[v1].append((v2, weight))
+ adjacency_list[v2].append((v1, weight))
+ correct_dist = float(file.readline())
+ correct_path = [int(v) for v in file.readline().split()]
+ dist, path = dijkstra(adjacency_list, source, target)
+ assert abs(correct_dist-dist) < 1e-3
+ assert correct_path == path
+ print("Passed test case {}".format(testcase))
except AssertionError:
- print('Failed one or more tests')
-
+ print("Failed test case {}".format(testcase))
+ except IndexError:
+ print('Passed all test cases')
+ except EOFError:
+ print('Passed all test cases')
+