Overview
It is assumed that the reader has some knowledge of HTML (HyperText Markup Language) and programming logic. Access to reference materials is recommended!
The four-function calculator PY (Python) page uses HTML, CSS and JQuery for web page presentation and Python programming logic.
This application utilizes a client-server architecture where the client (Web Browser) initiates a request by POSTing to the web server using HTTP (Hypertext Transfer Protocol). In turn, the web server reciprocates with a web page to the client (Web Browser) as a response.
The following sections exhibit and explain the code snippets for web presentation and page processing logic including installation instructions onto a Windows operating system.
This web calculator is hosted at this link: Python_Calculator
Web Page Presentation
#' #'******************************************************** #' Browser output #'******************************************************** #' print "Content-type: text/html" print print """ <html> <head> <style> #t1 {color:green; font-size: 8pt; text-align: right;} #t2 {color:red; font-size: 8pt; text-align: right;} #btn {width:32; height:32;} </style> <title>myCalc</title> <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script> <!-- <script type="text/javascript" src="Sys_web/Incl/jquery-latest.js"> </script> --> <!-- Script to scroll both result windows simultanously --> <script type="text/javascript"> $(function() { $('#t1').scroll(function() { $('#t2') .scrollTop($('#t1').scrollTop()); }); $('#t2').scroll(function() { $('#t1') .scrollTop($('#t2').scrollTop()); }); }); </script> </head> <body> <!-- Calculator FORM --> <form method="POST" action="%s" name="CalculateIT"> <!-- Place border on FORM and border title accordingly --> <fieldset style="border-color:green; background-color:beige"> <legend style="color:blue; font-size: 18pt; background-color:lightsteelblue">%s</legend> <!-- Audit Trail and Intermediate Result textboxes --> <table align="center"> <tr> <td align="center">Audit Trail</td> <td align="center">Intermediate Results</td> </tr> <tr> <td><textarea id="t1" rows="15" name="AuditTape" cols="30" readonly="readonly">%s</textarea></td> <td><textarea id="t2" rows="15" name="AccumTape" cols="50" readonly="readonly">%s</textarea></td> </tr> </table> <!-- Script to scroll both result windows to bottom of window simultaneously --> <script type="text/javascript"> function Scroll_to_Bottom() { document.getElementById('t1').scrollTop=document.getElementById('t1').scrollHeight; document.getElementById('t2').scrollTop=document.getElementById('t2').scrollHeight; } // Call the function Scroll_to_Bottom (); </script> <!-- Audit Trail and Intermediate Result textboxes --> <br/> <table border="1" cellpadding="10" cellspacing="0" align="center" style="border-collapse: collapse ; background-color:DarkSeaGreen"> <tr> <td> <!-- Place border on keyboard and display components --> <fieldset style="border-color:green; background-color:lightsteelblue"> <!-- Calculator Display Title --> %s Digit Display <br/> <!-- Calculator Display --> <input name="NumIn" size="15" value="%s" style="text-align:right; font-size: 10pt" readonly="readoly"> <!-- Calculator Error Message area --> <br/> <font color=red size="2">%s</font> <!-- Calculator Keypad --> <br/> <input id="btn" type="submit" value="C" name="Fclear" > <input id="btn" type="submit" value="CE" name="Fcleare" > <input id="btn" type="submit" value="off" name="Poff" style="background-color: red; "> <input id="btn" type="submit" value="on" name="Pon" style="background-color: green; color:lawngreen; "> <br/> <input id="btn" type="submit" value="7" name="B7" > <input id="btn" type="submit" value="8" name="B8" > <input id="btn" type="submit" value="9" name="B9" > <input id="btn" type="submit" value="/" name="Fdiv" > <br/> <input id="btn" type="submit" value="4" name="B4" > <input id="btn" type="submit" value="5" name="B5" > <input id="btn" type="submit" value="6" name="B6" > <input id="btn" type="submit" value="x" name="Fmult" > <br/> <input id="btn" type="submit" value="1" name="B1" > <input id="btn" type="submit" value="2" name="B2" > <input id="btn" type="submit" value="3" name="B3" > <input id="btn" type="submit" value="-" name="Fminus" > <br/> <input id="btn" type="submit" value="0" name="B0" > <input id="btn" type="submit" value="." name="Bdot" > <input id="btn" type="submit" value="=" name="Fequal" > <input id="btn" type="submit" value="+" name="Fplus" > </fieldset> </td> </tr> </table> </fieldset> <input type="hidden" value="%s" name="Session_NumberIn" > <input type="hidden" value="%s" name="Session_NumberInFunction" > </form> <u><i>myCalc</i></u> is for illustrative and educational purposes and does not represent a fully robust and tested calculator product.<br> Copyright © 2015 Larry Belmontes, Jr. </body> </html> """ % (myScriptName, myTitle, frm_AuditTape, frm_AccumTape, MaxInput, frm_NumIn, ErrMsg, frm_Session_NumberIn, frm_Session_NumberInFunction)
The above snippet represents the HTML BODY section which is rendered to the browser via a set of PRINT statements. The FORM, which is within the BODY, contains three components (keypad, audit trail and results) used to interact with the web browser and web server. Below is a description of HTML used in this web page.
Line | Description |
4 | FORM declaration containing all interactive components contained within the <FORM> and </FORM> HTML tags. When form is submitted (any keypad button is pressed), form data is POST-ed to the web server by invoking ASPX script calc_42.aspx. |
6-7 | Declare a green border with the title of myWeb Calculator. The border surrounds all calculator components. A beige background is applied within the green boarder. |
9-18 | Declare a one-row, two-column table containing two text boxes (AuditTape, AccumTape) centered horizontally within the FORM. |
21-29 | Javascript to scroll down both text boxes (AuditTape, AccumTape) simultaneously keeping current activity visible. |
33 | Declares a one-row, one-column table to contain the display and keypad components centered horizontally within the FORM. A DarkSeaGreen background is applied to the this table. |
37 | Declare a green border with a lightsteelblue background for keypad components (display, error message, keypad). |
39 | Display title (e.g. 12 Digit Display) on the calculator keypad. |
42 | Numeric entry text box on the calculator keypad. |
45 | Error message area to display errors in red. |
48-71 | The buttons representing the calculator keypad. When any keypad button is pressed, the FORM contents are POSTed to the web server for processing. |
Application Processing Logic
#!/usr/bin/python # Import os functions import os # Import for CGI handling import cgi, cgitb # # Enable script debugging cgitb.enable() #' #'******************************************************** #' My first web calculator #' #' Author : Elario Belmontes, Jr. #' Description: Four function calculator simulator for #' educational purposes to illustrate the #' use of a web page on a personal web #' server #' Languages : Python, JAVASCRIPT, JQUERY, HTML, CSS #' File Name : calc_42.py #' Disclaimer: This software is intended for educational learning #' purposes. #' #' This software is provided "AS IS" and without any #' expressed or implied warranties, including, without #' limitation, the implied warranties of merchantability #' and fitness for a particular purpose. #' #' No guarantee; No warranty; Install / Use at your own risk. #' #' #' Copyright (C) 2015 Larry Belmontes, Jr. #' #' #' #'******************************************************** #' #' #' #'******************************************************** #' Script Mainline #'******************************************************** #' #' #'******************************************************** #' Create/Resume a session #'******************************************************** #' # Session variables exist as INPUT hidden fields #' for this script #' #'******************************************************** #' Get my script file name #'******************************************************** #' myScriptName = os.path.basename(os.environ['SCRIPT_NAME']) #' #'******************************************************** #' Initialize variables #'******************************************************** #' myTitle = "myWeb Calculator"; ErrMsg = " "; MaxInput = 12; #' #'******************************************************** #' Process FORM post (i.e. calculator button pressed) #'******************************************************** #' if os.environ['REQUEST_METHOD'] == 'POST': #' #'******************************************************** #' Create instance of FieldStorage from FORM #'******************************************************** form = cgi.FieldStorage() #'******************************************************** #' Obtain data from FORM controls #' and initialize variables #'********************************************************/ if form.getvalue('AuditTape'): frm_AuditTape = form.getvalue('AuditTape') else: frm_AuditTape = "" if form.getvalue('NumIn'): frm_NumIn = form.getvalue('NumIn') else: frm_NumIn = "" if form.getvalue('AccumTape'): frm_AccumTape = form.getvalue('AccumTape') else: frm_AccumTape = "" #'******************************************************** #' Obtain data from FORM controls #' The following are used as session variables #'********************************************************/ if form.getvalue('Session_NumberIn'): frm_Session_NumberIn = form.getvalue('Session_NumberIn') else: frm_Session_NumberIn = "" if form.getvalue('Session_NumberInFunction'): frm_Session_NumberInFunction = form.getvalue('Session_NumberInFunction') else: frm_Session_NumberInFunction = "" #' #'******************************************************** #' Button on FORM pressed - #' Process number, function or housekeep button on form #' #' Loop through each FORM field and take appropriate #' action from POST data #' (i.e. AuditTape=&AccumTape=&NumIn=&B8=8) #'********************************************************/ for frm_Control in form.keys(): #' #'******************************************************** #' Math functions: add, subtract, multiply, divide #'********************************************************/ if frm_Control in ["Fplus", "Fminus", "Fmult", "Fdiv"]: Do_Math(); #' #'******************************************************** #' Terminate Math function: equals #'********************************************************/ elif frm_Control in ["Fequal"]: Finalize_Math(); #' #'******************************************************** #' Housekeep: Clear all #'********************************************************/ elif frm_Control in ["Fclear"]: Clear_key(); #' #'******************************************************** #' Housekeep: Power Off #'********************************************************/ elif frm_Control in ["Poff"]: Power_Off_key(); exit(); #' #'******************************************************** #' Housekeep: Power On #'********************************************************/ elif frm_Control in ["Pon"]: Power_On_key(); #' #'******************************************************** #' Housekeep: Clear entry #'********************************************************/ elif frm_Control in ["Fcleare"]: Clear_Entry_key(); #' #'******************************************************** #' Numeric entry #' Limit to 16 digits entry excluding decimal point #'********************************************************/ elif frm_Control in ["B0", "B1", "B2", "B3", "B4", "B5", "B6", "B7", "B8", "B9"]: Numeric_key(); #' #'******************************************************** #' Decimal point entry #'********************************************************/ elif frm_Control in ["Bdot"]: Decimal_key(); else: #' #'******************************************************** #' NOT a POST, initialize session variables #' Assume first time invoked #' ** Session variables are kept as hidden INPUT fields in form #'********************************************************/ frm_AuditTape = "" frm_AccumTape = "" frm_NumIn = "" myTitle = "Welcome to myWeb Calculator and happy calculating!" frm_Session_NumberIn = "" frm_Session_NumberInFunction = ""
The above code snippet does not include functions (subroutines). Functions are defined before this code snippet and use global variable declarations for global access scope.
On initial calculator submission, the client PC web browser sends a calc_42.py URL request to the web server (IIS) via HTTP. The calc_42.py code starts execution on IIS at line 1 by importing the OS, CGI, and CGITB modules. For example, the OS module provides access to the script name and CGI module for form access.
The script mainline starts with initializing variables (lines 58-64), including the setting of variable myScriptname (line 56), and first time action logic (lines 171-176). An HTML response is constructed from the code between the <HTML> and </HTML> tags that includes STYLE, JavaScript and FORM code via a set of Python PRINT statements (lines 6-129 in the Web Presentation xxx section). The HTML response is sent via HTTP to the client PC and rendered by the web browser as an initial calculator page.
On subsequent calculation submission, the client PC web browser posts a calc_42.py request to the web server (IIS) via HTTP. The calc_42.py code starts executions on IIS at line 1. POST action logic (lines 70-163) processing occurs via the associated functions (e.g. Call Numeric_key when key 0-9 is clicked) including the updating of FORM fields. An HTML response is constructed from code between the <HTML> and </HTML> tags that includes STYLE, JavaScript and FORM code via a set of Python PRINT statements. The HTML response is sent via HTTP to the client PC and rendered by the web browser as an updated calculator page. Below is a description of Python logic for the above snippet.
Line | Description | ||||||||||||||||||||||||||||
56 | Initialize myScriptName variable | ||||||||||||||||||||||||||||
62 | Set myTitle to “myWeb Calculator” | ||||||||||||||||||||||||||||
63 | Set error message (ErrMsg) to blanks | ||||||||||||||||||||||||||||
64 | Set maximum number of digits (MaxInput) to 12 | ||||||||||||||||||||||||||||
70-163 | Logic to execute when post method = POST (keypad button has been pressed)
|
||||||||||||||||||||||||||||
171-176 | Logic to execute when post method does not = POST (first time action)
|
||||||||||||||||||||||||||||
Download and Installing Python Web Calculator
This application was successfully installed and tested on:
- Windows Home Server (part of MS Server 2003), IIS 6 with Python support, IE10, Chrome41
- Windows 7 Home Premium 64-bit,, IIS 7, IE 10, Chrome v41 (this machine acted as a client only )
** Used Python 2.7 for IIS from python.org
1. The web server, IIS (Information Internet Services), must be installed with support of Python on your desktop or laptop computer before attempting to run this web application.
2. Download the ZIP file and extract to a temporary directory.
3. Open the ZIP file and copy the file, calc_42.py, to the IIS webroot directory.
Typically, the default directory name is c:\Inetpub\wwwroot\
4. Open a browser window (e.g. Internet Explorer or Chrome)
5. Type http://localhost/calc_42.py in the address bar and press ENTER.
6. The calculator web page should display.
7. On the calculator keyboard –
Click 3. Click +. Click 7. Click /. Click 2. Click =. The result should be 5.
8. Happy calculating!!
Next Learning Experience
Extend the calculator exercise into a PERL client-server application. PERL started as a UNIX scripting language in the late 1980’s. Now, PERL has undergone several improvements and porting to different operating systems including Windows. Today, PERL scripting provides a quick, easy and powerful website development environment.
Also, developing the calculator logic using Python will facilitate comparable similarities between PHP, ASP, Javascript, and ASPX.
Take a look at related posts below!