diff --git a/calculator.py b/calculator.py index a46affd..ae1f930 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,33 +27,81 @@ http://localhost:8080/divide/22/11 => 2 http://localhost:8080/ => Here's how to use this page... ``` +""" -To submit your homework: +op_output = 'Your Answer is: ' - * 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! +def 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)', + '') + return '\n'.join(body) 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" + sum = 0 + + for item in args: + sum += int(item) + + 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] + + try: + diff = in_list.pop(0) + except IndexError: + diff = 0 + + for item in in_list: + diff -= item + + 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] + try: + prod = in_list.pop(0) + except IndexError: + prod = 0 - return sum + for item in in_list: + prod *= item -# TODO: Add functions for handling more arithmetic operations. + return op_output + str(prod) + +def divide(*args): + """Return a STRING with quotent of the arguments""" + in_list = [int(x) for x in args] + + try: + quot = in_list.pop(0) + except IndexError: + quot = 0 + + if 0 in in_list: + raise ValueError + + for item in in_list: + quot /= item + + return op_output + str(quot) def resolve_path(path): """ @@ -63,22 +113,53 @@ 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, + '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 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 + """Return byte code for wsgi server""" + 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 ValueError: + status = "400 Bad Request" + body = "

Bad Request

" + 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()