Thursday, June 28, 2007

10 Steps to Win the Family IT Guy Award

I’m sure that most of my readers are the “Family IT” people to their relatives.  You know, the kind of person that gets regular phone calls from parents, aunts, uncles, cousins, brothers, sisters, grandparents, kids, etc.

I have filled that role since I was probably 13.  Most of the time I would just get annoyed, but now, in my infinite maturity (), I have fully accepted this responsibility.  Here are the 10 steps you (and I) should take to win the Family IT Guy award…  come on, you know you want it!

Family_it_guy

Step 1:  Get a Good Backup Strategy

It starts with a backup strategy.  I have a 500GB Western Digital My Book that takes images of my home PCs and stores them.  This pretty much works, except when my house burns down I have nothing.  My wife has about 45 GB worth of family photos and digital scrapbooking material.  It would be catastrophic to lose all that stuff.  It’s irreplaceable.  Other data that is important to backup are digital scans of driver’s licenses, social security cards, birth certificates, tax forms, etc.

So I setup both of our computers (mine and my wife’s) on Carbonite online backup.  Carbonite installs a little background process that will backup your files behind the scenes.  It’s less than $50/year and you can store unlimited data.  Your data is encrypted and uploaded and you can pull it down at any time.

It also installs a little explorer overlay icon that shows you a blue, green, or yellow dot.  Green means backed up, so your family knows they’re safe.

Step 2:  Keep Spare Parts Around

I can’t begin to count how many times a family member has asked me for a network cable, or a sound card, or a network card, or just about any other piece of hardware that a computer needs.  Since I do a lot of tinkering with computer hardware, I tend to have a lot of spare parts.

Your uncle will appreciate not having to order a new sound card for $15 at the local computer shop or (gasp!) online at newegg.

Step 3:  Keep a Digital Toolbelt on you – A 2GB USB Drive

I have a copy of every tool from SysInternals on my USB Key. They are invaluable when digging deep into Windows problems.

I also put portable apps such as Firefox Portable my thumb drive.  This allows me to run a better browser when nothing but IE 6 is installed.

Also grab a copy of ClamWin Antivirus Portable (or regular version) or another free AV program.  You never know when you’ll have a cousin jump out of the bushes and ask you to clean their laptop.

Keeping a thumb drive on you will make it a lot easier to use a family member’s computer.  The last thing you want to do is have to come back later with the right tools!

For a good list of essential tools, check out Scott Hanselman’s Ultimate Tools List.

Step 4:  Setup Family Email

We’re all tired of email addresses like JRod44222354@aol.com. (Apologies if that is your email address.)  I recently setup scheirman.com as my family domain name and gave most of my relatives their own email address.  Most of them were pretty excited to have a firstname@lastname.com email address.  Of course if your last name is Smith, then you’ll have to get creative.

To host the email I’m using Google Apps for Your Domain and it works like a charm.  Not only do you get all the goodness of GMail, but you get a personal email address as well!  Their interface is slick and easy to use.

Step 5:  Advise on New Computer Purchases

Don’t let your Grandmother buy that new computer from the neigbor kid down the street.  If you see your cousin walk into the Sony Style store at the mall with an armload of cash, stop her

Computers are cheap.  Unless you want a high-end gaming rig or a video processing machine, your standard Dell fare will do you just fine, and often times under $600.  It comes with a warranty, which saves you a headache for at least a year .

Step 6:  Get a Remote Access Plan

When your sister calls you from Montana and says she needs help adding a user to her computer, be ready.  With some good remote access software it can be painless to just take control and do it for her.

FogCreek Copilot is supposed to be good.  Joel Spolsky’s company Fog Creek Software wrote it and I have heard good reviews.  It’s very cheap for about an hour of use and “it just works.”

Crossloop_screenshot_small

CrossLoop is a tool I just tried out the other day, and it also “just works.”  You and your relative can download this in less than a minute, run it, and be connected even behind firewalls.  Best of all, it’s free!

I used this the other day when I was helping my wife upload some files to her blog with an FTP client.  I didn’t have much time and it was a bit difficult to explain over the phone, so I told her to download the client, click “Host” and then read me the number on the screen. 

That’s all it took!

 

 

Step 7:  Don’t Get Annoyed

PC Enthusiasts frequently whine and moan about having to help their relatives about how to use the computer.  It’s easy for us because we use it everyday.  Many non-techies perceive computer gurus like they do auto mechanics or lawyers.  We don’t want this kind of image!

The next time you walk up to your computer, take a look at how many buttons there are.  What if your Grandmother sat down for the first time to use a PC?  It is incredibly intimidating and complicated.  How did you react when you first got a virus? 

Cut your family some slack.  Be Patient.

Step 8:  Spread the word. 

Get your peeps using Firefox instead of Internet Explorer.  Tell them the wonders of GMail.  Explain to them that there’s more than the MSN home page.  Getting the word out is the only way you can ever expect people to see the light.

When someone forwards you an email with a taseless joke or a reason why you should thank the heavens for waking up in the morning, only in ALL CAPS… politely inform them of internet etiquette.  Don’t just push the SPAM button.

I bought my dad a copy of the Lifehacker book for Christmas last year.  He loved it.  It’s full of useful tools and tricks to make your computer work for you.  He’s a computer guy, mind you… but not the typical person who would read www.lifehacker.com on a daily basis (though now he proabably does).

Step 9:  Find a Protogé

You can’t do this stuff forever.  Look at the younger folks in your family that can help take the throne.  Tell them, “One day….  this will all be yours…”

Be a mentor about good computer usage and troubleshooting.  Don’t be stingy with The Badge.  Pass it on.

Step 10:  Let Your Family Know Your Other Interests

I enjoy playing guitar, swimming, grilling food with family, playing board games, reading books, watching movies and addicting TV shows.  If all you talk about is World of Warcraft, people are going to think you are weird.  Let your family know that you are at least a tad normal, and that you do enjoy sunlight once in a while.

 

So there you have it, there are my 10 steps to becoming a good Family IT Guy.  A lot of my Family IT Guy inspiration comes from Scott Hanselman, who seems to have all this down pretty darn good.  I hope his family knows how good they have it.

Friday, June 22, 2007

Run as Administrator on Vista to Fix Weird Program Issues

I’ve been running Vista for about 6 months now, and I really like it.  There are a lot of issues that I have run into, but some of the minor ones are easy to fix.

For example, I downloaded e-texteditor which is like TextMate for Windows.  It uses Cygwin for some advanced features, so when you try to use then (like Alt-Shift-Comma for auto-wrapping html brackets and closing tags on a word) — E goes to install Cygwin.  Under Vista, clicking on “Install” does nothing.

E - a TextMate clone for Windows

The solution is to Run as Administrator.  A lot of programs out there aren’t testing on Vista so they don’t realize that many of the features require elevated access, and if they silently suppress the issue, the user never knows what’s going wrong.  It’s the fault of the application, not Vista.

SQL Management Studio Express does this to me as well.  I always have to run that program as Administrator.

Tuesday, June 19, 2007

Reflection and Inheritance with Generics

I was working on some SubSonic entities today and I wanted to access some of the properties of the generated classes, not knowing which database objects will exist.

Basically I wanted to write a utility method that would pull out all of the ActiveRecord<T> types in a given assembly.

This was my first attempt:

public static Type[] GetActiveRecordTypes(Assembly assembly)
{
	List<Type> types = new List<Type>();
	foreach (Type type in assembly.GetTypes())
	{
		if(type.IsSubClassOf( typeof(ActiveRecord<__WHAT_GOES_HERE_?__>) )
			types.Add(type);
	}
	return types.ToArray();
}

The part in bold is where I got stuck. Sticking in type there doesn't work. It won't compile.  I wouldn't let that stop me, so I created a temporary solution like this:

if(type.BaseType.Name.Contains("ActiveRecord")) { ... }

This works, but it's a hack and it's brittle. I asked a few friends and Gary DeReese came to my rescue with the following code:

  Type baseType = type.BaseType;
  if(baseType.IsGenericType && 
	baseType.GetGenericType() == typeof(ActiveRecord<>) &&
	baseType.GetGenericParameter()[0] == type) { ... }

It's good to have smart friends you can reach out to in times like this where you just aren't thinking about the problem the way the framework wants you to. Thanks Gary!

Monday, June 18, 2007

VSTS Db Pro - Which Database Project?

I installed Visual Studio Team Edition for Database Professionals the other day and I was about to create my first DB Pro project.

Check out the New Project dialog box.  This is with VSTS Developer, and DB Pro installed:

Image001

and…

Image002

Seeing as how I never used the standard database project in Visual Studio before, I couldn’t tell which one I was supposed to choose. 

It turns out that you need to pick the one in the 2nd screenshot, the Microsoft SQL Server project. 

Wasn’t very intuitive which project to choose.

Tags: ,

ASP.NET Essentials - The Label

After talking to developers for a few days about basic HTML and ASP.NET topics, I find that I always focus on the Label control.

More specifically, I’m talking about the <label> tag in HTML.  What does this tag do?  Why should we care, when we can just write the text before an input control on the page?

For starters, the label has semantic meaning.  The <label> tag gives meaning to a textbox or a dropdown.  If you were blind and browsing using a screen reader, you’d appreciate the little semantic tidbits that give you an easier browser experience.

Another benefit is that we can select and style the label easily, making the transition to table-less forms so much easier.

A third and possibly more useful benefit is that the mouse stays as a pointer, and clicking on the text sets the focus to the corresponding control.

The usage in standard HTML is like this:

<label for='user_name'>User Name:</label>
<input type='text' id='user_name' />

This results in the following example:

(notice how the mouse cursor stays as a pointer, instead of the standard text cursor)

If you were a reasonable person, you’d think that the <asp:label> control would render as an HTML <label>, but you’d be wrong.  ASP.NET renders a standard <asp:label> as a <span>.  ASP.NET 2.0 fixed this, however you have to specify the AssociatedControlID property to change the rendering behavior.

This leads me to another point that I’d like to make with the Label control.  Often times we just want a static label, like in the example above.  If we use the <asp:label> then we’ll have a server-side component as well and a viewstate hit.

Label_render

We certainly don’t need viewstate in this scenario,  Often times we just neglect these things until they are a problem. 

I can hear you say it now… “but Ben, you can disable Viewstate by specifying EnableViewState=’false’ “…  I know you can.  But it’s too easy to just leave it as is.  There’s also an easy alternative.

You can accomplish the same rendering without the viewstate issue by just typing this:

<label for='<%= txtUsername.ClientID %>'>User Name:</label>

This will render the same way, but also ensure that we get the generated ID of the control that we are associating with.  This will not have any server-side component or any correlation to ViewState, and it is actually less characters to type.

Hope you find this information useful!

Friday, June 15, 2007

HDNUG Last Night

Last night I gave a talk to the largets crowd I have ever spoken in front of.  There were over 100 people in the room and they were a great audience.  I received lots of devoted attention and people were eager to participate.  I was quite nervous in the beginning, but once I got into the material I think it came across very well.

I spoke about why to use CSS and what we can do to overcome some of the pitfalls.  I also explained why we don’t want to be using tables for layout. 

I moved from there to some javascript techniques and a little bit of ajax.  From what I got from that portion, it could have probably warranted more time, but there was just so much to cover.

The files that I used during the demo are available for download here:

File Attachment: AdvancedCSSAndJavascript.zip (1140 KB)

 

I received a number of questions about the tools I was using during the demo.  The text editor I was using was e.  You can download it at www.e-texteditor.com.  The application launcher that I use is launchy.  It is available at www.launchy.net.  Finally the Keyboard shortcut window, called Key Jedi is available here.

If you attended the presentation, I would love to hear your feedback in the comments.  Thanks for coming!

Update:  The links that I wanted to show (but couldn't) during the presentation are:

Wednesday, June 13, 2007

Safari On Windows

So I went out and installed Safari 3 for Windows yesterday.

I just had to see what all the fuss was about.  How do you piss off a number of Windows users simultaneously?  Release a product that has a different font rendering technology than their native OS.

Seriously, people are going nuts about this font thing.  Joel Spolsky and Jeff Atwood have covered the details nicely, but I find it quite interesting that something so trivial can make such an impact.  You generally don’t even think about it, but I’ve always noticed that Safari on Mac looked somehow different than Firefox on Windows.  I’m not talking about the browser itself, I’m talking about the pages that get rendered.

I can see everyones argument, but I really happen to like the Apple mentality, and as Atwood says, this debate will be gone once higher dpi screens become available.

There is just something beautiful about the way that plain text looks with Safari, particularly at large sizes.  At tiny sizes, however, I get a headache reading it.

Firefox is still my browser-o-choice, but Safari does give me a nice experience.  I hope more Mac software ends up on Windows.  Choice is good.

 

Monday, June 04, 2007

Speaking at HDNUG on June 14th

For those of you near Houston, I will be speaking about advanced CSS and javascript techniques on June 14th.

The Houston .NET User Group is located in Westchase.  For more info, see their website at http://hdnug.org.

My presentation will cover some of the foundations of CSS-based web development and what it means to develop with web standards in mind.  We’ll also take a look at how to apply JavaScript in a safe and effective way to ensure that we still function when JavaScript is disabled, but also to allow the rest of the world to enjoy a richer web browsing experience.  If there’s time towards the end, we’ll also see how this applies to ajax.

Hope to see you there!

Sunday, June 03, 2007

A Journey with Domain Driven Design (and NHibernate) - Part 9

Back by popular demand… (and WAY too late, I might add…)

In this article, part 9 of the series, we’re going to wrap up our initial feature list and focus on building a user-interface for our video store, named Videocracy.

Here is our feature list:

  • Add new Customer / Account
  • Add other members to an account
  • Restrict Certain members from renting certain content
  • Query for a customer by customer # (swipe card, etc), phone number, or last name
  • Add new rental item (move game, console, vcr, etc)
  • Rent an item to a customer
  • Check Items Back in
  • Get movies checked out for a customer
  • Query for an item, see who has it

Let’s implement Check Items Back In.

What is the use case here?  Typically a customer drops off a movie, either in the slot from the outside of the store, or directly to an employee.  Either case starts with the movie, or the Item.

So the employee is going to scan the item.  At this time, they are going to need to see the details of who and when the item was checked out (the Rental object), and then have a confirmation button to finalize the check-in (which will update the Rental object).

In order to facilitate scanning the item, we need to be able to query the database for a particular UPC.

In implementing this next test I noticed a large problem with my domain.  Our Item class defines a name property with a mapped column in the database.  The problem with this is that not all items have names of their own.  They might have display names that are a combination of other properties.  For example, a video copy of the movie The Matrix shouldn’t have a name of ‘The Matrix’ (it really belongs to the Movie class).  Typically the text on the outside of a video rental is the movie name followed by maybe the year, and the format that the movie is in.  These are deferred properties, so there is no more need for a database column in the item class.  I still provide a read-only Name property, and inherited classes have to provide this information.  Would you have made a large change like this so eagerly in your project?  If you did, how would you know if you broke some existing functionality?  As I always say, it’s a good thing I have the tests to back me up…

Here’s our next test:

      [Test]

        public void Can_Check_In_Item()

        {

            Item i = TestHelper.CreateTestItem("Test_ITEM123", "1234_UPC");

            Customer c = TestHelper.GetTestCustomer();

            Employee empl = TestHelper.CreateTestEmployee();

 

            using (ISession session = SessionSource.Current.GetSession())

            {

                using (ITransaction tx = session.BeginTransaction())

                {

                    //store the customer and employees

                    session.Save(c);

                    session.Save(empl);

 

                    //check the item out to the customer

                    Rental r = new Rental(i, 2.30f);

                    RentalTransaction trans = c.CreateTransaction();

                    trans.Employee = empl;

                    trans.AddRental(r);

 

                    session.Save(c);

                    session.Save(trans);

 

                    tx.Commit();

                }

            }         

 

            //item is checked out, can we check it back in?

            Item i2 = Repository<Item>.FindSingleByProperty("UPC", "1234_UPC");

            Assert.IsNotNull(i2); //just a sanity check.  Item exists in the table.

 

            //we need to get the rental by the item upc

            Rental r2 = new RentalFinder().FindByItemUPC(i2.Upc);

 

            Assert.IsNotNull(r2, "Rental was null!");

        }

There is a lot going on in this test, so let’s break it up and take a look at each part.

            Item i = TestHelper.CreateTestItem("Test_ITEM123", "1234_UPC");

            Customer c = TestHelper.GetTestCustomer();

            Employee empl = TestHelper.CreateTestEmployee();

 

            using (ISession session = SessionSource.Current.GetSession())

            {

                using (ITransaction tx = session.BeginTransaction())

                {

                    //store the customer and employees

                    session.Save(c);

                    session.Save(empl);
                    . . .

Here we setup our environment.  We have to have a lot of entities that already exist in order to test our new funtionality.  We need an item, a customer, and employee, and an account.  We create all of those and save them.  (Remember all of this happens within a transaction that is rolled back, so this doesn’t stay in the database).

 

                    //check the item out to the customer

                    Rental r = new Rental(i, 2.30f);

                    RentalTransaction trans = c.CreateTransaction();

                    trans.Employee = empl;

                    trans.AddRental(r);

 

                    session.Save(c);

                    session.Save(trans);

 

                    tx.Commit();

 

Here we setup the rental and perform the rental transaction.  This is how the UI will structure the business process.  Once everything is saved, it’s time to verify that we can retrieve the data solely based on the item’s upc code.

            //item is checked out, can we check it back in?

            Item i2 = Repository<Item>.FindSingleByProperty("UPC", "1234_UPC");

            Assert.IsNotNull(i2); //just a sanity check.  Item exists in the table.

 

            //we need to get the rental by the item upc

            Rental r2 = new RentalFinder().FindByItemUPC(i2.Upc);

 

            Assert.IsNotNull(r2, "Rental was null!");

The Rental Finder class will encapsultate common queries so that we can reuse them across the application.  Here’s the code for that method:

public Rental FindByItemUPC(string upc)

{

    Rental r = Repository<Rental>.FindSingleByQuery("from Rental r where r.Item.Upc = :upc and r.DateReturned is null", new Parameter("upc", upc));

    return r;

}

There is a lot going on here in this test, but what you need to get from this is that we are setting up the stage for our scenario.  As our tests get more involved we are verifying that business cases are being met.  If we make drastic changes later on, we will know if we have broken existing business functionality.

The next thing to check is to make sure that we can check the item back in.  I add a .Return() method on the rental, which doesn’t exist yet, so I need some additional tests.

I also need to be able to calculate late fees in a central place to make that easy to change later.  I add a few tests for this as well.

It turns out that the Return() method is easy to implement.  All we need to do is set the return date and calculate the late fee and save it.

[Test]

public void CanReturnItem()

{

    Rental r1 = GetTestRental(DateTime.Now.AddDays(-6));

 

    r1.Return();

 

    Assert.IsTrue(r1.DateReturned.HasValue);

 

    //it's 1 day late, so expect the right late fee

    float lateFee = Utility.LATE_FEE_PER_DAY;

    Assert.AreEqual(lateFee, r1.LateFee);

 

}

which leads to the following code in the Rental class…

public void Return()

{

    this.DateReturned = DateTime.Now;

    this.LateFee = Utility.CalculateLateFee(_dateDue, _dateReturned.Value);

}

Now we need to finish the original test and verify that we can save the rental.

 r2.Return();

 

 //save the rental

 using (ISession session = SessionSource.Current.GetSession())

 {

    using (ITransaction tx = session.BeginTransaction())

    {

        session.SaveOrUpdate(r2);

        tx.Commit();

    }

 }

This test passes and we’ve implemented our feature!

I think I’m at a point where I have demonstrated how we can work on core business features for an application test-first, using NHibernate along the way for persistence.  A lot more work has to be done to complete our domain model, but that will be left as an excercise for the reader.

Instead, I would like to focus my efforts on getting a basic UI in place using ASP.NET.  I said in part 1 that I wanted to demonstrate how to work with the NHibernate Session in a web environment, so that’s where I will pick up next time.

Until then, you can download and view the current project here:

File Attachment: Videocracy_09.zip (3442 KB)

Wednesday, May 30, 2007

Microsoft Surface

http://www.microsoft.com/surface/

This is so cool I just had to blog about it.  Take a minute to watch the videos, they are quite impressive.

Basically it's a 30 inch surface that is monitored by tiny wireless cameras.  Hand gestures can rotate and resize images and videos and things.  I don't think we're at a point where we can give up the keyboard or the mouse, but think of some of the other uses it would be good for.

In the videos they show a simple paint program that kids would enjoy.  They also show it at a restaurant where the menu is all digital and you flip through it using your fingers.  When you're ready to order, you just drag the item to the center.  The same would go for paying the bill.  Set your credit card on the table, split the checks up, calculate the tip, and charge the card all without waiting for a server to do it for you.

I think we're going to see some really cool uses for this thing outside of normal computing.

Secured Loan - Loans - Mortgage Calculator - Phoenix Landscaping