Tuesday, October 31, 2006

Annologger Update: now with microformats and iCal


It's been long overdue, but I've added features that I've wanted for some time--mainly microformats and iCalendar. iCalendar isn't fully featured yet, meaning if you subscribed to it using your outlook calendar, you cannot update your annolog from your outlook calendar. That said, I'm working on it, and trying to keep the code base organized and healthy, so that it's not a mess that can easily be broken. It's like cleaning up your kitchen as you cook.

So while it might not look like much, there have been some minor bug fixes and major refactoring to get these features in. Thanks for the feedback so far, and keep them coming. :)




Wilhem has built Annologger, a tool that lets people worship your dentist appointments.

Thursday, October 26, 2006

Time can be needlessly complicated

International standard date and time notation

To think that of all things I could have picked to build, it was something centered around time. Having worked on a sunrise/sunset and moonrise/moonset calculator, you'd think that I would have learned my lesson.

Time is difficult because there's always exceptions to the rule, and some specifics are unclear on first thought.

Does midnight belong to the beginning of the day, or the end? Is the end date and time of an all day event inclusive or exclusive? It ends up that luckily, there were plenty of smart people that thought about all of this decades before I came about, but they like to write in a boring prose, in specs like ISO8601.

By the way, midnight belongs to the beginning of the day, and all day events have exclusive end times. However, that's not what people mean when they say they're going to iceland from october 18th to october 22nd. When people say that, the date is inclusive. Aye.

And do you store all times in UTC? Depends on the application. Throw in time zones, there's even more confusion, not to mention taking day light savings into account. And if you really want to get nitpicky, there's always leap years and leap seconds to think about.

Wilhem has built Annologger, a tool that lets people worship your dentist appointments.

Saturday, October 14, 2006

Enumerable still...

Still playing around with Enumerables. It was almost not worth mentioning, but it's a short post. I was looking for a short way to read in a file's contents all into memory all at once. Normally you wouldn't do this, because it eats up memory if you do it this way. But my files were short.
File.open('README', 'r') do |file|
file.inject { |contents, line| contents << line }
end

This will open up a file README and return the entire contents as a string. It's pretty cool, since I don't have to muck around with temporary variables much...and it's readable...well, if 'inject' makes sense to you. Also cool is that, like Java container classes, as long as you implement 'each' in your Ruby class, you get all the ones in Enumerable for free. You just have to include it.


Wilhem has built Annologger, a tool that lets people worship your dentist appointments.

Friday, October 13, 2006

Screencast of Annologger

Screeniac � Annologger.com

I'm usually pretty busy so I don't search often on the web for what people have been saying about Annologger. But for the first thing that I put out, it's both a bit exciting and apprehensive to hear about it.

I had a really hard time choosing a name for it. To this day, I'm still not quite satisfied with the name, but apparently, people get what it is. So that's good news.

And secondly, it seems easy enough to use, so people seem to get it. I've had a lot more japanese users lately, (presumably from this review and others), and they seemed to put more stuff on there than 'test'.

But all in all, I need to put in the other features that I've been dying to get done, so people get see what its potential is.

Time to get back to work.

Tuesday, October 10, 2006

Singleton classes not seemingly the same as Singleton pattern

So I was looking at someone else's code today, and I saw this:

module Formats
class BasicNestedFormat
class << self
def foo
...foo code...
end
end
end
end


Huh? What did "<< self" mean? I guess I didn't read my Ruby book closely enough. It's apparently a "singleton class", which doesn't seem to be exactly a "singleton pattern".

A "singleton class" is a sole metaclass that 'holds' methods for a single object. It would have been called a 'metaclass', except that it's not the class of a class, but a class of a class that only exists for that one object.

Keep in mind that this is the case because you can add methods to objects in ruby at runtime. Since everything in Ruby is an object(even the classes), it has to go somewhere, and in an anonymous metaclass is where it goes.

One can almost think of them as 'static' methods in Java. However, because objects can be added methods at runtime, they don't necessarily belong in the class, but to the metaclass of an object that only belongs to that object.

They're not like 'static' classes of Smalltalk or Java. You can call self (like this in Java) in Ruby's 'static' methods.

It's a curious construct because you can use it to specify 'static' methods all in one go. It's the equivalent of the following:

module Formats
class BasicNestedFormat
def self.foo
...foo code...
end
end
end


Apparently, you can also use it to do prototype factories. There's more to it than meets the eye. You can find better explainations here and here.

Ruby is weird.


Wilhem has built Annologger, a tool that lets people worship your dentist appointments.

Thursday, October 05, 2006

The need to write code, the need to ease reading

Lately, I've been doing more thinking, reading, prototyping, and moving, than I've actually been writing code. One of the things that got me thinking enough to write this post was the classic syndrome of software developers and engineers to be gripped by the "Not invented here" syndrome.

Some would say that's because engineers and developers like to create. That's part of it too, but I think it's also partially because we only get better if we write things ourselves. The only way to learn about something fully is to actually do it. The problem is, a lot of things that we would learn by doing, has already been done for a while now. Beyond linked lists and parsers, most anything you can think of has already been done. Not that we can necessarily do it better, but doing it is half the fun, and it's the only way you can get better.
You won't become a better programmer by passively studying other people's code. Similarly, you don't magically become a better writer by reading a lot of books. You become a better writer by.. wait for it.. writing. - Jeff Atwood
So it's a balancing act between using other people's code and reusing code to be more productive, and writing your own to learn and reduce dependencies.

Another aspect that compells people to write things themselves is that
It's harder to read code than to write it. - Joel S.
I think it's because code, like math, like poetry, is dense. There are meanings and implications that aren't literal and aren't at the surface. There are implications for what gets written at every line, and relies on a culture and context behind it to fully understand it. This is why it's hard to read math equations, Alexander Pope(first one that came to mind), and much less code.
But that doesn't mean that there can't be language constructs to faciliate the ease of reading code. Python does it as a language choice that restricts whitespace. Maybe the computer doesn't care about whitespace, but people surely do.

I have recently found that iterators with descriptive names actually help in reading code. Instead of a generic for or while loop, it kinda helps to have collect, and inject.

It would be nice if code was self-documenting, meaning that you would be able to tell what the code was doing from what the method names and variables were, rather than the comments around it. It would be nice if method signatures were all you needed to know what to put into a method (and no, static typing doesn't help completely here). I wonder if language constructs could help out with it, or would we always need to rely on the stylistic tastes and discipline of the individual programmer to write readable code and documentation?



Wilhem has built Annologger, a tool that lets people worship your dentist appointments.

Looking for cumulation in Ruby?

Module: Enumerable

This is pretty basic, but I only recently discovered it. I have a task that I do often in code. Usually, there is some list of things that I'd need to go through, and tack it on to another list if it meets some condition.

funny_posts = []
posts.each do |post|
if post.is_funny?
funny_posts << post
end
end

The same problem appears when I try to summate all the things that fit some condition. I dislike having the initialization there in the beginning. Is there a better/prettier way? I would have thought collect() would be it, but it is mapping one value for another. It's almost like a function in math--a certain input gives you a certain output.

So it was finally that I saw inject(), and it seems to be what I want.

funny_posts = posts.inject([]) do |funny_posts_thus_far, post|
if post.is_funny?
funny_posts_thus_far << post
end
end

I think that'll work. The difference doesn't look like much, but somehow it bothers me when I have that floating assignment before the loop. It's easy during maintainance that someone moves 'funny_posts=[]' far away from the loop, when semantically, it's a part of how the loop will work correctly.

inject() also applied to cases where you're trying to find the maximum in a list.

# find the longest word
longest = %w{ cat sheep bear }.inject do |memo,word|
memo.length > word.length ? memo : word
end
longest #=> "sheep"

I guess it's the difference between functional programming and procedural...using return of value instead of relying on side effects. I use to write off functional programming as something that was antiquited, but now, I'm finding gems here and there in functional programming. It makes me wonder how procedural took off so rapidly. Perhaps programmers think easier in procedural programming?

Update: I guess I should read Enumerable more closely. The example I had with collecting funny posts is done with a method called partition() in Enumerables.

Sunday, October 01, 2006

The names of things

In a number of fairy tales and old legends, the name of a fairy, a monster, or a god was pivotal to the story. 'To know someone's name is to control them', it is said. I actually never gave it much thought growing up. How silly. What's in a name? A Rose by any other name would smell just as sweet.

But when it comes to ideas and concepts, a name is pretty important. Naming a variable, class, or method correctly means that there's some convention the reader of the code can go by to be able to infer how to use it. It's a type of documentation.

So when it comes to finding names for things, I have a hard time. How are 'agreements' and 'disputes' related? Are agreements and disputes the same type of thing? If so, what is the name of that thing? Or are they not the same type, but merely the same thing in different states? An agreement is the alignment of opinion between two parties where a dispute is the disalignment of opinion between two parties?

How about the person that 'seconds a motion'? What do you call that person? What do you call the person that brought up the motion in the first place?

When I think about it, public method signatures should be well designed, so that, like well designed tools, it should be obvious how to use it. However, 'obvious' comes with a background and context, and even culture.

Update:
According to wikipedia, A person that makes the motion is a mover. The person that seconds a motion could be called a supporter. And according to my lawyer and english major friends, agreements and disputes are apples and oranges, apparently. agreements and disagreements are more on the same type.

Saturday, September 30, 2006

Designing iPod vulnerability into it makes it cuddly

Everyone often raves about apple design. How sleek they look. How cool they look. However, there are sometimes practical design aspects that people complain about. Namely, I remember the first generation Nanos would have a faceplate that scratched easily.

However, I wonder if there is a side to the design that hadn't been considered. For a device like the iPod, it had the requirement of storing large amounts of data, but flash devices weren't that big in size yet. Therefore, hard drives were the only choice. However, we all know that electronics and especially hard drives are sensitive to shock. It would lose its performance and its ability to store data if it was knocked around all the time.

Whether it is intentional or a consequence of making it look sleek, the exterior of the iPod, and perhaps its vulnerability, leads people towards behavior that make them take care of it. They buy protective accessories for it, and I'm sure they throw it around less than their phones.

It would be brilliant if that was part of the requirements and spec: to get people to take care of their iPod by making it both sleek and vulnerable. It's much the same way (in function, not in emotion) that a certain instinct gets triggered when we see cute fuzzy things, except Apple managed it without fur or a large forehead.




Wilhem has built Annologger, a tool that lets people worship your dentist appointments.

Sunday, September 17, 2006

Waiting for camera manufacturers

Jeffrey Veen

You know I'm not writing code since I've been posting a lot, and also reading feeds. But one last post...

"But simplicity isn't just interface improvements, but acknowledging the right tool for the job. One of the things that has always impressed me about the iPod, for example, is that the devices have no capacity for editing metadata, deleting or moving songs, or any of the other mundane tasks of maintaining your music library. Instead, designers at Apple moved all those tasks to iTunes, exploiting your computer's keyboard, mouse, and screen real estate. Flickr takes the same approach. They could have waited for camera manufacturers to add GPS chips or asked cameraphone users to thumb in their location. They chose, however, to exploit the fact that metadata can be added asynchronously without much penalty."

spoke to me. I have been thinking about this, and was wondering if geo metadata was in pictures. My initial thought was, camera vendors really need to move beyond just taking pictures. Cameras should send photos to a repository automatically over wifi, or cameras should record not only when but also where you took a photo.

Sometimes, you can't, because you don't have any control over those products. Therefore, you make due with whatever interface is available to tie things together first, and then slowly make it better.

Simple yet deep

Point and shoot software - Signal vs. Noise (by 37signals)

I think 37signals has it right with making things simple, and emphasizing simplicity, at least on a first use basis. But I still maintain something that Guy Kawasaki said in his book, art of the start...

I'm paraphrasing, but basically simple for new users, but deep for veteran users. There's something to be said about keep mastering a product over time.

New users, no matter how tech savvy, like simple to use. But there's something to be said for the constant exploration of a device (or domain for that matter). I liken it to driving stick after learning to drive automatic.

It's often hard to build the two conflicting things in a product...control vs simplicity. But I think it's important to think of deepness as well.

Too little focus in the information we get

My Whole Life in Happy Little Folders, by Jeffrey Veen

Jeffrey Veen was complaining that it seemed like all he did was un-bold things in RSS feeds. There's just so much info that you get overwhelmed. This was one of the primary reasons I unsubscribed to ridiculously prolific blogs like smartmobs, and now signal vs noise has hell of a lot more noise now. I still subscribe due to the few gems that get dropped occasionally. But once I find others that are more quality and less quantity, I'm ready to drop them off my feed reader.

But other than complaining about blogs, this was the primary reason that I moved from bloglines to reader google. I found that having the number of unread items just felt like I was being a slacker by not reading it. Google reader is much more unforgiving. News you don't read just become that--news you don't read, and it just scrolls on by as the days past by.

It's not something foresight would have seen, unless you've actually used a feed reader before. But I'm glad that google got that right with their feed reader.

I think there's always phases to technology, as others pointed out. But beyond the adoption curve, there is the phase where the users are over-saturated, and need some type of filter. This is often overlooked in my opinion.

Saturday, September 16, 2006

The FIRST keynote of Steve Jobs 1984

cyberian.nomad.blog: The FIRST keynote of Steve Jobs 1984 - a Legend !

I often wonder what it'd be like to go back to the past knowing what you know. It's been a good 22 years since 1984. The technology back them seems primative, although you recognize a lot of the same elements that you do now.

Could some people envision 2006 if we were to tell them about it in 1984? I think some would. And others, were probably more optimistic about certain things. Notice the AI thing with the Macintosh talking.

What would it be like in 20 years? I have to admit, I am optimistic about the advance of technology. I have dreams for the future. I dream that computing will really be ubiquitous, and that mobile computing and information gathering will be more common. I dream that augmented reality will come to be common place, whether on PDAs, cell phones, eye glasses, contacts, VRDs, or ocular implants. Devices, whether microwave to cell phones, will really begin to interoperate on open standards, and have a collective intelligence for the whole house. I dream that bio interfaces will allow the blind to see, to store information, or to access information. I dream that quantum computers will start to appear on the market. And I dream that code will be modular, reuseable, simple to read, and simple to maintain. haha.

Friday, September 15, 2006

First Principles of Interaction Design

AskTog: First Principles of Interaction Design

To be honest, this is a boring list of things to read through. Some seem obvious and common sense. But you'll find that in design, often times, obvious is shadowed by functionality and common sense is hard when you have constraints. This might have been better reading if it contained examples, like in The Design of Everyday Things.

But what I noticed was that these principles were very similar to those of game design. I can't pinpoint the article this afternoon, since I read it close to six years ago. But there was an article on gamasutra that talked about how hard it was to design games to make the player happy.

The game designer has to balance the hardness of the game. Too challenging, the game will be unobvious and frustrating (like this game was purported to be). Too trivial, the game will lose the interest of its players quickly (like Eat the stick.

I remember another thing about consistency. One game designer was talking about how he met a gamer, and the gamer had the idea that once you go to another section of the game, all the properties of the spells you could cast would change. The game designer went into detail about how this was one of the worst mistakes that early game designers make. Consistency affords a sense of building up a knowledge of the world around you from a player point of view.

If every time you went to another section of the game, and you had to relearn the mechanics of the game all over again, it would probably piss you off.

In a lot of ways, there are parallels between game design and application design. I also remember all those comic strips in the 90's satirizing how kids can't get jobs playing video games growing up. I think that's more and more untrue, with the way the gaming industry is unfolding. The idea the games are a diversion and are for children will be a thing of the past.

Monday, September 11, 2006

Friendships aren't binary

I feel old. Partially because social networks separate me from friends that are merely two years younger. I am part of the 'Friendster' generation. I was able to sign up for that, before the meteoric rise of 'MySpace', and 'Facebook'. I ignored MySpace invitations, writing it off as 'nothing special' (I also thought that Britney Spears was going to be a one-hit wonder), and by the time facebook rolled around, I had already left graduate school.

While I'm excited about social network applications, my opinion of social network apps was that they didn't actually DO anything. Beyond the novelty of being able to see my network, trouncing about the network didn't actually let me get anything DONE. No wonder why people called them the biggest waste of time. Perhaps, like bad TV, it was just a reaction to a guilty pleasure.

However, it was recently that I was able to sign on to Facebook, because I found that there is an alumni web mail service that I was able to utilize. I liked the Facebook interface immediately. Unlike friendster, it was clean, and it was fast. It didn't feel cluttered at all.

On the friends page, it would tell you that a profile was updated, and yet, I didn't know what. So I never really browsed, knowing that I won't want to spend time trying to find it. Therefore, I was pleasantly surprised by the mini-news feeds: now I knew exactly what was updated, so I don't have to look around for it.

Here, I was able to see what my network was doing. What groups they were joining, what messages they were posting. Perhaps here-in lies the utility of a social network; an individual would know what's going on with his or her friends. The flipside of this feature was that most people felt like their privacy was invaded.

It's odd, because I, as a newcomer, didn't have much expectations of how things worked, so I more readily accepted the mini-news feeds. Therefore, I wonder if facebook had this feature in the beginning, would there be as much of a protest? Perhaps it would have had slower growth?

I think the assumption that facebook developers had was that
  1. users wouldn't mind that their friends knew what they were up to because of #2
  2. everyone named as friends were trusted
  3. all friendships are created equal
In reality, often times, the people in your friendship list might not be friends, but contacts, or campers. And even if the only people that you accepted were friend friends, not all friends are created equal. I think it's safe to say we all have aspects of ourselves that we show in front of some friends but not others. I remember I had friends in college that did weed or drank a ton, but they never invited me out with them to do it.

Given that, I can definitely see how they went ahead and did it. And often times, as a developer, if you don't simplify things, you'll never get anything done.

One, facebook's reaction to the backlash was a pretty good one, in my opinion. They put out a major announcement, as well as give one-click options to remove it by choice within two days. I applaud them for it. However, they managed to keep things simple. Choice can easily come with its strange bedfellow, complexity.

Second, perhaps, the model for naming friends should be changed. Perhaps it shouldn't be activated by individuals, but rather, inferred through activities. Then, you can be able to tell between active friends, and long lost friends. You would also be able to tell the context of the relationship, as well as which domain it falls under. Then perhaps, privacy would be less of an issue with a selected multicast of information, such as photos, who I'm dating, and where I'm going.



Wilhem has built Annologger, a tool that lets people worship your dentist appointments.

Sunday, September 10, 2006

Cavets for doing what you love

The usual thing that you hear we tell kids is "you can be whatever you want to be" when it's really not entirely true. A more accurate saying might be, "you can be whatever you work hard at, even if you might not be the best." For adults, the line is, "do what you love."

What if you suck at what you love? If American Idol is any indication, passion doesn't always equal aptitude. Beyond American Idol, there are plenty of people that are always 'striking it out on their own' that are still doing so. There's plenty of actors and actresses that are waiters and waitresses. I suppose the assumption is that when you do what you love, you will spend time doing it, instead of going out, instead of playing video games, instead of watching TV. You'll keep going at it even after failure and rejected. And the biggest assumption is that you'll get better as you keep going at it.

So keep at it. And get better.



Wilhem has built Annologger, a tool that lets people worship your dentist appointments.

Thursday, August 31, 2006

Getting Started - UIDWiki

Getting Started - UIDWiki: "Turn on Javascript errors for extensions. Normally the Javascript console only displays errors for web pages, not for Firefox or its extensions. Go to the URL about:config and turn on javascript.options.showInConsole."

This'll help speed development.

Sunday, August 27, 2006

Moving people versus building things.

My sister often marvels at my ability to build things.
You know, I always feels useless around you because you have tangible skills.
Being an engineer, I often found envy from the liberal arts majors on having 'tangible skills'. I was in a business writing class that was required of all majors, where we learned the basics of writing letters, resumes, and memos. During the resume writing session, we were doing peer critiques.

Looking at the number of projects that I've done, the programming languages I knew, the liberal arts majors exclaimed "Wow, you actually have skills!"

However, I find that the ability to move people is just as important. There are many things you can do as an individual nowadays. We have plenty of tools and information available for us to do that, more than ever. And yet, there are certain types of things where you need a group of people to move forward with together. And in order to do that, one has to be able to guide people in the same direction, to be able to move them in the same direction.

That, I find to be a skill more enviable.

Friday, August 25, 2006

Temporal Expressions as a cousin to Regular Expressions

When thinking about recurring dates, I realized that it's actually a pretty tough problem. How do you represent recurring dates in a database? Ideally, you don't want all the instances of recurring dates from the epoch until the End of Time. I had an inkling that it should be possible to express a generalized sense of a range of dates, but I didn't really know exactly how that would manifest itself.

That's when I started looking for what people had done before me, since I dislike reinventing the wheel. The first thing I came upon was this recurrence python module. Reading his comments in the code, I thought being able to express dates as an equivalent of a polynomial made a lot of sense.

In fact, functions are condensed form of a set of numbers. Not all sets of numbers can be expressed by functions, but most of the ones that we care about can usually be. That makes them useful. Are there equivalent of 'functions for dates'?

That's when I ran into Runt, a ruby library that deals with recurring dates, which are based off of temporal expressions pattern by Martin Fowler.

But it wasn't exactly what I had in mind when I read 'temporal expressions'. I was thinking that Martin Fowler came up with something like regular expressions, but for time. After reading the tutorial, it wasn't exactly what I had in mind. It used classes and patterns to represent recurring dates, rather than an expression, like a function.

So we come to the crux of my musing. Are there the equivalent of regular expressions for time, and would it be a good idea to use it?

When I first started using regular expressions, I thought it was hard to use. Not only could I not remember what some of the symbols meant, but it was dense and not easy to read. A complicated regex quickly got out of hand. I wondered if there were alternatives to regex. And apparently I wasn't the only one either(and that post was from 2001).

If I were to use something like regex for date and time, like a temporal expression--tempex*, I wouldn't want something syntactically like regex. It's really rather hard to read, even if it's powerful (read "dense": can say alot with a little).

In drawing the parallel between regex and functions, that could be the reason why people find math arcane: the expressions in math and regex both can say alot with a little.

One should be able to represent dates and times in a matter that you can express sets of dates succinctly, and event better, be able to do operations on them, such as union, intersect, and difference.

I was surprised that it seems like there's nothing out there that I can find that is a regular expression for time. This shouldn't be the case. Runt is the closest thing that I can find so far. Anyone else know of anything else out there?

* I'll have to pick some other name later. people already use the term for natural language processing of time-related phrases, in addition to Martin Fowler's usage for the pattern

Friday, August 18, 2006

Back to coding

I've been getting back into the swing of things after a brief haitus. Currently, there's a code freeze, so I can catch up with the tests. I know I'm not suppose to do it backwards like this, but when you're sketching out how things should work, updating both code and tests are tedious.

I figured this is a good time to update all the tests, so code freeze for about 3 days. Code coverage at...53%

I'll do more tonight. Then it's off to do more cool and exciting features!
  • RSS feeds
  • iCal publishing
  • better date/time selector
  • end dates that matter
  • photo posting
  • "I'll go if I can"