Friday, December 5, 2014

Some CodeSkulptor Tricks

As we've seen before, Codeskulptor is a browser-based Python programming environment built by Scott Rixner of Rice University, and uses Skulpt to interpret/run python code.

Codeskulptor screenshot

Since Skulpt's python interpreter switches back and forth between Javascript objects and Python objects, some pieces of python code have slightly different effects when run within the Codeskulptor enviromnent than they would if run in Python, and these differences can be used to create useful effects.

Reading the Console

One such useful effect comes from using the open keyword. This keyword uses the ids of the page's DOM elements as filenames, but these "files" are currently read-only.

Everytime you use the print keyword, the string is shown in the console (on the right-hand column of the screen). This function will read the contents of the console and return it as a string.

def readConsole():
    a = open("console")
    return a.read()

Browser type detection

Another useful effect comes from using the file keyword. The open keyword uses file to find and return the contents of the DOM element whose id matches the "filename" being opened. However, if you call file directly, it returns an inmutable object of unknown type, which is actually a referrence to the Javascript window variable. Although this object is inmutable, dir is able to read its list of properties and methods.

This function is a moddified version of the browser-detection code used in Codeskulptor's simplegui module.

def browserPrefix():
    w = dir(file("code"))
    v = ['ms', 'moz', 'webkit', 'o'];
    z = ''
    for y in v:
        if y+"RequestAnimationFrame" in w:
            z += y
    if z=='': z='unknown'
    return z

Session cookies

This class uses file to set up a reference to the Javascript window variable. Then creates a simplegui Control class object with this reference to window. In combining these, the Control class is able to read and write to window.textContent. Since the window variable doesn't change when you re-run or reset the python code, window.textContent can be used to simulate session cookies.

import simplegui as sg
class SessionCookie:
    __init__ = type('',[])
    def __str__(self):
        return ""
    def setup():
        a = file("code")
        c = sg.Control(a)
        def rsc(a):
            try:
                b = a.get_text()
                return b
            except:return ' '
        c.set_text(rsc(c))
        return c
    __init__.setup = setup
    del setup
    def get_pos(c,name):
        t = c.get_text()
        r = t.find(" "+name+"=")
        if (r==-1): return [-1,-1,-1,t]
        else:
            s = r + len(name) + 2
            p = t.find(";",s)
            return [r,s,p,t]
    __init__.get_pos = get_pos
    del get_pos
    def get(self,name=None):
        if name==None:
            name = self
        self = SessionCookie.__init__
        a = self.get_pos(self.setup(),str(name))
        if (a[0]==-1): return 'None'
        else: return a[3][a[1]:a[2]]
    def set(self,name,value=None):
        if value==None:
            name,value = self,name
        self = SessionCookie.__init__
        a = self.get_pos(self.setup(),str(name))
        if (a[0]==-1): v = a[3]+" "+str(name)+"="+str(value)+";"
        else:
            v = a[3][0:a[0]]+a[3][a[2]+1:len(a[3])]+" "+str(name)+"="+str(value)+";"
        self.setup().set_text(v)

Set an Unload Handler for a simplegui Frame

By default, when the user closes the simplegui popup window, the code is not notified of this event. This sometimes results in background audio that continues to play until the "reset" button is clicked. This function appends a set_unload_hander method to simplegui's Frame class. Any frames created after this automatically include this method. In this way, you can define a function to be called when the user closes the popup window.

def simplegui_frame_set_unload_handler(self,hand):
    def unload_timer_check():
        def gct():
            try:
                return self.get_canvas_textwidth("t",12)
            except:
                return 0
        t = gct()
        if t==0:
            hand()
            self.unload.stop()
    self.unload = simplegui.create_timer(1000,unload_timer_check)
    self.unload.start()
simplegui.Frame.set_unload_handler = simplegui_frame_set_unload_handler

Include these functions in you code

These functions can all be seen working here:http://www.codeskulptor.org/#user28_SWD5iUaoIAQvHpx_1.py.

To include these in your own projects, you can use import user28_SWD5iUaoIAQvHpx_1 in your code. Here's an example of the unload handler in use: http://www.codeskulptor.org/#user29_EdgayhvhdrqOaXu.py

No comments :

Post a Comment