From a7d5a905b060b43d3bb91ae2c4d89d904663adf3 Mon Sep 17 00:00:00 2001 From: b_galloway Date: Tue, 19 Jan 2021 23:15:50 -0800 Subject: [PATCH] Submitting for review --- calculator.py | 155 ++++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 138 insertions(+), 17 deletions(-) diff --git a/calculator.py b/calculator.py index a46affd..dd43fa6 100644 --- a/calculator.py +++ b/calculator.py @@ -40,31 +40,127 @@ """ - +import traceback +from functools import reduce + +def home(*args): + page = ''' +

WSGI Calculator

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Calulator tutorial
The calculator takes three paths.
+ One declaring the intended action and two representing the operands.
+ It can perform one of four actions depending on the path provided.

+ + The four paths for the calculation actions are: +
    +
  • add
  • +
  • subtract
  • +
  • multiply
  • +
  • divide
  • +
+
Syntaxhttp://127.0.0.1:8080/path/operand/operand
Examples
Additionhttp://127.0.0.1:8080/add/2/2
Subtractionhttp://127.0.0.1:8080/subtract/4/2
Multiplicationhttp://127.0.0.1:8080/multiply/3/24
Divisonhttp://127.0.0.1:8080/divide/8/4
''' + return page def add(*args): """ Returns a STRING with the sum of the arguments """ - - # TODO: Fill sum with the correct value, based on the - # args provided. - sum = "0" - - return sum - -# TODO: Add functions for handling more arithmetic operations. + body = ['

Addition Calculator

'] + _sum = sum(map(int, args)) + body.append(f'Total equals: {_sum}') + return '\n'.join(body) + +def subtract(*args): + """ Returns a STRING with the difference of the arguments """ + body = ['

Subtraction Calculator

'] + diff = reduce(lambda x,y: x - y, map(int,args)) + body.append(f'Total equals: {diff}') + return '\n'.join(body) + +def multiply(*args): + """ Returns a STRING with the product of the arguments """ + body = ['

Multiplication Calculator

'] + product = reduce(lambda x,y: x * y, map(int,args)) + body.append(f'Total equals: {product}') + return '\n'.join(body) + +def divide(*args): + """ Returns a STRING with the quotient of the arguments """ + body = ['

Divison Calculator

'] + try: + quotient = reduce(lambda x,y: x / y, map(int,args)) + body.append(f'Total equals: {quotient}') + except ZeroDivisionError: + raise ZeroDivisionError + return '\n'.join(body) def resolve_path(path): """ Should return two values: a callable and an iterable of 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 = { + '': home, + 'add': add, + 'subtract': subtract, + 'multiply': multiply, + 'divide': divide + } + + path = path.strip('/').split('/') + func_name = path[0] + args = path[1:] + + try: + func = funcs[func_name] + + except KeyError: + raise NameError return func, args @@ -73,12 +169,37 @@ def application(environ, start_response): # 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) + + body = func(*args) + status = "200 OK" + except NameError: + status = "404 Not Found" + body = "

Not Found

" + except ZeroDivisionError: + status = "405 Not Allowed" + body = f'

Cannot Divide by zero

Return home' + 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')] + + 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()