From e3105633364cee2db6414eb601443c325b6ebaf0 Mon Sep 17 00:00:00 2001 From: Chase Dullinger Date: Wed, 10 Mar 2021 19:08:27 -0800 Subject: [PATCH] Finishing assignment 4 --- calculator.py | 110 ++++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 88 insertions(+), 22 deletions(-) diff --git a/calculator.py b/calculator.py index a46affd..207a814 100644 --- a/calculator.py +++ b/calculator.py @@ -41,17 +41,49 @@ """ +import numpy as np + def add(*args): """ Returns a STRING with the sum of the arguments """ + return str(sum(args)) + + +def multiply(*args): + """Returns a string witht the product of the arguments""" + return str(np.prod(args)) + + +def subtract(*args): + """Returns a string with the subtraction of the arguments""" + value = args[0] + + for v in args[1:]: + value -= v + + return str(value) + - # TODO: Fill sum with the correct value, based on the - # args provided. - sum = "0" +def divide(*args): + """Returns a string with the division of the arguments""" + value = args[0] - return sum + for v in args[1:]: + value = value/v + + return str(value) + + +def homepage(): + body = """Welcome to the calculator. Enter your desired operation + and input values as shown below.
+http://localhost:8080/multiply/3/5 => 15
+http://localhost:8080/add/23/42 => 65
+http://localhost:8080/subtract/23/42 => -19
+http://localhost:8080/divide/22/11 => 2
+http://localhost:8080/ => this page""" + return body -# TODO: Add functions for handling more arithmetic operations. def resolve_path(path): """ @@ -59,26 +91,60 @@ def resolve_path(path): arguments. """ - # TODO: Provide correct values for func and args. The - # examples provide the correct *syntax*, but you should - # determine the actual values of func and args using the - # path. - func = add - args = ['25', '32'] + funcs = {'': homepage, + 'add': add, + 'subtract': subtract, + 'multiply': multiply, + 'divide': divide} + path = path.strip('/').split('/') + + func_name = path[0] + args = path[1:] + + try: + args = map(float, args) + except TypeError: + raise TypeError + + try: + func = funcs[func_name] + except KeyError: + raise NameError return func, args + def application(environ, start_response): - # TODO: Your application code from the book database - # work here as well! Remember that your application must - # invoke start_response(status, headers) and also return - # the body of the response in BYTE encoding. - # - # TODO (bonus): Add error handling for a user attempting - # to divide by zero. - pass + headers = [("Content-type", "text/html")] + try: + path = environ.get('PATH_INFO', None) + if path is None: + raise NameError + func, args = resolve_path(path) + result = func(*args) + + body = "

{}

".format(result) + status = "200 OK" + except NameError: + status = "404 Not Found" + body = "

Not Found

" + except TypeError: + status = "400 Bad Request" + body = "

Bad Request

" + except ZeroDivisionError: + status = "451 Unavailable For Legal Reasons" + body = "

Dividing by zero is mathematically illegal

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

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 + from wsgiref.simple_server import make_server + srv = make_server('localhost', 8080, application) + srv.serve_forever()