Pete Ryland

 Home  Projects  Words  Photos  Information  Themes  News  Links  Blog

Pete Ryland's Web Log

I didn't want a blog but they made me do it.

Wed, 29 Aug 2007

An Evening with William Gibson [] (17:27)

Last night I attended a quite memorable event entitled An Evening with William Gibson. The author of classics Neuromancer and Pattern Recognition, Mr Gibson read from chapter two of his new book Spook Country, which he indicated was orignially intended to be the primary chapter. To be honest, his oratory skills pale in comparison to his story-writing ability, but it was great to be read to by the author himself.

The reading was followed by an interview on stage with John Sutherland, with questions from the floor after that. There was also the obligatory signing once the formal part was over.

Many topics were discussed but a few topics recurred and stuck with me. One was the political nature of the new book compared with the previous books to which he stated that he wouldn't be offended if someone considered Neuromancer (which was set some time in the future) anti-Regan, and in the same way, Spook Country (which I haven't yet read, but is set in the very near future) could be called by someone anti-Bush without causing offence to the author. I liked the way he phrased the sentiment, but his thinking is that all his books have some political angle, and the time of the setting makes little difference.

Reference was also repeatedly made to Node Magazine and the interactiveness of modern fiction. He considers that we are already in a world of interactive fiction and that he planted many pages on the internet for people to find when reading his books and performing web searches on the characters and other things mentioned in the narrative. This was very much the case with Spook Country but was also the case with Pattern Recognition but to a much smaller degree, and with less community involvement.

He mentioned he'd been working that day on the Wikipedia entry for the Bigend character in the book, which raised a chuckle from Prof Sutherland and he offered a more French-like pronounciation to replace Mr Gibson's overtly Engligh-based take on the fictional name.

See also:

>

Wed, 29 Nov 2006

Loop The Loop [] (21:49)

I am quite fond of the Loop The Loop (aka Slither Link) puzzles so I decided to write a solver in python for them. It reads in files like this example puzzle file. It wasn't very quick, so I ported it to this C version which is much much quicker.

>

Mon, 30 Oct 2006

DStats [] (00:00)

I was playing with GWT the other day, and with RRDtool as well, and made a little stats generation thing for my computers at home:

You can see it live too at http://pdr.cx/dstats/ but note that it will come up with a broken image the first time you load it (I have fixed that now, but it's not in a version ready for the live site) so just click on the broken image to select the server, statistic and time period.

I don't have exactly oodles of outgoing bandwidth, but locally it is very quick to load. It updates every minute, and the stats are acurate to the minute with no real lag involved. It can actually be quite difficult to see the graph moving but believe me, it actually is - no more refresh meta tags for updating stats pages!

>

Wed, 18 Oct 2006

EGG! Prototype 2! [] (10:30)

And here it is: egg20061018.tar.gz complete with two example applications as described below.

A week on from last week's release and it has really moved on in leaps and bounds. The following is a list of the recent improvements:

  • The variety of decorators has been replaced with one, egg.eggify, which intelligently decides how to wrap the method
  • Toolbar support has been added
  • Statusbar support has been added

Internally, the biggest change is that the wrapper now replaces the callback method with a (callable) object of type Egg. This turns out to be much more efficient than simply adding attributes to the existing function, although there is a tradeoff with the time it takes for the getwidget() et al calls.

Anyway, on with an example:

#!/usr/bin/python

import egg, gtk

class EGGFileView(egg.App):
  """A file viewer example application for EGG."""

  # Set up filename as a context since some functions require an open file.
  # When set to None, 0 or False, it will disable widgets needing this context.
  filename = egg.context(None)

  # The egg.eggify() decorator wraps all our callback methods in order to
  # provide necessary widgets automatically
  @egg.eggify()
  def open(self, filename):
    # Note that method docstrings are in the imperative
    """Open a file (read-only)"""
    # Pretty rough code: just read the *whole* file into a gtk TextBuffer
    file = open(filename)
    mytext = "".join(file.readlines())
    file.close()
    self.textbuffer.set_text(mytext)
    self.textbuffer.apply_tag(self.mytexttag, self.textbuffer.get_start_iter(), self.textbuffer.get_end_iter())
    # Tell the user what we've done
    self.feedback(filename + " opened.")
    # Provide the filename context, enabling appropriate widgets
    self.filename = filename

  # We provide the filename as our context to the eggify decorator function,
  # since we can't perform a close() without a non-None filename
  @egg.eggify(context=filename)
  def close(self):
    """Close the current file"""
    self.textbuffer.set_text("")
    # Tell the user what we've done
    self.feedback(self.filename + " closed.")
    # Remove the filename context, disabling functions requiring an open file
    self.filename = None

  def __init__(self):
    egg.App.__init__(self,
                     menu=[["_File", self.open, self.close, None, self.quit],
                           ["_Help", self.about]],
                     tools=[self.open, self.close, self.quit],
                     version="1.0",
                     authors=["Pete Ryland "],
                     copyright="Copyright (c) 2006 Pete Ryland",
                     license=egg.GPL
                    )
    # The below is standard gtk-type code.  This gives you an idea of what
    # we're saving ourselves from by using EGG.  Of course, EGG will eventually
    # provide TextView setup stuff somehow.  Please let me know if you have any
    # good ideas about this or other unprovided stuff like layouts.
    self.mytexttag = gtk.TextTag()
    self.mytexttag.props.family = "Monospace"
    self.textbuffer = gtk.TextBuffer()
    self.textbuffer.get_tag_table().add(self.mytexttag)
    textview = gtk.TextView(self.textbuffer)
    scrolltextview = gtk.ScrolledWindow()
    scrolltextview.add(textview)
    scrolltextview.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
    self.set_contents(scrolltextview)

if __name__ == "__main__":
  a=EGGFileView()
  a()

Here's a few things to note:

  • The menu and toolbar are set up in the egg.App.__init__ call with lists of methods. The About information is set there too.
  • The methods are called open and close which happen to resemble the names of gtk stock items, and so those items along with their standard shortcuts and pretty icons are used.
  • Because open takes a single argument called filename, eggify automatically knows to launch a file selection dialog first, and send it the filename. The method name and its argument are used to determine whether the file selection with be an "open" or "save" one, work on directories, and/or allow multiple selections.
  • The inherited feedback method sets the statusbar message, but it's still very early days for this part of the API.

Well, please do try it out, the tarball is linked at the top. And don't hesitate to send me an email with any feedback you may have (whether positive or negative!).

>

Wed, 11 Oct 2006

EGG! Prototype now available [] (22:46)

As promised, I have started on a higher-level pythonic API for gtk/gnome, built on top of pygtk/pygnome. As I'm too busy right now to package it properly, the prototype is available as a single file called egg20061011.py so if you want to try it out with the following examples, please rename it egg.py.

Well, after a brief amount of hacking about, egg now supports menus, buttons, the about dialog and the start of file selection support. On to the first example:

#!/usr/bin/python

import egg

class ButtonExample(egg.App):
  """A button example for EGG."""

  @egg.button()
  def clickMe(self):
    """Prints a message to standard ouput"""
    print "You pressed my button!"

  def __init__(self):
    egg.App.__init__(self, version="1.0")
    mybutton = self.clickMe.getbutton(self)
    self.set_contents(mybutton)

if __name__ == "__main__":
  a=ButtonExample()
  a()
This example shows the general feel of what I'm aiming at. Notice a few time-saving features:
  • Default menus are provided, with File->Quit and Help->About
  • A default About dialog is provided automatically
  • A button factory (clickMe.getbutton) is created automatically by the egg.button() decorator, and connects the button to the callback
  • The callback doesn't need to receive the widget that caused it as an argument
  • The docstring for the button is used for the tooltip and the callback method's name is used for the button's label string
  • The docstring for the App is used as the AboutDialog comment, and the class's name is used for the application name by default
It's these sort of features that will help get both new and seasoned coders producing applications quickly. The plan is to enforce good GUI practice by using sensible defaults, like the following example shows:
#!/usr/bin/python

import egg

class MenuExample(egg.App):
  """A simple example of how to do menus in EGG!"""

  @egg.menuitem(accel=ord('n'))
  def newWindow(self):
    """Creates a new window"""
    print "My callback was called!"

  @egg.stockmenuitem(stock_id=egg.STOCK_OPEN)
  @egg.fileselector()
  def open(self, filename):
    print "Opening:", filename

  def __init__(self):
    egg.App.__init__(self, version="1.0",
                     menu=[["_File", self.newWindow, self.open, None, self.quit],
                           ["_Help", self.about]]
                    )

if __name__ == "__main__":
  a=MenuExample()
  a()
This shows how to set up menus with egg. Simply create the appropriate methods, decorate them with one of the menuitem decorators, then specify them in the menu parameter of the constructor to egg.App, which takes a special format. Each menu is represented as a list, with the first item being its title, and the following items being either a menuitem method, a submenu array or None for a separator. The top-level menubar is different only in that it doesn't contain a title. There are also decorators for RadioMenuItems and CheckMenuItems. Notice how two decorators have been used on the open method; one creates an intermediate callback that creates a file open dialog and then calls back the open method with the filename if the operation was not cancelled. Notice how the open menu item's label has "..." appended? Egg knows the menuitem will be opening a dialog, so does this automatically. Don't be too scared, though, you can specify a label yourself too!

>

Tue, 10 Oct 2006

EGG [] (22:26)

Well, I've not done any major gtk programming for some time, and certainly not much gtk stuff in python, so I thought I'd see where that was at, and was quite dissappointed. Last time I looked, the documentation was pretty sparse, and pygtk was not much more than a swigging of libgtk. Now, well, it hasn't really improved a lot. It's up to date with the latest gtk and gnome versions at least and has improved the way gtk objects are mapped, but the documentation is still pretty lame, and the few tutorials I've found have been more about using glade than getting dirty with pygtk and pygnome. And quite right, too, it really does feel like a C API, which basically defeats the purpose of using python -- I may as well just code in C! The #gnome channel on gimpnet wasn't much help either, unfortunately, suggesting that people were moving away from this API.

So, I've decided to take on the challange of writing a more pythonic higher-level API for gtk, building on pygtk and pygnome (and their hard work) using more pythonesque features, including some newer ones such as decorators. The intention is to create an API that is primarily easy to use, so will do things like allow gui objects to be provided automatically by simply decorating a method with the appropriate wrapper, and provide sensible, working defaults to enable users to get something working quickly, a bit like scaffolding in RoR.

First things first then, the name. After not too much thought, I came up with EGG, Easy Gnome Gubbins. So there we have it. Expect to see some more about this in the very near future!

>

Thu, 30 Mar 2006

Tomcat Wiki [] (03:04)

Funny that Tomcat's official wiki is Python Powered. :-)

>

Request served by muriel.pdr.me.uk located in London, UK.

Trademarks owned by their respective owners.

Original content Copyright (c) 1991-2005 Pete Ryland (gpg key).