I’ve been using python for a while now. First, it was slightly forced at me as a configuration language of large software framework (C++ based) of one of the largest physics experiments to date. Then I’ve implemented data analysis in python that was a basis of my Ph.D. dissertation. Finally, for the last couple of years, I was using python for a wide range of activities that one would call “data science”.

Some while ago I’ve decided that trying something different would be essential for my mental hygiene. As a typical nerd, I didn’t go for rock climbing or piano lessons, but choose to apply python in a different manner. That is to flirt with the web world.

Last time I’ve tried web page programming, netscape browser was still a thing. And in each HTML file created you had to include an animated gif of a digger saying “under construction”. As you can see my webdev skills at that point were somewhat dated…

I knew earlier that python offers a number of web frameworks, with different philosophies behind them. I decided to go for flask, as it is quite popular and seems to be more DIY than django. As an initial project I decided to implement a tic-tac-toe game, with the following goals:

  • AI  must be implemented server side to force AJAX use
  • As much UI as possible is done via CSS
  • App is flask based

A basic AJAX example

It turns out, basic AJAX part is rather easy to implement in flask. Example below demonstrates basic javascript (browser) – python (server) interaction using AJAX. File structure of this simple experiment is the following:

├── basic
|     ├── __init__.py
│     ├── server.py
│     └── templates
│           ├── index.html
│           └── script.js
├── setup.py

Python part (server.py) looks the following

import datetime
from flask import Flask, send_from_directory, jsonify

app = Flask(__name__)
app.config.from_object(__name__)

@app.route('/')
def index():
    return send_from_directory("templates", "index.html")

@app.route('/<string:name>')
def static_files(name):
    return send_from_directory("templates", name)

@app.route('/hello')
def hello():
    result="Hey, I saw that! You clicked at {}".format(datetime.datetime.now())
    return jsonify(result=result)

Lines 4-5 are needed by flask to create the application. The “@app.route” decorator is a flask way to define what functions should be used to handle given URLs. The first two functions are created to handle standard requests for web page files (e.g. index.html). As a response, predefined files from templates directory are served (note: nothing is generated dynamically). The last function will be our AJAX handler. It simply returns a string with the current time and date, packed as a JSON (which stands for JavaScript Object Notation).

Client (javascript) part is the following:

function receive_hello(data){
    $("#mytarget").html(data.result)
}

function send_hello(jqevent) {
    $.getJSON("/hello", {}, receive_hello)
}

$( document ).ready(function() {
  $( window ).click(send_hello);
});

There are a couple of things happening in the listing above:

  • first of all, note the “$” sign being used a number of times. It is a way to call the jQuery javascript library. Apart from providing lots of time-saving utility functions, this shields you against subtle (and often back-stabbing) differences of javascript implementations between web browsers.
  • lines 9-11 translate to the following: “when web page finishes rendering, register a callback (the send_hello function) that will be called each time the web page is clicked inside the browser”
  • lines 5-7 define the mentioned send_hello function. Inside, the get_json helper function from jQuery is used. The first argument defines the URL (note the most part of URL – server address – is omitted here). The second argument is the (empty) arguments call list. Finally, the last argument defines which function to call when response from the server comes.
  • lines 1-3 takes any data server happily sent us and puts it on the webpage. The ‘#mytarget’ string defines where to put content (it is an identifier inside HTML source)

Getting the code and running

The source code for the example above (and not yet mentioned tictactoe implementation) can be downloaded in the following way:

git clone https://github.com/fruboes/tictactoe.git

cd tictactoe/
virtualenv venv
source venv/bin/activate

pip install -e basic/
pip install -e tictactoe/

In order to run simply execute the following

cd basic/
./start_basic.sh 

You should see a link in the terminal. After opening it and clicking anywhere on the web page in the browser you should see current date and time printed in the window. Subsequent clicks should update the time.

Da game!

If you followed the setup instructions above, you have already downloaded the source code for the tictactoe implementation. Since this was supposed to be an exercise in web development, the AI part was intentionally left stupid. If you care enough, you may want to experiment and improve it. I won’t go through the sources, since essentially this is an extended version of the basic example above.

In order to run the game, you should execute the tictactoe/start.sh script. Or you may use a running instance at http://tictactoe.pythonanywhere.com/ (as this is a free tier of pythonanywhere, I’ll keep it running for next month).

Lessons learnt along the way

Basic web development with python is rather easy to start. If you are going to try it yourself, the following may be helpful:

  • Maybe surprisingly, only a basic understanding of html5, javascript and css is needed for such exercises. I found “A Software Engineer Learns HTML5, JavaScript and jQuery: A guide to standards-based web applications” book quite helpfull, as it contains rather condensed introduction to the topic.
  • Thirst thing you should do after learning basics of javascript is to learn the javascript debugger bundled with your browser. Playing a little with rest of web developer tools you’ll find in your browser may be beneficial. At least you’ll know what’s there to use if needed.
  • If you want to play with web development, learn at least the basics of jQuery (a javascript library). As I wrote above – jQuery provides lots of time-saving utility functions and shields you against subtle (and often back-stabbing) differences of javascript implementations between web browsers.
    • In order to learn jQuery basics, I took this free MOOC, courtesy of udacity.
  • Inbetween creating the game described and writing this post I have learned basics of the Bootstrap framework. Using it to implement the tictactoe grid would probably be much simpler than implementing with CSS.
    • To learn Bootstrap, I have also gone for another free MOOC, this time by Microsoft and edx.

Multiprocessing - understand your exception Python 3.6 - Critical Mass Reached?

  1. You just earned a new regular visitor. That tic tac toe looks great. This was the kind of tutorial I was looking for, thanks.

Leave a Reply

Your email address will not be published.