From 85f7d8d72ff1bc3fa570f9726b145371a2747219 Mon Sep 17 00:00:00 2001 From: Clemente Fortuna Date: Thu, 18 Jun 2020 16:49:03 -0400 Subject: [PATCH] submission of L04 assignment, with bonus completed --- calculator.py | 112 +++++++++++++++++++++++++++++++++++++++----------- tests.py | 2 +- 2 files changed, 90 insertions(+), 24 deletions(-) diff --git a/calculator.py b/calculator.py index a46affd..30c2107 100644 --- a/calculator.py +++ b/calculator.py @@ -40,45 +40,111 @@ """ +import traceback +from numpy import prod def add(*args): """ Returns a STRING with the sum of the arguments """ + return sum(map(int, args)) + + +def subtract(*args): + """ Returns a STRING, in which the first number retains its value, the remaining numbers + take their negative value, and all numbers are summed.""" + args_mut = [] + for i in range(len(args)): + args_mut.append('') + if i == 0: + args_mut[i] = int(args[i]) + else: + args_mut[i] = int(args[i]) * -1 + return sum(map(int, args_mut)) + + +def multiply(*args): + """ Returns a STRING, in which all numbers are multiplied in sequence.""" + return prod(list(map(int, args))) + + +def divide(*args): + """ Returns a STRING, in which the numbers are divided in sequence. + ZeroDivisionError included.""" + if '0' in args[1:]: + raise ZeroDivisionError + + args_mut = [] + for arg in args: + args_mut.append(int(arg)) + quotient = args_mut[0] + for i in range(1, len(args_mut)): + quotient /= args_mut[i] + + return quotient + + +def instructions(): + """Return an html string of instructions.""" + page = """ +

Instructions

+ +""" - # TODO: Fill sum with the correct value, based on the - # args provided. - sum = "0" - - return sum + return page -# TODO: Add functions for handling more arithmetic operations. def resolve_path(path): """ Should return two values: a callable and an iterable of arguments. """ + funcs = {'': instructions, 'add': add, 'subtract': subtract, 'multiply': multiply, + 'divide': divide} + + path = path.strip('/').split('/') - # 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'] + func_name = path[0] + args = path[1:] + + 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 + """Provide the response, including for raised ZeroDivisionError.""" + headers = [('Content-type', 'text/html')] + try: + path = environ.get('PATH_INFO', None) + if path is None: + raise NameError + func, args = resolve_path(path) + body = func(*args) + status = "200 OK" + except NameError: + status = "404 Not Found" + body = "

Not Found

" + except ZeroDivisionError: + status = "403 Forbidden" + body = "

Division by Zero Not Permitted

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

Internal Server Error

" + print(traceback.format_exc()) + finally: + headers.append(('Content-length', str(len(str(body))))) + start_response(status, headers) + return [str(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('127.0.0.1', 8080, application) + srv.serve_forever() diff --git a/tests.py b/tests.py index c2a8dcb..7a91ed5 100644 --- a/tests.py +++ b/tests.py @@ -26,7 +26,7 @@ def get_response(self, url): Helper function to get a response from a given url, using http.client """ - conn = http.client.HTTPConnection('localhost:8080') + conn = http.client.HTTPConnection('127.0.0.1:8080') conn.request('GET', url) response = conn.getresponse()