Thursday, January 29, 2009

Brother MFC-490CW printer does not print in Vista

I was unable to successfully print from my Windows Vista laptop to my new Brother MFC-490CW wireless printer. The laptop was successfully able to connect to the wireless printer as I was able to scan images from the MFC-490CW. But when I sent a document to the printer – it just sat in the spool and wasnt getting sent to the printer.

Here is what I had to do to get it working:

Type “printers” in the search bar.

image

This will bring up the printers link.

image

Click on the link to open the panel for configuring printers.

Right click on the “Brother MFC-490CW printer” icon and click on “Properties”.

Go to the “Ports” tab and click on “Configure Port…” button.

image

Make sure that “LPR Byte Counting Enabled” is checked.

image 

Click ok and you should now be able to print from your Vista computer.

Sunday, January 25, 2009

My latest mashup – Denver Traffic Camera Map

My latest mashup “Denver Traffic Camera Map”, is online.

image

The mashup grew out of a curiosity to take the new ASP.Net Virtual Earth control for a spin. The DenverGov traffic camera web-page is currently a static map and I wanted to see what it would take to use the VE control to display the same data. And it turned out to be pretty easy to create a prototype – approximately 2 hours.

Most of the time spent in creating the prototype was spent in collecting the data: manually clicking through each link on the traffic camera page and saving it to a text file. For this prototype, I wanted to test out the SQL Server database that came with my website hosted on Verio (http://www.revertoself.com/). So, I created a table in the database provided to me. This was done in SQL Server Management Studio 2008 (SMS2008). The data was loaded into the table using insert statements in SMS2008 (check out this post if you have problems opening the Verio SQL Server database in SMS 2008).

Once the data was loaded into SQL Server, I was able to create a data-set in Visual Studio. Visual Studio’s data-set creation wizard had no problems creating the data-set. Once the data-set was created, all I had to was create push-pins for each row in the table and load them into Virtual Earth.

foreach(SamplesTrafficCams.dnvr_traffic_camsRow dr in dt)
{
    LatLongWithAltitude latLong = new LatLongWithAltitude(Convert.ToDouble(dr.l_lat), Convert.ToDouble(dr.l_long));
    Shape shape = new Shape(ShapeType.Pushpin, latLong);
    shape.Description = "<b>" + dr.st_location + "</b>" + "<br/>" + 
        "<a href=\"" + dr.web_page + "\">" + 
        "<img src=\"" + dr.thmb_nail + "\" height=95 width=150/>";
    shape.CustomIcon = "image/cam.png";
    trafficMap.AddShape(shape);
}

dt is a typed DataTable that is retrieved using the table-adapter created using Visual Studio. The code then enumerates over the tables data, creating the pushpins from each field in the table. Once the push-pins are created, you simply add each one to the VE map (trafficMap in the above code).

The ASP.Net Virtual Earth control is very easy to use and allows you to create simple mash-ups very quickly.

One problem I had was in trying to display the latitude and longitude values when one clicks on the map within the client (browser). This is very easy using server-side events, but I wanted to do this in the browser and eliminate the round-trip caused by using a server side event on the ASP.Net control. To do this, I needed access to the VirtualEarth map control in JavaScript. (The reason I needed access to the VE control is that I needed to call PixelToLatLong to get the Lat/Long location of the point at which the user clicked). The control that you get in sender, does not give you access to the PixelToLatLong method. Instead I found that if you used $find method on the VE ASP.Net control, it gives you access to VE control inside it. You can then call any VE method available on the control.

The following snippet shows how I did it:

function OnMapClick(sender, args) 
{
    var map = $find("trafficMap");
    var loc = args.get_MapEvent();
    var ll = map.PixelToLatLong(new VEPixel(loc.mapX, loc.mapY));
    var lbl = document.getElementById("textMapInfo");
    lbl.value = roundNumber(ll.Latitude, 5) + "," + roundNumber(ll.Longitude, 5);
}

Links:

http://www.verio.com/about/newsroom/pr/index.cfm?fuseaction=press&Year=07&id=118067678025721

http://www.revertoself.com/

Virtual Earth SDK

BODMAS or PEMDAS: It is elementary!

Growing up in India I learnt the mnemonic BODMAS (pronounced: bodmas!) to help me with remembering the order of operations when solving equations. It stands for:

B Brackets
O Order
D Division
M Multiplication
A Addition
S Subtraction

My wife, who grew up here in the U.S., uses the phrase “Please excuse my dear aunt Sally” to remember the order of operations.

P Parenthesis
E Exponents
M Multiplication
D Division
A Addition
S Subtraction

But, hold on, there is a difference between BODMAS and PEMDAS, in India we seem to be performing the division before the multiplication, and here we seem to be multiplying before division! Yikes! what is going on here, who is correct?

They both are, the one thing the mnemonic does not show is that some operations have the same precedence as follows:

(Multiplication and Division) and

(Addition and Subtraction)

Thus M&D and D&M are exactly the same and so is A&S and S&A.

Why is this? Simple, because division can be replaced by a multiplication operation and subtraction can be replaced by an addition, as follows:

x / y = x * (1/y)

and x – y = (x + (-y))

http://mathforum.org/dr.math/faq/faq.order.operations.html

Saturday, January 24, 2009

My first DeepZoom – Obama’s mosaic

I recently made a mosaic from images of the front-pages of newspapers taken on the day after President Obama’s inaugural on Jan 20th, 2009. Here is the same image as a Deep-Zoom mashup.

DeepZoom link

Track the IP using a GUI created in VB

Heard on CSI NY - "Let's create a GUI interface using Visual Basic, see if I can track an IP address..."

 

And the original video (15 second clip), which has been deleted by YouTube for copyright infringement! (Thought a 15 second clip would come under the Fair-Use act)

CSI-NY Clip of VB GUI for tracking serial killer’s IP address.

Photosynth: Makes an appearance on CSI: NY

PhotoSynth gets used on CSI: NY.

Image Mosaic: Obama Inaugural Day

Someone sent me a link to Ben Wikler’s site, which was a giant aggregation of images of front-pages of news papers from across the globe. I took Ben’s idea one step further and created a mosaic image from all those images. Check it out at Obama Inaugural Day Mosaic page.

image

And here is a DeepZoom version of the above image: My first DeepZoom – Obama’s mosaic

Friday, January 23, 2009

SQL Server Management Studio: Unable to open database because the physical files have been deleted

I use my laptop for development and I often download sample .NET projects which have database files which need to be loaded into my SQL Server instance. But when I deleted the sample project, I ended up deleting the MDF and LDF files that were part of the database in that project. After that I was unable to browse all the other databases that were on my laptop using SQL Server Management Studio 2008.

The error message that would pop up when I used to connect to my laptop’s SQL Server instance and then browse the database node is shown below:

------------------------------ ------------------------------

Failed to retrieve data for this request. (Microsoft.SqlServer.Management.Sdk.Sfc)

For help, click: http://go.microsoft.com/fwlink?ProdName=Microsoft+SQL+Server&LinkId=20476

------------------------------------------------------------
ADDITIONAL INFORMATION:

An exception occurred while executing a Transact-SQL statement or batch. (Microsoft.SqlServer.ConnectionInfo)

------------------------------ ------------------------------

Unable to open the physical file "xxxxx.mdf". Operating system error 3: "3(The system cannot find the path specified.)".
Database 'xxxxxxxx.MDF' cannot be opened due to inaccessible files or insufficient memory or disk space.  See the SQL Server errorlog for details.
File activation failure. The physical file name "xxxxxxxx.ldf" may be incorrect. (Microsoft SQL Server, Error: 5120)

For help, click: http://go.microsoft.com/fwlink?ProdName=Microsoft+SQL+Server&ProdVer=10.00.1600&EvtSrc=MSSQLServer&EvtID=5120&LinkId=20476

------------------------------ ------------------------------

To get around this problem, do the following:

1. In the connection dialog, click on the “Options” button. This will display tabs at the top.

2. Click on the “Connection Properties” tab.

3. In the drop down “Connect to database”, click on “Browse Server…”

image

4. Select a database that you know exists on your computer.

image

5. Click Ok and the Connect. You should be able to successfully connect to the database and browse its objects.

I think the problem arises from the fact that SQL Server Management Studio remembers the last database that was used for a connection and hence continues to try and connect to that database.

SQL Server: The server principal "userID" is not able to access the database "xxxxxx"

image 

I was getting the error “The server principal "userID" is not able to access the database "xxxxxx" under the current security context. (Microsoft SQL Server, Error: 916)”, while trying to connect to a remote SQL Server database using “SQL Server Management Studio 2008”. After Googling for over an hour and not finding any solution, I tried connecting to the database using “SQL Server Management Studio Express 2005” and voila! I was able to successfully able to connect to the database.

More info:

The SQL Server database was remotely hosted by Verio.
I was able to successfully connect to the remote database. The above error occurred only when I tried to browse the tables stored in my database. It seems like SMS (SQL Server Management Studio) was trying to connect to a database called xxxxxx which did not belong to me. I tried setting the default database to my database, but that didn’t seem to help either. Not sure if there is another option that might help fix this issue using SMS 2008 (I am not a SQL Server DBA).
The only way I was able to browse the tables in my database was by using SMS 2005.

Get SMS 2005 Express from: http://www.microsoft.com/downloads/details.aspx?familyid=C243A5AE-4BD1-4E3D-94B8-5A0F62BF7796&displaylang=en

UPDATE: January 23, 2009: The correct way to fix this problem:

I finally figured out the correct way to get around this problem, so that I could connect and view my tables using SQL Server Management Studio 2008. Not sure if it is a bug in SMS 2008 or not, but here is what you need to do:

1. Connect to the SQL Server

2. Click on the “Databases” node. If you get an error message, dismiss it.

3. Press “F7”, to show the Object Details panel (right hand side panel).

4. In the Object Details panel, right click on the column header and deselect the “Collation” header option.

image

5. Now refresh the database node by click the refresh button (image) in the Object Details toolbar (image ).

6. You should be good to go!

Denver makes it to the top 10 most wired U.S. cities list

Forbes.com

image

Denver lists at no. 8 after Minneapolis and before New York on the most wired American cities list for 2009.

SQL Server 2008 Sample Data – How to install the data

When I installed the sample AdventureWorks database for SQL Server 2008, there were some options that I overlooked during the setup, which resulted in the database not being attached to the SQL Server instance.

If that happens to you – then go to the folder “C:\Program Files\Microsoft SQL Server\100\Tools\Samples\AdventureWorks 2008 OLTP” and run the script “instawdb.sql”.

If you would like the installer to attach the database to your SQL Server instance, then remember to select the “Restore AdventureWorks DB” (which is by default disabled).

1

Note:

If the installer fails one reason might be that during the installation of SQL Server, you might have not installed the “Full Text Search” component. The only way to fix this is to re-run the installer and modify the installation options to include the full text search component.

FileStream needs to be enabled on the SQL Server instance. To do this,  go to “SQL Server Configuration Manager” and enable “FileStream”.

image

Different versions of the AdventureWorks database:

image

There are 3 versions of the database that gets installed to the hard-disk by the installer. They are

image

OLTP: supports online transaction processing (full fledged version)

DW: shows how a data warehouse is built

AS: supports Analysis Services

LT: lite version of the database – great for someone starting with RDBMSs.

Wednesday, January 21, 2009

Satellite Imagery of the Inauguration

DigitalGlobe and GeoEye have release satellite imagery of the National Mall taken at the time of the inauguration.

image

1/2 meter color image from GeoEye (click on image to download the high-resolution - 8218px × 7608px – 10mb - image that spans from the Capitol to the Washington Monument)

 

image

From DigitalGlobe (6125px × 4985px – 4.3mb)

Tuesday, January 20, 2009

Inauguration of the 44th President and the Address

Obama’s inauguration and address.

 

And here is the Transcript of the address:

My fellow citizens:

I stand here today humbled by the task before us, grateful for the trust you have bestowed, mindful of the sacrifices borne by our ancestors. I thank President Bush for his service to our nation, as well as the generosity and cooperation he has shown throughout this transition.

Forty-four Americans have now taken the presidential oath. The words have been spoken during rising tides of prosperity and the still waters of peace. Yet, every so often the oath is taken amidst gathering clouds and raging storms. At these moments, America has carried on not simply because of the skill or vision of those in high office, but because we the people have remained faithful to the ideals of our forebears, and true to our founding documents.

So it has been. So it must be with this generation of Americans.

That we are in the midst of crisis is now well understood. Our nation is at war, against a far-reaching network of violence and hatred. Our economy is badly weakened, a consequence of greed and irresponsibility on the part of some, but also our collective failure to make hard choices and prepare the nation for a new age. Homes have been lost; jobs shed; businesses shuttered. Our health care is too costly; our schools fail too many; and each day brings further evidence that the ways we use energy strengthen our adversaries and threaten our planet.

These are the indicators of crisis, subject to data and statistics. Less measurable but no less profound is a sapping of confidence across our land — a nagging fear that America's decline is inevitable, and that the next generation must lower its sights.

Today I say to you that the challenges we face are real. They are serious and they are many. They will not be met easily or in a short span of time. But know this, America — they will be met.

On this day, we gather because we have chosen hope over fear, unity of purpose over conflict and discord.

On this day, we come to proclaim an end to the petty grievances and false promises, the recriminations and worn out dogmas, that for far too long have strangled our politics.

We remain a young nation, but in the words of Scripture, the time has come to set aside childish things. The time has come to reaffirm our enduring spirit; to choose our better history; to carry forward that precious gift, that noble idea, passed on from generation to generation: the God-given promise that all are equal, all are free and all deserve a chance to pursue their full measure of happiness.

In reaffirming the greatness of our nation, we understand that greatness is never a given. It must be earned. Our journey has never been one of shortcuts or settling for less. It has not been the path for the faint-hearted — for those who prefer leisure over work, or seek only the pleasures of riches and fame. Rather, it has been the risk-takers, the doers, the makers of things — some celebrated but more often men and women obscure in their labor, who have carried us up the long, rugged path towards prosperity and freedom.

For us, they packed up their few worldly possessions and traveled across oceans in search of a new life.

For us, they toiled in sweatshops and settled the West; endured the lash of the whip and plowed the hard earth.

For us, they fought and died, in places like Concord and Gettysburg; Normandy and Khe Sanh.

Time and again these men and women struggled and sacrificed and worked till their hands were raw so that we might live a better life. They saw America as bigger than the sum of our individual ambitions; greater than all the differences of birth or wealth or faction.

This is the journey we continue today. We remain the most prosperous, powerful nation on Earth. Our workers are no less productive than when this crisis began. Our minds are no less inventive, our goods and services no less needed than they were last week or last month or last year. Our capacity remains undiminished. But our time of standing pat, of protecting narrow interests and putting off unpleasant decisions — that time has surely passed. Starting today, we must pick ourselves up, dust ourselves off, and begin again the work of remaking America.

For everywhere we look, there is work to be done. The state of the economy calls for action, bold and swift, and we will act — not only to create new jobs, but to lay a new foundation for growth. We will build the roads and bridges, the electric grids and digital lines that feed our commerce and bind us together. We will restore science to its rightful place, and wield technology's wonders to raise health care's quality and lower its cost. We will harness the sun and the winds and the soil to fuel our cars and run our factories. And we will transform our schools and colleges and universities to meet the demands of a new age. All this we can do. All this we will do.

Now, there are some who question the scale of our ambitions — who suggest that our system cannot tolerate too many big plans. Their memories are short. For they have forgotten what this country has already done; what free men and women can achieve when imagination is joined to common purpose, and necessity to courage.

What the cynics fail to understand is that the ground has shifted beneath them — that the stale political arguments that have consumed us for so long no longer apply. The question we ask today is not whether our government is too big or too small, but whether it works — whether it helps families find jobs at a decent wage, care they can afford, a retirement that is dignified. Where the answer is yes, we intend to move forward. Where the answer is no, programs will end. Those of us who manage the public's dollars will be held to account — to spend wisely, reform bad habits, and do our business in the light of day — because only then can we restore the vital trust between a people and their government.

Nor is the question before us whether the market is a force for good or ill. Its power to generate wealth and expand freedom is unmatched, but this crisis has reminded us that without a watchful eye, the market can spin out of control — and that a nation cannot prosper long when it favors only the prosperous. The success of our economy has always depended not just on the size of our gross domestic product, but on the reach of our prosperity; on our ability to extend opportunity to every willing heart — not out of charity, but because it is the surest route to our common good.

As for our common defense, we reject as false the choice between our safety and our ideals. Our founding fathers ... our founding fathers, faced with perils we can scarcely imagine, drafted a charter to assure the rule of law and the rights of man, a charter expanded by the blood of generations. Those ideals still light the world, and we will not give them up for expedience's sake. And so to all the other peoples and governments who are watching today, from the grandest capitals to the small village where my father was born: know that America is a friend of each nation and every man, woman, and child who seeks a future of peace and dignity, and that we are ready to lead once more.

Recall that earlier generations faced down fascism and communism not just with missiles and tanks, but with sturdy alliances and enduring convictions. They understood that our power alone cannot protect us, nor does it entitle us to do as we please. Instead, they knew that our power grows through its prudent use; our security emanates from the justness of our cause, the force of our example, the tempering qualities of humility and restraint.

We are the keepers of this legacy. Guided by these principles once more, we can meet those new threats that demand even greater effort — even greater cooperation and understanding between nations. We will begin to responsibly leave Iraq to its people, and forge a hard-earned peace in Afghanistan. With old friends and former foes, we will work tirelessly to lessen the nuclear threat, and roll back the specter of a warming planet. We will not apologize for our way of life, nor will we waver in its defense, and for those who seek to advance their aims by inducing terror and slaughtering innocents, we say to you now that our spirit is stronger and cannot be broken; you cannot outlast us, and we will defeat you.

For we know that our patchwork heritage is a strength, not a weakness. We are a nation of Christians and Muslims, Jews and Hindus — and non-believers. We are shaped by every language and culture, drawn from every end of this Earth; and because we have tasted the bitter swill of civil war and segregation, and emerged from that dark chapter stronger and more united, we cannot help but believe that the old hatreds shall someday pass; that the lines of tribe shall soon dissolve; that as the world grows smaller, our common humanity shall reveal itself; and that America must play its role in ushering in a new era of peace.

To the Muslim world, we seek a new way forward, based on mutual interest and mutual respect. To those leaders around the globe who seek to sow conflict, or blame their society's ills on the West — know that your people will judge you on what you can build, not what you destroy. To those who cling to power through corruption and deceit and the silencing of dissent, know that you are on the wrong side of history; but that we will extend a hand if you are willing to unclench your fist.

To the people of poor nations, we pledge to work alongside you to make your farms flourish and let clean waters flow; to nourish starved bodies and feed hungry minds. And to those nations like ours that enjoy relative plenty, we say we can no longer afford indifference to the suffering outside our borders; nor can we consume the world's resources without regard to effect. For the world has changed, and we must change with it.

As we consider the road that unfolds before us, we remember with humble gratitude those brave Americans who, at this very hour, patrol far-off deserts and distant mountains. They have something to tell us, just as the fallen heroes who lie in Arlington whisper through the ages. We honor them not only because they are guardians of our liberty, but because they embody the spirit of service; a willingness to find meaning in something greater than themselves. And yet, at this moment — a moment that will define a generation — it is precisely this spirit that must inhabit us all.

For as much as government can do and must do, it is ultimately the faith and determination of the American people upon which this nation relies. It is the kindness to take in a stranger when the levees break, the selflessness of workers who would rather cut their hours than see a friend lose their job which sees us through our darkest hours. It is the firefighter's courage to storm a stairway filled with smoke, but also a parent's willingness to nurture a child, that finally decides our fate.

Our challenges may be new. The instruments with which we meet them may be new. But those values upon which our success depends — honesty and hard work, courage and fair play, tolerance and curiosity, loyalty and patriotism — these things are old. These things are true. They have been the quiet force of progress throughout our history. What is demanded then is a return to these truths. What is required of us now is a new era of responsibility — a recognition, on the part of every American, that we have duties to ourselves, our nation, and the world, duties that we do not grudgingly accept but rather seize gladly, firm in the knowledge that there is nothing so satisfying to the spirit, so defining of our character, than giving our all to a difficult task.

This is the price and the promise of citizenship.

This is the source of our confidence — the knowledge that God calls on us to shape an uncertain destiny.

This is the meaning of our liberty and our creed — why men and women and children of every race and every faith can join in celebration across this magnificent Mall, and why a man whose father less than sixty years ago might not have been served at a local restaurant can now stand before you to take a most sacred oath.

So let us mark this day with remembrance, of who we are and how far we have traveled. In the year of America's birth, in the coldest of months, a small band of patriots huddled by dying campfires on the shores of an icy river. The capital was abandoned. The enemy was advancing. The snow was stained with blood. At a moment when the outcome of our revolution was most in doubt, the father of our nation ordered these words be read to the people:

"Let it be told to the future world ... that in the depth of winter, when nothing but hope and virtue could survive...that the city and the country, alarmed at one common danger, came forth to meet (it)."

America, in the face of our common dangers, in this winter of our hardship, let us remember these timeless words. With hope and virtue, let us brave once more the icy currents, and endure what storms may come. Let it be said by our children's children that when we were tested we refused to let this journey end, that we did not turn back nor did we falter; and with eyes fixed on the horizon and God's grace upon us, we carried forth that great gift of freedom and delivered it safely to future generations.

Thank you. God bless you. And God bless the United States of America.

Obama’s speech on Climate Change

Here is a speech by Obama given to the Global Climate Summit conference that was held in november 2008. I just came across it and found it comforting that we finally have a president that understands the importance of combating climate change.

It is also interesting to see the reaction of the gathering to this speech, which was delivered by video: Obama gets a standing ovation as though he were in the room.

“Now is the time to confront this challenge once and for all. Delay is no longer an option. Denial is no longer an acceptable response. The stakes are too high. The consequences, too serious. Stopping climate change won’t be easy. It won’t happen overnight. But I promise you this: When I am President, any governor who’s willing to promote clean energy will have a partner in the White House. Any company that’s willing to invest in clean energy will have an ally in Washington. And any nation that’s willing to join the cause of combating climate change will have an ally in the United States of America. Thank you.” - Transcript

Sunday, January 18, 2009

Static Variables and their implications in ASP.Net websites

Are you using static variables in your ASP.Net websites? Do you know the implications that they have on your website? (Especially the security implications?)

Well, first off go visit this ASP.Net site which will demonstrate the dangers of using static variables in your website: http://www.aggregatedintelligence.com/Samples/StaticsDemo/default.aspx

There are 2 sets of text boxes. The first one stores values using static variables, the second set stores variables using the Session object. Try and type in each box and update the values using the buttons. Now try closing your browser and then go back to the site. Also, try and access the site from a different browser. See anything interesting? The first set of boxes will either end up showing you values that you typed in during a different session (if you closed and reopened the browser) or values from a different computer (if you closed and the reopened the page from a different computer) or values from another user (if another user changed the values while you were looking at the page).

This is a BAD code smell and here is a little bit about why it might get used and why you should not use it and what are the alternatives.

Why do developers use static variables? Typically, it is used to persist values in class member variables across post-backs. Normally, if you create a member variable and store a value in it – you will find that the value gets erased after a post-back (such as that caused by a button click event)

Why should you not use static variables? Static variables are global variables for that page. This means that they will hold their value across post-backs (which is the behavior the developer wants), but the value in that variable is also available to all users accessing the website!!!! Think about this for a minute: if you use a static variable to store the current user's login-id, or security level, or a password, then that value becomes available to anybody else who accesses that page. If your code is badly written – it is conceivable that the other user can gain access to data that they should not have access to. There is another problem, that can lead to weird behavior in your website. Static variables are not thread-safe. Each user that accesses your website is running within a separate thread. If 2 people do some action that tries to update the variable at the exact same time – you can get weird issues – such as web-site locking up. Basically, it boils down to the fact that the life-time of a static variable is for the life of the application (actually it is more like for the life time of the process hosting the website, but that is a detail we can gloss over for this topic). And furthermore, the scope of the static variable is page/application wide and NOT session specific. And those 2 are extremely important details to remember when you use a static variable in your ASP.Net web application.

Static variables should smell bad to you ALWAYS! (in an ASP.Net application that is - but read caveat below)

What should you use instead of a static variable? There are 3 places available to you to store values that persist across page post-backs: Session – use this when you need access to the variables value across multiple pages ViewState – use this when you need access to the variable only within the current page. (Don't use ViewState to store objects that can potentially get very large, such as DataSets, as this information gets serialized and sent to the client browser during each round-trip. Cache – One more location that you can store user specific information.

Caveat: What if you want to store a value that should be accessible across the website? There are always cases where one would want to set a variable that is then accessible across the website and all users that use that site. (A good example for such a variable is one that flags if the website is available or not, depending on which – logins to the site are allowed or denied). (Update: 02-24-2009: I have removed the recommendation of using ONLY the application object, this is because the Application object was made to provide an easy route to migrate old ASP apps. Using static variables - sensibly - can lead to more performant code). One can use the Application object instead of static variables, which is similar to Session object, only it is available to the entire application. Only thing to remember is that one should use locks on the static variables in the Application container to make it thread-safe (otherwise you might see weird run-time behavior and hours spent trying to debug them). This is not an issue with non-static variables stored in the Application object. When the data that you are storing is not temporary and not user specific, then you can use a static variable to store that information. A lot of the data used by your web-site is already static - one such example is the ConfigurationManager and this makes sense: the Configuration properties for your web-site apply site wide and are not user specific. Static variables are more performant than the Application object and one should keep this in mind when they are trying to decide which route they wish to take. (Also, using a static variable will typically lead to more readable code when compared to using the Application object).

Here is a good article on how to use Application object: http://support.microsoft.com/default.aspx?scid=kb;en-us;Q312607

The bottom line is that: never use a static variable to store user-specific data.

Thursday, January 15, 2009

Microsoft Tags – Next generation barcodes

With the release of phones that are constantly connected to the Internet (iPhone, G1), applications that can decode bar-codes and then retrieve information connected to that bar-code have become common. But most phones have a fixed focus camera, which makes it very hard to take a clear picture of the bar-code on most phones (for those that have the iPhone – you know how bad the camera is at taking close by pictures). The only phone that I have seen that is able to take pictures that allow it to reliably decipher the bar-code is the G1.

IMG_0095 Picture of a bar-code taken using the iPhone.

But what about all the other phones with those cameras that just wont take a picture that is good enough to decipher the code behind the bar-code?

Microsoft has an answer and it is called “Tag”.

image

The technology is called “High Capacity Color Barcodes” (HCCB). The technology is optimized so that it will work with even blurred pictures taken by most mobile phones. The bar-code uses colored triangles (as opposed to black and white bar-codes) and can be printed in a space that is much less than traditional bar-codes.

image

There a ton of cool uses for this technology. The one I like – it will make my life a ton easier to exchange my contact details with other people. Just take a picture of my tag (I will need to either keep the tag on my phone or it could be a part of my business card) and you will have all my information.

Here is a live image of the tag reader for iPhone after it has recognized a tag. The thing to notice is how much out of focus the image is and yet the tag reader was able to successfully find and decode the tag.

IMG_0001

To create your own tags, go to the tag creation page. And to be able to decode tags, you need to install the tag reader made for your device.

At this point a Tag reader is available for these phones that come with a built in camera:

  • Windows Mobile
  • J2ME
  • iPhone
  • Blackberry
  • Symbian S60 phones

Here are tags that link to my website and my blog

 BarCode

Website

BarCodeBlog

Blog

Monday, January 12, 2009

LIDAR Data Viewers – LP Viewer

imageIn the very beginning there was GeoCue’s PointVue. And then there was Cloud Peak’s LAS-Edit. (Which disappeared after CloudPeak was bought by Fugro). PointVue was cool at a time when there were almost no point cloud viewers capable of viewing LAS files. LASEdit, was my favorite LIDAR point cloud viewer software for the longest time ever. (I still have their installer tucked away some place safe – just in case I ever needed it).

Today, QCoherent released its free stand-alone version point cloud viewer, called LP Viewer (link).

Multiple simultaneous views (2D, 3D, Profile)LP Viewer fills the huge gap left by the departure of LASEdit and then adds some more to the pot. From my initial evaluation of LP Viewer, the tool is just as cool as their LP360 tool which plugged into ArcGIS, only this application is a stand-alone tool. The interface is pretty much the same, making it a lot more easier to move between their stand-alone viewer and ArcView. The viewer allows you to view the point cloud in 2D as well as 3D, simultaneously and also adds a profile view (similar to LASEdit).Tinned 3D view

The viewer is fast and allows you multiple ways to navigate through the point cloud. Boxes and cursors (an airplane) show you at all times, where in the frame you are, making it difficult to get lost in space (a constant problem I had with LAS Edit).

The viewer also allows you to view the point cloud as a solid surface (tinning). 

In every view, I never felt like the viewer got bogged down with the point cloud. (I did not try it with a large point cloud – I used the toronto core data-set from Optech).

The viewer also allows you to view the classified point cloud. This I think is an extremely important feature – because it allows you to perform QA/QC on your classified data (manual or automated).

The following screen shot shows the Toronto point cloud with a solid surface (TINNED). The point cloud was classified using VLS’s automated feature extraction software LIDAR Analyst. The screen shot is remarkable for 2 reasons – it shows how accurate the automated classifier in LIDAR Analyst is and how well LP Viewer allows you to visualize the data.

Toronto point cloud, classified using LIDAR Analyst and viewed in LP Viewer using an hill-shaded TIN

(red – buildings, brown – ground, green – trees)

Drawbacks? For a first release, free viewer – there are none. The viewer does everything one would want from a 3D point cloud viewer. The only issues I had was a crash of my display driver on my Vista machine (which might have been a random occurrence – because it hasn't occurred since). The one thing that I do miss is that in the 3D view, when you rotate the TINned point cloud, during the rotation it switches to the point cloud view – I wish this could be controlled via a switch.

But, tonite, I can go and delete the old installer for LASEdit, and replace it with the LP Viewer installer.

note: other tools such as Isenburg’s tools also exist, but I never had a chance to use them more than just a quick evaluation.
disclaimer: I was the lead engineer for LIDAR Analyst from 2004 to 2008. It still seems to be the best automated feature extraction software for LIDAR data.

Crystal Reports for Visual Studio: 2 useful C# functions

When I first started working with Crystal Reports, what I found troubling was that when you connect to a database and select a table to use in your report (or for that matter any stored procedure), you provide Crystal Reports with the connection information which is then stored in some hidden place within the RPT files. The reason that this was troubling to me was that there did not seem to be any way to point to have different databases for development and production.

Sure, I tried the "SetDatabaseLogon" that is available on ReportDocument within the CrystalReportSource object - but that never seemed to work. After a lot of frustration, what I ended up doing was creating data-sets and then creating reports using the data-sets. Then during run-time, I had a method that would return the data-set from the appropriate database (dev or production), which was then set into the report using "SetDataSource" that is also available on on the ReportDocument object in the CrystalReportSource object.

By setting the DataSource for the CrystalReport, I was able to get a solution where depending on what mode I was running the application - I was able to get the data from the development, test or production databases.

This solution worked fine and dandy for a while, until I came across a complex report that had a sub-report embedded inside it. The sub-report had to be run once for every record in the main report. This is something that cannot be done using the DataSource method, because, even though I could give CR the main report's data-source, I would not be able to provide a data-source for each sub-report that needed to be run.

This time while looking for a solution, I found out 2 things:

1. The reason SetDatabaseLogon does not work is that it only allows you to change the user-id and password. The four parameter version will not change the database and server names: It will change the user-id and password for all those objects that share the database and server name passed in as part of the arguments. (This information is unfortunately buried in the remarks part of the documentation).
2. To change the database that is being used one needs to use the "ApplyLogOnInfo" on each table (CrystalDecisions.CrystalReports.Engine.Table) that is in the CrystalReport object.

So here is my first useful C# function for working with CrystalReports. It is used to change the database used by CrystalReports to get its data. (use it when you need to use separate development, test and production servers as your data-source for CrystalReports)

public static void SetCRLogOnInfo(ReportDocument mainInRD, string dataSource, string userId, string pwd)
    {
        //do the main reports database
        TableLogOnInfo logonInfo = null;
        foreach (CrystalDecisions.CrystalReports.Engine.Table table in mainInRD.Database.Tables)
        {
            logonInfo = table.LogOnInfo;
            logonInfo.ConnectionInfo.ServerName = dataSource;
            logonInfo.ConnectionInfo.DatabaseName = "";
            logonInfo.ConnectionInfo.UserID = userId;
            logonInfo.ConnectionInfo.Password = pwd;
            table.ApplyLogOnInfo(logonInfo);
        }
        try
        {
            //now update logon info for all sub-reports
            if (!mainInRD.IsSubreport && mainInRD.Subreports != null && mainInRD.Subreports.Count > 0)
            {
                foreach (ReportDocument rd in mainInRD.Subreports)
                {
                    SetCRLogOnInfo(rd, dataSource, userId, pwd);
                }
            }
        }
        catch
        {
        }
    }
The second method is used to export the CrystalReport as a PDF file. The reason it takes a HTTPResponse, is that this snippet is used in a ASP.Net application and it outputs the PDF to the browser.
public static void ExportToPDF(CrystalReportSource crs, HttpResponse response)
{
    try
    {
        response.Buffer = false;
        response.ClearContent();
        response.ClearHeaders();
        response.ContentType = "application/pdf";
        
        Stream pdfStreamFromCR = crs.ReportDocument.ExportToStream(ExportFormatType.PortableDocFormat);
        byte[] outputBuffer = new byte[(int)pdfStreamFromCR.Length];
        pdfStreamFromCR.Read(outputBuffer, 0, (int)pdfStreamFromCR.Length);
        response.BinaryWrite(outputBuffer);
        response.Flush();
        response.End();
    }
    catch(ThreadAbortException)
    {
        //expected do nothing
    }
    catch (Exception ex)
    {
        //Log4Net
    }
}

(updated on 1/12/2008)

Oracle: Calling PL/SQL procedures that return a cursor

How does one go about calling a PL/SQL procedure that returns a cursor as an OUT parameter from a SQL script?
For example how do you call the following procedure?

PROCEDURE GETCURSORS (
DEPARTMENTID IN NUMBER,
EMPLOYEESCUR OUT SYS_REFCURSOR)

Well, you use a bind variable. Here is how to do it:
variable retCur refcursor; --declare the bind variable
exec GetCursor(119,:retCur); --call the procedure and have the bind variable filled out
print :retCur; -- print the results to output - this is handy for debugging

This is truly handy for debugging. And here is how one can use bind variables to increase application performance.

Bind variables - The key to application performance.

Sunday, January 11, 2009

KB957000 fails to update with an error code of 8000FFFF

Since the new year, my Dell 1520 laptop was unable to run Windows Update and it used to fail with an error code of 8000FFFF on update KB957000.

Installation status: Failed
Error details: Code 8000FFFF
Update type: Important Fix for KB957000
More information: http://support.microsoft.com/?kbid=957000

"Update for Windows (KB957000)" could not be installed because of an error: 2147549183 "Catastrophic failure"

One reason that this error might be occurring on the computer is that the following values might exist on your computer.

  • HKEY_LOCAL_MACHINE\COMPONENTS\PendingXmldentifier
  • HKEY_LOCAL_MACHINE\COMPONENTS\NextQueueEntryIndex
  • HKEY_LOCAL_MACHINE\COMPONENTS\AdvancedInstallersNeedResolving

Capture2Capture1

This is a known issue and Microsoft has a quick fix for it.

Fix it http://download.microsoft.com/download/E/F/2/EF215D7B-1BEA-4233-AB24-F93E0211CA2E/FixWindowsUpdateError0x8000FFFF.msi

Or if you would like to get your hands dirty – then just open the registry and delete the 3 registry values described above (but before you do – remember to backup the registry).

Here are the details from Microsoft’s site:

  1. Click Start
  2. In the Start Search box, type regedit.
  3. In the Programs list, click Regedit.exe.

    If you are prompted for an administrator password or confirmation, type the password or click Continue.

  4. Find and then click the following registry subkey:

    HKEY_LOCAL_MACHINE\COMPONENTS

  5. Right-click COMPONENTS.
  6. Click Export. (Important – as it can save you – in case things go bad after this)
  7. In the File Name box of the Export Registry File dialog box, type COMPONENTS.
  8. Click Save, and then click COMPONENTS.
  9. In the details pane, right-click PendingXmldentifier, and then click Delete. If this value does not exist, go to the next step.
  10. In the details pane, right-click NextQueueEntryIndex, and then click Delete. If this value does not exist, go to the next step.
  11. In the details pane, right-click AdvancedInstallersNeedResolving, and then click Delete. If this value does not exist, go to the next step.
  12. Restart the computer, and then try again to update the computer.

 Important:

  • Remember to save the component hive of the registry. This is your insurance policy.
  • You might have to restart and run Windows Update multiple times. It took me 3 restarts, before all the updates managed to get installed and the error message would finally go away.
  • I also had to turn off the Customer Experience Improvement Program for the changes to take effect.
    Start –> Control Panel –> Problem Reports and Solutions
    Customer Experience Improvement settings (left hand side bottom) and turn it off.
     image

Squanderville vs. Thriftsville and the problem with Import Certificates

In a previous post SNL makes fun of the residents of Squanderville, I had excerpted Warren Buffet’s story about Squanderville vs. Thriftsville, a story that in 2003 showed the dangers of having years of trade deficit with other countries.

image This problem is further exacerbated by the fact that for all the stuff that we buy from other countries, because of the trade deficit, we are paying for these commodities with assets from our country. Further, into the article, Warren Buffet goes on to describe his solution to this problem of a growing US trade deficit using an instrument called Import Certificates (ICs). Basically, other countries would have to buy (import) an equal amount in dollar terms before they would be able to sell (export) to us. I am not sure if Warren Buffet has changed his thoughts on how to fix the problem, but using an instrument that is nothing more than a trade tariff seems to be calling for trouble.

For one, using ICs seems to make the assumption that we will have stuff to sell to the rest of the world, that the rest of the world wants. This eventually might be possible, but in the short run – I am not sure how we will get over the fact that we currently have a trade deficit of $57.2 billion and that is being caused by the fact that we need to buy from other nations not just clothes, toys, electronic (consumer goods), but also industrial supplies and raw materials, foods, feeds all an important input for a lot of our industries. Another issue I have trouble figuring out is what about smaller, 3rd world countries like those in Africa. These nations might have important low cost materials to sell to us, but they might not have the money to buy from us; in such a case, we would have to stop trading with such a nation. Now one might say that there might be surplus ICs in the world, but I highly doubt that, because nations like China and India definitely would have more than enough stuff to export that the ICs would become an extremely important commodity to them. Another issue might be that some nations might have to export to us first, before they can begin importing from us – in which case how do we break the impasse? buffett-thumbWe would have to allow for a mechanism where-by the other nation would first be allowed to export to us and then we would have to trust that they will have the money in the future to import from us (clearly this can be a problem in times of world-wide economic recession, like we are seeing today). Finally, also note that in some cases – other nations might have to export to us for many years before we might come into a position where we can begin selling them something. A good example would be a car manufacturing plant – that needs building and raw materials from other countries to build the plant in the first place. Only once the plant is built (which can take from 2 to 5 years, not including design time for the car itself), will we have a car to sell to other nations to close the trade gap. 

Well, I don't have an economics degree – so what do I know when it comes to stuff thought up by the oracle of Omaha? But to me it just seems that the right way to fix the trade deficit (a real, present and clear danger) would be to figure out how to bring back the competitive edge back to the U.S. This economic crisis seems to me to be the ideal cauldron which can allow the country to cook up what it needs to make it a positive trader of goods that in general the world wants more off.

So given my lack of an economics background – is there something that I am missing in this proposed solution by Warren Buffet? Or do you have a link to some new information from the WB?

McAfee and Internet Explorer 8 Beta

imageI am not sure why McAfee’s security suite has such a strong dependency on Internet Explorer, but ever since I installed IE 8 beta on my machine in late august of last year (2008) – the Security Center would come up blank. I was able to continue using my machine and McAfee would perform its scans and updates properly. The only thing that I could not do was change my settings or cancel a scan or any number of other things that would need the scanner’s UI.

After almost 6 months of waiting for McAfee to release a fix for this issue – I just gave up and uninstalled IE8 (uninstallation was smooth and clean and it automatically puts IE7 back on the machine).

I miss IE 8, but I needed to check on some warnings that McAfee was notifying me off, but I just could not view in the Security Center. So now I guess I have to wait until IE 8 is released as a finished product and then wait for McAfee to update its product.

Seems to me that such a strong dependency on a 3rd party product is just a recipe for trouble. And if you do have such a strong dependency – I would assume that you would push out a fix as early as possible, that way by the time IE 8 releases to all computers, all of them will be in a position for McAfee to continue working properly.

Saturday, January 10, 2009

A 100 beautiful wall-papers for your iPhone

http://www.smashingmagazine.com/2009/01/06/100-really-beautiful-iphone-wallpapers/

Here are some that I liked.

summer0 vlad2 dharma

fr1 lo lost

 mario me3 nat8 su

An inconvenient truth about our economy

I.O.U.S.A – is as the Huffington Post labeled it a documentary about the inconvenient truth about our economy. It is timely and thought provoking.

As Abraham Lincoln said “I am a firm believer in the people. If given the truth, they can be depended upon to meet any national crisis. The great point is to bring them the real facts.”

View the trailer for the film and then if you have the time, check out the 30 minute version (embedded after the trailer). Also, remember that CNN is airing the full movie with commentaries on January 10 and January 11 (2009)

A 30 minute version of the movie

Check out more clips on YouTube - http://www.youtube.com/user/IOUSAtheMovie

SNL makes fun of the residents of Squanderville

Who are the residents of Squanderville? It’s us Americans dummy.

Clip from I.O.U.S.A showing an animation of Squanderville vs. Thriftville.

Squanderville vs. Thriftville – an article by Warren Buffet – Fortune Magazine October 2003

squanderville

To understand why, take a wildly fanciful trip with me to two isolated, side-by-side islands of equal size, Squanderville and Thriftville. Land is the only capital asset on these islands, and their communities are primitive, needing only food and producing only food. Working eight hours a day, in fact, each inhabitant can produce enough food to sustain himself or herself. And for a long time that's how things go along. On each island everybody works the prescribed eight hours a day, which means that each society is self-sufficient.

Eventually, though, the industrious citizens of Thriftville decide to do some serious saving and investing, and they start to work 16 hours a day. In this mode they continue to live off the food they produce in eight hours of work but begin exporting an equal amount to their one and only trading outlet, Squanderville.

The citizens of Squanderville are ecstatic about this turn of events, since they can now live their lives free from toil but eat as well as ever. Oh, yes, there's a quid pro quo -- but to the Squanders, it seems harmless: All that the Thrifts want in exchange for their food is Squanderbonds (which are denominated, naturally, in Squanderbucks).

Over time Thriftville accumulates an enormous amount of these bonds, which at their core represent claim checks on the future output of Squanderville. A few pundits in Squanderville smell trouble coming. They foresee that for the Squanders both to eat and to pay off -- or simply service -- the debt they're piling up will eventually require them to work more than eight hours a day. But the residents of Squanderville are in no mood to listen to such doomsaying.

Meanwhile, the citizens of Thriftville begin to get nervous. Just how good, they ask, are the IOUs of a shiftless island? So the Thrifts change strategy: Though they continue to hold some bonds, they sell most of them to Squanderville residents for Squanderbucks and use the proceeds to buy Squanderville land. And eventually the Thrifts own all of Squanderville.

At that point, the Squanders are forced to deal with an ugly equation: They must now not only return to working eight hours a day in order to eat -- they have nothing left to trade -- but must also work additional hours to service their debt and pay Thriftville rent on the land so imprudently sold. In effect, Squanderville has been colonized by purchase rather than conquest.

It can be argued, of course, that the present value of the future production that Squanderville must forever ship to Thriftville only equates to the production Thriftville initially gave up and that therefore both have received a fair deal. But since one generation of Squanders gets the free ride and future generations pay in perpetuity for it, there are -- in economist talk -- some pretty dramatic "intergenerational inequities."

Let's think of it in terms of a family: Imagine that I, Warren Buffett, can get the suppliers of all that I consume in my lifetime to take Buffett family IOUs that are payable, in goods and services and with interest added, by my descendants. This scenario may be viewed as effecting an even trade between the Buffett family unit and its creditors. But the generations of Buffetts following me are not likely to applaud the deal (and, heaven forbid, may even attempt to welsh on it).

Think again about those islands: Sooner or later the Squanderville government, facing ever greater payments to service debt, would decide to embrace highly inflationary policies -- that is, issue more Squanderbucks to dilute the value of each. After all, the government would reason, those irritating Squanderbonds are simply claims on specific numbers of Squanderbucks, not on bucks of specific value. In short, making Squanderbucks less valuable would ease the island's fiscal pain.

That prospect is why I, were I a resident of Thriftville, would opt for direct ownership of Squanderville land rather than bonds of the island's government. Most governments find it much harder morally to seize foreign-owned property than they do to dilute the purchasing power of claim checks foreigners hold. Theft by stealth is preferred to theft by force.

So what does all this island hopping have to do with the U.S.? Simply put, after World War II and up until the early 1970s we operated in the industrious Thriftville style, regularly selling more abroad than we purchased. We concurrently invested our surplus abroad, with the result that our net investment -- that is, our holdings of foreign assets less foreign holdings of U.S. assets -- increased (under methodology, since revised, that the government was then using) from $37 billion in 1950 to $68 billion in 1970. In those days, to sum up, our country's "net worth," viewed in totality, consisted of all the wealth within our borders plus a modest portion of the wealth in the rest of the world.

Additionally, because the U.S. was in a net ownership position with respect to the rest of the world, we realized net investment income that, piled on top of our trade surplus, became a second source of investable funds. Our fiscal situation was thus similar to that of an individual who was both saving some of his salary and reinvesting the dividends from his existing nest egg.

In the late 1970s the trade situation reversed, producing deficits that initially ran about 1% of GDP. That was hardly serious, particularly because net investment income remained positive. Indeed, with the power of compound interest working for us, our net ownership balance hit its high in 1980 at $360 billion.

Since then, however, it's been all downhill, with the pace of decline rapidly accelerating in the past five years. Our annual trade deficit now exceeds 4% of GDP. Equally ominous, the rest of the world owns a staggering $2.5 trillion more of the U.S. than we own of other countries. Some of this $2.5 trillion is invested in claim checks--U.S. bonds, both governmental and private--and some in such assets as property and equity securities.

In effect, our country has been behaving like an extraordinarily rich family that possesses an immense farm. In order to consume 4% more than we produce--that's the trade deficit--we have, day by day, been both selling pieces of the farm and increasing the mortgage on what we still own.

To put the $2.5 trillion of net foreign ownership in perspective, contrast it with the $12 trillion value of publicly owned U.S. stocks or the equal amount of U.S. residential real estate or what I would estimate as a grand total of $50 trillion in national wealth. Those comparisons show that what's already been transferred abroad is meaningful--in the area, for example, of 5% of our national wealth.

More important, however, is that foreign ownership of our assets will grow at about $500 billion per year at the present trade-deficit level, which means that the deficit will be adding about one percentage point annually to foreigners' net ownership of our national wealth. As that ownership grows, so will the annual net investment income flowing out of this country. That will leave us paying ever-increasing dividends and interest to the world rather than being a net receiver of them, as in the past. We have entered the world of negative compounding--goodbye pleasure, hello pain.

We were taught in Economics 101 that countries could not for long sustain large, ever-growing trade deficits. At a point, so it was claimed, the spree of the consumption-happy nation would be braked by currency-rate adjustments and by the unwillingness of creditor countries to accept an endless flow of IOUs from the big spenders. And that's the way it has indeed worked for the rest of the world, as we can see by the abrupt shutoffs of credit that many profligate nations have suffered in recent decades.

The U.S., however, enjoys special status. In effect, we can behave today as we wish because our past financial behavior was so exemplary--and because we are so rich. Neither our capacity nor our intention to pay is questioned, and we continue to have a mountain of desirable assets to trade for consumables. In other words, our national credit card allows us to charge truly breathtaking amounts. But that card's credit line is not limitless.

Friday, January 09, 2009

Software bugs – A tale of dates (Zune)

The recent zune fiasco, brought to the fore-front the ever present problem of software bugs. The Zune issue was caused by a bug in the code that reads the hardware timer and returns breaks it down into the date, month, year, minutes, seconds components. See if you can pin-point the issue from the following code:
year = ORIGINYEAR; /* = 1980 */
while (days > 365)
{
    if (IsLeapYear(year))
    {
        if (days > 366)
        {
            days -= 366;
            year += 1;
        }
    }
    else
    {
        days -= 365;
        year += 1;
    }
}

Basically, in a leap year, the code that would determine the year would end up in an infinite loop.

Here is what happens:Zune BSOD The year 2008 is a leap year, which means that it has 366 days.
    So, at 12:00am on Jan 1, 2009, the value of days will become 366. (The year will be 2008, remember this code is used to increment the year).  
    But because 2008 is a leap year, it will enter the first if block of the code. 
           But because the number of days is 366, it will never enter the inner if block that decrements the number of days
                  And hence the Zune will sit in an endless loop, until the timer increments the day to 366. The timer code is accessed during the boot up process of the Zune. So, if you turned on your Zune anytime between 12:00am Jan 1, 2009 and 11:59pm Jan 1, 2009, the Zune would seem like it was stuck on the bootup screen! The problem automatically fixes it-self on Jan 2nd, 2009, as the number of days becomes 367 and the new number of days will become 2 and the year will become 2009. In actuality, the Zune’s timer is based off GMT and based on Microsoft’s press release, you didn’t have to wait for 2nd Jan, but 12pm (noon) on Jan 1st GMT. Can you think of a way to fix the code shown above? Do you know how to check if a year is a leap year or not? Here is C# code for checking for a leap year:

static bool IsLeapYear(int year)
    {
        if ( ((year%4)==0 && (year%100 != 0)) || (year%400 == 0))
            return true;
        return false;
    }
Or just use the in-built method
DateTime.IsLeapYear(int year);
Here are two articles on some famous software bugs: “To err is human, but to really foul things up you need a computer.”  –Paul Ehrlich
ps: Microsoft’s solution for this was to tell Zune owners to wait until Jan 1, 2009 12pm GMT. This means that the bug it-self has not been fixed. Which means that this issue could re-appear in 4 years (2012). But if you are using the Zune, 4 years from now – I think you have bigger problems, than having to worry about not having your zune for 1/2 day.