I program stuff.

Thursday, June 07, 2007

Mike Nelson's Mantras on Programming.

Mantra 1: Today's hot new system is tomorrow's legacy system. It will be hard to use, interface with, and support given enough time.

Mantra 2: Never call a routine 'smart', it is not. It doesn't matter how dumb the code was that it is replacing.

Mantra 3: Don't build for the future, it is unknown. Don't build for the past either for it is just as unknown. Building a new system to replace an old one is tantamount to ignoring the lessons of the past.

Mantra 4:
Build for the now. Only consider what it should do today. Not what may happen tomorrow or what it could do.

Mantra 5: Mostly the tenants of maintainable code are fallacies. When he says maintainable code he just means code that he would write.

Mantra 6: All code takes effort to understand. No matter how beautiful it is. Beautiful code just makes the puzzle more interesting.

Mantra 7:
No code is maintainable. Code is an object. It is only the coder that can take the action to maintain it.

Mantra 8:
Is the effort to make code maintainable greater than the effort to maintain it? Why do more of a thing in order to do less of another?

Mantra 9: Do not attempt to do today what you will know how to do tomorrow.

Mantra 10: Just because you are doing work that does not mean you are adding value; you might be removing value.

Mantra 11: Just because I am using newer tools that does not mean that I am smarter.

Mantra 11: Just because I am using better tools that does not mean that I am better.

Mantra 12: A programmer is not defined by his tools.

Mantra 13: Why must I always use the latest swiss army knife when I can use the sturdy blade?

Mantra 14: Just because I write the code that does not mean I am better than the people that maintain the code. They have to deal with what I write.

Mantra 15: Just because I write the code that does not mean I am better than the users. They are the ones that I wrote it for.

Mantra 16: My software is not a gift of my benevolence.

Mantra 17: How would it help for us all use the same tools? We are not all doing the same thing.

Mantra 18: Software is never good enough. Just make sure that it is good.

Mantra 19: Do not say, "I am a C++ programmer," or "I am a Windows programmer." Don't even say, "I am a computer programmer." Instead declare, "I am a programmer."

Tuesday, May 22, 2007

I got hit by this MSN messenger spam attack last night. It looked like someone I knew sent this in messenger,
"hi, check this http://whoadmitsyou.com and find out who deleted and blocked you from the Msn"

Thursday, May 10, 2007

Footboard

This is pretty ingenious. Might not be too useful but I can imagine that it could be useful in some settings. Like for voice bindings ut2004 for instance. :)

footboard

Friday, May 04, 2007

Web 2.0 is the future now!!!

Seriously, what the hell is wrong with us?

Sunday, March 25, 2007

I was poking around at some programming languages again while thinking about concurency in programming and ran into a discussion on this very thing. Someone there mentioned Erlang as a good language to solve these sorts of problems. I'd never heard of it so I started checking it out. It does indeed have great concurrency support. I was going through their white paper and I found this other great feature that it has that has nothing to do with concurrency.


This program sorts a list using the Quicksort algorithm:
     sort([]) -> [];
     sort([Pivot|T]) ->
          sort([X||X <- T, X < Pivot]) ++
          [Pivot] ++
          sort([X||X <- T, X >= Pivot]).


from "Example 4 - Sort" of the whitepaper.

As it says in there ++ is the infix append operator and this example introduces what they call a list comprehension. Like it says in the whitepaper,


The notation [Expr || Qualifier1, Qualifier2, ...] introduces a list comprehension. Here Expression is an arbitrary expression, and each Qualifier is either a generator or a filter.

For example, the list comprehension

[X || X <- [1,2,a,3,4,b,5,6], integer(X), X > 3].

should be read as:

The list of X such that X is taken from the list [1,2,a,3,4,b,5,6] and X is an integer and X is greater than 3.

Here X <- [1,2,a,3,4,b,5,6] is a generator, and integer(X) and X > 3 are filters. This list comprehension evaluates to [4,5,6].


I was very impressed with this, at one time I was trying to come up with a syntax for this type of expression myself. At that point I'd never seen a language with a compact expression of this idea. I thought SQL where clauses are very close but the rest of the SQL statement is a bit to verbose for this type of case.

Then as I read the example program after understanding this I could clearly see the logic of the Quicksort program and for the first time I understood how the Quicksort algorithm works. I'm a little embarrassed to say but I've never fully understood how a Quicksort algorithm worked before reading the Erlang example. I very clearly remember reading my first introduction to this algorithm back in 1986, or something like that, in a Compute!'s Gazette (a magazine for Commodre computers). I never understood how that Basic implementation worked and from then on I've had some sort of block on my understanding how this algorithm worked. I've come across it may times in may different languages but all the implementations have been cryptic to my eyes. All I could clearly remember is the phrase "divide and conquer", which I think was mentioned in that first Computes!'s Gazette article, but never quite understanding how that helps you sort quickly. This phrase haunting my memory whenever I came across the Quicksort.

Well after about 10 minutes into reading Erlang's whitepaper with no exposure to Erlang before this and once I finished reading their "Example 4 - Sort" the program,


This program sorts a list using the Quicksort algorithm:
     sort([]) -> [];
     sort([Pivot|T]) ->
          sort([X||X <- T, X < Pivot]) ++
          [Pivot] ++
          sort([X||X <- T, X >= Pivot]).


simply blew me away. Suddenly all the pieces fell into place in my mind that had been starting to build in my mind since 1986 till now, 2007, and I suddenly for the first time in 20 years actually understood how Quicksort is implemented. It was here staring me in the face, plainly and succinctly written, which lead me directly to reasoning and logic behind it just like how a great equation compactly and cleanly describes the core of an idea. As a bonus I could see that my work on what they call a list comprehension was not only a good idea but is even a more powerful construction than I originally thought it was. It had helped me understand a difficult concept almost effortlessly.

I suspected before that something like a "list comprehension" is a very common abstraction in algorithms that really should be expressed in a language directly. Coding this sort of construction in C or similar languages is difficult and tiring, especially after you write and debug one for the hundredth time. But now I can see the raw power of using this kind of construction in practice. I think it was probably these details of the implementation of the Quicksort that was getting in my way of understanding the core idea behind the Quicksort itself for all these years. I can see that this language construction is a wonderful tool.

Wednesday, February 28, 2007

There's a great post at WTF about how bad programmers can continue to write bad code for a long time and think they have been writing great applications that whole time. This probably applies to most people, myself included. Not too surprising when you consider that usually the only real post-mortem is usually what you write up right before it hits production and all the data comes from memory with no hard evidence from production behind it.

What Could Possibly Be Worse Than Failure?

Tuesday, February 27, 2007

Here's a dandy in Ruby, that I just wrote up.

Rather than go the direct approach (like "'remove my spaces'.tr(' ','')") this will do the same thing but in the process will,

- Find all the combinations of characters than can be removed.
- Then removes them for each combination.
- Then takes those removed characters from each combination and finds which one removed the most spaces without removing any other character and picks that solution.

Man, it's hard to write code this convoluted, but fun!


# remove_spaces.rb

def do_combos(range, pos, combos)
  if range.last - range.first == 0 then return combos end
  split = range.first + ((range.last - range.first) / 2)
  range.each { |i| combos[i][pos] = i>split }
  combos = do_combos(range.first..split.to_i, pos+1, combos)
  do_combos(split.to_i+1..range.last, pos+1, combos)
end

class String
def remove_spaces
  # make map of possible combinations
  combos = (0..2**length-1).map { [] }
  combos = do_combos(0..2**length-1, 0, combos)

  # make map of possible solutions
  solutions = combos.map do |combo|
    i = -1
    combo.inject(['','']) do |solution, do_it|
      i += 1
      if do_it then
        [solution[0]+self[i..i], solution[1]]
      else
        [solution[0], solution[1]+self[i..i]]
      end
    end
  end

  # find best solution, the one that removed the most spaces without other characters in there
  solutions.inject(['',self]) { |best, sol| (sol[0].match(/^ +$/) and sol[0].length >= best[0].length) ? sol : best }[1]
  end
end

p ARGV.shift.remove_spaces

A typical example,


mike@dedeX ruby $ time ruby remove_spaces.rb "test this string ! "
"testthisstring!"

real 12m3.352s
user 11m27.059s
sys 0m35.102s


But be sure to have a good machine to run this on if you are removing spaces from a string with more than like 20 some odd characters. It quickly gets out of hand and gets killed on my iron.

mike@dedeX ruby $ time ruby remove_spaces.rb "test this string ! "
Killed

real 3m31.015s
user 1m20.429s
sys 0m19.149s

I originally posted this here in WTF?!

Man I hate posting code in blogger, grrr.

Wednesday, February 21, 2007

Ray-tracing 3D app built over the weekend -- Pics, video & source code!

This really inspired me to start blogging my progress on my current project.



read more | digg story

Saturday, February 10, 2007

A very good recommended read for all coders. This specifically covers web coding but is applicable to any type of code.

Getting Real: The Book by 37signals
http://gettingreal.37signals.com/

A basic takeaway from this book is to keep it simple. Which is not new (and they say so) but pushes the idea a lot further than traditional thinking on development. The keep is simple approach is usually in practice only applied to the actual coding and architecture part, not to the requirements. Usually people throw in as many features as possible to their apps which always makes them bloated in the long run. This is really a marketing problem. They want more customers so they try to appeal to all possible customers so they put in all possible features, which in the end makes a big lumbering app that arguably becomes less useful to all because it has so many random features that they never will use that gets in the way here and there. Most of the most useful apps are the ones that are super specialized like grep, tail, or ls (a.k.a. dir).


Another great takeaway is an important key to business, which I like to characterize by the phrase, "Never underestimate the power of doing nothing." The idea is not to sit around a do nothing all day but not to jump at things like it's a do or die emergency, sit back and allow the alleged emergencies to settle in. Most things are not as important as you think they are when you first encounter them. Sit back a while and let it digest for you and others involved and see how important it looks in a few days or weeks.

The big benefit to this is that doing this errs on the side of doing less and not on the side of doing more so you have much less of a chance getting into the situation where you are spinning your wheels all day fighting fires and not getting much done in the process. The dangerous cycle of doing more to accomplish less. If something is important to work on it will still be important to work on next week. Also this helps the "getting into the zone" process where it give you more freedom to focus on one thing at a time to do good work rather than doing many things at once.

I used to jump at every little thing like it needed to be done right now. When you do that you increase the amount of work you have to do in an exponential way. You begin to meddle in things that are not so important which tends to make things worse. This requires you to keep fixing things over and over again because you have a perception that it's not good enough when it actually was good enough in the first place and you didn't need to do anything about it. It's not that the work you do is bad when you do this it's just that you're adding value to something that is not important as something else more important. There is a huge opportunity cost that you are paying here. Usually no one really cares all that much when they step back from things anyway. Following a ton of little emergencies takes a huge chunk out of your moral in the long run. You'll start saying to yourself, "nothing I do is ever good enough."

Remember that odds are that most things are not that important relative to all the tasks that show up on your radar. Take comfort in the fact that if it is important that it will be pretty obvious that it is important next week or even in a few weeks. Let things compete for your time rather than you competing with yourself in order to do everything.

Start saying to yourself, "this is emergency is not good enough for my time, it's not worth it."

A way that can help to start to think about it is, only do something if it was obvious last week that you needed to do this today. Like, "okay, I knew that I would have to eat lunch today so I'll go ahead and do that rather than fix this bug that I didn't know about yesterday." There are a lot of other little examples that help in this book that I very much recommend reading if only for this single reason alone. They took this idea to heart and it shows on every page. This important concept makes for better work and a better work environment.

Tuesday, February 06, 2007

Ran into this today. Has some interesting thoughts on the whole nasty thing of why is there is much bad etiquette on-line that I haven't considered before.

http://pogue.blogs.nytimes.com/2006/12/14/14pogue-email-2/

Like this one,

"Young people who spend lots of time online are, in essence, replacing in-person social interactions with these online exchanges. With so much less experience conversing in the real world, they haven't picked up on the value of treating people civilly. That is, they haven't yet hit the stage of life when getting things like friends, a spouse and a job depend on what kind of person you are."

What also might be the case is that even if an adult has this type of experience in in-person social interactions they might not even try to apply this to their on-line presence, until they somehow learn that it's a good idea to apply it there.

This one is interesting too,
"Many parents haven't been teaching social skills (or haven't been around to teach them) for years, but Web 2.0 is suddenly making it apparent for the first time. ('Web 2.0' describes sites like Digg and Slashdot, where the audience itself provides material for the Web site.)"

If parents haven't been teaching social skills for a while, this would seem to make sense. There seems to have been a sort of a non-goal oriented approach to parenting in general over the last 30 years or so for most parents. My pseudo-unthought-about-idea is, when I say "non-goal oriented parented", I mean that the parents sort of perceive that the child is already in the end game of their social development so to speak and don't treat them like they need a behavioral adjustment or can even be changed, they sort of are that why and can't be changed. In a sense they treat them like an adult from day one. The parents don't try to hold up a goal for the type behavior of the child, they just work with the one that the child sort of naturally, or accidentally, acquires. They seem to believe that the child will end up acquiring the proper behavior once they come face to face with the reality around them, which I think is sort of true although there is a lot to be said for helping your child become mentally and socially prepared before you come face to face with it all at once when it is do or die, when first going out on their own, and not run into the probably if falling down so hard when you hit that reality. That traumatic experience I think has emotionally scared some people pretty badly to the point where it becomes very hard to get up from.

Also, it's weird that in general you used to hear a lot about the importance of netiquette a little while ago. Now there is not much talk about it anymore at all. I don't even remember the last time I heard the term until I read this article. He's right on when he titled this "Whatever Happened to Online Etiquette". Web 2.0 seems like it would make this even more important in peoples minds.