From f4ddfac83f055483adaae6a39f1c70e3964b6a00 Mon Sep 17 00:00:00 2001 From: Ian Mayther Date: Mon, 31 May 2021 08:47:21 -0700 Subject: [PATCH 01/10] Completed boiler plate wsgi for if --- calculator.py | 22 +++++----------------- 1 file changed, 5 insertions(+), 17 deletions(-) diff --git a/calculator.py b/calculator.py index a46affd..04286f7 100644 --- a/calculator.py +++ b/calculator.py @@ -1,3 +1,5 @@ +import re +import traceback """ For your homework this week, you'll be creating a wsgi application of your own. @@ -25,20 +27,6 @@ http://localhost:8080/divide/22/11 => 2 http://localhost:8080/ => Here's how to use this page... ``` - -To submit your homework: - - * Fork this repository (Session03). - * Edit this file to meet the homework requirements. - * Your script should be runnable using `$ python calculator.py` - * When the script is running, I should be able to view your - application in my browser. - * I should also be able to see a home page (http://localhost:8080/) - that explains how to perform calculations. - * Commit and push your changes to your fork. - * Submit a link to your Session03 fork repository! - - """ @@ -79,6 +67,6 @@ def application(environ, start_response): pass 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() From 136ea47ade7be952b82d63a37594b28d5acac853 Mon Sep 17 00:00:00 2001 From: Ian Mayther Date: Mon, 31 May 2021 08:48:49 -0700 Subject: [PATCH 02/10] Inserted app code from bookapp --- calculator.py | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/calculator.py b/calculator.py index 04286f7..40e6b53 100644 --- a/calculator.py +++ b/calculator.py @@ -64,7 +64,25 @@ def application(environ, start_response): # # 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 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__': from wsgiref.simple_server import make_server From d612f68807370329321f1b142a921161a957be37 Mon Sep 17 00:00:00 2001 From: Ian Mayther Date: Mon, 31 May 2021 10:22:35 -0700 Subject: [PATCH 03/10] Stubbed out '' response --- calculator.py | 20 +++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/calculator.py b/calculator.py index 40e6b53..030f10b 100644 --- a/calculator.py +++ b/calculator.py @@ -28,7 +28,8 @@ http://localhost:8080/ => Here's how to use this page... ``` """ - +def operations(): + return '

Operations

' def add(*args): """ Returns a STRING with the sum of the arguments """ @@ -51,8 +52,21 @@ 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'] + + funcs = { + '' : operations, + 'add' : add, + } + + path = path.strip('/').split('/') + + func_name = path[0] + args = path[1:] + + try: + func = funcs[func_name] + except KeyError: + raise NameError return func, args From 9b58c7ce3eae99b169437054413cdfc70ec8d9d4 Mon Sep 17 00:00:00 2001 From: Ian Mayther Date: Mon, 31 May 2021 10:27:48 -0700 Subject: [PATCH 04/10] Add function to work correctly --- calculator.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/calculator.py b/calculator.py index 030f10b..b298515 100644 --- a/calculator.py +++ b/calculator.py @@ -36,9 +36,12 @@ def add(*args): # TODO: Fill sum with the correct value, based on the # args provided. - sum = "0" + sum = 0 - return sum + for item in args: + sum += int(item) + + return str(sum) # TODO: Add functions for handling more arithmetic operations. From fc85153389449c61a8298322146ebd8bb125293a Mon Sep 17 00:00:00 2001 From: Ian Mayther Date: Mon, 31 May 2021 10:38:45 -0700 Subject: [PATCH 05/10] Subtracty function working correctly --- calculator.py | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/calculator.py b/calculator.py index b298515..d975e91 100644 --- a/calculator.py +++ b/calculator.py @@ -43,6 +43,17 @@ def add(*args): return str(sum) +def subtract(*args): + """Return a STRING with the difference of the arguments""" + in_list = [int(x) for x in args] + + diff = in_list.pop(0) + + for item in in_list: + diff -= item + + return str(diff) + # TODO: Add functions for handling more arithmetic operations. def resolve_path(path): @@ -59,6 +70,7 @@ def resolve_path(path): funcs = { '' : operations, 'add' : add, + 'subtract': subtract, } path = path.strip('/').split('/') From e21fce5f751ae9141dc015286145f5044a51cb19 Mon Sep 17 00:00:00 2001 From: Ian Mayther Date: Mon, 31 May 2021 10:43:13 -0700 Subject: [PATCH 06/10] Multiply function working correctly --- calculator.py | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/calculator.py b/calculator.py index d975e91..58665c7 100644 --- a/calculator.py +++ b/calculator.py @@ -34,8 +34,6 @@ def operations(): 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 for item in args: @@ -54,6 +52,16 @@ def subtract(*args): return str(diff) +def multiply(*args): + """Return a STRING with the product of the arguments""" + in_list = [int(x) for x in args] + + prod = in_list.pop(0) + + for item in in_list: + prod *= item + + return str(prod) # TODO: Add functions for handling more arithmetic operations. def resolve_path(path): @@ -71,6 +79,7 @@ def resolve_path(path): '' : operations, 'add' : add, 'subtract': subtract, + 'multiply': multiply, } path = path.strip('/').split('/') From 4a80df5e1c5f2ae1b40a45a8781a75e78feb8c04 Mon Sep 17 00:00:00 2001 From: Ian Mayther Date: Mon, 31 May 2021 10:45:29 -0700 Subject: [PATCH 07/10] Multiply function working correctly --- calculator.py | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/calculator.py b/calculator.py index 58665c7..eda72b9 100644 --- a/calculator.py +++ b/calculator.py @@ -62,6 +62,17 @@ def multiply(*args): prod *= item return str(prod) + +def divide(*args): + """Return a STRING with quotent of the arguments""" + in_list = [int(x) for x in args] + + quot = in_list.pop(0) + + for item in in_list: + quot /= item + + return str(quot) # TODO: Add functions for handling more arithmetic operations. def resolve_path(path): @@ -80,6 +91,7 @@ def resolve_path(path): 'add' : add, 'subtract': subtract, 'multiply': multiply, + 'divide' : divide, } path = path.strip('/').split('/') From 25f4f09d7e36c5b5123356ec96b229103aaae75b Mon Sep 17 00:00:00 2001 From: Ian Mayther Date: Mon, 31 May 2021 10:54:58 -0700 Subject: [PATCH 08/10] Divide by zero error handling --- calculator.py | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/calculator.py b/calculator.py index eda72b9..1bde21a 100644 --- a/calculator.py +++ b/calculator.py @@ -69,11 +69,14 @@ def divide(*args): quot = in_list.pop(0) + if 0 in in_list: + raise ValueError + for item in in_list: quot /= item return str(quot) -# TODO: Add functions for handling more arithmetic operations. + def resolve_path(path): """ @@ -125,6 +128,9 @@ def application(environ, start_response): except NameError: status = "404 Not Found" body = "

Not Found

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

Bad Request

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

Internal Server Error

" From 5615c44b072e7d83c54675366d4adf49d3a05a3e Mon Sep 17 00:00:00 2001 From: Ian Mayther Date: Mon, 31 May 2021 11:41:15 -0700 Subject: [PATCH 09/10] Root directory working correctly --- calculator.py | 47 ++++++++++++++++++++++++++++++++++++----------- 1 file changed, 36 insertions(+), 11 deletions(-) diff --git a/calculator.py b/calculator.py index 1bde21a..3700735 100644 --- a/calculator.py +++ b/calculator.py @@ -28,8 +28,26 @@ http://localhost:8080/ => Here's how to use this page... ``` """ + +op_output = 'Your Answer is: ' + def operations(): - return '

Operations

' + """ Returns a STRING with instructions """ + body = [ + 'WSGI Calculator', + '

Operations

', + 'Select an operation. Then append the web address with /(any number you want)/(any number you want)', + '
    '] + + ops = ['Add','Subtract','Multiply','Divide'] + + item_template = '
  • {1}
  • ' + + for item in ops: + body.append(item_template.format(item.lower(),item)) + body.append('
') + + return '\n'.join(body) def add(*args): """ Returns a STRING with the sum of the arguments """ @@ -39,35 +57,43 @@ def add(*args): for item in args: sum += int(item) - return str(sum) + return op_output + str(sum) def subtract(*args): """Return a STRING with the difference of the arguments""" in_list = [int(x) for x in args] - diff = in_list.pop(0) + try: + diff = in_list.pop(0) + except IndexError: + diff = 0 for item in in_list: diff -= item - return str(diff) + return op_output + str(diff) def multiply(*args): """Return a STRING with the product of the arguments""" in_list = [int(x) for x in args] - - prod = in_list.pop(0) + try: + prod = in_list.pop(0) + except IndexError: + prod = 0 for item in in_list: prod *= item - return str(prod) + return op_output + str(prod) def divide(*args): - """Return a STRING with quotent of the arguments""" + """Return a STRING with quotent of the arguments""" in_list = [int(x) for x in args] - quot = in_list.pop(0) + try: + quot = in_list.pop(0) + except IndexError: + quot = 0 if 0 in in_list: raise ValueError @@ -75,8 +101,7 @@ def divide(*args): for item in in_list: quot /= item - return str(quot) - + return op_output + str(quot) def resolve_path(path): """ From dbffdf9d8891a7516568574c48a932018cae0920 Mon Sep 17 00:00:00 2001 From: Ian Mayther Date: Mon, 31 May 2021 11:45:03 -0700 Subject: [PATCH 10/10] Passes test and returns correct results --- calculator.py | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/calculator.py b/calculator.py index 3700735..ae1f930 100644 --- a/calculator.py +++ b/calculator.py @@ -135,13 +135,7 @@ def resolve_path(path): 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. + """Return byte code for wsgi server""" headers = [('Content-type', 'text/html')] try: path = environ.get('PATH_INFO', None)