Chinh Do

My Multiple-Monitor Programming Setup

First time here? Check out my greatest hits or look around in the archives, and consider subscribing to the latest posts via RSS or email. Thanks for visiting.
23rd February 2009

My Multiple-Monitor Programming Setup

In my opinion, the top three hardware items that help maximize programmer productivity are sufficient RAM, multiple monitors, and a fast multi-core CPU. For RAM, try to have at least 2GB for Visual Studio development, especially if you have additional applications such as Resharper, a local SQL Server instance, IIS, etc. Remember that on Windows XP or Vista 32-bit, the maximum usable RAM is limited to about 3.2 GB or so.

My current company-provided laptop, which I must perform most programming activities on, is a Core 2 Duo 2.4 Ghz. It is satisfactory for what I am doing. Given the choice however, I would go for a quad-core CPU desktop. Desktop usually has faster drives, better video cards, etc. And the additional cores allow for smooth multitasking and better performance when using virtual machines.

image

Plenty of RAM and multiple fast CPU cores will keep the waiting down to a minimum. Now you need to give yourself the ability to see all of those things that you have going on. Research has demonstrated that multiple monitors increase productivity. For most programmers, I would recommend two monitors. Adding that second monitor is a relatively inexpensive affair. Most laptops or desktop video cards has built-in support for a second monitor so all you have to do is getting that second LCD, which cost very little these days compared to three years ago. The third monitor and beyond is where things start to get complicated. You either have to install a second video card, or use a second PC/laptop in conjunction with a software application named MaxiVista. Unless you have spare monitors sitting around, I think the return on investment starts to diminish greatly beyond two monitors.

Another way to use that third or fourth monitor is to simply attach them to additional computers. Sure, you won’t be able to control all those monitors with the same mouse and keyboard but this setup is not without advantages:

  • When the first computer is rebooting or not responding, you still have a fully functioning computer.
  • The screens on the second computer are not using CPU/memory resources on the first computer.

My 5-Monitor Setup

I work from home most of the time and on my desk, there are five monitors, hooked up to three laptops. I know… it’s over the top but it’s not like I bought all of these laptops/monitors specifically for this setup. The second laptop is my personal laptop. The third one is another old personal laptop that would otherwise would be sitting around gathering dust. I might as well put them all to use. Here’s how the monitors are arranged:

image

The main laptop is hooked up to monitor #1, an ASUS 24″ running at 1920×1080 resolution and monitor #2, the main laptop’s built-in 15.4-inch LCD running at 1680×1050. I spend most of my time on these two monitors. The ASUS 24″ is great for programming/debugging and is where I normally park Visual Studio 2008 or Rational Software Architect. If you can get one with more vertical resolution (such as 1920×1200), that’s even better.

Visual Studio

The extra width on the main monitor allows me to permanently open supporting panes like Solution Explorer that I otherwise would configure to “auto hide”. Note where I have my Start menu: on the right edge of the main monitor. This gives me more vertical space so I can see more code without scrolling. The additional benefits are that more opened windows can fit on the task bar, and that I don’t have to move the mouse as much to access the start menu.

The built-in laptop monitor (#2) is where I have miscellaneous supporting windows such as rolling logs, instant messaging client, email client, documents, etc.

For taking notes, I use Microsoft OneNote and since it’s not installed on my company PC, I use my own laptop for it. This laptop is monitor #3, sitting to the left of the main monitor. Monitors #4 and #5 are used once in a while to display server logs, various server telnet and remote desktop connections, and anything I don’t need to control often.

Update 2/25/2008 - Synergy

Rohan kindly pointed out to me a free keyboard/mouse sharing utility called Synergy. You should give this a try if you have multiple computers on your desk. Synergy lets you use a single keyboard/mouse to control multiple computers, running multiple operating systems. Additional features include clipboard sharing, screen saver, and single password login. The configuration is not the most intuitive but once you have everything set up correctly, it works like a charm.

I now can control all three laptops and 5 monitors with one mouse/keyboard combo! Very nice.

Synergy animation

posted in Dotnet/.NET - C#, Java, Programming, Software/tools, Technology, Tips | 3 Comments

9th January 2009

How to Use VISA Gift Card on Amazon

I googled this and didn’t find anything useful so I thought I’d share this. If you have a VISA gift card and want to use it on Amazon.com in conjunction with a credit card (to pay for any amount over the gift card value), the trick is to use the VISA gift card to purchase an Amazon gift card for yourself. Once you have the Amazon gift card, you can then use it to pay for part of your order, with the remaining balance being charged to your credit card.

I am sure this trick works with most other online merchants too.

posted in Tips | 6 Comments

1st January 2009

Enabling Anonymous File Sharing with Vista

On my home network, I have a media file server running Vista 64-bit that serves out music and movies. Since everything is behind a router, I decided to make the shared media folders accessible to anyone on my home network. All you have to do is browse to the media server and start accessing content, without having to log in.

To enable anonymous browsing of a shared folder that is shared by a Vista PC (that is not on a domain), do the following:

  • Enable the Guest Account:
    • Run "lusrmgr.msc", select the Users folder.
    • Right click on the Guest user and choose Properttes.
    • Uncheck "Account is disabled".

      image

  • Enable "Public folder sharing" and disable "Password protected sharing":
    • Choose Start, right click on Network, and choose Properties.
    • Enable "Public folder sharing".
    • Disable "Password protected sharing".

      image

  • For each shared folder:
    • Grant Everyone Read permission to the Share.
    • Grant Everyone Read and Execute (NTFS) permission on the shared folder itself.

      image

posted in Technology, Tips | 0 Comments

23rd December 2008

Vista 64-bit and SoundBlaster X-Fi Crackling/Popping

Against popular wisdom, I decided to upgrade my bedroom home theater PC to Vista 64-bit a couple days ago (just have to make full use of all of my precious 4GB of RAM). Everything is working surprising well so far, with the exception of sound! Whenever I play any audio, my speakers now produce all kinds of pops and crackles along with the normal audio stream. Urgg.

After a couple of days of googling, tweeking various sound settings, uninstalling/reinstalling drivers, etc. without success, I almost gave up on the thing. Then I decided to try just one more thing, changing the default sample rate to “2 channel, 16 bit, 44100 Hz (CD Quality)” from the default “2 channel, 24 bit, 48000Hz” and just like magic, the pops and crackles are gone.

SPDIF Out Properties

posted in Software/tools, Technology, Tips | 4 Comments

29th August 2008

Web Scraping, HTML/XML Parsing, and Firebug’s Copy XPath Feature

If you do any web scraping (also known as web data mining, extracting, harvesting), you are probably familiar with the main steps: navigate to page, retrieve HTML, parse HTML, extract desired elements, repeat. I’ve found the SgmlReader library to be very useful for this purpose. SmglReader turns your HTML into XML. Once you have the XML, it’s fairly easy to use built-in classes such as XmlDocument, XmlTextReader, XPathNavigator to parse and extract the data you want.

Now to the labor intensive part: before your program can make sense of the XML, you have to manually analyze the HTML/XML first. Your program won’t know jack about how to extract that stock price until you tell it exactly where the stock price is, typically in the form of an XPath expression. My process of getting that XPath expression goes something like this:

  1. Scroll to/find desired element in the XML editor.
  2. Does element have unique attributes that can be used?
    • a - If yes, code XPATH statement with filter on attribute value. Example: //Table[@id="searchResultTable"].
    • b - If no, code an absolute XPATH expression. Example: /html/body/div[4]/pre[2]/font[7]/table[2]/tr[5]/td[2]/table[1]/tr[2]/td[5]/span.

Step 2b is where it gets very labor intensive and boring, especially for a big web page with many levels of nesting. Visual Studio 2005 XML Editor/Resharper have a couple of features that I find useful for this:

- Visual Studio’s Format Document (Edit/Advanced/Format Document) command formats the XML with nice indentation and makes it a lot easier to look at.

- With Resharper, you can press Ctrl-[ to go to the start of the current element, or if you are already at the start, go to the parent element.

Even with the above tools, it's still a painful and error-prone exercise. Luckily for us, Firebug has the perfect feature for this: Copy XPath. To use it, open your HTML/XML document, open the Firebug pane (Tools/Firebug/Open Firebug), navigate to the desired element, right click on it and choose "Copy XPath".

Firebug Copy Xpath

You should now have this XPath expression in the clipboard, ready to be pasted into your web scrapper application: "/html/body/div[2]/table/tr/td[2]/table”.

A feature that I would love to have is the ability to generate an alternate XPath expression using “id” predicates, such as this: “//Table[@id="searchResultTable"]“. With web pages that are not under your control, you want to minimize the chance that changes on the pages impact your code. Absolute XPath expressions are vulnerable to any kind of changes on the page that change the order and/or nesting of elements. On the other hand, XPath expressions using an “id” predicate are less likely to be impacted by layout changes because in HTML, element IDs are supposed to be unique. No matter where your element is on the page, if it has the same ID, you should still be able to get to it by looking up the ID. Hmm… this sounds like a good idea for a Visual Studio Add-in.

posted in Dotnet/.NET - C#, Programming, Software/tools, Technology, Tips | 4 Comments

1st June 2008

Finds of the Week - May 31, 2008

Programming

.NET/C#

Software and Tools

  • Google Maps Street View is in Richmond.

    Google Street View Richmond Virginia Goo

    It looks like the Street View images were taken around September 2007 because according to IMDB, the movie Game Plan was playing in the US starting 9/23/2007:

    Google Street View Richmond

  • Google Maps adds user-created photos, videos, maps. Via CNET.

    Google Maps Goog

Something Different

posted in Dotnet/.NET - C#, Gadgets, Programming, Software/tools, Technology, Tips | 1 Comment

15th March 2008

Installing Windows Vista without CD/DVD Drive

Just in case anyone else needs to do this out there…

I recently got myself a nice ThinkPad X60 Tablet PC. It doesn’t come with a DVD-Drive and although I have an external DVD drive, I just can’t seem to find its power adapter. Argg!

In order to do this, you must have the following:

  • Windows XP installed on the PC you want to install Vista to.

Procedure

  1. Log in into Windows XP on the PC you want to install Vista to.
  2. Use Partition Magic or another partitioning tool and create a second partition for Vista. Make it a Primary Partition (don’t know if this is required but this is what I did). Format the second partition with NTFS. Your Windows XP installation will be left alone and you will be able to dual boot to it.
  3. Create a folder (let’s called it "c:\VistaInstall") and copy all files from the Vista DVD / ISO there (either extract the files from an ISO image using a Virtual CD/DVD emulator like Daemon Tools, or copy the files from another PC with a DVD drive over the network).
  4. Run Setup.exe from c:\VistaInstall.
  5. Choose Custom Install and follow the prompts to select the second partition you created.
  6. Follow the rest of the on-screen instructions.

As part of the installation, Vista Setup will copy the installation files to the new partition. After it reboots, it’ll have all the files there to continue.

After you are done with the install, you can delete the temporary folder c:\VistaInstall that you created.

posted in Software/tools, Technology, Tips | 2 Comments

4th March 2008

Finds of the Week - March 2, 2008

Programming

C#.NET

.NET Tips & Tricks

  • Did you know you can give threads any names you want (MSDN)? The names are extremely useful when it comes to debugging time:

    Thread names and debugging

  • System.IO.Directory.CreateDirectory will create all directories and subdirectories as specified by the path parameter. No need to write code to create each directory in the chain. Just do this:
    Directory.CreateDirectory(@"c:\MyApp\Env\Dev");
  • System.IO.Path.GetDirectoryName returns the directory name from a fully qualified file name.

Powershell

  • Round-robin game scheduling algorithm in Powershell. By Scott Hanselman. Check out my C# 2.0 algorithm in the comments section.
  • Mitch Denny wrote How To: Host the PowerShell Runtime.
  • Use Powershell array expression syntax @(…) allows you to force a scalar return value to be wrapped in a array, if it’s not already in an array. I learned about this the hard way while trying to figure out while Get-Childitem sometimes returns an array and sometimes a scalar. Bruce Payette wrote more about it here.

Windows Mobile / Pocket PC

  • I needed a way to stream music and other media to my Windows Mobile phone (Samsung SCH-i760) and all the PCs around the house. Orb seems to be the answer. I’ve only had it running for a few days but it seems to be working great. I can stream music and photos (have not tested videos yet) to any PC in the house or anywhere on the net. I can also listen to my entire music library on my i760 phone anytime, anywhere through Verizon Wireless’s unlimited (with a catch… not to exceed 5GB) EDVO connection.

    Orb Mycast

  • I am a Google Mobile guy, but Yahoo! Go for Windows Mobile also looks very cool. I downloaded it to my Samsung SCH-i760 a few days ago. I am still checking it out but here are a few things I like:
    • Nice and responsive interface.
    • Built-in RSS Reader.
    • Street and satellite maps.

      Here are a few screenshots:

      Yahoo! Go

      Yahoo! Go

      Yahoo! Go Weather 

Software and Tools

  • You can configure Notepad++ to always use spaces for tabs/indentation. The option is a little hidden. It’s in Settings/Preferences/MISC, under Tab Setting:

    Notepad++ tab to spaces setting

Something a Little Different

posted in Dotnet/.NET - C#, PowerShell, Programming, Technology, Tips, Windows Mobile / Pocket PC | 1 Comment

6th February 2008

Put GetOrdinal Method to Good Use

How often do you see DataReader code that looks like this?

using (IDataReader dr = cmd.ExecuteNonQuery())
{
    while (dr.Read())
    {
        int orderId = dr.GetInt32(0);
        string customerId = dr.GetString(1);
        int employeeId = dr.GetInt32(2);
        DateTime orderDate = dr.GetDateTime(3);
        double freight = dr.GetDouble(4);

        // do stuff
    }

    dr.Close();
}

If that looks like your code, you are not alone :-). Try searching codesearch.google.com for the following:

lang:c# (reader|dr)\.GetInt32\(

codesearch google

With the above code, anytime the order of columns in the SQL statement or stored procedure changes, the code is broken. And if you have lots of columns to read from, it’s a real nightmare to maintain the indexes.

The next time you write another DataReader loop, consider doing it this way instead:

using (IDataReader dr = cmd.ExecuteNonQuery())
{
    int ORDER_ID = dr.GetOrdinal("OrderID");
    int CUSTOMER_ID = dr.GetOrdinal("CustomerID");
    int EMPLOYEE_ID = dr.GetOrdinal("EmployeeID");
    int ORDER_DATE = dr.GetOrdinal("OrderDate");
    int FREIGHT = dr.GetDecimal("Freight");

    while (dr.Read())
    {
        int orderId = dr.GetInt32(ORDER_ID);
        string customerId = dr.GetString(CUSTOMER_ID);
        int employeeId = dr.GetInt32(EMPLOYEE_ID);
        DateTime orderDate = dr.GetDateTime(ORDER_DATE);
        double freight = dr.GetDouble(FREIGHT);

        // do stuff
    }

    dr.Close();
}

Using GetOrdinal makes the code much more readable and maintainable. You are calling GetOrdinal just once for each column, any performance penalty is insignificant compared to the benefits. Be careful not to put the GetOrdinal code inside the while block as that will unnecessarily slow you down (about 3% according to this article).

kick it on DotNetKicks.com

posted in Dotnet/.NET - C#, Programming, Tips | 2 Comments

7th January 2008

How to Open Containing Explorer Folder in Visual Studio

I think this is useful and not well known enough to warrant its own blog post.

Did you know that there is a Visual Studio command called File.OpenContainingFolder? Asmita A Wankhede wrote about it, but he left a few important details out.

By default, this command does not have a shortcut, so you would have to assign one to it (try CTRL+SHIFT+ALT+O). Also, the "item" that this command works on is the currently opened item in the editor, not the selected item in the Solution Explorer. See my Visual Studio tips article for instructions on how to create new shortcuts (section 3 - Make New Shortcuts).

File.OpenContainingFolder

This works with both Visual Studio 2005 and 2008.

kick it on DotNetKicks.com

posted in Dotnet/.NET - C#, Programming, Tips | 0 Comments