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
+
+ |
+
+
+ | Syntax |
+ http://127.0.0.1:8080/path/operand/operand |
+
+
+ | Examples |
+
+
+ | Addition |
+ http://127.0.0.1:8080/add/2/2 |
+
+
+ | Subtraction |
+ http://127.0.0.1:8080/subtract/4/2 |
+
+
+ | Multiplication |
+ http://127.0.0.1:8080/multiply/3/24 |
+
+
+ | Divison |
+ http://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()