Wednesday, April 19, 2006

AACS: Day of .NET GrokTalks

Leading up to the Day of .NET in Ann Arbor event, the Ann Arbor Computer Society (AACS) is hosting an evening of GrokTalks as part of their regular meeting on May 3, 2006 featuring a lot of the same speakers that will be presenting at DoDN.

What's a GrokTalk, you ask? It's a short (~10 minute) presentation on a single topic ("All Stuff and No Fluff" is the format). The Regional Directors gave a series of GrokTalks at last year's TechEd (http://www.groktalk.com/).

The May 3 evening will feature 8 or 9 talks in 90 minutes. At this time, speakers include Aydin Akcasu, Jason Follas, Darrell Hawley, Jim Holmes, Josh Holmes, John Hopkins, Martin Shoemaker, Bill Wagner, and a very special disembodied guest presenter: Carl Franklin (.NET Wonk, MVP for Visual Basic, Regional Director, Hunter/Gatherer... oh yeah, and host of a little podcast called .NET Rocks! ).

(The final list of confirmed speakers will be posted to the AACS site prior to the event).

AACS meetings are free and open to the public. Supporting membership is $20 per year.

Time: 6:00 pm
Location: Spark Central. 330 E. Liberty, Ann Arbor MI

Tuesday, April 11, 2006

Concours


Connie Arrives! I initially doubted it, but using a ratchet strap on each side of the handlebar really does hold a bike secure in the bed of a pickup truck. I had some webbing also tied around the rear of the bike, just in case it fell to one side or the other, but it didn't budge.


Know your knots! There's a clove hitch around the hand grip. One end also tied around the handlebar (couple half hitches) just to keep the clove hitch from working loose, and the other end had a bowline. The ratchet strap's hook connected to the bowline. For security, I also tied a rope through the bowline and the webbing of the ratchet strap (in case the hook somehow magically slipped off).


I had to take a 2-step process to get it off of the truck. The first step went from the truck to my front porch. The second step went from the porch to the driveway. (Notice the 2-year old supervisor watching through the window).


Finally got 'er on the ground! One of the front brakes was seized, so I actually removed the caliper, tie-wrapped the pads into place, and pumped the brake to push the pistons out. Then I tie-wrapped the caliper to the front fork. The Connie has 2 calipers for the front wheel, so I still had a front brake (which is good, since I used it exclusively as I rode down the ramps).


I even managed to figure out how the saddle bags are mounted.

Monday, April 10, 2006

Day of .NET in Ann Arbor

 Registration for the Day of .NET in Ann Arbor is now open!

Day of .NET is a one-day conference on all things .NET organized by developers for developers. This event is being offered at no cost to anyone interested in .NET development, and features speakers from across the Heartland Region, as well a special guest speaker: Mark Miller from Developer Express and Mondays.

The Day of .NET in Ann Arbor is a collaborative effort between the following INETA member groups:

This rare event takes place Saturday, May 13, 2006 on the campus of Washtenaw Community College (Business Education Building) in Ann Arbor, Michigan from 9:00 am to 5:15 pm.

Further details and event registration at: http://dayofdotnet.org

Sunday, April 09, 2006

YALAL (Yet Another Look At Linux)

Linux is interesting to play with, I'll give it that. There's something awe inspiring about seeing the console screen scroll through all of that information when it runs for the first time, and starts firing up different device drivers. And the fact that this operating system has been compiled for just about every device in pretty cool.

Even usability has come a long way. KDE has some pretty cool little widgets, yet things seem strangely familiar to the old Sun SPARCs that I used to use back in college. I also like the behavior when you run as a regular user (not root) and you access something that requires administrative access: it simply prompts you for the root password, and then runs that one application as root. Sure, Windows has Runas just like *nix has su, but the autodetection makes this is a step beyond simple user switching.

The trip down Linux Lane this time started with a New World G3 iMac that I happen to have acquired. I don't have a MacOS CD, and there's no way that I'm going to buy one just for this old thing. So, what's the next best thing? Yellow Dog Linux.

I upgraded the iMac to 256MB of RAM, and dropped in a 20GB Hard Drive. Then, I downloaded and burned the YDL 4.1 CDs. Installation was pretty easy with the exception of partitioning the drive.

To make a long story short, in order to have OpenFirmware load yaboot, your drive will need an Apple_Partition_Map partition, and YDL's installer does not seem to be able to create one. Normally, after dropping in a new hard drive, you would use the MacOS CD to create the Mac partitions, including the all-important Partition Map, and then install YDL. Without a MacOS CD, I had to find a PowerPC LiveCD (Gentoo project has one), and then use mac-fdisk to initialize the disk (i), which creates the Partition Map partition. Once that was done, the YDL installer did everything else for me.

So, now that I have Linux running on a PowerPC, is it usable? Yes, as far as everything that comes on the CDs. However, if you want to install something else, you need to look for a source-code distribution and build it yourself. That pretty much rules out commercial software.

You see, it's almost guaranteed that any company that distributes a binary Linux version of their product will only have x86 available (not PPC). That makes it kind of tough to download things that you take for granted in the Windows environment that only runs on x86.

Case in point: almost every web site out there that my daughter would want to visit seems to use Flash, but Macromedia does not have a PPC Linux version of the Flash player (they do have a Linux x86 version, though). So, this means that this new machine, even with it's very standards compliant FireFox 1.5, is almost worthless in the eyes of an 8-year old.

I'll give it another 6-12 months, and then I'll get the urge to see what's new in Linux. Next time, I'll likely install on x86 so that I can get a true representative experience.

Thursday, April 06, 2006

Congratulations Jim!

When you become involved in user groups to the point that you're either helping to lead a group, or actually leading, it becomes inevitable that you'll form acquaintances (if not friendships) with leaders from other groups in your region. As such, I've gotten to know [at some level, at least] John Hopkins, Bill Wagner, James Avery, Dave Donaldson, Brian Prince, Patrick Steele, and the Holmes Brothers (Josh and Jim).

Congratulations to the latter: Jim was awarded the Microsoft MVP Award for Visual C#!

Wednesday, April 05, 2006

CableCards and the DIY HTPC

It's been widely discussed, including on this blog, that because of certification requirements, only the big system builders will be able to put together a HTPC (Home Theater PC, like Media Center) that includes CableCard technology.

As a refresher, a CableCard is an addressable device that you would register with your local cable company, and is essentially a whole digital cable converter box on a little card. The point is that with a CableCard, you don't need the converter box in order to tune in the digital-only channels (including premium channels).

I have always said that this would be a PCI form factor. But, I went over to my friend Mokee's house over the weekend, and he showed me his new HDTV. Among other things, it had CableCard support built into the TV (and they, in fact, are renting a CableCard from Adelphia). To my surprise, a CableCard actually uses the PC Card (PCMCIA) form factor. I didn't get to fully examine it, but I'm assuming/guessing that the tuner itself is built into the TV and the CableCard is just a decryption device.

Given the fact that the cable companies will rent you one of these for your TV, I don't see why you wouldn't be able to just move one from the TV into a PC after the cable guy leaves your house. This is assuming that you'll have drivers for it, and can somehow integrate with your existing ATSC tuner card, but I'm sure that the gray market folks and/or Open Source crowd will ensure that those are available.

Bottom line: At this time, I think that the Do It Yourself'ers will be very likely to build a Media Center PC with CableCard support (renting the card from the cable company).

Ghost Hunters were in Louisville, KY

Last week kicked off Season 3 of Ghost Hunters on SciFi. That episode took place at an old Sanitorium (Waverly Hills) in Louisville, KY, and they captured a couple of neat pieces of evidence.

The Where Clause

I've been listening to some of Chuck Boyce's interviews from DevConnections. Chuck has a podcast called The Where Clause that is hosted on SSWUG Radio, and my blog has been linked to on a couple of his shows.

In particular, the Matt Nunn interview is interesting because it contains some enlightening information about SQL Server Express (I met Matt last year at the CSD Competition dinner. At the time, he was a Program Manager for SQL Server, but now has moved on to a VSTS role).

Carl Franklin interview is next...

Friday, March 31, 2006

It's Coming!

Year: 1995 (?)
Make: Kawasaki
Model: Concours 1000cc
Class: Sport-Touring
Current Location: LaGrange, KY

A regular reader of this blog has generously donated his mid-1990's Connie for my riding enjoyment! (Disclaimer: I also call this reader "Dad").

It's been in storage ever since he picked up a Drifter.




I'm heading down on or about April 10 to pick it up.

Sunday, March 26, 2006

Rotavirus

Tina and I had the joy over the past week of watching our 2-yr old son suffer the effects of Rotavirus. This is a virus that almost everyone has experienced by 3 years of age, and is dangerous because of the dehydration that it brings on.

This morning, he was suffering the full symptoms (vomiting and diarrhea). We put him down for his afternoon nap, and as suddenly as the symptoms came on a week ago, they totally disappeared after he woke up. He appears to be fine now!

But, his twin sister woke up from her nap and started vomiting... Here's to another week of this fun!

One big problem with a toddler that has Rotavirus is that the child likely does not want to drink anything. Below are some tips that our Pediatrician recommended for keeping a child hydrated (the alternative is IV therapy in a hospital).

1. Give 2 fluid ounces of liquid at a time. Wait 15-30 minutes to see the results.

2. No fats: For milk, serve only skim milk. In Evan's case, he had absolutely no interest in drinking anything other than milk. Even though it came back up more often than not, he still got some hydration benefits from it (we just had to do MANY loads of laundry). BTW: Rotavirus is known to cause temporary lactose intolerance.

3. You can give Gatoraide if they'll take it. Yeah, yeah, it has loads of sugars, etc, but with this game, getting them to drink liquids is what's important, not healthy habits. Plus, the electrolytes will help.

4. Try small amounts of applesauce, if they are up for eating.

5. Try popsicles if they don't want to drink anything (this didn't even work for Evan).

6. Try ice chips.

7. Be persistant, but not forceful.

Saturday, March 25, 2006

Mesothelioma Lawyer, Consolidate Loans, and DUI

I found this particularly disturbing. Since placing Google AdSense spots on this blog, I've accumulated a grand total of $7.50 to date (that's probably a total of 30 clicks for 10,000 page impressions). Payout is not until $100.

But, there are some AdSense keywords where the advertiser will pay $20 - $50 PER CLICK! And if you look through the list below, it's obvious that these advertisers are looking for people who are suffering in one way or another (i.e., ambulance chasing).

I guess I just need to start a blog all about Mesothelioma or finding personal injury lawyers in California, or fighting DUI charges in Toledo. Oh, and if you happened to find this page by searching for any of these types of terms, please look for the link to a qualified lawyer in the Advertisements at both the top and in the sidebar. ;-)

Source: http://www.cwire.org/2006/03/23/updated-highest-paying-adsense-keywords/

$54.33 mesothelioma lawyers
$47.79 what is mesothelioma
$47.72 peritoneal mesothelioma
$47.25 consolidate loans
$47.16 refinancing mortgage
$45.55 tax attorney
$41.22 mesothelioma
$38.86 car accident lawyer
$38.68 ameriquest mortgage
$38.03 mortgage refinance
$37.55 refinancing
$35.99 auto accident attorney
$35.52 equity mortgage
$34.34 mesothelioma texas
$34.05 mortgages
$33.80 criminal defense attorney
$33.54 epocrates
$32.95 mesothelioma
$32.08 car accident attorney
$31.60 mortgage refinance rate
$31.38 loan refinance
$31.29 personal injury attorney
$31.24 best refinance
$30.14 register domain names
$29.86 medical malpractice lawyer
$29.68 incorporate
$29.68 malignant mesothelioma
$29.49 mortgage refinance
$29.45 freecreditreport
$29.41 fargo refinance
$28.53 mortgage loans
$28.15 125 refinance
$28.05 los angeles lawyer
$27.96 re mortgage
$27.38 how to register a domain name
$27.31 mortgage refinance rate
$26.86 personal injury
$26.48 refinance
$26.17 refinance
$25.43 mortgage loan
$25.35 texas refinance
$25.33 medical malpractice attorneys
$25.33 mortgage application
$24.46 mortgage companies
$24.33 countrywide
$23.92 low mortgage rate
$23.26 va refinance
$22.83 gmac mortgage
$22.17 california mortgage rates
$21.86 ameriquest
$21.68 florida lawyer
$21.41 dui
$21.29 refinance leads
$21.16 domain register
$21.07 refinance new york
$20.62 refinance rental property
$20.46 utah mortgage
$20.38 mortgage lenders
$20.35 find a lawyer
$20.20 mortgage note
$20.17 wrongful death

PwopCatcher Alpha is Released To Public

Carl Franklin has had this vision for about a year now (maybe more) of what a podcast client should be. His program, dubbed PwopCatcher, is a podcast management application that will discover new podcast episodes (by polling RSS feeds that you subscribe to), download content (direct and BitTorrent supported), and automatically prune old episodes.

It has been vaporware for, oh, about a year now. ;-) The Pwop Ambassadors have had the opportunity to view bits and pieces as Carl worked on them, but today, he released an Alpha version to the greater public.

Better details here:

http://www.intellectualhedonism.com/2006/03/25/PwopcatcherAlpha.aspx

Friday, March 24, 2006

End of the Tour

Last night, Greg Huber and I gave the final installment of a 4-city tour of our joint Media Center presentation:

  • Dayton-Cincinnati Code Camp
  • Detroit, MI
  • Toledo, OH
  • Columbus, OH
Each time that we did it, the presentation got better and better. Unless my ears deceived me, the crowd last night actually applauded when the demo (that I wrote from scratch) worked. That's a big change from the first presentation where we had to keep rebooting the MCE machine!

Greg's going to start working on his Atlas presentation, and I'm going to start looking for something new to play with (but most likely something from WinFX). That's not to say that one or both of us couldn't pull this presentation back out if someone really wants to see it.

Wednesday, March 22, 2006

NWNUG Meeting 3/28/2006: Dustin Campbell

I've got to be honest to my three readers: Greg and I had no clue who was going to present at our next meeting until yesterday. We had a couple of ideas, but no firm commitments.

Then, as Josh Holmes was talking to Mark Miller (Developer Express) the other night, an interesting fact came to our attention: One of the developers who actually works on the CodeRush and Refactor! products lives and works in my town!

After a quick email introduction, and a few other emails virtually begging him, Dustin Campbell agreed to be our speaker on Tuesday evening, March 28th (6:00 PM, HCR Manor Care building, downtown Toledo, Ohio, USA, planet Earth, Sol System, Milky Way Galaxy, etc).

He agreed to show off two of my favorite Visual Studio add-ins: CodeRush and Refactor! Pro. He will also show the group how they can hit the ground running by building their own DXCore plugin (you don't necessarily need CodeRush or Refactor! to use DXCore).

Dustin will have some time constraints due to his pre-existing schedule, so we will start the meeting promptly at 6PM (and he may have to leave at the Pizza break).

To encourage a good turn out, Greg Huber will be offering one of his Silver Tickets for the prize raffle. This ticket is good for a full MSDN Premium subscription, and I believe that this is the big subscription too with the full Team System Suite. Basically, you can buy a car with the retail value of this prize (but this is a not-for-resale subscription, so you are not permitted to profit from it in any way).

One caveat: We must have 25 people in attendance before the MSDN subscription will be offered up. We encourage you to bring a friend and spread the word!

Also, please be kind and pass on this prize if you already have a MSDN subscription--the goal is to put this software into the hands of developers who otherwise would not have this opportunity.

The current meeting topic is always available at:

http://www.nwnug.com/dotnetnuke/Default.aspx?tabid=31

Monday, March 20, 2006

Team Hanselman: Diabetes Fund Raiser

Most readers here probably already know who Scott Hanselman is. He's a Microsoft Regional Director and MVP who resides in Portland, OR. Maybe more importantly, he is also the Chief Architect for a company whose software might be running your bank's internet banking website. (Why that is relevant to the topic of this post is beyond me; it's just a fun fact).

Scott is just an all-around great guy: fun to listen to, smart as anyone I've ever ran into, and even takes time out to answer emails from the little people. Besides blogging on technical topics, he also occasionally throws out a post on Diabetic topics.

When he was 21, he lost a considerable amount of weight over a short period of time, and was finally diagnosed as a Type I Diabetic. According to his story, there is no family history, so the likely cause in his case was a virus that he contracted.

That last piece of information is what should give you something to think about: You could just have the flu on one day, and then a short time later, have to start giving yourself 8 shots of insulin a day (not to mention the countless pricking of your finger to measure blood sugar levels).

Team Hanselman will be participating in this year's America's Walk for Diabetes on May 6th. He and his wife have set a pretty ambitious goal of raising $10,000 for the American Diabetes Association. If anything is worthy of charitable donations, I think this is it.

But don't just take it from me--check out Scott's blog post for yourself:

http://www.hanselman.com/blog/TeamHanselmanAndDiabetesWalk2006.aspx

Friday, March 17, 2006

New Strings: Martin Acoustic SP

I've been playing on the same set of Elixir Nanoweb strings for quite a few months now, and it was only recently that I noticed the tone changing. Those Elixirs are nice, and the coating really keeps the squeaking down, but they're $15 a set.

I went to Guitar Center tonight and played with a few of the guitars that I could never afford (case in point: I really liked this Martin that they had, but it was $2500). I was mainly looking for a set of strings that I liked the feel of.

I went to the counter and asked what those Martins were strung with, and they said that they were Martin Acoustic SP's: $6. I'll give them a shot!

The first thing that I noticed was that I'm now squeaking a lot. I must have really took those Nanowebs for granted and got lazy on my fret transitioning. But, the bright tone is back into the guitar's sound, so I'm happy. We'll see how long this set lasts.

And Jiko: We still need to talk guitars sometime. ;-)

Media Center and Digital Cable

I've been asked by quite a few people lately about how Media Center works with Digital Cable (particularly in respect to High Definition). While I don't at all mind fielding these questions, I don't think that I'm the best subject matter expert, since I don't have HDTV at home, and don't use Media Center in conjunction with my cable converter box.

But, I'll attempt to capture my responses here (hopefully it will be more concise than my off-the-cuff babbling that some of you had to suffer through).

First off, let's understand what's coming into your house on that coax cable. Unless your local cable company does something radically different than mine, then you should have a range of channels that are analog. That is, you can plug the coax into a regular television, and be able to tune to these channels. Note that the channel numbers might be different from what you would use on your converter box, but the point is that these lower channel numbers are not digital.

Your local network television affiliates are included in this range of analog channels, as is the Weather Channel, several home shopping networks, and the usual "Basic Cable" stations. For Media Center, a regular television tuner card, like the Hauppauge PVR-150MCE, works nicely, and can tune in these channels directly from the coax without needing your converter box.

Now, what if your local network affiliate simulcasts both analog and digital (ATSC) signals, as most stations in the USA are doing? This is outside of my domain of expertise, but I would guess that the digital portion of the broadcast might be included along with the analog signal, the same as it is over the airwaves. So, for instance, if your local CBS is channel 11, then perhaps you would be able to plug your coax right into your television (or separate tuner), change to channel 11, and then get the 16x9 ATSC picture instead of the old 4x3 NTSC picture. I welcome comments on this.

At the moment, Media Center only supports Terrestrial (off-the-air) HDTV. That is, you can buy a ATSC capture card, like the DVICO FusionHDTV5, that will tune in the same local digital signals that you can normally tune in on your television. If these signals are indeed available right off of the coax, then you again don't need the cable converter to record shows using Media Center.

So, where does that digital cable box come into the picture? Well, all of the digital cable channels that you cannot receive on the coax using a standard television are actually being "broadcast" on the coax as encrypted MPEG-2 streams. You can fit so many more digital streams into the same bandwidth as an analog channel, so this is what makes it possible to cram hundreds of channels into the same bandwidth as maybe 20 regular channels would occupy.

Let's say that you want to watch the Science Channel. Your cable box will actually receive the decryption keys from the head-end (assuming that you are authorized to receive the channel), and then will decrypt the signal and reassemble the video. Where it goes from here depends on your setup, but somehow, the video comes out of the converter box as a signal that your television can use.

In order to record these "digital only" channels on Media Center, you need to receive the signals coming out of the converter box (in effect, your Media Center becomes the television in the above description).

Using a cable converter introduces a few issues:

1. How does Media Center change the channel in order to record a show? This is usually done using an IR blaster. Your Media Center remote control probably has a blaster built into the USB device that you thought was just a receiver. What you have to do is RTFM and figure out how to program the blaster. Then, Media Center will have the ability to emulate your converter box's remote control, and change the channel. The caveat here: Media Center has no idea about the state of your converter box; it is just blindly trying to change the channel. If the converter is powered off, then you're not going to record your show.

2. What about different TV Guides for direct-cable versus through-the-converter-box (since the channel numbers might be different between the two)? At this time, the standard response is that Media Center only supports one Electronic Programming Guide (EPG) at a time. You need to choose to use Media Center only with your cable box, or only with direct coax, but not a combination. However, for the homebrew PVR builders: Other PVR software, like GBPVR, etc, will allow you to have different EPGs tied to each tuner card, if you need it.

3. Can I tune in the digital-only channels without a converter box? Nope. Remember that these MPEG-2 streams are encrypted, so the tuner needs to communicate with the headend in order to get the decryption keys. However, there will be a type of tuner coming out in the near future called a Cable Card. This is essentially a converter box built into a PCI card. However, the homebrew PVR builder will not be able to use these, because the DRM folks are requiring that a converter card be certified for use with a complete system, and the certification process costs $10,000 per attempt. The end result is that you'll have to buy a complete Media Center PC from one of the big system builders (Dell, HP, Gateway, etc) if you need Cable Card support.

That just about sums up what I've been telling people lately. Please feel free to comment on your own experiences to support or refute anything that I've stated here.

Diff'rent [key]Strokes

I found one disadvantage to writing code on a laptop:

I added some functionality to a web app that filters keystrokes using client script so that only numbers could be entered into textboxes. I also had to allow for Delete, Backspace, Enter, decimal point, and Arrow Keys. But, all other keystrokes were just simply ignored.

And, then comes demo day. I go to the client's location, and we pull up the web application in her browser. Everything looks great. I tell her, "Go ahead and enter numbers. Try some letters and symbols, too."

What does she do? Immediately tries to type numbers using the numeric keypad on her full-size keyboard.

What does my script do? Filter out those keypresses because it did not recognize them as being numeric. Blah!

It seems that the number keys across the top of your keyboard and the number keys in the keypad have different keycodes, which actually makes a lot of sense. But, since I developed the site using a laptop, it didn't even occur to me to test the 10-key functionality.

For reference the keyCodes for 0-9 are:

"regular" numbers: 0x30 - 0x39
"number pad" numbers: 0x60 - 0x69

The decimal point (period) also has different keyCodes. 0xbe for the "regular", and 0x6e for the "number pad".

Thursday, March 16, 2006

Ann Arbor Day of .NET: Call for Speaker Abstracts

There's an exciting event coming to the Ann Arbor, MI area on May 13, 2006: A Day of .NET organized by the following area User Groups (all INETA Members):

  • Great Lakes Area .NET User Group (GANG)

  • Northwest Ohio .NET User Group (NWNUG)

  • Ann Arbor .NET Developer Group (AADND)

A user registration site will go live around the beginning of April, so you'll have to wait until then before you can sign up for this FREE event.

But, there is currently an open call for speaker abstracts. If you are interested in giving a presentation on a .NET-related topic, then please see the following page on the event's website:

http://dayofdotnet.org/blogs/homepageblog/archive/2006/03/03/9.aspx

The cutoff date is Wednesday, March 22, 2006, so please hurry!

Updated 3/16/2006: Deadline extended by a week.

rgvac

A couple of people have asked what the letters in one of my email addresses means: RGVAC

It stands for rec.games.video.arcade.collecting, and is a Usenet newsgroup that I used to spend quite a bit of time on. Coin-op video game repair and restoration used to be a hobby of mine (I say "used to" because I just haven't had the time or money in the past year to do anything at all with it).

It's a fascinating hobby, actually. Restoring a video game is very much like restoring an old car. You spending months tracking down original artwork, painstakingly restoring a damaged wooden cabinet, bringing a dead monitor back to life, and doing a 4116-to-4164 conversion to get rid of that old RAM that runs too hot and requires three different voltages.

And, after all that, there's nothing like the feeling of turning the completed game on for the first time. All of your hard work is finally realized in that one moment.

Then, you load it into the back of your pickup truck, take it to an auction, and sell it to the highest bidder because your house payment for that month went into artwork, monitor parts, and new 4164 RAM. ;-)

Meeting Miguel Castro

Tonight, I officially met Miguel Castro at the GANG user group meeting. He's an INETA speaker, and was presenting on WebControls. I say "officially", because it just so happens that a few weeks ago, I was introduced to Miguel via email through Josh Holmes when I had some related questions.

As part of that email conversation, I naturally had to show him a couple frames that I captured last fall when Carl, Richard, and Geoff was on the DNR Roadtrip:



Miguel's response in email was "How in the world did you ever capture that? I was chatting with Carl at the time, and said that Geoff looked like a cross between Yanni and the Unabomber". Hence, the reason for the second picture:



Well, tonight, we were at dinner together after the meeting. I bring up the story about the "Geoff looks like a cross between...", and Miguel asks me for my email address, because he has a "friend" that built an application to capture all of the DNR webcam frames.

I simply stuck out my hand, and said "Hi! I'm your friend. Glad to meet you." Suddenly, he put two-and-two together and realized which Jason I was! ;-)

Tuesday, March 14, 2006

Writing a DXCore Plugin

As part of evaluating the CodeRush and Refactor! Pro products from Developer Express, I decided that I wanted to write my own plugin. Both of these products are based on the DXCore API, which is the layer that allows access to Visual Studio and the source code that you are editing. DXCore is freely available, and any plugin that you write will always work (i.e., no timeout/expiration periods).

I use copy/paste A LOT when writing code. Often, I will create something outside of Visual Studio, like a XML document or a piece of JavaScript code, that I then need to use within my code as a string. So, I would find myself pasting the text into my code, and then manually wrapping each line with some sort of string-building syntax:

<xml>
<element1 />
<element1 />
</xml>
would become:
string xml = "<xml> \n" 
+ "<element1 /> \n"
+ "<element1 /> \n"
+ "</xml>";

What I wanted to do for my first DXCore plugin was to be able to highlight a range of text in Visual Studio, hit some key sequence, and then have the string-building code automatically added for me. Instead of using string concatenation, I wanted to wrap everything in StringBuilder code. Sounded simple enough.

Following Mark Miller's example on dnrTV, I came up with the following action:
StringBuilder code = new StringBuilder();

TextSelection selection = CodeRush.Selection.Active;

code.AppendLine("System.Text.StringBuilder ___sb = new System.Text.StringBuilder();");

foreach (string s in selection.Lines)
{
code.AppendLine("___sb.AppendLine(\"" + s.Replace("\"", "\\\"") + "\");");
}

selection.Replace(code.ToString(), true);
This worked nicely, except the output was restricted to C#, and it didn't have all of the nice touchy-feely stuff that CodeRush and Refactor! gives you.

Trying to figure out the DXCore API was a little overwhelming, so, I approached Mark via email for some pointers of how to use DXCore to generate output in whatever language you're using (VB.NET or C#). A couple of emails later, and he finally understood what this plugin was trying to do. Note to self: always provide clear examples when talking to Miller.

Much to my surprise, instead of just pointing me to a couple of classes or methods, he returned a fully functional piece of source code to me that I could then study, complete with Undo functionality, language-independent code generation, and the cool caret and linking stuff that you come to expect when working with DXCore products:
private string CreateTextCommand(string command)
{
return CodeRush.Constants.TextCommandBegin + command + CodeRush.Constants.TextCommandEnd;
}

private string CreateLink(string linkName)
{
return CreateTextCommand(String.Format("Link({0})", linkName));
}

private string Caret
{
get
{
return CreateTextCommand("Caret");
}
}

private string BlockAnchor
{
get
{
return CreateTextCommand("BlockAnchor");
}
}



private void actWrapText_SB_Execute(ExecuteEventArgs ea)
{
WrapSelectionInStringBuilder();
}

public string GenerateStringBuilderWrapper(string text)
{
ElementBuilder eb = new ElementBuilder();

string variableName = CreateLink("__sb");

eb.AddInitializedVariable(null, "StringBuilder", Caret + variableName + BlockAnchor,
new ObjectCreationExpression(new TypeReferenceExpression("StringBuilder")));

string[] lines = text.Split('\r');

foreach (string lineToAdd in lines)
{
string trimmedLine = lineToAdd.Trim();

ExpressionCollection expressionCollection = new ExpressionCollection();

expressionCollection.Add(new PrimitiveExpression("\"" + trimmedLine + "\""));

eb.TopLevelElements.Add(eb.BuildMethodCall("Append", expressionCollection, variableName));
}
return eb.GenerateCode();
}

private void WrapSelectionInStringBuilder()
{
TextDocument activeDoc = CodeRush.Documents.ActiveTextDocument;

if (activeDoc == null)
return;

TextView activeView = activeDoc.ActiveView;

if (activeView == null)
return;

TextViewSelection activeSelection = activeView.Selection;

if (activeSelection == null)
return;

string replaceCode = GenerateStringBuilderWrapper(activeSelection.Text);

DevExpress.CodeRush.Interop.OLE.Helpers.ParentUndoUnit lParentUnit =
CodeRush.UndoStack.OpenParentUnit("Text to StringBuilder", true);

try
{
activeDoc.Selection.Delete();

SourceRange rangeExpanded = activeDoc.ExpandText(CodeRush.Caret.SourcePoint, replaceCode);

activeDoc.Format(rangeExpanded);

CodeRush.Source.DeclareReference("System.Text");
}

finally
{
CodeRush.UndoStack.CommitParentUnit(lParentUnit);
}
}

Miguel Castro at GANG on March 15, 2006

SOUTHFIELD, MI - GANG (The Michigan Great Lakes Area .NET Users Group) is proud to have Miguel A. Castro presenting this Wednesday, March 15th at 6:00 PM. Miguel will be doing "Hitting the Ground Running with Custom Webcontrols – Parts 1 and 2". Should be a great presentation. And don't forget -- free pizza and pop!

(from Patrick Steele's blog)

Thursday, March 09, 2006

Orb

Over the past six months, or so, there has been a lot of talk about a device called SlingBox, which essentially allows you to stream television (live or recorded) from your home to wherever you may be over the Internet. But, it wasn't until I was reading Jamie's blog that I learned about a similar service called Orb that will allow you to do the same thing with nothing to buy.

It was priced right ($0.00), but I was skeptical (as you should be for free services where there's no obvious revenue stream). Regardless, I created a user account, and installed the client-side software. Because my machine was already running Media Center, I found that the client essentially configured itself! As a disclaimer, though, I have not used Orb with a non-Media Center PC.

The magic of Orb occurs through the piece of client software that runs on your PC at home. This is what has access to both your hardware/media and the Orb servers. So, as long as the client software is running (i.e., icon appears in the task tray) and your home PC is always connected to the Internet via broadband and you have port forwarding properly configured on your firewall, then you can stream any media from that PC to wherever you are by means of the Orb web site.

For example, here I sit at Panera Bread. I know that I recorded Mike Birbiglia on Comedy Central the other day, but that video is on my Media Center PC, not this laptop. Through the magic that is Orb, I'm able to play that video and watch it here through WMP:



In this case, I'm not simply watching the 2 GB MPEG2 stream that Media Center recorded--that's too high of a bitrate to be streamed over my cable modem's uplink. Instead, the Orb client is actually transcoding it: it takes the original video file and transforms it so that it can be streamed across the internet (i.e., changes the audio/visual resolution, changes the compression codec, etc, all the while taking in account the available upload bandwidth of my home connection and the download bandwidth of my current location).

And, I guess this is cool too (for the Europeans and other WMP-haters): it doesn't just transcode to Windows Media format, but will also generate Real Media, 3GP Media, and Winamp streams.

What's more is that you are not just limited to watching video on a PC. I have successfully watched video on a PocketPC, and Jamie reported that he was able to do the same from his EVDO cell phone!

So, the first thing that I see when I login to http://my.orb.com is a dashboard, of sorts. This shows me some of the media that is available, including my most recent recordings:



Because my Media Center has a TV Tuner card in it, I could start to stream live television. Orb helps me decide what to watch by displaying TV Guide data for what's currently playing on the various channels:



When the live television is playing, you can change the channel using WMP's previous/next track buttons. In my tests, there was a lag of about 10 seconds while the transcoding took place.

Orb also provides you with the ability to remotely schedule a television show to be recorded, just in case you forgot to do so when you left the house. This is a common feature of many of the other HTPC software titles, but it is oddly not available out-of-the-box for Media Center (seems like such an obvious feature).

In this case, it is the Orb client that is actually doing the recording, not the Media Center recording service. The resulting file is in DVR-MS format (MPEG2 with metadata saved in the file), which is also the native format of Media Center. However, in my test, no metadata (episode description, TV rating, etc) was saved in the file.

All of the same media that is available to my Media Center is also exposed through Orb, from the Television capabilities, to Audio and Video libraries, and even pictures (for when you want to show off your latest photos that are trapped on your PC at home):



Now for some of the tricky stuff. The Orb client is supposed to have UPnP functionality, which if it worked, would automatically open up the ports on your firewall that needed forwarding (assuming that your firewall/router supports UPnP). In my case, it didn't work, but I didn't really spend a lot of time troubleshooting.

Whatever the issue was, I had to change the Orb client to use port 81 for streaming (instead of Port 80, since my Media Center was also running IIS). Then, I had to manually configure port forwarding in my router:

81 TCP
554 TCP
13398 - 13401 UDP

I'm assuming that the original port 80 was in place to promote access to the streams from behind corporate firewalls and through proxy servers. If I didn't want or need my web server to be exposed as port 80, then I can actually set up my Linksys firewall for PAT (Port Address Translation), which would take any incoming port 80 traffic from the Internet and send it to the Orb client listening on port 81.

I could go on and on, but that would take the fun away from you! Give it a try.

If Carl asked me today "What's the coolest thing that you've downloaded lately?", then this would definitely be my response.

UPDATE 03/13/2006: Uh, oh. The honeymoon is over and now I'm starting to see a few issues. I scheduled my Media Center (i.e., not Orb) to record Saturday Night Live, and when I went to watch the show, it wasn't there. Turns out that Media Center had shown a dialog saying that it couldn't activate the recording service when SNL started. I'm thinking that Orb's own recording service has something to do with this (i.e., if it still had a handle to the DirectShow graph that it was using to access my tuner card, then MCE wouldn't be able to create its own graph).

Scoble at the Oscars?

When I first saw a picture of Scoble, I thought that he reminded me of somebody famous (an actor) but I really couldn't put my finger on it.

Then I watched the Oscars last weekend.

Is it just me, or does Robert look a lot like Philip Seymour Hoffman?

Exhibit A: Click Here
Exhibit B: Click Here

Wednesday, March 08, 2006

ASP.NET Forms Authentication - Problem Solved

ASP.NET is not my forte. Having disclosed that, I'm currently working on a ASP.NET application that takes advantage of the Membership Provider in ASP.NET 2.0 and uses Forms Authentication.

This application worked great from the development web server (you know, that Cassini web server that comes with Visual Studio 2005). But, when I tried to deploy this to a real IIS6 web server, I ran into problems.

When I hit the site, the web server would correctly redirect my browser to the login page. However, upon logging in, my browser would keep getting sent back to the login page (with no error message, like "Bad User name or Password").

I was just about ready to throw my server across the room, and was even drafting a "please help" letter to Josh, when I decided to take another look at my web.config.

And that's when I saw it:

<authentication mode="Forms">
<forms name="AppNameCookie"
loginUrl="~/membership/Login.aspx"
path="/web"
cookieless="UseCookies" />
</authentication>

You see, in my Visual Studio solution, the web project was simply named "web". But, I was trying to deploy it to a more meaningful virtual directory name (i.e., "myapp").

So, I changed the above "/web" to "/myapp", and it started working. I hope that this saves someone the hours of frustration that I experienced today.

µTorrent 1.5 is Out

The latest release of µTorrent is now available from http://www.utorrent.com.

In case you don't know by now, µTorrent (the funny "u" is the symbol for "micro", so I guess it's pronounced MicroTorrent) is a fully featured BitTorrent client that is completely contained in a 150 kB exe. This means that you don't install anything; just download the program and run it. I don't even think that I can get Hello World to compile to under 150 kB with .NET or Java!

The best part, though, is that it only uses around 2-3 MB of RAM as it runs (and maybe another 5 MB of Virtual Memory). Azureus, on the other hand, would sometimes eat 60 MB of physical RAM (according to Task Manager).

Saturday, March 04, 2006

1 << 5

Person Jason = new Person();
Jason.DateCreated = ScottHanselman.DateCreated.Add(TimeSpan.FromTicks(35424000000000));

Thursday, March 02, 2006

What My Readership Looks Like

Interesting to see readership accumulate over time.

14 month graph
The two larger spikes are from when Rory linked to a post I wrote, and when I posted something about brrreeeport.

Comet Now Visible in Pre-Dawn Sky

There is a comet (Comet Pojmanski, designated C/2006 A1) just visible to the naked eye in the pre-dawn sky (i.e., 90 minutes before sunrise). It is located slightly northward of Venus, which will be the brightest "star" in the eastern sky.

http://skyandtelescope.com/observing/objects/comets/article_1684_1.asp

Wednesday, March 01, 2006

Television on Your Car's Radio

I discovered this by chance while driving in Columbus, OH, and rediscovered it the other day while driving in Ann Arbor, MI:

The frequencies used for VHF television channel 6 are:

CH  BAND     VIDEO   CHROMA    AUDIO
6 82- 88 83.25 86.8295 87.75


If you noticed, the audio is 87.75 MHz, and is modulated using Frequency Modulation. Guess what that means? If you are in an area of the country that can receive VHF Channel 6 on rabbit ears, then you can also listen to the programming on a FM radio, since the FM band starts at 87.7 MHz.

For Ann Arbor, I was receiving WLNS (CBS affiliate out of Lansing), while in Columbus, I was listening to WSYX (ABC affiliate).

Interesting Asteroid

On 22-Feb-2006, an interesting 16 meter "asteroid" named "2006 DQ14" passed by the Earth with a miss distance of about 5.2 Lunar Distances (about 2 million km, or 1.2 million miles).

What's the big deal about this? Well, the orbit of this "asteroid" was calculated, and it's roughly equivalent to the Earth's own orbit around the sun. Working backwards in time, they figured out that the last time we had close approaches with this object was in the 1977-1979 timeframe.

The interplanetary spacecraft Voyager 2 launched on 5-Sep-1977. It just so happens that a "near miss" of this "asteroid" occurred on 8-Sep-1977. Coincidence? Or is this object actually a piece of space junk from the Voyager 2 mission, like a rocket body stage or something else?

It's scary to think that a huge part of a rocket launched in 1977 could actually slam back into the Earth decades (or centuries) later with no warning at all.

Here's NASA JPL's asteroid orbit applet:
http://neo.jpl.nasa.gov/cgi-bin/db?name=2006+DQ14

Tuesday, February 28, 2006

Driving the Speed Limit

You can thank Aaron for introducing me to this viral video. See what happens when a group of people decide to drive the posted speed limit on I-75 through Atlanta. Four lanes of the highway blocked by four cars all going 55 miles per hour. Pretty funny!

http://video.google.com/videoplay?docid=-5366552067462745475&q=speed

Nick Landry on DNR

On this week's .NET Rocks!, Nickolas Landry talks about Windows Mobile 5.0.

Say, isn't he the one who was trying to pick up the girl on Caesars 24/7 (reality show on A&E):

"... In Vegas, it's said that for every man there's a woman and for every woman there's a man. But does that include geeks? Four big time nerds in town for a computer programmer's convention decide to take a break from boring seminars and try to pick-up a woman they meet at the bar. Are they up to the challenge?"

Reference: http://weblogs.asp.net/cfranklin/archive/2005/01/19/355841.aspx

Monday, February 27, 2006

Upcoming Speaking Engagements

Greg Huber and I have a few more Media Center Presentation's lined up:

Feb 28, Northwest Ohio .NET User Group - http://www.nwnug.com

March 23, Central Ohio .NET Developers Group- http://www.condg.org/default.aspx

Abstract:
Will this be the year of the Home Theater PC (HTPC)? Come learn about Windows Media Center 2005 and decide for yourself. Topics covered include: Overview of Media Center, Alternatives to Media Center, The 10-foot Experience, Developing for Media Center, and using the Xbox 360 as an Extender.

Come check 'em out if you get a chance!

Disclaimer: Blatently plagerized from Greg's post!

I'm really digging this tag-team presentation style. It lets one person have a little bit of downtime to mentally prepare for their next part while the other person does their thing.

Greg and I still do post-mortems and refine the presentation every time that we do it: we watch the audience and make note of where people were falling asleep, and then decide to either improve that section of the agenda, or drop it altogether. And, of course, we've made it part of the show to make an actual sacrifice to the Presentation Gods (hoping that this gesture somehow makes the gremlins go into hiding).

Four Things Meme

This meme has gotten pretty popular lately among the blogs that I follow, so I knew it was only time until I myself got tagged. Thanks, Jim!

Four Jobs I've Had...

  1. Bailing Hay and Straw
  2. McDonald's
  3. Sorting Freight
  4. Programmer

Four movies I can watch over and over...
  1. Back To The Future (trilogy)
  2. Office Space
  3. There's Something About Mary
  4. The Matrix

Four TV shows I love to watch...
  1. LOST
  2. Ghost Hunters
  3. Two and a Half Men
  4. My Name is Earl

Four places I've been on vacation...
  1. Cancun
  2. Turks and Caicos Islands
  3. Virginia Beach
  4. Smoky Mountains

Four favorite dishes...
  1. Lasagna
  2. Mashed Potatoes and Gravy (served with just about anything else)
  3. Steak (medium-rare)
  4. Any burrito at Qdoba

Four websites I visit daily...
  1. www.bloglines.com (aggregates almost all of my reading)
  2. www.spaceweather.com
  3. news.google.com
  4. statcounter.com (Narcissism: I regularly check who reads my blog)

Four places I'd rather be...
  1. On vacation somewhere that it is warm
  2. Hiking
  3. Riding a motorcycle with no particular destination
  4. Sitting at the swim-up bar in a pool at the Moon Palace in Cancun

Four bloggers I'm tagging...
  1. Aaron
  2. Greg
  3. Carl
  4. Rory

resizeable != resizable

Here's a tip that might save you 30 minutes of debugging a silly problem: Resizable is spelled R-E-S-I-Z-A-B-L-E, not "resizeable".

When using in conjunction with window.open(), it seems that this feature name must be spelled correctly in order to work. ;-)

Hating Mark Miller About Now

Just wanted to add to the cliche: CodeRush rocks! And Refactor! Pro is not too shabby, either.

Now, I'm hating Mark Miller (the Architect of CodeRush) because I have to think of a way to come up with the funds to buy these products outright (or get my employer to do it for me, which I would greatly prefer!).

BTW: Inspired by the dnrTV episode, I wrote a CodeRush plugin myself. The first iteration was quite simple, but when I wanted to get into some language-independent code generation, I quickly got lost in the DXCore API. However, Mr. Miller was extremely helpful in pointing me in the right direction. Great product, great personal support--these guys are awesome players in a neat little niche. Plus, they're sponsors of .NET Rocks, which carries a lot of weight when it comes to me selecting/recommending products.

Saturday, February 25, 2006

Xbox 360 Extender: My "Session Terminated" Cause Identified

Before Greg Huber and I presented on Media Center for GANG, I had built a MCE box that was clean and contained everything that we needed for the presentation. Before (at the Dayton-Cincinnati Code Camp), we had his MCE PC, his laptop, and my laptop, and experienced all kinds of technical issues trying to network everything together for the presentation.

The box worked great, and was all set to go. Well, that was until I tried to connect my XBox 360 to it (which was needed for part of the presentation).

I ran through the PCSETUP program, and everything seemed fine. But, when the XBox attempted to connect to the Media Center session, I would always get a "Session Terminated" error. I tried for hours that day to get the connection to work, but everything failed. Then, when I tried to systematically remove one installed program at a time (hoping that it was my DVD software, or something else that was 3rd party), I ended up hosing the box big-time.

So, we ended up reverting back to Greg's MCE machine and both of our laptops... :(

I recently paved that machine and reinstalled everything. But, wouldn't you know it, the "Session Terminated" problem was still there! However, this time, I had the opportunity to dig deeper into the problem, since I wasn't pushing up against the start time of a presentation.

I was actually able to determine that a GeForce FX5200 was at fault. In order to promote discussion, I detailed the situation on The Green Button:

http://www.thegreenbutton.com/community/shwmessage.aspx?ForumID=58&MessageID=157807

Friday, February 24, 2006

The Code Room Episode 3 Is Out

The third installment of The Code Room is now online:

http://msdn.microsoft.com/msdntv/episode.aspx?xml=episodes/en/20060223CodeRoom3/manifest.xml

This episode is obviously scripted, whereas the previous two episodes were "reality television". Nonetheless, there is still a very important message presented: developers must consider security during the entire development process, and once a system is compromised, you cannot just patch the original holes because the hackers probably have a collection of backdoors.

(The first Code room "starred" Chris Menegay, Scott Bellware, and Tracy Sawyer).

Thursday, February 23, 2006

Good Week For Observing ISS in North America

Ever get a chance to see the International Space Station (ISS) with your own eyes? Its orbit will provide for a series of highly favorable passes over North America over the course of the next week or so.

To be favorable for naked-eye observation, you must be in the dark while the ISS, flying overhead, is illuminated by the sun (so, this happens either hours after sunset or hours before sunrise).

Use the Heavens-Above web site to help figure out when the ISS is visible from your location, and where to look in the sky. Be sure to synchronize your clock with the official time (important, since the window is only a few minutes).

When it's flying over, you pretty much can't miss it. It will be comparable to viewing Venus or an airplane with its landing lights on, but will slowly move across the sky until it crosses into the day/night terminator, at which time, it will just disappear.

Heavens-Above will also calculate for you other satellites that you can observe in pretty much the same way. The best viewing that I can remember was one year when the ISS and Space Shuttle flew overhead shortly after the Shuttle had detached from the space station. So, instead of one point of light, I saw two in close proximity to one another.

Windows Vista SKU Featureset Revealed

I hope that KenLin had the authority to reveal this info at this time:

http://msmvps.com/blogs/kenlin/archive/2006/02/23/84582.aspx

Since I've been presenting on Media Center lately, I immediately scanned the features matrix to see if it was going to be available across all of Vista's SKUs. Bottom line: Nope! Only the Windows Vista Home Premium and Windows Vista Ultimate SKUs will include the Media Center functionality.

Wednesday, February 22, 2006

MSDN on DVD

I received my first MSDN shipment yesterday from the subscription that I was awarded for being a Finalist in the Connected Systems Developer Competition.

I've been in charge of receiving the MSDN subscription media for my branch, which we receive as being part of the Microsoft Certified Partner program. These always came on CD, because all of our servers have CD-ROM drives (not a one has a DVD drive).

But, my personal subscription is on DVD. I'm amazed at how many products are crammed onto each disk, and by how much smaller the shipments are when compared to the number of CD's that we would normally receive at a time.

This comes as a relief to me, because I don't know what I would do with hundreds of CDs in my house (it's going to be bad enough keeping track of scores of DVDs!)

Mug Shot

The observant ones among you regular readers might notice a new addition to the sidebar...

Tuesday, February 21, 2006

Miniature Windmill Generator

This should come as no surprise to anyone, but somebody came up with a miniature windmill generator that looks like a small electric fan. At peak output, it appears that it can do 1 amp with a potential difference of 12 volts, which could be used to recharge a cell phone.

Big deal? Yeah. But, it interested me because of my thoughts a while ago of using arrays of micro-generators, like these, in order to produce significant levels of power (maybe enough for your house):

http://jasonf-blog.blogspot.com/2005/10/pressure-generator-array.html

One caveat, though: The huge electric generating windmills with the 30-foot blades continue to spin after the wind has stopped. This is because they store energy as angular momentum, like a flywheel. So, that benefit would not exist with the array of micro-generators (essentially, when the wind stops, so does your electric generation).

Monday, February 20, 2006

Burned by Floating Point Numbers

For those following along at home, you know that I've been working over the past few weeks with a big SQL Server database on a relatively small partition (until the new hardware arrives). Because of this, I've been trying to keep space consumption/database growth under strict control. When you're talking about millions of rows of data in a table, even 1 byte difference in the size of one numeric field translates to millions of bytes of extra disk space.

Well, one choice that I made was to represent decimal numbers using the "real" data type. This is a floating point decimal that uses 4 bytes per number. Other possible alternatives were all 8 bytes per number, so I essentially cut my storage in half (albeit, with some "acceptable" loss in precision).

While reconciling the results of my calculations to the set of control data, we came across a very good example of where this absolutely is the wrong choice of data type.

One field of the table contained Quantity information, and this was not always integer data (i.e., maybe it was weight). Well, my "real" numbers had no problems representing this data, for the most part. But, there was one point of sale where all of the sales were reversed (so that every record with a positive Quantity value would have a corresponding record with a negative Quantity value). The net quantity for this location was zero.

But, upon examination, my net quantity was coming out to be something like 0.000007472 due to errors introduced by the floating point math. Yeah, it's close to zero, but, it led to a serious flaw in my calculations.

You see, I was already trapping for Divide by Zero situations using a CASE clause:

SELECT CASE 
WHEN SumQty <> 0
THEN (Qty/SumQty)* ValToSpread
ELSE 0
END

If it weren't for the floating point math, then this particular SumQty value would have been zero, and the result of the calculation would have been zero. But, in this case, the floating point's "zero" was a small fraction--not zero.

A tangent: Do you know why Divide by Zero is illegal? It's because the Y-axis (x=0) is an asymptote for the hyperbola y = a / x. This means that as the number that you're dividing by gets closer and closer to zero (i.e., a fraction approaching zero) that the quotient gets larger and larger (approaches infinity). So, dividing by zero is undefined because it's actually +/- infinity at the same time.

What's the point of this mathematical mumble-jumble? Well, the sum of my quantity was not zero, but rather a small fraction: 0.000007472. The result of dividing by this number turned out to be a very big number, when the true result that was needed in order to reconcile with the control data should have been zero. So, my results were way off of where they should have been (to the tune of millions of dollars). Whoops! Good thing this was just in QA!

To resolve this one case, I changed the quantity field's data type to a "decimal", which is a fixed-precision number (I can specify how many total digits and decimal digits are maintained). I still went from a 4-byte number to a 8-byte number, but the result of the calculation was dead on.

So, the lesson learned: sometimes it's quite necessary to make the trade-off of space and speed provided by floating point numbers for the accuracy of fixed precision.

Day of .NET

Here's an exciting announcement:

What: Day of .NET (1-day Conference)
When: May 13, 2006 9:00 AM - 5:15 PM
Where: Washtenaw Community College, Ann Arbor, MI

Website: http://dayofdotnet.org/

A cooperative effort between:

Sunday, February 19, 2006

Breaking Change in No-Touch Deployment (2.0 Framework)

A peer of mine (Murph) brought this breaking change to my attention:

In prior version of the .NET Framework (v1.0 and v1.1), you had an option to distribute executables by hosting all of the files (EXE, config, and other necessary assemblies) on a web server, and then opening the EXE file by means of a URL. This is actually a precursor to ClickOnce, and was referred to as No-Touch Deployment (or HREF EXEs).

Well, it seems that by simply installing the 2.0 Framework onto a machine, you break the ability to continue using HREF EXEs.... when the server is in the Internet zone. The web server will log the GET request for the EXE, but you will not see any requests logged for the config file, and the user will get an OPEN or SAVE AS dialog, which in turn does absolutely nothing.

Credit to another member of my organization (Jones) for pointing out the following MSDN Product Feedback record, which discusses that this is by design:

http://lab.msdn.microsoft.com/ProductFeedback/viewfeedback.aspx?feedbackid=ef4ae9a2-1d40-4241-aca4-61d579929793

The workaround is to get the site out of the Internet zone. If it's a trusted server, then you can trust the site, and that will change the zone. Otherwise, you're left creating a new CAS policy. Either way, this does not sound like fun if the application was deployed to hundreds of client machines using HREF EXEs.

Saturday, February 18, 2006

Spot the Bug

Here is a completely made up query, but is close to one that I wrote recently to spread an overhead cost value (@MarketingExpenses) over a list of invoices. This is just one step in a complex series of calculations that helps to determine profitability of products or services sold.

SELECT 
CASE
WHEN COALESCE(b.sum_of_sales,0) > 0
THEN (a.sales / b.sum_of_sales) * @MarketingExpenses
ELSE 0
END AS ShareOfMarketingExpenses
FROM
invoice a LEFT JOIN regional_sum b
ON a.region_code = b.region_code


This query assumes that there's a table called [regional_sum] that has the sum of sales for each region. The [invoice] table is joined to [regional_sum] by linking the "region_code" fields of both tables, and since a LEFT JOIN is used, it will include all rows from [invoice] and only those rows in [regional_sum] that matches (if there is not a match, then NULL values will be used for the [regional_sum] data).

Now, the point of the COALESCE function is to return the first non-NULL value in the supplied list of values (b.sum_of_sales and zero). In this case, I'm simply trying to handle NULL values by changing them into zeros.

You'll also notice that I'm using a SQL CASE statement. I do this because I need to prevent the dreaded "divide by zero" error, so I ensure that the "sum_of_sales" field is not zero before trying to calculate a percentage (otherwise, I return zero as the result of the calculation).

The percentage is then multiplied by the predetermined "@MarketingExpenses" value in order to give you a number of marketing dollars that could be attributed to that one invoice record ("ShareOfMarketingExpenses").

Let me just assure you that the query above compiles and works as written, so the bug is not a syntax error. However, there was an issue that came up as we were trying to reconcile data from the new system with old/validated numbers (the sum of all of the "ShareOfMarketingExpenses" values did not equal the specified "@MarketingExpenses" value).

I'll leave it as an exercise to the reader, but I'll also provide some sample data:

============
REGIONAL_SUM
============

region_code sum_of_sales
----------- ------------
a0001 12345.67
a0002 432312.33
b0001 -123.23
b0004 34322.23
b0005 -12.12
c0006 234328.23

(Negative sales are probably due to internal accounting of moving inventory around from one region to another, but I'm not that close to this [fictitious] business, so I can't explain the numbers any better).

=======
INVOICE
=======

customer_id region_code sales
----------- ----------- ----------
1 a0001 12.32
1 a0001 33.23
2 b0001 5.34
3 c0006 1232.21
3 b0004 322.22
4 a0003 232.23
[the list goes on, but pretend that the
sales for each region correctly sums up
to the values listed in the above table]

It was a pretty cool "Ah ha!" moment for me when I spotted the flaw. Your mileage may vary.

Thursday, February 16, 2006

Is Google Preventing Analysis of Their Search Results?

Robert Scoble has been doing an experiment over the past few days where he asks his readers to include a simple non-existent word in their blogs in order to create a new meme: brrreeeport.

Some initial findings can be found here:

http://scobleizer.wordpress.com/2006/02/15/brrreeeport-crazy-and-more-search-engine-lies/

Now I don't know the full story, but Google is apparently no longer serving up any results for the term "brrreeeport". Is the DNE (Do No Evil) Gang worried about Robert's findings surrounding the accuracy of their reported search results? (In other words, it appears that Scoble's experiment is calling them out on the fact that they inflate the reported number of search matches)

Where did all of the brrreeeport matches go?

UPDATE Feb 17, 2006 8:00AM EST: I checked this morning, and the 22,700 results are back online from the main Google web search. But, since you can only have a maximum of 1000 results returned for any given query, how can anyone verify that there are indeed 27,000 real matches for "brrreeeport" in the Google database?

They're Back!

Tuesday, February 14, 2006

Special Appearance, 1 Night Only!

Greg and I will be presenting at the Great Lakes Area .NET User Group (GANG) meeting on Wednesday, February 15th at 6PM (Microsoft Southfield office (in the Fifth-Third tower near Evergreen and 10-mile/Lodge)).

http://www.migang.org/Default.aspx?tabid=22

The topic will be Windows XP Media Center Edition 2005. The first part will include a general introduction to MCE (what, why, and how). The second part will include some examples of how to develop for this platform. And, we're sure to whip out my XBox 360 at one point or another.

There is a bit of irony in me doing this presentation on Wednesday: I'll be bringing my HTPC machine with me for the demo, so there will be no PVR at my home to record LOST. :)

BlogCode looks cool

Scoble blogged about this: If you have a blog that you like, BlogCode will let you find other blogs that are similar in nature. It goes well beyond just keyword matching.

brrreeeport!

Monday, February 13, 2006

Future of Touchscreens

You MUST watch this if you haven't already:

http://www.youtube.com/w/Crazy-Multi-Input-Touch-Screen?v=zp-y3ZNaCqs&search=crazy%20multi-input%20touch%20screen

UPDATE: Richard covered this on this week's Mondays!

Sunday, February 12, 2006

Cool Video

HV Switch Opening at a power substation

Friday, February 10, 2006

Overlooked Database Space Optimization

While looking for places to cut down the size of this huge database that I'm working with, I realized that all strings were being stored in nvarchar fields, which uses Unicode, or 2-bytes per character. This is likely because the database was originally prototyped in MS-Access, and when they imported all of the Access data into SQL Server 2000 using DTS, it transformed the Text fields into nvarchar fields.

Well, it turns out that all of the string data is ASCII anyways, so I was able to nearly cut in half the storage requirements of the database by changing the nvarchar fields into regular varchar fields. This also had a positive affect on the runtimes of my stored procedures that moves data around within the database.

Thursday, February 09, 2006

Finally Saw the Light

After all of the wondering I did about the value of the new DELETE TOP(x) in SQL Server 2005 (here), I finally saw the light today as I worked on a SQL Server 2000 project.

Picture this:

  • A huge-ass table with 2.5 million records taking up about 5.5 GB of disk space.
  • Most, but not necessarily all, of this data needs to be replaced monthly with a new snapshot that will be generated via an ETL (Extract, Transform, Load) process.
  • Due to disk space, the database has a hard limit of 12 GB, and the transaction log is also size fixed.


The data is marked with a month and year, so replacing data consists of deleting existing records for the months/years that are being imported, and then copying the new records into the table. But, it's not that simple.

If you just remove all of the records in one batch using DELETE FROM table WHERE..., then you need to have enough room in the transaction log to write the "undo" information in case the batch fails (so it can roll back the entire DELETE). If the transaction log cannot accomodate the 5.5GB of data that will be stuffed into it, then the batch will fail.

So, you need to find a way to break up the deletes into smaller chunks. Each smaller DELETE will still use the Transaction log, but after the command successfully terminates, that space will be reclaimed for subsequent operations.

Under SQL 2000, you're stuck with things like using Cursors in order to iterate through a list of month/year combinations from the incoming data (assuming that it was saved to an intermediate table first), and then using those values as part of a DELETE statement within the loop.

But, with our new friend SQL Server 2005, you can use something like multiple "DELETE TOP(1000) FROM table WHERE..." in order to break up the transaction.

Now That's Product Placement!

On last night's LOST, Hurley was reading a manuscript for a mystery novel that was presumably written by one of the people aboard Flight 815 who did not survive.

Well, looky what's on Amazon (read the "About the Author" in the Editorial Review):

http://www.amazon.com/gp/product/1401302769/sr=1-1/qid=1139457754/ref=pd_bbs_1/002-3377525-3860841?%5Fencoding=UTF8

So, LOST is not using product placement in the form of showing a character drinking Pepsi. It's introducing original works, and then marketing those same products to us consumers in the real world. Brilliant, IMHO!

Wednesday, February 08, 2006

Has Anybody Seen My Code?

About 6 years ago, I wrote some great code as part of an ASP site. There was a SQL Server stored procedure that ran for a long time, an because of this, it would periodically update a status table with percent complete (it was performing cursor-based operations that applied a set of rules to a set of data, so it could accurately report how far long in the set of rules it was at any one time). The stored proc was kicked off from ASP/ADO script, and that web page would keep refreshing itself in order to update the % complete.

I had a very similar need today: to kick off a stored procedure from an OSASPADO (Old-School ASP/ADO) site and load a status page that kept refreshing while the proc continued to execute on the server. You know what? I can't find my old code, and I couldn't find a way to recreate it!

In the world of classic ASP running on IIS 6 (Windows 2003 Server) using a SQL Server 2000 backend, connections appear to be recycled shortly after the script finishes executing. I tried probably 6-10 different ways of starting the stored procedure, but it would always stall out within a minute.

I finally gave up, and went with the out-of-band approach: The ASP script would insert some parameters into a "jobs" table, and then a SQL Server scheduled job (via the SQL Agent) would check this table, and execute the stored procedure using these parameter values if data existed in the "jobs" table.

I realize that this description is a little bit on the abstract side, but how the heck was I able to accomplish this task in the past on IIS 5/Windows 2000/SQL Server 7.0???

Thursday, February 02, 2006

@!#%& Quicktime

Every time that I pave my machine, I swear that I'm not going to load Quicktime again, but I eventually need to because I have yet to find a way to play Quicktime videos in Windows Media Player.

Despite explicitly telling the installer that I DO NOT WANT QUICKTIME TO BE MY DEFAULT PLAYER for anything but Quicktime videos, I always seem to see the plugin pop up when I click on, say an MP3 file link on a web page:

Quicktime Plugin Playing My Browser's MP3 Files

(the link being displayed in this screenshot, btw, is another SSWUG podcast where a blog post of mine was mentioned:

http://www.sswug.org/sswugradio/the_where_clause_02feb2006.mp3)

PwopWatcher

Note: I did some blog refactoring, and extracted this information into it's own post. It originally was here.

My little program is a console app that I scheduled to run every 3 hours using the Windows Task Scheduler. It looks to the config file for a list of feeds, and then fetches the RSS from those feeds, and searches for //item/enclosure[@url] elements in order to get the URL for each .torrent file that Pwop publishes. The .torrent file is then downloaded and saved to the drop directory that I configured µTorrent to watch. I mean, this is what everyone's looking for when they say that they want RSS capabilities in their BitTorrent client, right?

Oh, and I kind of take advantage of a little error-handling feature of µTorrent: if it already loaded a particular torrent, it will simply log a warning if you try to load that torrent again. This is useful because my console app blindly downloads torrents each time that it runs, but µTorrent just ignores the duplicates (only new torrents placed in the drop directory will be processed).

I call the program PwopWatcher, but only because I'm not too imaginative in naming projects, and chose this name because... well, because I use it to watch the Pwop RSS feeds (in other words, I don't mean to imply that it was produced by Pwop Productions).

It is a .NET 2.0 console application, and here's the source code (for Program.cs, the main class file that VS2005 creates for Console Application projects). I'm listing it here because I don't think this is rocket science, and it will hopefully benefit people looking for examples of processing RSS feeds and downloading files from the Internet using the .NET 2.0 Framework.


class Program
{
  static string dropDir = @"c:\pwop\drop\";

  static void Main(string[] args)
  {
    try
    {

      dropDir = System.Configuration.ConfigurationManager.AppSettings["dropDir"];

      if (!dropDir.EndsWith(@"\"))
      {
        dropDir += @"\";
      }

      foreach (string feed in System.Configuration.ConfigurationManager.AppSettings["feeds"].Split(";".ToCharArray()))
      {
        ParseTorrentsFromFeed(feed);
      }
    }
    catch (Exception ex)
    {
      Console.Beep();
      Console.WriteLine(ex.ToString());
    }

    System.Threading.Thread.Sleep(30000);
  }

  static void ParseTorrentsFromFeed(string feed)
  {
    if (feed == string.Empty || feed == null)
      return;

    System.Xml.XmlDocument xDoc = new System.Xml.XmlDocument();

    try
    {
      xDoc.Load(feed);
    }
    catch (System.Xml.XmlException ex)
    {
      Console.Beep();
      Console.WriteLine("XmlException encountered while loading feed:\n\n" + ex.ToString());
      return;
    }

    System.Xml.XmlNodeList nl = xDoc.SelectNodes("//item/enclosure[@url]");

    foreach (System.Xml.XmlNode n in nl)
    {
      DownloadTorrent(n.Attributes["url"].Value);
    }

  }

  static void DownloadTorrent(string url)
  {
    try
    {
      string filename = url.Substring(url.LastIndexOf("/") + 1);

      using (System.Net.WebClient wc = new System.Net.WebClient())
      {
        wc.DownloadFile(url, dropDir + filename);
        Console.WriteLine("Fetched " + filename);
      }
    }
    catch (Exception ex)
    {
      Console.Beep();
      Console.WriteLine("Exception encountered while downloading torrent:\n\n" + ex.ToString());
      return;
    }
  }
}


The config file is expected to have two appSettings:

"feeds" is a semicolon-delimited list of RSS feeds
"dropDir" is the directory where the .torrent files will be saved to

µTorrent r0x0rz!

I've been seeding torrents for the different Pwop shows for a couple of weeks now. At first, I used Azureus, simply because that's what Carl initially recommended, plus it supported RSS feeds. Then, I discovered µTorrent.

Azureus is by far the most popular BitTorrent client at the moment. However, it is written in Java, and consumes a lot of memory. "But, memory is cheap," you might say. True, but my seeding system only has 256MB in it to start with, so I'm looking for something that is REALLY light on the physical memory.

That's the niche that µTorrent fills. The whole program is contained in a small 133kB executable, and it hardly consumes any memory when it runs. For example, it's been running for a couple weeks now, and I'm currently seeding 23 torrents, and the process is only consuming 2.8MB of physical memory and another 5MB of virtual memory. Compare that to the 40-60MB of physical memory that I sometimes saw Azureus using!

I'm not sure how well the built-in RSS capabilities of µTorrent are. To be truthful, after discovering that it has a built-in directory watcher that will automatically load any .torrent file that is placed into a drop directory, I just rolled my own RSS consumer.

Note: There was originally more info here that detailed the small "PwopWatcher" app that I created to consume the Pwop RSS feeds. I moved that content to it's own post:

http://jasonf-blog.blogspot.com/2006/02/pwopwatcher.html

I'm Trapped in a Time Warp

If anyone is able to read this, please help! I'm blogging from my room at a bed and breakfast in Punxsutawney, Pennsylvania. I've been waking up to the same Sonny and Cher song every day for about a year now, and no matter what I seem to do, tomorrow always turns out to be February 2nd!



(Happy Groundhog Day)

Wednesday, February 01, 2006

Database Performance Increase Tip: Avoid MS-Access

A client of mine wanted to put together a tool to help them determine the profitability of their products. They didn't have a big budget, so initially (last year), they opted for a MS-Access based tool, since they already knew (or thought that they knew) how to use Access. They were also under the assumption that this would be cheaper than designing and building a purely SQL Server based solution (because they don't understand SQL Server).

So, my company developed the tool for them to take a bunch of overhead numbers and distribute the associated costs for a period of time over the list of invoice line items for the same period. Using Access. From a desktop client.

Ok, that's fine. The tool worked really fast with the sample data that they provided. Party on.

But, whoa! Their production data for just 1 month's worth of invoice data was multiple gigabytes in size - much too large to transfer into an Access database (which apparently has a 2GB file size limit). And, typically, the profitability was measured on a quarter's worth of data (3 months). Well, now we needed to introduce SQL Server into the equation in order to hold the large sets of data, while the business logic continued to exist in Access.

Did I mention that I was NOT involved in the architecture or construction at this point?

So, picture this: They would use Access to drive the data migration by linking to the source database in their data warehouse (using ODBC) and the destination database in SQL Server (also using ODBC) and pump all of those gigabytes worth of data through the desktop client. Besides being extremely slow, this also had a nice side effect of bloating the transaction log file (LDF) to the point that it actually filled the disk.

Then, once data for a period was in place on the SQL Server, a VBA module in Access would fire off, open about 15 recordsets to various lookup tables, loop through each row of the invoice data, search the 15 recordsets for corresponding data using .FindFirst, and then eventually update the row in the invoice table with calculated data.

This whole process, end-to-end, would literally take them 3+ days to run. They would start it on a spare machine, and check back days later to see if it completed, or if it errored out (in which case, they had to start over).

Ok, so the MS-Access solution is now being called a prototype, and I'm now in the picture to ensure that they get better performance out of the next iteration of the project. The obvious improvements that I'm making are to use DTS to pump the data from Oracle into SQL Server 2000, establishing proper indexes (including a clustered index that includes the invoice date), and to move everything out of Access. That VBA module is being ported to a stored procedure, and instead of using cursor-based processing, I'm manually converting everything to set-based.

(To be fair, a lot of these changes were actually identified by the original developer of the MS-Access developer before I became involved)

I don't have access to their production data at this point, but based on the data that I have, I'm predicting that the 3-days worth of processing can be completed in 10 minutes. That's 432 times faster (which, if I'm calculating correctly, is 21,600% faster??!), chiefly due to the logic being moved to the data tier instead of pumping data across the wire using ODBC and MS-Access.

I'm excited to see this run on the actual production system...

Warner Bros. In2Movie Service To Use P2P

Something caught my eye as I read Neowin this morning: Warner Bros. is going to start offering movies and television shows for download (obviously at a cost).

But, that's not what caught my eye. The article was a little light on details, but it seems that Warner Bros. will use Peer-to-Peer (P2P) technology to distribute the content. Looking into my crystal ball, I can foresee this service failing, and here's why:

P2P distribution technology, like Gnutella or BitTorrent, depends on users uploading in addition to downloading. As a user, I don't mind providing the bandwidth to upload because I see that as a tax for being able to download content faster. But, this concept only works when the content is free to start with.

As soon as I have to pay for content, then I'm not interested in sharing my uplink. I expect the content provider to have a really big pipe so that I can download everything from that one source, and I don't want to wait forever for the content to arrive. I don't believe that I'm alone in thinking this way, either.

So, if WB is planning to just distribute their content using BitTorrent, then they're going to find a vast majority of downloaders who simply leech from the swarm (leeching is when someone downloads without providing any uploading at all, or who turns off the BitTorrent software after the download completes so that no further uploading occurs). The result will be the opposite of what BitTorrent was designed to do: instead of downloads getting faster as more machines participate in the swarm, they will get slower because more demand will be placed on fewer nodes of the network.

Of course, I could be interpreting this incorrectly. Look at what Pwop Productions is starting to do by establishing a network of BitTorrent seeds through their Ambassador program. This is the future of P2P distribution, in case you haven't been paying attention.

Carl, who truly believes that his content must be of great quality, and must be free to the listener, assembled an army of volunteers (this blogger included). BitTorrent clients on these machines subscribe to an early feed that allows them to access torrents hours before they are released to the general public. The goal is that by the time a DNR, Mondays, dnrTV, or Hanselminutes show goes live, that there is already a number of machines seeding the content.

This benefits Pwop in the fact that there are lower demands on their network bandwidth, and benefits the listener in that they are able to download the content faster.

So, any major studio, like Warner Bros., should look to the Pwop model as inspiration for setting up their own distribution network. They can set up a grid of P2P seeder nodes scattered throughout the world, thus eliminating the need for one big central pipe. However, unlike Pwop, the studios cannot count on the same type of upload capability from their downloaders.