Python WHL naming and platforms

Experimenting with Pypy, I wanted to try Panda3D - while its WHL builds OK,
attempting to install it generates an error about the platform -

$ pip install ./panda3d-1.10.0-cp35-cp35m-linux_x86_64.whl
panda3d-1.10.0-cp35-cp35m-linux_x86_64.whl is not a supported wheel on this platform.

Pypys CPython support keeps improving so I wanted to try it anyway - on the Panda3D forum I got a suggestion to try renaming the package.
A post on tensorflow[1] shows how to get pips supported python platforms, here's a snippet to list them:

$ python -c "import pip; print('\n'.join(['-'.join(platform) for platform in pip.pep425tags.get_supported()]))"

Here is some output for pypy3

$ python -c "import pip; print('\n'.join(['-'.join(platform) for platform in pip.pep425tags.get_supported()]))" | sort

Unfortunately, the WHL doesn't work yet, even after renaming:

$ cp panda3d-1.10.0-cp35-cp35m-linux_x86_64.whl panda3d-1.10.0-pp3510-pypy3_510-linux_x86_64.whl
$ pip install ./panda3d-1.10.0-pp3510-pypy3_510-linux_x86_64.whl
Processing ./panda3d-1.10.0-pp3510-pypy3_510-linux_x86_64.whl
Installing collected packages: panda3d
Successfully installed panda3d-1.10.0
$ python -c "from panda3d.core import *"
Traceback (most recent call last):
File "", line 1, in 
ImportError: /home/stu/.virtualenvs/pypy-nightly-py3.5/site-packages/panda3d/ undefined symbol: PyExc_ImportError

While this doesn't work, it's enough info to report a bug [2] - if that gets fixed then there are bound to be others, alternately it might just work.


Script to get Pypy nightly builds

Started a script to download Pypy nightly builds and create virtualenvs for them.

Virtualenvs are at ~/.virtualenvs where virtualenvwrapper can find them and named by pypy branch - e.g.

Downloads only happen when there are new builds, and will resume if they were interrupted.

Dronetronics VJ Set, Taipei.

Here is a pic from my first VJ outing, for Dronetronics, in Taipei, back in December. IMG_0340_4-cropped Lars from Dronetronics got in contact 2 hours before the gig, to see if I had anything for a gig at a studio not far away.   I quickly repurposed my smilies test vis (see previous post) to be suitable for Drone Music.
  • Removing the smilies
  • Added functionality to change the graphic when a button was pressed
  • Removed the OSC control - due to how sensitive the APC Mini sliders were, it looked quite amateurish (as they pick up every jolt as you move).
  • Put in new graphics (here, I only had time to find some black and white ideograms of a skull and a 'warning') sign plus an "X" I drew in the two minutes before the gig.
  • Added an option for graphics to wrap around (in the taxi on the way to the gig).
In the end, it was a great learning experience VJing for the first time, from the tech through to the setup. With thanks to Dronetronics and the studio crew at UUMouth Studio.   Sourcecode for the vis will go up shortly.

Everyday graphic

Not sure how practical it is, but will try and upload a new graphic everyday .. to start with will probably be quite basic 🙂 Here is the first, some moving granular thingies..


Shoebot code:

import random
from math import sin, cos

size(800, 800)

def draw():
    scale(1, 1)
    fill(0.1, 0.2, 0.3)

    for y in xrange(0, HEIGHT, 80):
        wiggle = sin(FRAME * 0.1)
        xs = 2.0 + (cos(y * 0.1) + sin(y) * 8.1)

        distance = 1.0 / HEIGHT * y
        fill(1.0, 1.0-distance, 0, distance)
        for x in xrange(0, 60):
            xpos = ((xs * FRAME-x * 40) % (WIDTH + 40)) - 20
            circle(xpos, y + (wiggle * random.random() * 20.0), 20 + (wiggle * 2.0) * distance * 8.0)

        #xs = -sin(y) * 4.0
        #for x in xrange(0, 60):
        #    circle(WIDTH-xs * WIDTH - FRAME + x * 40, y+40, 20)

To run this, install shoebot and type: sbot -w granuals.sbot

Drawing to the same content to many windows, cairo and zeromq

Playing with python, zeromq and Gtk, I made this code to send graphics commands to several windows.

Commands are sent over a zeromq PUB socket, the windows recieve them using zeromq SUB.

Only a few commands are wrapped as it's a proof of concept.

I'll clean it up and abstract some bits and it should be quite easy for building something like a live coding environment.

Screenshot from 2013-06-15 19:19:37

See below for code -

Posted code to github, update to work with multiprocessing.



Shoebot experiment – perlin noise..

Perlin noise is pretty cool, you can use it to generate realistic looking clouds or mountains. Here's a bot for shoebot I made a while back that uses perlin noise to generate some nice circles. You'll need shoebot and the lib "noise" installed into your environment for it to work;
# pip install noise
Then to run;
sbot -w
Here's a video of them in action - See below the break for the code - (more…)

Moving things in shoebot – simple particles…

OK, part 3 - now for something fun - extending parts 1 + 2 into a simple particle system.

Particles, generally means - a lot of things moving around (the particles) and a way to generate them, an "emitter"

Here we're going to take the code from the previous two parts and add a couple of things to make a basic particle system.
Note - shoebot, isn't the fastest; but we do get nice looking results.

Here's a video of our arrows as particles (arrowsplosion!):


Adding files to the django auto refresh

Django runserver and the app django-autotest are both good as they'll restart when modifcations are made to files in the app they will restart, however not *all* files will trigger a restart. Wanting to get some other files noticed, I added some in the of my app, so it looked like this:
    from django.conf import settings

    if settings.DEBUG:
        import forms, util, tests
This seemed to be working fine until I swapped to postgres and tried to do syncdb .. and reset, uh oh ! Postgres said (names changed to protect the innocent):
2012-05-10 09:47:57 BST STATEMENT:
                    SELECT c.relname
                    FROM pg_catalog.pg_class c
                    LEFT JOIN pg_catalog.pg_namespace n ON n.oid = c.relnamespace
                    WHERE c.relkind IN ('r', 'v', '')
                        AND n.nspname NOT IN ('pg_catalog', 'pg_toast')
                        AND pg_catalog.pg_table_is_visible(c.oid)
2012-05-10 09:47:57 BST LOG:  could not receive data from client: Connection reset by peer
2012-05-10 09:47:57 BST LOG:  unexpected EOF on client connection
2012-05-10 09:49:14 BST ERROR:  relation "sandwich_maker_filling" does not exist at character 72
2012-05-10 09:49:14 BST STATEMENT:  SELECT "sandwich_maker_filling"."id", "sandwich_maker_filling"."name" FROM "sandwich_maker_filling"
2012-05-10 09:49:14 BST ERROR:  current transaction is aborted, commands ignored until end of transaction block
And django wasn't too happy either:
Traceback (most recent call last):
  File "", line 10, in <module>
  File "/home/stu/.virtualenvs/the_app/local/lib/python2.7/site-packages/django/core/management/", line 443, in execute_from_command_line
  File "/home/stu/.virtualenvs/the_app/local/lib/python2.7/site-packages/django/core/management/", line 382, in execute
  File "/home/stu/.virtualenvs/the_app/local/lib/python2.7/site-packages/django/core/management/", line 196, in run_from_argv
    self.execute(*args, **options.__dict__)
  File "/home/stu/.virtualenvs/the_app/local/lib/python2.7/site-packages/django/core/management/", line 232, in execute
    output = self.handle(*args, **options)
  File "/home/stu/.virtualenvs/the_app/local/lib/python2.7/site-packages/django/core/management/", line 371, in handle
    return self.handle_noargs(**options)
  File "/home/stu/.virtualenvs/the_app/local/lib/python2.7/site-packages/django/core/management/commands/", line 60, in handle_noargs
    tables = connection.introspection.table_names()
  File "/home/stu/.virtualenvs/the_app/local/lib/python2.7/site-packages/django/db/backends/", line 896, in table_names
    return self.get_table_list(cursor)
  File "/home/stu/.virtualenvs/the_app/local/lib/python2.7/site-packages/django/db/backends/postgresql_psycopg2/", line 33, in get_table_list
    AND pg_catalog.pg_table_is_visible(c.oid)""")
  File "/home/stu/.virtualenvs/the_app/local/lib/python2.7/site-packages/django/db/backends/", line 40, in execute
    return self.cursor.execute(sql, params)
  File "/home/stu/.virtualenvs/the_app/local/lib/python2.7/site-packages/django/db/backends/postgresql_psycopg2/", line 52, in execute
    return self.cursor.execute(query, args)
django.db.utils.DatabaseError: current transaction is aborted, commands ignored until end of transaction block
In the end the solution was simple, just check for the args where we need the refresh to happen automatically:
## Automatically reload when forms or tests changed
    from django.conf import settings

    if settings.DEBUG:
        import sys
        if sys.argv == ['', 'autotest'] or sys.argv == ['', 'runserver']:
                # Need to check params as otherwise this can break syncdb, reset and
                # Friends !!
                import forms, util, tests
Hopefully this will be helpful to somebody with a similar error or that wants autotest or runserver to see more files.   This article was particularly helpful in debugging this:  debugging django syncdb

Cairo with python Ctypes

Uploaded some experiments with python and ctypes to here:   This is a really rough proof of concept that the pycairo API can be implemented with ctypes + metclasses.     So far only ImageSurface is supported on the SVG backend, along with Contexts.   The nice thing about this is that you can use a pycairo like API on pypy, where things should be faster (in theory).   There's a test that can be run to show the outputs the same for pycairo and cairo ctypes.