diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..600d2d3 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +.vscode \ No newline at end of file diff --git a/calculator.py b/calculator.py index a46affd..33b50e4 100644 --- a/calculator.py +++ b/calculator.py @@ -1,84 +1,100 @@ -""" -For your homework this week, you'll be creating a wsgi application of -your own. +import traceback + + +def home(): + page = ''' +

Welcome to gerardop's WSGI Calculator App

+

Addition

+

To add two integers, visit the page http://localhost:8080/add/integer1/integer2, replacing integer1 and integer2 with the integers you wish to add.

+

Example: http://localhost:8080/add/27/20

+

Subtraction

+

To subtract two integers, visit the page http://localhost:8080/subtract/integer1/integer2, replacing integer1 and integer2 with the integers you wish to subtract.

+

Example: http://localhost:8080/subtract/100/53

+

Multiplication

+

To multiply two integers, visit the page http://localhost:8080/multiply/integer1/integer2, replacing integer1 and integer2 with the integers you wish to multiply.

+

Example: http://localhost:8080/multiply/11/15

+

Division

+

To divide two integers, visit the page http://localhost:8080/divide/integer1/integer2, replacing integer1 and integer2 with the integers you wish to divide.

+

Example: http://localhost:8080/divide/235/5

+ ''' + return page -You'll create an online calculator that can perform several operations. -You'll need to support: - - * Addition - * Subtractions - * Multiplication - * Division - -Your users should be able to send appropriate requests and get back -proper responses. For example, if I open a browser to your wsgi -application at `http://localhost:8080/multiple/3/5' then the response -body in my browser should be `15`. - -Consider the following URL/Response body pairs as tests: - -``` - 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/ => 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! +def add(*args): + """ Returns a STRING with the sum of the arguments """ + sum = str(int(args[0]) + int(args[1])) + return sum -""" +def subtract(*args): + """ Returns a STRING with the difference of the arguments """ + difference = str(int(args[0]) - int(args[1])) + return difference -def add(*args): - """ Returns a STRING with the sum of the arguments """ +def multiply(*args): + """ Returns a STRING with the product of the arguments """ + product = str(int(args[0]) * int(args[1])) + return product - # TODO: Fill sum with the correct value, based on the - # args provided. - sum = "0" - return sum +def divide(*args): + """ Returns a STRING with the quotient of the arguments """ + quotient = str(int(args[0]) / int(args[1])) + return quotient -# TODO: Add functions for handling more arithmetic operations. 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 + 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) + body = func(*args) + status = '200 OK' + except NameError: + status = '404 Not Found' + body = '

Not Found

' + except ZeroDivisionError: + status = '400 Bad Request' + body = '''

Bad Request

+

Can't divide by 0

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