The next relational operator I implemented in my relational python experiment was RESTRICT.
Restrict filters the set of tuples by some condition. In many formulations of the relational algebra, the restriction is on just one attribute at a time and you chain RESTRICTs together but for relational python, we'll use a lambda that can do rich testing across one or more attributes.
Here was my first attempt:
def RESTRICT(orig_rel, restriction):
new_rel = Rel(orig_rel.attributes())
for tup in orig_rel.tuples():
if restriction(tup):
new_rel.add(tup)
return new_rel
but I thought it would be neater as a list comprehension. The only problem was, there was no way in Rel to add multiple tuples at a time so I added the following method to Rel:
def add_multiple(self, tupset):
self.tuples_.update(set([self._convert_dict(tup) for tup in tupset]))
This enabled me to rewrite RESTRICT as:
def RESTRICT(orig_rel, restriction):
new_rel = Rel(orig_rel.attributes())
new_rel.add_multiple([tup for tup in orig_rel.tuples() if restriction(tup)])
return new_rel
Here's how to use the function:
rel4 = RESTRICT(rel1, lambda tup: tup["SALARY"] > "30K")
And, of course, I had to write a lazy "view" version:
class RESTRICT_VIEW(Rel):
def __init__(self, orig_rel, restriction):
Rel.__init__(self, orig_rel.attributes())
self.orig_rel = orig_rel
self.restriction = restriction
def add(self, tup):
raise Exception
def tuples(self):
for tup in self.orig_rel.tuples():
if self.restriction(tup):
yield tup
As always, suggestions for improvements are welcome in comments.
Next up, I'll implement the cross product.
by : Created on Nov. 29, 2005 : Last modified Nov. 29, 2005 : (permalink)
I've decided my Atom server prototype written in Python is probably at the stage where it needs some interoperability testing.
You can download a very early alpha at http://jtauber.com/2005/demokritos/demokritos-0.1.0.tgz
Alternatively, if you have a client and want to do some interop testing with me, either email me directly or look for me on #atom at irc.freenode.org.
Some caveats about this version:
by : Created on Nov. 29, 2005 : Last modified Nov. 29, 2005 : (permalink)
On 1st November I decided to try to lose some weight. I was already overweight at the start of this year but then put on an additional 15 pounds during the five months I was in the US and Europe.
I need to lose somewhere between 30 and 50 pounds. My first goal is to lose the 15 pounds to get me back to my weight at the start of the year. The next goal after that is to lose an additional 15 pounds to get me to the weight I was five years ago. Anything after that is a bonus but I'm going to go for another lot of 15 pounds to lose a total of 45 pounds.
My target is to lose 2 pounds per week.
I'm not doing anything dramatic. I'm easing my way into the first phase by doing four things:
For the most part, I've stuck with that so far.
More than anything, this strategy is simply reflective of what I was doing wrong before.
How am I going? I've lost 8 pounds as of last weekend (i.e. after 4 weeks). I already feel a lot less bulky. Hopefully I'll reach my first 15 pound milestone by the end of the year.
The real test will be whether I can continue the loss when visiting the US next.
by : Created on Nov. 29, 2005 : Last modified Nov. 29, 2005 : (permalink)
Devin Kilminster has taken the lead in category III of my ongoing programming competition. Unlike Mark Ellison, who used a deterministic algorithm, Devin used simulated annealing like I did.
I'm starting to put together a second edition of the programming competition that will involve more complex relationships between prerequisites. I don't think that will make the problem any harder for simulated annealing approaches (it will just involve changing the scoring function) but it will probably require quite different deterministic approaches than the current competition. I might have two divisions to keep it fair between the 'annealers' and the 'deterministas'.
by : Created on Nov. 29, 2005 : Last modified Nov. 29, 2005 : (permalink)
I haven't blogged for a week. Here's a quick summary of what I've been up to:
by : Created on Nov. 27, 2005 : Last modified Nov. 27, 2005 : (permalink)
Tim Bray has a nice summary of how the Atom Publishing Protocol works and a note on the current status.
On the weekend I worked more on my Python implementation of said protocol, Demokritos. I'm close to an initial release which won't be usable as a real Atom server yet but should be good enough for interop testing.
The small hurdle I've just encountered is that (at least in the 06 spec), Atom entries sent from clients to a server need not be fully valid entries. They can omit information that will be subsequently provided by the server itself. The mistake I've make is that my code for parsing Atom entry xml and building an object model is strict about the entry xml being valid. I'll need to relax that for incoming entry POSTs.
by : Created on Nov. 21, 2005 : Last modified Nov. 21, 2005 : (permalink)
Today I turned 040. In octal that is. 0x20 in hex.
That's 32 for the humans.
Achieved almost none of the goals that I set for myself last birthday but it was a great year nevertheless. I'll write more later.
by : Created on Nov. 19, 2005 : Last modified Nov. 19, 2005 : (permalink)
Now that we have a basic class for relations and a method for displaying them, we'll now start to go through some relational operators, starting with PROJECT.
PROJECT is defined such that if rel1 is:
+-----+-------+-----+--------+ | ENO | ENAME | DNO | SALARY | +-----+-------+-----+--------+ | E1 | Lopez | D1 | 40K | | E3 | Finzi | D2 | 30K | | E2 | Cheng | D1 | 42K | +-----+-------+-----+--------+
then PROJECT(rel1, ["ENO", "ENAME"]) is:
+-----+-------+ | ENO | ENAME | +-----+-------+ | E1 | Lopez | | E3 | Finzi | | E2 | Cheng | +-----+-------+
It's sometimes useful, even when not dealing with relations, to be able to do projections of dictionaries. The following function does that:
def project(orig_dict, attributes):
return dict([item for item in orig_dict.items() if item[0] in attributes])
This can then be used to define PROJECT:
def PROJECT(orig_rel, attributes):
new_rel = Rel(attributes)
for tup in orig_rel.tuples():
new_rel.add(project(tup, attributes))
return new_rel
(Note that if Rel took an iterator over tuples in its constructor, this could be simplified further—I might do that at some stage)
This PROJECT function implements the relational operator PROJECT. It makes a new relation based on a point-in-time snapshot of another. However, it's easy to make the projection dynamic as well.
The following class allows one to create a projection of a relation that is dynamic. In other words, it is a projection of the current state of the original relation not just at a point in time.
class PROJECT_VIEW(Rel):
def __init__(self, orig_rel, attributes):
Rel.__init__(self, attributes)
self.orig_rel = orig_rel
def add(self, tup):
raise Exception
def tuples(self):
for tup in self.orig_rel.tuples():
yield project(tup, self.attributes_)
rel3 = PROJECT_VIEW(rel1, ["ENO", "ENAME"]) works just like rel2 = PROJECT(rel1, ["ENO", "ENAME"]) except that if new tuples are added to rel1, then rel3 changes whereas rel2 stays the same.
As always, I welcome people's suggestions as to how to improve this.
by : Created on Nov. 17, 2005 : Last modified Nov. 17, 2005 : (permalink)
I want to try out Google Analytics so I've temporarily added it to this site. Just letting everyone know in the interests of openness.
by : Created on Nov. 16, 2005 : Last modified Nov. 16, 2005 : (permalink)
It's my 32nd birthday on Saturday, but Australia's soccer team, the Socceroos, gave me an early present by beating Uruguay to qualify for the World Cup in Germany next year.
The last time the Socceroos made it into the World Cup, I was only a few months old.
To give those of you in the US an idea of the significance of this: it's almost the Australian equivalent of the Red Sox winning the World Series.
One of my fondest memories growing up was watching the 1986 World Cup in Mexico. I went for Germany, as I have every time since. Next year, I'll be able to follow my home country for the first time.

by : Created on Nov. 16, 2005 : Last modified Nov. 16, 2005 : (permalink)
So my iMac is completely dead now.
I rang the local AppleCentre and asked if they had power supplies in stock. I had dreams of them being able to replace it on the spot (assuming that is the problem) so I could be up and running by this afternoon.
"We're not allowed to carry spare parts" was the response. I'm trying to keep an open mind but I'm not sure why Apple would not allow spare parts to be kept on site at an AppleCentre. Especially given how far away Perth is and how long it takes for things to get shipped here.
The estimate for the replacement power supply to come in (again assuming that's the problem—I haven't actually brought the machine in to them yet) is 1-2 weeks.
1-2 weeks without my main non-work computer!
I (stupidly in hindsight) didn't get AppleCare on the iMac (although I have it on other Apple hardware that's never had a problem). The guy on the phone claimed AppleCare owners would get priority but given it's a shipping issue I doubt it makes much difference to the 1-2 weeks.
While I do do regular backups, there's a lot of cool stuff I've been working on in the last week that isn't in the last backup.
So I'd really like access to the stuff on the hard drive. I wonder if I take my iMac apart, whether the drive will just plug straight in to my PowerMac (temporarily replacing the second drive in that).
UPDATE: When I got to the AppleCentre I asked if they could open up the iMac right away and give me the hard drive. Fortunately they were happy to do this for me. I should be able to hook it up to my PowerMac (the one usually used for music and film) and get my stuff off. Now I don't really mind the 1-2 weeks as much :-)
by : Created on Nov. 14, 2005 : Last modified Nov. 14, 2005 : (permalink)
I think I just had an epiphany regarding the upcoming coroutine support in Python. I don't mean I came up with anything new (I think Ruby programmers have been doing it for a long time), just that I finally grok it—or at least, I think I do.
You see, I'm writing a little AJAX-based flash card website and I started off writing a standalone dynamic HTML mock-up of (obviously) the client side but without any communication to the server yet.
I then wrote a console-based flash card program to experiment with the algorithm I want to use for what card to show when, when to learn new cards, etc. The console-based program just has a function called test that takes a card object, tests the card on the user and returns a boolean as to whether the user got the card right or not.
So my code has a bunch of places where I say:
for card in to_test: correct = test(card) if correct: ... else: ...
In theory, it's only this test function that's throw away. It would be nice if I just had to replace those calls to test when I come to write the server version.
The only catch is that it will be the client that initiates requests for cards. Easy, I thought: I can use yield statements in the server code wherever I want to present the user with the next card. That way, the client (or more accurately some proxy for the client running on the server) can do a next() to get the next card.
The problem is that the client needs to return the result. The yield can't be a one-way street. At the point the server yields a card, it needs to also find out the result of that yield.
Enter coroutines. If I understand correctly, this is exactly the kind of problem coroutines solve. The yield statement in my server-side code becomes a yield expression. The client sends the generator the result of testing the card and that becomes what the yield expression evaluates to.
Have I understood coroutines correctly? If so, I can't wait for Python 2.5!
by : Created on Nov. 13, 2005 : Last modified Nov. 13, 2005 : (permalink)
Okay, so this is just about the coolest optical illusion I've ever seen. Especially the second part about the pink dots disappearing all together.
Apparently the visual cortex only cares about differences and the pink dots are fuzzy enough (especially when you are focused on something else) that they seem constant even though the eye is doing its usual fast little movements (saccades). The green appears because a reduction in pink and a gain in green are the same thing.
Jenni pointed out to me that
if you fixate somewhere outside the circle, it still works, but if you move your focus to another point outside the circle, you can see the pink again. You don't have to look at the pink dots again to make them reappear. You just have to move them to a different point on the retina.
by : Created on Nov. 13, 2005 : Last modified Nov. 13, 2005 : (permalink)
In response to my comments on One Red Paperclip project and the benefits of trade, Mark Baker wonders:
if there's any way to benefit from this asymmetry on a large scale?
But I'm not sure there is an asymmetry. Remember that both parties in each exchange value what they are receiving more than what they are giving. The exchange might look asymmetric to a third party but that third party might have different values than the two participating in the exchange.
Clearly it seems dramatic when you look at the start and end points but remember also that each step is with a different person. So say A gets traded for B which gets traded for C and so on to Z.
It's possible that every participant along the way could value Z more than A but still be perfectly happy with their individual exchange.
One might argue that the person giving up Z for Y might have accepted A on the grounds that they could have done the A, B, ... Y exchanges themselves but there is the transaction cost of discovery that the person doing all the exchanges has to bear. When you think about it, the person who started with A is doing a benefit to everyone along the way, even if he's just motivated by getting Z for himself.
I think one also needs to consider that the person who gave up, say, L for K might then go trade K for something even more valuable to them, so it's not just the people on the path from A to Z that participate in some sense.
The transaction cost of discovery might be very high and this might be the undoing of a project like One Red Paperclip. How does Mr Paperclip know that exchanging P for Q gets him closer to Z? Do the self-organizing benefits of a free market really come into play when there is one person essentially trying to coordinate? Finding the individual exchanges that would lead to a particular goal sounds like a job for the market as a whole, not one individual.
Wow. Mark's question opened up a whole bunch of thoughts. And I didn't even get to his second question about the long tail. I also didn't talk about arbitrage which presumably is relevant to all this. And eBay has got to factor in somewhere :-)
As I'm just an economics novice, I'd really like to get some of my favourite economics bloggers to post their thoughts on this. I'll email Tyler Cowen and Peter Boettke and link to their posts if they make them.
by : Created on Nov. 12, 2005 : Last modified Nov. 12, 2005 : (permalink)
A couple of days ago, my iMac turned off. By itself. I didn't think much of it at the time. I thought maybe I'd shut it down and forgotten about it.
But it happened a couple more times last night and this morning. Now it dies within a minute or two of starting.
Definitely won't get stuff done this weekend that I was planning. Oh well :-)
UPDATE (2005-11-13): Now it dies within seconds of starting. I'd say the power supply is fried. From a little research it seems to be a known issue. Hopefully the local service place has power supplies in stock and can fix it on the spot.
by : Created on Nov. 12, 2005 : Last modified Nov. 12, 2005 : (permalink)
Here is the first pass of a method I wrote for displaying the relation in tabular form. One or two of the for loops could probably be replaced with a list comprehension and I should probably write to a file object that gets passed in rather than use print, but it serves the purpose of pretty printing during experimentation on the relational operators.
It will result in a display like:
+-----+-------+-----+--------+
| ENO | ENAME | DNO | SALARY |
+-----+-------+-----+--------+
| E1 | Lopez | D1 | 40K |
| E3 | Finzi | D2 | 30K |
| E2 | Cheng | D1 | 42K |
+-----+-------+-----+--------+
If it seems inefficient that display uses self.tuples() rather than self.tuples_, it is because that way it will work later on on views where tuples() is dynamic.
def display(self):
columns = range(len(self.attributes_))
col_width = [len(self.attributes_[col]) for col in columns]
for tupdict in self.tuples():
tup = self._convert_dict(tupdict)
for col in columns:
col_width[col] = max(col_width[col], len(tup[col]))
hline = ""
for col in columns:
hline += "+-" + ("-" * col_width[col]) + "-"
hline += "+"
def line(row):
l = ""
for col in columns:
value = row[col]
l += "| " + value + (" " * (col_width[col] - len(value))) + " "
l += "|"
return l
print hline
print line(self.attributes_)
print hline
for tup in self.tuples():
print line(self._convert_dict(tup))
print hline
by : Created on Nov. 11, 2005 : Last modified Nov. 11, 2005 : (permalink)
If you've sent me email in the last 18 hours, I haven't been able to read it and may not be able to do so for some time. My mail provider has had an outage (8+ hours so far) and is claiming that it will still be hours before service is returned.
UPDATE (2005-11-12): Email is still down. Could turn out to be days. Looks like Merlin Mann uses the same mail host.
UPDATE (2005-11-13): I woke up this morning and mail was working. Unfortunately iMac isn't.
by : Created on Nov. 11, 2005 : Last modified Nov. 12, 2005 : (permalink)
The One Red Paperclip project and the Donald Duck story it reminded Hans Nowak of is a nice example of a key principle in economics: voluntary trade benefits both parties.
Gene Callahan, in his wonderful book Economics for Real People, makes the point that when we trade voluntarily it isn't because we give equal value to what we are receiving and what we are giving—it is because we value what we are receiving more than what we are giving. If we valued them the same, there would be no reason to trade. (Note that I'm not just talking about monetary value.) The exact same thing is true of the other party.
People value things differently, in part because people just have different values but also because of marginal utility. Marginal utility is just the idea that the value to you of something is based on the value of getting it in addition to what you already have. e.g. if you already have enough food to eat, you might not value extra food as much. A second car isn't as valuable as the first. A third even less so. The animal in the Donald Duck cartoon that needed the string for his kite was willing to give up a pocket knife for it but if someone offered him the same deal again 5 minutes later, he likely would have rejected it as the marginal utility of the string had greatly reduced.
by : Created on Nov. 10, 2005 : Last modified Nov. 10, 2005 : (permalink)
Dave Warnock has tagged me in this blogospherical equivalent of a chain-letter.
Finishing up my linguistics degree at University of Western Australia. Working part-time there as their first webmaster. Conspiring to get SGML used on the Web.
Living in Portsmouth, New Hampshire. Working at Bowstreet Software as Director of XML Technology. Going to conferences every couple of weeks to talk on XML and Web Services.
Living back in Perth, but working for mValent in Boston. Working on the editing and scoring for my first short film, Alibi Phone Network. Resumed work on my morphological database of the Greek New Testament, MorphGNT and was in the midst of a major rewrite of Leonardo (release as 0.4)
Kaju katli, good sushi, anything at Tu Y Yo (Somerville, Mass.), anything cooked by HB, anything cooked by my Mum.
Too many to name. Certainly anything by Nelson James :-)
Relative to most of the rest of the world, I already do so I'd do what I'm already doing.
A library, a film, a piano, HB's house, my parent's house.
Wouldn't or shouldn't? :-)
Babylon 5, Seinfeld, ...
Writing open source software, making films, producing records, teaching, learning
My Macs, my Digi 002, my Canon 10D, my books (do they count as toys?)
Nelson, Graham, Rick, Anthony, Jenni
by : Created on Nov. 10, 2005 : Last modified Nov. 10, 2005 : (permalink)
A relation is basically a set of dictionaries (called tuples) where each dictionary has identical keys (called attributes).
While, as you'll see in the next couple of posts in this series, my display routine and the initial relational operators work on iterations over plain Python dictionaries, I found it useful to implement a relation, at least in these preliminary stages, using a different internal structure (something Date is clear in his book he has no problem with).
Basically, I store the each tuple internally as a Python tuple rather than a dictionary and the relation also keeps an ordered list of the attributes which is used as the index into the tuples. Amongst other things, this gets around dictionaries not being hashable. It's also a storage optimization akin to using slots for Python attributes.
Note that Rel.attributes and Rel.tuples return a set of attributes and a generator over dictionaries just as you would expect.class Rel:
def __init__(self, attributes): self.attributes_ = tuple(attributes) self.tuples_ = set()
def add(self, tup): self.tuples_.add(self._convert_dict(tup))
def _convert_dict(self, tup): return tuple([tup[attribute] for attribute in self.attributes_])
def attributes(self): return set(self.attributes_)
def tuples(self): for tup in self.tuples_: tupdict = {} for col in range(len(self.attributes_)): tupdict[self.attributes_[col]] = tup[col] yield tupdict
By implementing the handy little helper function:
def d(**args): return args
we can now create a relation and add tuples like so:
rel1 = Rel(["ENO", "ENAME", "DNO", "SALARY"])
rel1.add(d(ENO="E1", ENAME="Lopez", DNO="D1", SALARY="40K")) rel1.add(d(ENO="E2", ENAME="Cheng", DNO="D1", SALARY="42K")) rel1.add(d(ENO="E3", ENAME="Finzi", DNO="D2", SALARY="30K"))
In the next post I'll share my display routine and, following that, start on the relational operators, beginning with PROJECT.
by : Created on Nov. 9, 2005 : Last modified Nov. 9, 2005 : (permalink)
Sometimes I think about alternative paths I could have followed vocationally and the steps I would take to get there if I were much younger and making that choice now. It's almost like creating a new character in a role-playing game: "I'll start off as a economics undergraduate and then after five levels I'll switch to the prestige class Austrian Economist and go on a quest for Bigby's Prize in Honour of Alfred Nobel".
In RPGs, if you feel your character "concept" isn't working, you can go back and start a new one. Of course, that's much harder to do in real life, although some people do go back to undergraduate studies for a complete change in career.
I'm clearly multiclassing in real life. After getting a couple of levels in Mathematician, I switched over and progressed three or four in Linguist. Then I went and levelled up in Technologist a good eight or ten levels (the first few specialising in the schools of Web and XML but then also adding Python and Open Source). Somewhere along the way I picked up a level in Filmmaking and a couple in Music.
Progression as a multiclass character is much slower because you're a jack of...no...a journeyman of some.
Oddly enough, very few of my pen-and-paper RPG characters have ever been truly multiclass. They've either completely been in one class or had a few initial levels in one then made a permanent switch.
I think I'm attracted to the singular focus of just one class but, without the ability to go back and start a new character in real life, I've decided multiclassing is the way to go for me.
by : Created on Nov. 9, 2005 : Last modified Nov. 9, 2005 : (permalink)
Reading Chris Date's Database in Depth, I started to wonder what it would be like to have relational algebraic operations in Python. This is the first in a series of posts exploring that idea.
I'll start by defining a simple class for relations. In subsequent parts, I'll implement tabular display, the relational algebra and then see where it goes from there.
The goal is not to try to implement a SQL database in pure Python. Rather the goal is to extend Python's rich data structures like dictionaries and sets with additional concepts from relational theory.
It's an exploration for me and you get to come along for the ride (sort of like the Poincare Project which is by no means over yet). Maybe some of you will learn something. I certainly hope you'll teach me a thing or two in the comments and in your emails.
by : Created on Nov. 9, 2005 : Last modified Nov. 9, 2005 : (permalink)
Mark Ellison has regained the lead in Category IV of my ongoing programming competition.
by : Created on Nov. 8, 2005 : Last modified Nov. 8, 2005 : (permalink)
I've just started working on moving Demokritos over to supporting atompub-protocol-06.
I've completed the changes to the introspection document. Next step will be throwing away the old collection format in favour of a normal atom feed. I'll also need to implement support for collection indexing. I'm glad APP defines the manner in which ranges of a collection are accessed because it saves us having to come up with something proprietary for Leonardo.
by : Created on Nov. 8, 2005 : Last modified Nov. 8, 2005 : (permalink)
I'm pleased to announce the release of a new version of MorphGNT, the morphologically parsed Greek New Testament database made available under a Creative Commons license.
I haven't put together the change log yet but will shortly.
UPDATE (2005-11-08): Change log is now available on MorphGNT page.
by : Created on Nov. 7, 2005 : Last modified Nov. 8, 2005 : (permalink)
I made the mistake last week of ordering a bunch of stuff from the online Apple Store at the same time as preordering Aperture. Just about the time I thought the stuff shipping immediately would arrive, I discovered that it hadn't even shipped yet because Apple doesn't ship partial orders. I guess I'm spoilt by Amazon.
I'm going to try to give Apple a call on Monday to see if they'll just go ahead and ship the rest of the order now—otherwise I'll have to cancel the entire order and start again. Can't say this is the first time Apple shipping has let me down. (Actually, Amazon did once too, but it was an Apple product they were shipping!)
by : Created on Nov. 5, 2005 : Last modified Nov. 5, 2005 : (permalink)
Hans Nowak asks:
Why is "Iraq" spelled with a q?
Iraq in Arabic is العراق
The final letter (Arabic is written right-to-left) is ق (qāf) which is a uvular plosive. A uvular plosive is produced like a velar plosive (English 'k') but with the back of the tongue touching the roof of the mouth further back.
Arabic also has a velar plosive ﻙ (kāf).
'k' is a common transcription for velar plosives and 'q' is a common transcription for uvular plosives.
So Iraq is spelled with a 'q' because the final consonant is a uvular plosive and not a velar plosive (even though English speakers pronounce it as if it were a velar plosive). Irak would be a different word in Arabic.
by : Created on Nov. 3, 2005 : Last modified Nov. 3, 2005 : (permalink)
Bach's D minor Toccata and Fugue has long been one of my favourite works. Even though I find the exposition of the fugue oddly simplistic for Bach, I've always loved the drama of the work and its improvisational feel.
So, like Tyler Cowen, I'm shocked to discover that some scholars doubt its authenticity.
The arguments seem to include:
One theory is that it is an organ transcription of a piece for strings by another composer.
Like many popular articles on scholarly controversy, it's not easy to tell just how mainstream a view it is. It happens all the time in Biblical Studies that one scholar's controversial viewpoint is published in popular article as though it were scholarly consensus.
I'm also dubious of authorship debates in general just because I think the variation within one author can be much greater than the average difference between authors. And isn't a composer allowed to experiment and grow?
As (a sorry excuse for) a composer, I'm very aware of just how different my works from different time periods are.
Still, it's a fascinating theory, and one I might have to dive into a bit more.
by : Created on Nov. 2, 2005 : Last modified Nov. 2, 2005 : (permalink)
According to wikipedia, Mojibake refers to the gibberish characters one gets when a document's character encoding is wrongly interpreted.
(via Infundibulum)
It's actually a word I'll probably find myself using.
by : Created on Nov. 2, 2005 : Last modified Nov. 2, 2005 : (permalink)
In my previous blog entry I said:
so there need to be enough serviceable customers locally to sustain you
I initially wrote:
so there needs to be enough serviceable customers locally to sustain you
but I decided that "need" has to agree with "serviceable customers".
I confess, though, that I struggled for a while with it (although, as with many cases like this, it's clear to me now that I've thought about it).
by : Created on Nov. 2, 2005 : Last modified Nov. 2, 2005 : (permalink)
In an answer to a question asked at the end of my talk on Monday, I suggested that mValent couldn't have been started in Perth because the market is too small. I didn't say the market is too small for software companies in general, just that certain types of software (and markets) require you to be close to the customer in the early stages so there need to be enough serviceable customers locally to sustain you in the initial years. In mValent's case, I don't think that's true of Perth.
I suspect that successful software companies based in Perth generally either have an ideal customer profile that fits more local companies or have a more mature market that is easier to service remotely.
by : Created on Nov. 2, 2005 : Last modified Nov. 2, 2005 : (permalink)
Last night I was the guest speaker at the inaugural Commercial Technology Network. CTN is "an initiative to foster collaboration between entrepreneurs, service providers, suppliers, and most importantly, customers."
I was asked to speak on how I came to be involved in the founding of mValent and the role networking played.
Besides the actual telling of the story (starting all the way back at my childhood entrepreneurial endeavours) I tried to stress the importance of individual relationship building and, in particular, individual contributions to one's "tribe", particularly through a willingness to share knowledge.
One of my heroes, Tom Peters, has long talked about loyalty to one's network and recently, I've been reading the Tim Sanders book Love is the Killer App where he argues that "nice, smart people can win business and influence friends by sharing generously."
It was certainly a great honour that Michael Kyriacou and the other members of the CTN steering committee asked me to give the inaugural talk. It seemed to be well received.
by : Created on Nov. 1, 2005 : Last modified Nov. 1, 2005 : (permalink)