diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..5b2aee6 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,12 @@ +{ + "python.testing.unittestArgs": [ + "-v", + "-s", + ".", + "-p", + "*test*.py" + ], + "python.testing.pytestEnabled": false, + "python.testing.nosetestsEnabled": false, + "python.testing.unittestEnabled": true +} \ No newline at end of file diff --git a/__pycache__/tests.cpython-37.pyc b/__pycache__/tests.cpython-37.pyc new file mode 100644 index 0000000..e256127 Binary files /dev/null and b/__pycache__/tests.cpython-37.pyc differ diff --git a/calculator.py b/calculator.py index a46affd..70e3424 100644 --- a/calculator.py +++ b/calculator.py @@ -40,6 +40,61 @@ """ +import traceback + +def html_wrapper(body): + result = f""" + +Calculator + +{body} + + +""" + return result + +def instructions(*args): + """Index page""" + page = """ +

Calculator

+ +

Instructions:

+ + + +

Examples:

+ + + + + + + + + + + + + + + + + + + + + + +
OperationExample Link
Addhttp://localhost:8080/add/23/42
Subtracthttp://localhost:8080/subtract/23/42
Multiplyhttp://localhost:8080/multiply/3/5
Dividehttp://localhost:8080/divide/22/11
+ +""" + return page def add(*args): @@ -47,12 +102,42 @@ def add(*args): # TODO: Fill sum with the correct value, based on the # args provided. - sum = "0" - - return sum + # sum = "0" + result = str(sum(args)) + result += '
Back' + return result # TODO: Add functions for handling more arithmetic operations. + +def subtract(*args): + """Returns a string with the result a-b""" + + result = str(args[0] - args[1]) + result += '
Back' + + return result + +def divide(*args): + """Return a string with the result of """ + try: + result = str(args[0] / args[1]) + + except ZeroDivisionError: + result = "You can't divide by zero" + result += '
Back' + + return result + +def multiply(*args): + """Returns the result of a*b""" + + result = str(args[0] * args[1]) + result += '
Back' + + return result + + def resolve_path(path): """ Should return two values: a callable and an iterable of @@ -63,8 +148,30 @@ def resolve_path(path): # examples provide the correct *syntax*, but you should # determine the actual values of func and args using the # path. - func = add - args = ['25', '32'] + # func = add + # args = ['25', '32'] + + funcs = { + "add": add, + "subtract": subtract, + "multiply": multiply, + "divide": divide, + "instructions" : instructions + } + # print(f"!{path}!") + if "favicon.ico" in path or len(path) < 7: + func_name = "instructions" + left = "0" + right = "0" + else: + func_name, left, right = path.split('/')[1:4] + + args = [int(left), int(right)] + + try: + func = funcs[func_name] + except KeyError: + raise NameError return func, args @@ -76,9 +183,31 @@ def application(environ, start_response): # # TODO (bonus): Add error handling for a user attempting # to divide by zero. - pass + # pass + + status = "200 OK" + headers = [('Content-type', 'text/html')] + try: + path = environ.get('PATH_INFO', None) + func, args = resolve_path(path) + body = html_wrapper(func(*args)) + except NameError: + status = "404 Not Found" + body = html_wrapper("

Not Found

") + except Exception: + status = "500 Internal Server Error" + body = html_wrapper("

Internal Server Error

") + print(traceback.format_exc()) + finally: + headers.append(('Content-length', str(len(body)))) + start_response(status, headers) + return [body.encode('utf8')] + if __name__ == '__main__': # TODO: Insert the same boilerplate wsgiref simple # server creation that you used in the book database. - pass + # pass + from wsgiref.simple_server import make_server + srv = make_server('localhost', 8080, application) + srv.serve_forever() \ No newline at end of file diff --git a/tests.py b/tests.py index c2a8dcb..b7c435f 100644 --- a/tests.py +++ b/tests.py @@ -3,6 +3,13 @@ import http.client import random +""" +http://localhost:8080/multiply/3/5 +http://localhost:8080/add/23/42 +http://localhost:8080/subtract/23/42 +http://localhost:8080/divide/22/11 +http://localhost:8080/ +""" class WebTestCase(unittest.TestCase): """tests for the WSGI Calculator"""