[Edu-sig] Python + JS == more than their sum()

Wes Turner wes.turner at gmail.com
Tue Nov 22 20:02:47 EST 2016


A couple of points:

- strings are immutable
- every str.__add__ creates copies of strings
- str1 += str2 is equivalwnt to str3 = str1 + str2

  So, if, for example, we have a 1KB string and we keep += adding 1KB
strings, the allocated memory looks like:
  str1  # 1KB
  str2  # 1KB
  str_n # 1KB
  str1 += str2  # 1KB (str1), 1KB (str2), 2KB (str1` = str1 + str2) = 4 KB
  str1 += str_n # 1KB (str1), 1KB (str2), 2KB (str1` = str1 + str2), 3KB
(str1`` = str1` + str_n) = 7 KB

There's StringIO. StringIO supports .write() and doesn't require copying.

AFAICT, there's not any user supplied input in the example you've shared
here.
If there was (e.g. "include the  player name"), we would need to **escape**
it in order to prevent XSS ("Cross-Site Scripting"); so that users couldn't
add arbitrary HTML, JS, CSS to the page.

Methods for escaping user-supplied input:
HTML:
- cgi.escape * (see: bleach)
- https://pypi.python.org/pypi/bleach
- Use a templating language and configure it to "autoescape" (e.g. Jinja2)
  -  http://jinja.pocoo.org/docs/dev/api/#autoescaping is *off* by default.
     - https://pypi.python.org/pypi/MarkupSafe Markup(str) // __html__
     - https://github.com/pallets/jinja/issues/528
       - Django Templates have autoescaping on by default
         - (Jinja2 is very similar to Django Templates)
  -
https://docs.djangoproject.com/en/1.10/ref/templates/language/#automatic-html-escaping

JS:
- json.dumps

CSS:
-

... "XSS"

- https://cwe.mitre.org/top25/#CWE-79
- https://www.owasp.org/index.php/Cross-site_Scripting_(XSS)
- https://en.wikipedia.org/wiki/Cross-site_scripting#Preventive_measures


On Tuesday, November 22, 2016, kirby urner <kirby.urner at gmail.com> wrote:

>
> Wow, thank you Kevin and Wes for some
> eye-opening contributions!
>
> I really welcome their mind-expanding
> potential and have been diving into demos
> and docs all morning. [1]
>
> In my course last night we looked at that
> Jupyter Notebook comparing ES6 and
> Python scripts [2] and I also showed them
> how Python may be used to write
> HTML + CSS for browser rendering.[3]
>
> Output:  https://flic.kr/p/PjQ6Bg  (screen
> shot).
>
> Some of my students are beginner programmers,
> with little to no programming background
> so we're really just going over the basics, but at
> the same time we need to tune in the
> ecosystem with is typically a combination of
>
> Python + HTML + CSS + JS + SQL + regex
>
> at least.
>
> I use sqlite3 module for the SQL part, re module
> for regex.
>
> What we have in these resources though is
> something even more ambitious, including
> the ability to compile Python to JS!  Wow.
>
> You know what they say:  JS is the
> assembly language of the web.
>
> Even developers using JS full stack use
> transpilers to go from future JS -> past
> JS (using Babel mostly).
>
> Future JS  (from where we stand now) is
> what looks more Python-like than ever.
>
> My current mode of teaching is to have
> students install the Anaconda distro and
> then to extend the library with the requests
> and flask modules for exploring web stuff.
> Anaconda includes command line conda
> for using in place of pip, to get packages
> from a large web of repositories.
>
> Now I see conda lets me install mpld3 to
> my Mac with no issues.
>
> mackurner:~ kurner$ conda install mpld3
>
> My teaching application is here:
> thekirbster.pythonanywhere.com
>
> Kirby
>
> [1] Kevin, http://pyeverywhere.org/docs/ 404s
>
> [2] https://github.com/4dsolutions/Python5/blob/master/
> Comparing%20JavaScript%20with%20Python.ipynb
> (that's direct to Github -- nbviewer is having problems
> right now, no wait it's working again)
> https://goo.gl/nj9RPO (using nbviewer) renders the
> JS output whereas Github does not.
>
> [3] a chess board generator, just uses string
> substitution ala str.format( ) method, helps
> beginners see how HTML + CSS might be
> string output from a Python script on the server:
>
> # -*- coding: utf-8 -*-
> """
> Created on Thu Nov 17 09:02:27 2016
> https://flic.kr/p/PjQ6Bg  (screen shot).
> @author: Kirby Urner
>
> Run the script and open the output .html file
> in any browser.
> """
> from collections import namedtuple
>
> Piece = namedtuple('Piece', 'type color position unicode')
>
> black = [
>     Piece("Rook"   , "black", [7,0], "♜"),
>     Piece("Knight" , "black", [7,1], "♞"),
>     Piece("Bishop" , "black", [7,2], "♝"),
>     Piece("Queen"  , "black", [7,3], "♛"),
>     Piece("King"   , "black", [7,4], "♚"),
>     Piece("Bishop" , "black", [7,5], "♝"),
>     Piece("Knight" , "black", [7,6], "♞"),
>     Piece("Rook"   , "black", [7,7], "♜") ]
>
> for c in range(8):
>     black.append(Piece("Pawn", "black", [6,c], "♟"))
>
> white = [
>     Piece("Rook"   , "white", [0,0], "♖"),
>     Piece("Knight" , "white", [0,1], "♘"),
>     Piece("Bishop" , "white", [0,2], "♗"),
>     Piece("Queen"  , "white", [0,3], "♕"),
>     Piece("King"   , "white", [0,4], "♔"),
>     Piece("Bishop" , "white", [0,5], "♗"),
>     Piece("Knight" , "white", [0,6], "♘"),
>     Piece("Rook"   , "white", [0,7], "♖") ]
>
> for c in range(8):
>     white.append(Piece("Pawn", "white", [1,c], "♙"))
>
> the_board = \
> """
> <table>
> {white_royals}
> {white_pawns}
> {empty_cells}
> {black_pawns}
> {black_royals}
> </table>"""
>
> white_royals = "<tr>{}</tr>".format("".join(
>     ["<td>{}</td>".format(piece.unicode) for piece in white[:8]]))
> white_pawns = "<tr>{}</tr>".format("".join(
>     ["<td>{}</td>".format(piece.unicode) for piece in white[8:]]))
> black_royals = "<tr>{}</tr>".format("".join(
>     ["<td>{}</td>".format(piece.unicode) for piece in black[:8]]))
> black_pawns = "<tr>{}</tr>".format("".join(
>     ["<td>{}</td>".format(piece.unicode) for piece in black[8:]]))
>
> empty_cells = ""
> for row in range(4):
>     empty_cells += "<tr>{}</tr>".format("".join(
>         ["<td></td>" for _ in range(8)]))
>
> chess_board = the_board.format(white_royals = white_royals,
>                                white_pawns = white_pawns,
>                                empty_cells = empty_cells,
>                                black_royals = black_royals,
>                                black_pawns = black_pawns)
>
> the_page = \
> """<!DOCTYPE html>
> <html>
> <head>
> <style>
> body {
>     margin-left: 30px;
>     font-size: 20px;
> }
>
> table {
>     border: 1px solid black;
>     border-collapse: collapse;
>     border-color: black;
> }
>
> td {
>     padding: 15px;
>     border: 1px solid black;
>     height: 20px;
>     vertical-align: bottom;
> }
>
> tr:nth-child(even) td:nth-child(odd){
>     background-color: #FF8040;
> }
>
> tr:nth-child(odd) td:nth-child(even){
>         background-color: #FF8040;
> }
>
> td:hover {
>     background-color: #FF0000 !important;
>     border-color: blue;
> }
> </style>
> </head>
> <body>
> """ + \
> chess_board \
> + \
> """
> </body>
> </html>
> """
>
> with open("chessboard02.html", "w") as f:
>     f.write(the_page)
>
> print("Done!")
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/edu-sig/attachments/20161122/93bf5754/attachment.html>


More information about the Edu-sig mailing list