Problems with instructions in README.rst

10 views
Skip to first unread message

David

unread,
Mar 5, 2011, 6:21:40 AM3/5/11
to py2js mailinglist
Hi,

Referring to README.rst, I have 2 problems:

Problem 1:

I need to first run this command, otherwise examples/gol.py can't find
the py2js library:

export PYTHONPATH=.

(I'm using Python version 2.6.6 on Linux, and the latest code checked
out from the git repo, commit 5d4dcf).

Problem 2:

The examples/gol.html which ships with the source code works fine for
me, but if I generate it myself, then I get a blank page.

I compared the two versions:

-----------
$ diff examples/gol.html examples/gol_2.html
7c7
< window.gol = GoL();
---
> window.__setattr__("gol", GoL())
16a17
> GoL.__setattr__ = object.prototype.__setattr__;
20,24c21,25
< this.width = 75;
< this.height = 75;
< this.canvas =
document.getElementById(js(str("canvas"))).getContext(js(str("2d")));
< this.canvas.fillStyle = js(str("rgb(0, 0, 0)"));
< this.grid = list(range((this.width)*(this.height)));
---
> this.__setattr__("width", 75)
> this.__setattr__("height", 75)
> this.__setattr__("canvas", document.getElementById(js(str('canvas'))).getContext(js(str('2d'))))
> this.canvas.__setattr__("fillStyle", js(str('rgb(0, 0, 0)')))
> this.__setattr__("grid", list(range((this.width)*(this.height))))
41c42
< setInterval(js(str("window.gol.iter()")),250);
---
> setInterval(js(str('window.gol.iter()')),250);
203c204
< extend(GoL,[object]);
---
> extend(GoL, [object]);

------------

I don't know Javascript, but I think the problem is caused by my
generated javascript incorrectly including __setattr__ method calls.

Thanks,

David.

PS: Off-topic, but there's something I want to try using py2js for,
which is basically allowing the same Python game code to run both
through Pygame (original Python), and through javascript game
libraries (like gamejs and soundmanager2), after conversion with
py2js. Is something like that practical?

Neppord

unread,
Mar 5, 2011, 7:40:47 AM3/5/11
to py...@googlegroups.com
Hi David.

We are terribly sorry that the examples don't work at the moment.

Py2js is right now in a state that is unusable. At the moment it seams to be unable to interact with the pure JavaScript used In the example. And we got a until now known issue with the python path, if you haven't posted it as an issue at qsnake's py2js repository, please do so.

How ever we are working hard at giving it a new design that will allow It to look the same but will be able to translate it to working code

About what you want to use it for it's about the same I have in mind for it.

//Samuel Ytterbrink

Ondrej Certik

unread,
Mar 5, 2011, 1:20:01 PM3/5/11
to py...@googlegroups.com, David
Hi David!

On Sat, Mar 5, 2011 at 3:21 AM, David <wizz...@gmail.com> wrote:
> Hi,
>
> Referring to README.rst, I have 2 problems:
>
> Problem 1:
>
> I need to first run this command, otherwise examples/gol.py can't find
> the py2js library:
>
> export PYTHONPATH=.
>
> (I'm using Python version 2.6.6 on Linux, and the latest code checked
> out from the git repo, commit 5d4dcf).

I see --- this sometimes happen on Ubuntu, that the current directory
is not in the PYTHONPATH. Do you think we should just add this
information into the README, or would you suggest a different fix?

I see, this was broken by a recent change, apparently it doesn't work
for this example, thanks for discovering it!

Can you try this commit:

git co d2ccc1d66

and try again? I think it should work. If it doesn't, let me know and
I'll fix it. If it does, let me know anyway, so that we know and then
we'll fix the recent commits and write a test for this example.


> PS: Off-topic, but there's something I want to try using py2js for,
> which is basically allowing the same Python game code to run both
> through Pygame (original Python), and through javascript game
> libraries (like gamejs and soundmanager2), after conversion with
> py2js. Is something like that practical?

In the future, I think so! That is my aim with py2js to allow the same
code to run in regular Python, and also in the browser.

If you'd like to help us, that'd be absolutely awesome. :)

Ondrej

Ondrej Certik

unread,
Mar 5, 2011, 1:21:22 PM3/5/11
to py...@googlegroups.com
On Sat, Mar 5, 2011 at 4:40 AM, Neppord <nep...@gmail.com> wrote:
> Hi David.
>
> We are terribly sorry that the examples don't work at the moment.
>
> Py2js is right now in a state that is unusable. At the moment it seams to be unable to interact with the pure JavaScript used In the example. And we got a until now known issue with the python path, if you haven't posted it as an issue at qsnake's py2js repository, please do so.

This was broken by the recent commits, and we'll fix it.

>
> How ever we are working hard at giving it a new design that will allow It to look the same but will be able to translate it to working code
>
> About what you want to use it for it's about the same I have in mind for it.

Definitely, we all want this.

Ondrej

Ondrej Certik

unread,
Mar 5, 2011, 1:28:50 PM3/5/11
to py...@googlegroups.com
On Sat, Mar 5, 2011 at 10:20 AM, Ondrej Certik <ond...@certik.cz> wrote:
> Hi David!
>
> On Sat, Mar 5, 2011 at 3:21 AM, David <wizz...@gmail.com> wrote:
>> Hi,
>>
>> Referring to README.rst, I have 2 problems:
>>
>> Problem 1:
>>
>> I need to first run this command, otherwise examples/gol.py can't find
>> the py2js library:
>>
>> export PYTHONPATH=.
>>
>> (I'm using Python version 2.6.6 on Linux, and the latest code checked
>> out from the git repo, commit 5d4dcf).
>
> I see --- this sometimes happen on Ubuntu, that the current directory
> is not in the PYTHONPATH. Do you think we should just add this
> information into the README, or would you suggest a different fix?

If just the README.rst file, would you mind sending us a github pull request? :)

Ondrej

David

unread,
Mar 6, 2011, 5:28:56 AM3/6/11
to py...@googlegroups.com
Hi, thanks for the replies.

(and apologies in advance for the long mail).

On Sat, Mar 5, 2011 at 8:20 PM, Ondrej Certik <ond...@certik.cz> wrote:

> I see --- this sometimes happen on Ubuntu, that the current directory
> is not in the PYTHONPATH. Do you think we should just add this
> information into the README, or would you suggest a different fix?

That's probably the simplest.

Other ways of fixing it include:

- Update your ~/.bashrc file to set PYTHONPATH
- Before importing the library, first update sys.path
- Include a module which does ^ for you, possibly with some auto-detecting.

>
> Can you try this commit:
>
> git co d2ccc1d66
>
> and try again? I think it should work. If it doesn't, let me know and
> I'll fix it. If it does, let me know anyway, so that we know and then
> we'll fix the recent commits and write a test for this example.

I got it working by checking out 7f1ab98, just before the commit
messages relating to __setattr__

>
> In the future, I think so! That is my aim with py2js to allow the same
> code to run in regular Python, and also in the browser.
>
> If you'd like to help us, that'd be absolutely awesome. :)
>
> Ondrej
>

I did some research on this. I think there's 2 main ways of achieving this:

1. Use an embedded webbrowser, like pyjamas does.

Your original Python code runs untranslated, but the browser still
runs some javascript, eg whatever javascript game libraries you're
using.

This is probably better in the longer run (so that you can use a lot
of javascript libraries, and not have to re-implement a lot of stuff
in Python), but it's a bit more complicated initially, and has more
dependencies. Also it's re-inventing a lot of stuff that
pygame-desktop already does (probably a lot easier to just use that
instead of re-implementing on top of py2js).

2. Non-browser approach: Write python code that fakes the canvas, as
well as the game library API.

This is a lot more work (to re-implement the entire canvas API, plus
any game libraries), but possibly simpler for smaller projects where
you only need a handful of functions. Over time it might be possible
to build up a fairly comprehensive pygame wrapper library.

Another problem is that this only works for canvas-like drawing areas,
as opposed to an entire webpage. So you could make your web game in
Python (and run it in pygame too), but it's harder to run the entire
webpage inside pygame. Might be interesting though as an alternative
to flash, or for people who want "pygame in the web browser".

I did some work on (2), and got the Game of Life demo working in
Pygame, with a mostly unmodified gol.py.

Here's my code (a module called py2jsgame.py on my PC):

------------
import random
import sys
import time

import pygame
import cairo
import math

sys.path.append('py2js')

def rungame(module):
game = Py2JsGame(module)
game.run()


class Py2JsGame:
def __init__(self, module):
self.module = module

def run(self):
pygame.init()

mod = self.module
size = self.module.GAME_SIZE
self.fake2dcontext = Fake2DContext(size)

mod.js = FakeJs
mod.document = FakeDocument(self.fake2dcontext)

mod.Math = FakeMath()
mod.setInterval = self.fakeSetInterval
mod.window = FakeWindow()
mod.StartGame()
pygame.display.flip()

fps = 1.0 / (self.interval / 1000.0)

# Now do the animations:
clock = pygame.time.Clock()
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT: sys.exit()

clock.tick(fps)
mod.window.game.update()
pygame.display.flip()

def fakeSetInterval(self, callback_js, interval):
self.interval = interval


class FakeMath:
def random(self):
return random.random()


class Fake2DContext(object):

def __init__(self, size):
# Setup Pygame window:
self.screen = pygame.display.set_mode(size)

# Setup cairo for drawing on the pygame screen (it's faster for some
# operations :<)
pixels = pygame.surfarray.pixels2d(self.screen)
cairo_surface = cairo.ImageSurface.create_for_data(
pixels.data, cairo.FORMAT_RGB24, size[0], size[1])
self.cairo_context = context = cairo.Context(cairo_surface)

# Color to fill with
self._fill_color = (0, 0, 0)

def clearRect(self, x1, y1, x2, y2):
# Using cairo here instead of pygame, because it performs better
#pygame.draw.rect(self.screen, (255, 255, 255), (x1, y1, x2, y2))
ctx = self.cairo_context
ctx.set_source_rgb(255, 255, 255)
ctx.rectangle(x1, y1, x2, y2)
ctx.fill()

def fillRect(self, x1, y1, x2, y2):
# Using cairo here instead of pygame, because it performs better
#pygame.draw.rect(self.screen, (0, 0, 0), (x1, y1, x2, y2))
ctx = self.cairo_context
ctx.set_source_rgb(0, 0, 0)
ctx.rectangle(x1, y1, x2, y2)
ctx.fill()

@property
def fillStyle(self):
raise NotImplementedError

@fillStyle.setter
def fillStyle(self, new_fillstyle):
assert isinstance(new_fillstyle, FakeJs)
new = new_fillstyle.js
assert new == 'rgb(0, 0, 0)'
self._fill_color = (0, 0, 0)


class FakeCanvas:
def __init__(self, fake2dcontext):
self.fake2dcontext = fake2dcontext

def getContext(self, id_):
assert isinstance(id_, FakeJs)
assert id_.js == '2d'
return self.fake2dcontext


class FakeDocument:
def __init__(self, fake2dcontext):
self.fake2dcontext = fake2dcontext

def getElementById(self, id_):
assert isinstance(id_, FakeJs)
assert id_.js == 'canvas'
return FakeCanvas(self.fake2dcontext)


class FakeJs:
def __init__(self, js):
self.js = js


class FakeWindow:
pass


def fakeSetInterval(callback_js, interval):
assert callback_js.js == 'window.game.update()'
assert interval == 250

def main():
sys.path.append(sys.argv[1])
import game
rungame(game)
------------

You use it by running it with the path to your directory containing
game.py (a renamed gol.py).

gol.py also has a few minor modifications, mainly making changing the
canvas size into a global variable GAME_SIZE, and renaming from "gol"
to "game" (trying to make the GoL example into something more
re-usable for other apps, alongside the py2jsgame.py module).

The above is pretty ugly, and does hardcode things like colors for
now. Later it would need to interpret the method arguments properly.

It also has the limitation that basically all your games would need to
follow a specific template, and use only the functions implemented so
far in Python, for it to be able to run under Pygame.

Also, the Python code performs pretty badly with the GoL demo (with
all those rectangle draws), which is why I changed it to use cairo
instead (still slow, but a bit better).

But basically, that's more or less what I had in mind in my original
mail, and what I'd like to try get working for some libraries like
gamejs/gamequery/etc (the ones with a smaller API would be easier to
fake in Python, too, as opposed to javascript game libraries like
akihabara or cocos2d-javascript, which have larger APIs).

Perhaps later I'll try getting it working in an embedded browser.
Though in that case, it's probably a lot less work to just use
pyjamas-desktop (one downside being that desktop apps don't have sound
yet, just the web/javascript ones, if you include SoundManager 2. But
maybe it's possible to add sound there in some way).

On Sat, Mar 5, 2011 at 8:21 PM, Ondrej Certik <ond...@certik.cz> wrote:
> On Sat, Mar 5, 2011 at 4:40 AM, Neppord <nep...@gmail.com> wrote:
>> Hi David.
>>
>> We are terribly sorry that the examples don't work at the moment.

It might be good to add automated tests for the examples, eg under
py2js/tests/examples, that just run the example programs and verifies
their output against known-good output.

>>
>> Py2js is right now in a state that is unusable. At the moment it seams to be unable to interact with the pure JavaScript used In the example. And we got a until now known issue with the python path, if you haven't posted it as an issue at qsnake's py2js repository, please do so.

I don't know where to report bugs. Do I need a GitHub account for that?

(It might be useful to update http://qsnake.com/py2js/html/ to mention
how to report bugs).

And changing the subject a bit:

I was playing with py2js more, trying to get it to work with
Javascript game libraries (with the idea of then getting the
unconverted Python to then run under pygame or similar, like my GoL
attempt earlier). But I had these problems:

1. GameJS.

I looked for the simplest GameJS example I could find, a basic sprite demo:

http://apps.gamejs.org/example-sprite/

Source code over here:

https://github.com/oberhamsi/gamejs/blob/master/examples/example-sprite/main.js

Basically what I wanted to do, was make Python code, that when run
through py2js, it would produce javascript code that's functionally
the same as the above.

But I got stuck on this line, near the bottom of the script:

gamejs.preload(['images/ship.png']);

I'm using the same code in my Python script, and this is the generated
Javascript:

gamejs.preload(list([str("images/ship.png")]));

Here is the code for gamejs.preload:

var preload = exports.preload = function(resources) {
// attack appBaseUrl to resources
resources.forEach(function(res) {
// normalize slashses
RESOURCES[res] = ($g.resourceBaseHref + '/' + res).replace(/\/+/g, '/');
}, this);
return;
};

However, I'm getting an error here. Firebug is reporting
"resources.forEach is not a function"

I think that means that the standard Javascript Array object has that
method, but not the 'list' py2js type. Another issue with py2js
interacting with pure javascript?

After that I tried digging a bit into the 'list' py2js type, and
seeing if passing the ._items attribute into gamejs.preload, but had
the same problem.

Is there an easy work-around for this?

2. GameQuery:

It has a lot of JQuery syntax like this in it:

$(".foo").remove();

However that dollar sign is invalid Python syntax. Is there some way
to generate syntax like the above in py2js, while still keeping valid
Python syntax?

Main thing I can think of, is making some wrapper Javascript function
that calls $, and then calling that from the Python py2js code. Would
that work?

Thanks,

David.

Christian Iversen

unread,
Mar 6, 2011, 6:18:07 AM3/6/11
to py...@googlegroups.com
On 2011-03-06 11:28, David wrote:
> Hi, thanks for the replies.
>
> (and apologies in advance for the long mail).

Don't worry :)

I took the liberty to respond to the last part of your mail.

I'm responsible for making the __setattr__ change. It seems that change
broke the demos, but really, it demonstrates that we are missing a unit
test since it wasn't caught.

> I looked for the simplest GameJS example I could find, a basic sprite demo:
>
> http://apps.gamejs.org/example-sprite/
>
> Source code over here:
>
> https://github.com/oberhamsi/gamejs/blob/master/examples/example-sprite/main.js
>
> Basically what I wanted to do, was make Python code, that when run
> through py2js, it would produce javascript code that's functionally
> the same as the above.
>
> But I got stuck on this line, near the bottom of the script:
>
> gamejs.preload(['images/ship.png']);
>
> I'm using the same code in my Python script, and this is the generated
> Javascript:
>
> gamejs.preload(list([str("images/ship.png")]));

That's because ['images/ship.png'] is a python type. We have to support
python operations like .append() and .extend() on the list, which means
that it can't simply be a javascript list.

How we interface with javascript is a very hot topic right now, and we
have figured out a way to implement better support for this in the
compiler. In the future, you simply have to declare "gamejs" as being a
javascript variable, and then all values passed to functions of it will
be automatically converted.

For now, you have to perform this conversion explicitly, with the help
of the js() function. So try

gamejs.preload(js(['images/ship.png']));

> Here is the code for gamejs.preload:
>
> var preload = exports.preload = function(resources) {
> // attack appBaseUrl to resources
> resources.forEach(function(res) {
> // normalize slashses
> RESOURCES[res] = ($g.resourceBaseHref + '/' + res).replace(/\/+/g, '/');
> }, this);
> return;
> };
>
> However, I'm getting an error here. Firebug is reporting
> "resources.forEach is not a function"
>
> I think that means that the standard Javascript Array object has that
> method, but not the 'list' py2js type. Another issue with py2js
> interacting with pure javascript?
>
> After that I tried digging a bit into the 'list' py2js type, and
> seeing if passing the ._items attribute into gamejs.preload, but had
> the same problem.
>
> Is there an easy work-around for this?

js() :)

> 2. GameQuery:
>
> It has a lot of JQuery syntax like this in it:
>
> $(".foo").remove();
>
> However that dollar sign is invalid Python syntax. Is there some way
> to generate syntax like the above in py2js, while still keeping valid
> Python syntax?
>
> Main thing I can think of, is making some wrapper Javascript function
> that calls $, and then calling that from the Python py2js code. Would
> that work?

That would work. Another way to do it is to use jQuery(js(".foo)). It's
a bit longer, but it works.

Another way that I like, is to include this javascript snippet:

function Q(x) { return jQuery(js(x)); };

That way, you just write Q instead of $ (except when you write $.foo,
then you still have to write jQuery.foo).

--
Med venlig hilsen / Best regards
Christian Iversen

Sikkerhed.org ApS
Fuglebakkevej 88 E-mail: sup...@sikkerhed.org
1. sal Web: www.sikkerhed.org
DK-2000 Frederiksberg Direkte: c...@sikkerhed.org

Reply all
Reply to author
Forward
0 new messages