The Multiplication Table

Stephen Lukacs (2) iquanta.org/instruct/python
Enter the range of the times table:
"""
reference: https://iquanta.org/instruct/python ::: Example 5, The Multiplication Table ::: Stephen Lukacs, Ph.D. ©2021-09-19

this is a final example of pure server-side processing and pure python code using py4web html functions and returning the
result with "rtn" which will automatically place it in the <body> section.

notice the html style tag, below, which allows CSS code into your web browser.  CSS is Cascading Style Sheets which
display the raw html data and style it with proper font, font sizes, or boldness, or whatever.  CSS is another language of
web browsers.

using html forms, the code does allow for the user to enter an integer in the input box to prompt for the size of the
multiplication table to make. the integer is sent back to the server when the user presses the "Submit" button and the
server reads that value, converts that string into an actual python integer, and then creates and serves up the
multiplication table which is then simply displayed by the client web browser, as shown...
"""
from py4web import URL, request
from yatl.helpers import FORM, CAT, INPUT, XML, TABLE, TR, TH, TD, DIV, STYLE, A
if ('tt_range' not in request.forms):
    #if method not written to FORM then defaults to get and variable ends up in the url, else with post, ends up in locals. however, and better, by importing request from py4web these variables will end up under request.forms or request.query for post and get, respectively.  i'll choose post with request.forms from here on out.
	rtn = FORM(_method="post")
	rtn.append(CAT("Enter the range of the times table: ", INPUT(_type="text", _name="tt_range", _value="30", _style="width:90px; height: 30px; text-align:center; border-radius:7px;"), XML('&emsp;'), INPUT(_type="submit")))
else:
	#this is still pure python code, but under the web2py framework, we can format our data using HTML functions.
	max_range = 33
	try:
		irange = int(tt_range)
		if (irange > max_range):
			irange = max_range
	except:
		irange = max_range
	#so TABLE() translates into <table>...</table>, TR() into <tr>...</tr>, TD into <td>...</td>, etc.  research HTML tag and formatting.
	t = TABLE(_class="tt")
	#first the title line
	tr = TR(TH())
	for i in range(1,irange+1):
		tr.append(TH(i))
	t.append(tr)
	#second the actual multiplication table
	for i in range(1,irange+1):
		tr = TR()
		for j in range(1,irange+1):
			td = TD(i*j, _style="")
			if (j == 1):
				tr.append(TH(i))
			if (i == j):
				td['_style'] = "font-weight:bold; border: 3px solid black;"
			if (j <= i) and ((j % 2) == 0):
				td['_style'] += "background-color: #aaa;"
			elif ((i % 2) == 0):
				td['_style'] += "background-color: #ffff80;"
			tr.append(td)
		t.append(tr)
	#and finally, third, a heading and some styling.
	#HTML is really pure data and structures.  it couples to CSS (cascading style sheets), which i embedded under the STYLE tag below.
	rtn = DIV(_class="tt")
	rtn.append(STYLE('div.tt { width: 100%; margin: auto; text-align: center; } table.tt { margin: auto; } .tt th, .tt td { padding: 0px 6px; } .tt th { text-align: center; } .tt td { text-align: center; border: 1px solid gray; }'))
	PI = request.environ.get('PATH_INFO')
	rtn.append(CAT(t, A("start over", _href=URL("python/exec/"+PI[PI.rfind('/')+1:])), ))
	#and so the rtn is really returning HTML/CSS without using the body tag.