?

Log in

Michael Lehenbauer
Heh. I love Joel Spolsky. From his latest essay, The Development Abstraction Layer:
Management's primary responsibility is to create the illusion that a
software company can be run by writing code, because that's what
programmers do. And while it would be great to have programmers who are
also great at sales, graphic design, system administration, and
cooking, it's unrealistic. Like teaching a pig to sing, it wastes your
time and it annoys the pig.
1 comment or Leave a comment
So I just discovered SQLite. It's a small C library that implements a self-contained, embeddable, zero-configuration SQL database engine. Totally sweet, right? That's perfect for when you want to write a desktop app that would really benefit from an sql database backend... And guess what? It's public domain. Completely free.

But don't get too excited. It's a C library and everybody cool uses C# these days. So we're out of luck, right? NOPE! There's an equally sweet ADO.Net Provider for SQLite. And it must be Christmas because it's public domain too...

Seriously, I'm pretty excited by this discovery. I thought it was cool when I discovered MSDE, but this is a million times easier. I'm suddenly thinking, "Quick! What kind of apps can I write that need a database!?" which is probably why I never finish my projects... I'm more excited about the technology than the actual project. :-)

Tags: , , ,
Current Mood: excited
Current Music: Cesium 137 - Transient

Leave a comment
Dear internet, please solve my problem. Thanks!

So you create a C++ project in c:\projects\test\ that just prints out the current working directory and exits. You run it from Visual Studio (2005), first in debug mode and then in release mode. You find:

ConfigurationWorking Directory
DebugC:\projects\test
ReleaseC:\projects\test

You do the same thing in C# and you get:

ConfigurationWorking Directory
DebugC:\projects\test\bin\Debug
ReleaseC:\projects\test\bin\Release

I much prefer the c++ behavior. I currently am writing a C# app that needs to read in some data files. But I don't know where to put the data files. I don't want to put duplicate copies in bin\Debug and bin\Release! There's a project setting under Debug called "Working Directory" but it only applies when you run the project in the debugger. So it doesn't help.

What's wrong with Visual Studio? Somebody needs to get in there and fix problems like this... Please tell me there's a good solution that I'm overlooking!

Tags: , ,
Current Music: The Orb - Little Fluffy Clouds

10 comments or Leave a comment
So, I wasn't quite sure what to make of Microsoft's new Source Fource action heroes... But I just watched the first video of them in action and it's pretty sweet... http://msdn.microsoft.com/events/hero/videos/

Tags:
Current Mood: amused
Current Music: Chicane - Live in Palladium (22.01.2000)

2 comments or Leave a comment
So I knew Microsoft did some cool stuff with crash reports, but this video explains how they're kind of taking it to the next level.
Leave a comment
Today I received a very polite email kindly informing me that I would need to go to http://www.secure-auth.com/ and log in to my USAA account to verify my account information. Since the URL looked funky and I don't have a USAA account (or even know who they are), I quickly recognized it as a phishing scam. So I dutifully visited the site, typed in a bogus account number and password, a fake name and credit card number (using digits of pi just for fun!) and submitted my information. It promptly redirected me to USAA's actual Privacy Promise. Cute!

It occurs to me that this process could be automated. I could write a little script to submit lots of bogus data to the site, drowning out any real data they manage to collect. But they'd likely notice and filter out all submissions from my IP address... So to be effective you'd need lots of people to do it...

It wouldn't be too hard to write a client that connects to a central server, learns about current phishing sites, and then submits bogus data to each one. People from all over the world could run the client. With some effort, you could make the bogus submissions indistinguishable from real submissions so they couldn't be filtered out. And even if the evildoers still try to use the phished data by repeatedly trying to log in to the targeted site with their (mostly bogus) collected data, hopefully site administrators would start noticing and take measures to stop them.

Seems like it could be pretty effective. The main issuers I see are:
1) How many people would actually be willing to run the client? You don't really gain anything from it.
2) How would you manage the central repository of phishing sites? (I wonder how many there are at any given time... I have no clue.)
3) Who's going to write something like this? I'm busy and kinda' lazy. =]

Anyway, I think it's a nifty idea. =]
5 comments or Leave a comment
Typically, people are afraid to use .Net for new applications because many people don't have the .Net Framework installed yet (and installing it requires a 20+ meg download and a long installation process)...

But guess what!? There's a tool to package .Net applications into a single EXE that runs without the .Net Framework installed: Thinstall It'll run on any win98 or newer computer regardless of whether they've installed .Net.

I'm pretty amazed. I've always wondered if something like this was possible, but since I've never seen it done, I kind of gave up hope. Unfortunately, it's really expensive, so I won't be playing with it any time soon. But it's still cool that it exists. =]
Leave a comment
For those of you that don't read Joel on Software for some reason, you may be interested in knowing that you can follow the progress of my summer internship (which starts May 31) via the official project blog: Project Aardvark.

I'm not at liberty to discuss the details of the project, but it's going to redefine the world of software by empowering users to interact with their computers on new levels, eliminating boundaries, and expanding possibilities. It will also cure cancer. Or maybe it's a dumb web app. Who knows!? =]

And yeah, I'm going to be in a documentary. Not yet sure if I'm thrilled about that. =]
1 comment or Leave a comment
So I've become addicted to the del.icio.us/popular page. It's a list of sites that have recently been bookmarked by lots of people. If you find that between your rss feeds and news sites you somehow still don't have enough stuff to read, you should definitely check it out. =]

Anyway, last night while I was laying in bed not sleeping, I started thinking about making money (I'm a poor college student, after all)... specifically, making money on the web... and I started wondering what made for popular websites...

That's when I thought of del.icio.us. It just so happens that one of the main features of del.icio.us is tagging. Whenever you bookmark a site, you can specify some tags to describe it. And for any site on del.icio.us, you can get a list of everybody who has bookmarked it and what tags they used (example). So I had everything I needed to find out what makes for popular websites (content-wise, anyway).

As it turns out, del.icio.us already has an interesting visualization of popular tags, but I didn't let that stop me. =]

Over the course of a few hours I wrote some really hacky perl (using a mix of RSS and screen scrapting) to grab all of the tagging information for the most popular sites on del.icio.us and tabulate the results. First I just found the most popular tags. Then I thought it'd be interesting to look for pairs of tags that get used often, or even triplets, etc...

ResultsCollapse )

More Info
If you want the full results or to try it yourself or whatever, head over here.
Leave a comment
So Raymond Chen wrote a Chinese/English dictionary in C++ the other day.

Rico Mariani did a straight port to C# and it ran 10 times faster than the C++ version. Raymond has been writing a series of articles on optimizing the C++ version. After 5 versions, it finally ties with the unoptimized C# version. So Rico finally started optimizing the C# version and it's again faster than the C++ version (and loads cleaner).

I find it all pretty amusing. =]
Leave a comment
What is SuperMemo?
A while ago I happened across a piece of software called SuperMemo.  It's essentially a super-duper spiffy flash card program.  The main thing that makes it special is that it uses spaced repetition ("a learning technique in which increasing intervals of time are used between subsequent reviews").  The primary author, Dr. Piotr A. Wozniak, has done a lot of work in learning and memory (he's written tons of articles).  SuperMemo uses a special algorithm, based on models of human learning, which attempts to schedule reviews so that you review as infrequently as possible while retaining as much as possible.

Okay...  Why is this cool?
I've actually just barely started using it, but I think it's super cool for several reasons:
  • Learn more, faster.  SuperMemo is basically a highly optimized method of learning.  According to the website, "it makes it possible to closely approach the maximum natural capacity of the human brain to store and retain information," boasting learning speed increases of 10-50 times normal...
  • Learn what you want.  I have a tendency to learn new things and then to my great frustration, promptly forget them.  I read interesting articles and then forget the details or I say "I should remember that" and then promptly forget.  With SuperMemo, you can just add things you want to remember: important details from an article you read, the birthdays of your family and friends, facts about your favorite band, whatever.  And then SuperMemo will make sure that you don't forget it.  This gives you great control over your learning.  Everything you want to remember, you put in SuperMemo.  If you should no longer need to remember it, you can remove it.  It's that simple.
  • Share knowledge.  Once you create a set of question-and-answer pairs, you can easily export them as a collection and share them with other people.  There's already a decent-sized SuperMemo Library of collections available (unfortunately only a limited subset are free).  Want to learn Spanish?  The states and capitals?  Gastrointestinal Medicine? GRE General Vocabulary?  Just download some collection and start learning new stuff!

Any catches?
Unfortunately, yes. =[

  • Not Quite Free.  The latest version is SuperMemo 2004 and costs $40.  However you can download the older SuperMemo 98 for free here.  That's what I'm using and it works fine.  I may buy 2004 before long though...
  • Poor UI. SuperMemo is an awesome program functionally, but its user interface rather stinks.  It's not very intuitive and it's much more complicated than necessary.  Once you learn it, it's pretty usable, but it still gives me unpleasant feelings.  (Since I'm using the 98 version, it's possible that this has improved but the screenshots make me suspect not.)

Getting Started
The SuperMemo website is absolutely full of information on a variety of topics (as you browse, it's easy to feel overloaded)...  You might want to start at the SuperMemo Introduction page, but you may find yourself getting sucked into lots of long articles that are interesting, but not really required reading.  So if you're in a hurry, I'd recommend hitting the download page and then ABC of using SuperMemo and then maybe Hints&Tips.  Once you've figured out how to use the program, 20 rules of formulating knowledge is good reading for learning how to create good question-answer pairs.

Like I said, the UI is kind of rough.  So if you run into trouble, feel free to leave a comment and I'll try to help.

2 comments or Leave a comment
I haven't posted here in a while. Part of the reason is I've been reevaluating the purpose of this blog. In the past I've posted a lot of random technical junk that's boring to most people. (Don't try to tell me that you really care what PixelFormat you should use to create gifs.) So I think I might try to make it slightly less technical and more personal (but still focus on the technical-side of my personal life). =]

On that note, I'd like to announce that I'll be working as a software development intern at Fog Creek Software this summer! I'm really excited about it. I'll be working with three other interns (as well as Joel Spolsky and the rest of the Fog Creek developers) to create a brand-new product. The plan is to get the whole thing done in 10 weeks from design through release. It's going to be awesome.

In other news, I was recently part of a 3-person team from Rose-Hulman that competed at the Carnegie Mellon Invitational Programming Contest. Our team was victorious, coming in first place (out of 15 teams or so)! It was a lot of fun. It reminded me that I should be doing TopCoder more often!
Leave a comment
I kind of mentioned ReSharper a while back... I found it while looking for a C# refactoring tool, but it ended up being a lot more. When I first posted about it, they were doing a free public beta. But that ended long ago, and I actually purchased it for $100 which is quite a bit more than I've ever spent on any other piece of software. So I figured I should devote a post to it.

This is why it's totally worth it:
  • Improved Error Highlighting - VS.Net parses stuff as you type and hilights some mistakes. ReSharper improves upon this to the point that I rarely ever have build errors. ReSharper catches all of my mistakes as I make them (hilighting them appropriately). It's significantly easier to fix a mistake right after you make it than to fix it thirty minutes later when you finally get around to building.

  • Code Assistance - So I type "ArrayList a = new ArrayList();" but oh no! I forgot to add a using statement for System.Collections. Have no fear, ReSharper is here! It gives me a little icon I can click on and then choose "Add using statement" Two cool things just happened. 1) I didn't have to remember what namespace ArrayList is in. ReSharper found it automatically. 2) I didn't have to go to the top of the file, add the using statement, find my place again, and then try to remember what I was doing. This is a pretty big win! (Note: It helps you out with other things too. This is just my favorite.)

  • Code Completion - It has smarter code completion than VS.Net, based on context. So I can type "ArrayList a = new <ctrl><shift><space>" and it automatically completes to "ArrayList a = new ArrayList()" Pretty slick.

  • Refactoring - Yeah. It does all that.

There are lots of other features I'm leaving out, partially because it's hard to remember what features were in VS.Net already and which were added by ReSharper. You can check out their full list of features if you're curious. As I look at it, I'm noticing cool features that I don't even use yet! =]

The only real drawback is that it can be a little slow, especially with large projects. But so far it's just been a minor annoyance. If you spend much time writing C# code with VS.Net 2003, you should check it out. It's free for 30 days. $99 for a permanent license: http://www.jetbrains.com/resharper/download/  It'll be interesting to see how much of this stuff Microsoft incorporates in the next version of Visual Studio.  It's awesome stuff.
2 comments or Leave a comment
Over 4 years ago, I wrote the first version of my resume using Microsoft Word. It was made up of nested tables and some tricky formatting. It looked pretty good, but it was kind of a pain to maintain. Ever since I started using LaTeX last year I've been itching to convert my resume to LaTeX. Today after fighting with Word to stop making my resume two pages (with nothing on the second), I decided to take the plunge. It ended up being easier than I expected!

I found these resume templates which make use of this LaTeX Resume Style. I used one of the templates (res2.tex), put all of my content into the document, tweaked it a bit, and got a pretty good result! I think it looks better than my old one, it should be easier to update, and since TeX is just text, I could use revision control on it. =]

My resume: resume.pdf
Source file: resume.tex (depends on res.cls and tweaklist.sty)
Leave a comment
One of my favorite ".Net blogs" is Rico Mariani's Performance Tidbits. It tends to be pretty interesting. And I've learned quite a few things about performance from him... So since he just posted the Top Ten reasons you should subscribe to his blog, I thought I'd go ahead and point in his direction. =]

He was also Interviewed by Channel 9 recently if you want to put a face to the name.
Leave a comment
So if you are using the System.Drawing.Imaging.Bitmap class to create gif images, make sure you use PixelFormat.Format8bppIndexed, even if you don't need that big of a palette. I tried Format1bppIndexed and Format4bppIndexed in attempts to create smaller gif files. But I think the framework can only save 256-color gifs. So it converts them, and in the process changes the palette and (if necessary) dithers the image. Lovely. So I end up with a file as big as if I had used Format8bppIndexed in the first place, and my image has been tainted. So just use Format8bppIndexed.

While googling, I came across GD-Sharp, a .Net wrapper for the GD Graphics Library. Sounded promising. Sadly, it hasn't been updated since GD Library re-added gif support (after the LZW patent expired), so it doesn't quite help. Probably wouldn't be too hard to update it to get gifs working though...

Incidentally, after playing around in VC# 2005 Express a bit, it appears that the current .Net 2.0 beta doesn't fix this issue. Nor does it fix the ColorPalette weirdness I mentioned a while back. Nor does it seem to support animated gifs which was actually what I was originally going after. *sigh*
Leave a comment

For some reason the .Net Framework ColorPalette class (in System.Drawing.Imaging) doesn't have a public constructor. Combine this with the fact that the Palette property of the Image class returns a COPY of the palette rather than a reference to the actual palette and you end up writing code like this when you want to modify the palette for an image:

ColorPalette p = myImage.Palette;
for(int i = 0; i < p.Entries.Length; i++)
{
    p.Entries[i] = Color.Black; // well, probably something more useful here...
}
myImage.Palette = p;

You'd probably like to either replace the first line with "ColorPalette p = new ColorPalette();" or omit the last line, but the first is a compile error and the second will result in your code having no effect, since you're operating on a COPY of the image's palette. Lovely, eh?

I think this is probably the most unfriendly piece of .Net Framework API I've run into... I wonder if there are good reasons behind these decisions or if they're an oversight of some sort...

Leave a comment
Browsing blogs.msdn.com, I came across something cool, the pushd command:
C:\>pushd /?
Stores the current directory for use by the POPD command, then
changes to the specified directory.

PUSHD [path | ..]

  path        Specifies the directory to make the current directory.

If Command Extensions are enabled the PUSHD command accepts
network paths in addition to the normal drive letter and path.
If a network path is specified, PUSHD will create a temporary
drive letter that points to that specified network resource and
then change the current drive and directory, using the newly
defined drive letter.  Temporary drive letters are allocated from
Z: on down, using the first unused drive letter found.
Somehow, I didn't know about pushd/popd. That's super useful. And the fact that it works with network drives makes it super duper useful. =] (I saw it mentioned here.)
3 comments or Leave a comment
For my compilers class, I and a partner are giving a 40 minute presentation on debugging tomorrow. I was finishing up some demos for the talk just now and came across something really interesting. Check out the following code:</p>
int add(int a, int b)
{
	if (b == 0)
	{
		return a;
	}
	else
	{
		return add(1 + a, b - 1);
	}
}

It's an add function that works by calling itself recursively, adding one to the left and subtracting one from the right each time. Pretty silly, but fun to play with. Now when you compile with Visual Studio in debug mode, all optimizations are turned off. It executes each line exactly as shown, which means it grows the stack for each recursive call. So it ends up failing for big values of b due to stack overflow. Okay. Nothing shocking.

Now when you compile in release mode it turns on lots of optimizations. I expected it to take advantage of the tail recursion and effectively turn those returns into gotos, preventing the stack from growing. But that is not what happened! I got this assembly instead:

00401000  mov         ecx,dword ptr [esp+8] /* b */
00401004  test        ecx,ecx
00401006  mov         eax,dword ptr [esp+4] /* a */
0040100A  je          add+0Eh (40100Eh)
0040100C  add         eax,ecx               /* a + b */
0040100E  ret

Now, I'm not sure what that test and je are for. But ignoring that, it optimized out the entire function! It just uses the add instruction now! No recursive calls. I have no idea how they did that. Pretty amazing, if you ask me.

Current Mood: impressed impressed

17 comments or Leave a comment
Lately I've been running with my user NOT a member of the Administrators group (just like you're supposed to!). But sometimes I run into troubles. For instance, I need to install some package (Setup.msi) as Administrator rather than using my normal user account (which is of course what I'm logged in as). You'll notice that msi's don't have a "Run as..." option when you right-click on them, and if you try something like "runas /user:Administrator Setup.msi" from the command-line you'll get "193: Setup.msi is not a valid Win32 application."

So what do you do? I've found a pretty easy solution. Run "runas /user:Administrator cmd". This opens a new command shell which has admin privileges. Then you can just type in "Setup.ini<enter>" and the shell magically figures out the right thing to do with the .msi file and you're in business.

Need to add an exception to the SP2 firewall? cd to WINDOWS\system32\ and then type "firewall.cpl"

Maybe there's a better way, but this is working out pretty well for me!

Current Mood: good good

3 comments or Leave a comment