Friday, September 7, 2007

Code on the Road: Navigating The Minefield that is Visual Source Safe

Code on the Road: Navigating The Minefield that is Visual Source Safe

Such a no-brainer. Why do you even try VSS to begin with? Get the Subversion plugin, grab SVN, and 99% of these things go away.

If that's not enough, git, darcs, bzr, and mercurial provide reasonable distributed solutions. Miles ahead of VSS (Actually, three generations, but who's counting.)

Seems to me, if you're really running an 'ex-pat' office, you'd want distributed. That way you can all trade changes around without having to fight conflicts. Best part is, you can stage to production without branch/tag.

Basically, there's no excuse these days for using an old VCS. Or, dare I say, a Microsoft VCS.

Thursday, September 6, 2007

On convergent evolution, and the invocation of holy wars.

Python and Ruby are the same thing.

There, with that out of the way, let me explain myself.

I was looking at a post about scene carving image retargeting which thoughtfully includes a link to his python implementation of scene carving all nicely packaged into git.

So I grabbed it, used emacs to import it into a new file, and started converting it to Ruby, since that's the language which is hitting my happy button right now (Haskell is for when I want to hurt myself). (NB said conversion I plan to post here, or at least, link to SVN for it.)

Take a look at an excerpt:


class CostMatrix(ndarray):
def calculate(self, energy_map):
if not energy_map.shape == self.shape:
raise Exception, "Wrong shape"
(h, w) = self.shape
self[0] = energy_map[0].copy()
self[0] = self[0]
for y in range(1, h):
for x in range(0, w):
bestcost = inf
bestx = x
for dx in range(x - 1, x + 2):
if dx >= 0 and dx < w:
if self[y - 1, dx] < bestcost:
bestcost = self[y - 1, dx]
bestx = dx
self[y, x] = self[y - 1, bestx] + energy_map[y, x]
self._calculated = True

def _get_max_index(self, row, startcol = 0):
maxx = startcol
maxval = self[row, maxx]

for x in range(0, len(self[row])):
if self[row, x] > maxval:
maxx = x
maxval = self[row, x]

return maxx

def find_shortest_path(self):
(h, w) = self.shape

x = self._get_max_index(-1)
path = [x]
for y in range(h - 2, -1, -1):
bestcost = inf
for dx in range(x - 1, x + 2):
if dx >= 0 and dx < w:
if self[y, dx] < bestcost:
bestcost = self[y, dx]
x = dx
path.append(x)

path.reverse()
return path


def get_image(self):
scaling = 0.03
(h, w) = self.shape
im = Image.new("L", (w, h))
im.putdata(self.flatten() * scaling)
return im


Now, if you're a python person, that should be fine. But what if you're a ruby person? That looks like ruby, where someone added in a lot of colons, and didn't remember their end tags. Oh, and someone's using paretheses oddly.

So, having converted those things, I'm confronted with a syntactically valid chunk of ruby code. It no longer throws parse errors.

This is pretty mindblowing, to me. Maybe it's something that's long since been obvious to the old hands...

Anyway, this makes me wonder why Python and Ruby aren't implemented on the same core compiler/interpreter. I know Microsoft is doing something akin to this with their Dynamic Language Runtime, but why aren't the Ruby people stealing like mad from the Python people, and vice versa?

That said, this, to me, is only the midway step between Python and Haskell. Ruby will probably take a week to do anything fun with it, so, much as I might like to throw up a free image resizing service, I'm thinking I'd rather do it in HAppS, where at least it will be fast.

Any thoughts? Am I an idiot for not seeing this already?

PS there's also another implementation of scene carving based resizing that I've been looking at.