Tao of the Machine

Programming, Python, my projects, card games, books, music, Zoids, bettas, manga, cool stuff, and whatever comes to mind.

Eye-boggling

(via my referrer log ;-) A bunch of weird optical illusions here. Check out this one:

The squares with A and B are obviously different colors... until you inspect the image in PhotoShop or whatever, and discover that they have the same RGB values. Really weird. My eyes still refuse to believe it.

Update (2003.10.15): Apparently this is the original page. Image made by Edward H. Adelson.

Posted by Hans Nowak on 2003-09-05 11:54:52   {link}
Categories: general

Massive code breakage at 11 o'clock

It came as an unpleasant surprise that the transition from Python 2.2 to 2.3 breaks a lot of production code. More so than the previous one from 2.1 to 2.2 (which hardly broke anything, IIRC).

There were two major issues:

1. Different behavior of the xml.dom.minidom.Text object. In 2.2, you can create it like this:

t = Text(text)

But in 2.3, all of a sudden it doesn't take an argument anymore, and I'd have to do this to get the same behavior:

t = Text()
t.data = text

To be fair, this is not the correct way to create it (according to Martin von Löwis); it should be created using document.createTextNode. Unfortunately, in that particular piece code I don't use a Document. (Don't ask...!)

2. Booleans. I didn't expect any problems with these; however... our system contains some code that takes the string representation of various objects, and creates SQLXML or SQL statements. Some of those objects used to be 0 or 1 (repr values "0" and "1"), but in 2.3 they have become booleans (repr values "True" and "False"). This has the unfortunate side effect of turning SQL statements like

select foo from bar where closed=1

into

select foo from bar where closed=True

which doesn't work in SQL Server. It does similar things to the SQLXML. The eventual code changes were easy, but it's quite disturbing to see 50 tests break. :-)

Update (2003.09.12). On a more positive note, my other projects (that don't rely on the string representation of boolean values) worked right out of the box, and were noticeably faster.

Posted by Hans Nowak on 2003-09-04 21:29:41   {link}
Categories: Python

A little Wax teaser

The following mini-application shows a notebook with two pages. One shows PyCrust (Patrick O'Brien's Python shell), the other PyCrust with filling (a tree-based object/namespace inspector). (Note: this is all in the development version of Wax, currently at 0.1.26.)

from wax import *

class MainFrame(Frame):
    def Body(self):
        nb = NoteBook(self)
        self.AddComponent(nb)
        
        nb.AddPage(PyCrust(nb), "PyCrust")
        nb.AddPage(PyCrustFilling(nb), "PyCrustFilling")
        self.Pack()
        
app = Application(MainFrame, title="PyCrust demo")
app.Run()

PyCrust and PyCrustFilling are (under different names) staples in wxPython, and now in Wax as well. Being able to stick a (high-quality) shell in your programs is a very useful feature.

Some more code. I added a TextEntryDialog today. This is the source:

from dialog import Dialog
from textbox import TextBox
from label import Label

class TextEntryDialog(Dialog):

    def __init__(self, parent, title="Enter some text", 
     prompt="Enter some text"):
        self.prompt = prompt
        Dialog.__init__(self, parent, title)
        
    def Body(self):
        label = Label(self, self.prompt)
        self.AddComponent(label, stretch=1, border=7)
                
        self.text = TextBox(self, size=(100,25), process_enter=1)
        self.text.OnChar = self.OnTextBoxChar
        self.AddComponent(self.text, stretch=1, border=5)
        
    def OnTextBoxChar(self, event=None):
        # pressing Enter in the TextBox is the same as clicking OK
        if event.GetKeyCode() == 13:
            self.OnClickOKButton(event)
        else:
            event.Skip()
            
    def GetValue(self):
        return self.text.GetValue()

Some thoughts:

  • You shouldn't have to know the key codes. On the other hand, having tons of special variables around is not the way to go either. I plan on adding a module or class, called keys or whatever, containing attributes with the codes... so you can say keys.enter, etc.

  • Note that you just create controls in the Body() method, and add them. The Dialog class will stack them vertically, and add the OK/Cancel buttons automatically.

  • A little extra code was necessary to make the TextBox behave correctly when pressing Enter (this has the same effect as clicking OK). We create the TextBox with argument process_enter=1, meaning it will treat Enter as any other keypress, rather than moving to the next control (which is the default behavior). Then, we add an event that does the right thing when Enter is pressed.

  • Wax is not meant as a replacement for wxPython. Rather, it's a layer on top of it. You can use wxPython controls in Wax, and vice versa (I think; I haven't actually tried this). Also, it's technically easy to "Wax-ify" a wxPython control.

Posted by Hans "ik poets de plaat" Nowak on 2003-09-02 23:09:34   {link}
Categories: Wax

Recognizing Magic cards

To assess the (market) value of the Magic card, you need to know its expansion set or edition. Recognizing this is not always easy. Modern sets all have their own unique expansion symbol, but for older cards it's not always that simple. So here's a quick guide.

N.B. These rules are a concise version of what can be found at CrystalKeep.

1. Does the card have an expansion symbol? If so, then you're all set... unless it's Arabian Nights, Antiquities, Legends or The Dark. For other sets, just look up the symbol if you don't know it.

2. For Arabian Nights, Antiquities, Legends and The Dark: look at the border of the card. Is it black? Then the card is really from those sets. If it's white, though, it's a reprint from Chronicles.

3. OK, so we have a card that has no expansion symbol. Now look if there's a copyright notice at the bottom. Not with the artist's name ("© Anson Maddocks" or whatever), but something with a year in it, like "© 1995 Wizards of the Coast, Inc. All rights reserved."
If it's there, and the year is 1995, it's a 4th Edition card.
If the year is 1997, it's a 5th Edition card.

4. The oldest cards lack both the expansion symbol and the copyright notice. The edition can be determined by these rules:

  • Limited (Alpha, Beta): black borders; Alpha card corners have a wide, circular shape; Beta card corners look like those of all the sets after it
  • Unlimited: white borders; double border around colored area
  • Revised: white borders; *no* double border around colored area; colors of art look washed out

In the meantime, I've added more cards to the list. Check them out if you're interested in acquiring some uncommons and rares for cheap.

Posted by Hans Nowak on 2003-09-01 18:17:22   {link}
Categories: CCGs

Python beginner's mistakes

It's time for you to take another hit from the Python pipe. My new article, Python beginner's mistakes, is now online.

Again, it's late and I might have written silly things, so expect some revisions. I'm also open to suggestions. What beginner's mistakes did other people make?

Posted by Hans "happiness is only a snake away" Nowak on 2003-09-01 01:28:39   {link}
Categories: Python

Cheap goodies

I'm selling some stuff. Right now there are only Magic cards, but books etc. will follow. See the trade section.

Posted by Hans Nowak on 2003-08-31 16:48:06   {link}
Categories: general, CCGs

--
Generated by Firedrop2.