Skip to content

Instantly share code, notes, and snippets.

@mmaridev
Last active October 25, 2018 16:13
Show Gist options
  • Save mmaridev/e360c3b3b8a3cf3ff4fffbb348eded3d to your computer and use it in GitHub Desktop.
Save mmaridev/e360c3b3b8a3cf3ff4fffbb348eded3d to your computer and use it in GitHub Desktop.
Python 3 web calculator with POST
#!/usr/bin/python3
# This is a script written as homework for computer science
# (c) 2018 Marco Marinello <[email protected]>
# Import modules
from http.server import BaseHTTPRequestHandler,HTTPServer
import views
# Import settings
try:
from settings import *
except Exception as e:
print("Unable to load settings, %s occurred" % e)
URLS = {
"": views.index,
"/": views.index,
"/index.html": views.index,
"/compute": views.compute,
"#404": views.e404
}
class WebCalculatorHandler(BaseHTTPRequestHandler):
def do_GET(self):
if self.path in URLS:
URLS[self.path](self, posting=False)
return
# Custom 404 error page
URLS["#404"](self, posting=False)
return
def do_POST(self):
if self.path in URLS:
URLS[self.path](self, posting=True)
return
# Custom 404 error page
URLS["#404"](self, posting=True)
return
try:
server = HTTPServer(('0', PORT), WebCalculatorHandler)
print("Server running on 0:%s" % PORT)
server.serve_forever()
except KeyboardInterrupt:
print("CTRL+C pressed, exiting...")
server.socket.close()
exit()
#!/usr/bin/python3
# This is a script written as homework for computer science
# (c) 2018 Marco Marinello <[email protected]>
import cgi
def render(request, filename, substitutions=None, state=200):
try:
h = open("templates/%s" % filename, "r")
except IOError:
print("%s cannot be found" % filename)
request.send_error(500, "Template not found")
return
content = h.read()
h.close()
if substitutions:
content = content.format(**substitutions)
request.send_response(state)
if ".htm" in filename:
request.send_header("Content-type", "text/html")
request.end_headers()
# bytes are requested to send output, encoding needed
request.wfile.write(content.encode("utf-8"))
return
def redirect(request, url):
request.send_response(301)
request.send_header("Location", url)
request.end_headers()
return
def parse_post(request):
form = cgi.FieldStorage(
fp=request.rfile,
headers=request.headers,
environ={
'REQUEST_METHOD':'POST',
'CONTENT_TYPE':request.headers['Content-Type'],
}
)
return form
def parse_number(x):
try:
v = int(x)
except ValueError:
try:
v = float(v)
except:
raise Exception("Not a number")
return v
#!/usr/bin/python3
# This is a script written as homework for computer science
# (c) 2018 Marco Marinello <[email protected]>
from utils import render, redirect, parse_post, parse_number
def index(request, posting):
render(request, "index.html")
def e404(request, posting):
render(request, "404.html", state=404)
def compute(request, posting):
if not posting:
redirect(request, "/")
return
# Parse form Content
_POST = parse_post(request)
# First of all check the two numbers
try:
n1 = parse_number(_POST["n1"].value)
n2 = parse_number(_POST["n2"].value)
except Exception as e:
print(e)
render(request, "result.html", substitutions={"result": "n1 and/or n2 aren't numbers"})
return
result = ""
op = _POST["operation"].value
if op == "+":
result = "Result: {} + {} = {}".format(n1, n2, n1+n2)
elif op == "-":
result = "Result: {} - {} = {}".format(n1, n2, n1-n2)
elif op == "x":
result = "Result: {} x {} = {}".format(n1, n2, n1*n2)
elif op == ":":
# convert into float to prevent errors
n1 = float(n1)
# n2 will be converted automatically
result = "Result: {} : {} = {}".format(n1, n2, n1/n2)
elif op == "^":
result = "Result: {} ^ {} = {}".format(n1, n2, n1**n2)
render(request, "result.html", substitutions={"result": result})
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment