Quick thought
For some reason the comment spam bots love my "Learning Erlang" post.
For some reason the comment spam bots love my "Learning Erlang" post.
First Petabyte is $78,000, every subsequest Petabyte is $50,000 (that's just for the traffic). I'm sure everyone appreciates the lower prices. I know I do.
The problem with a company the size of Microsoft is that you can't reliably gauge how well it is doing why looking at any one part of it. The operating system division seems at least somewhat committed to return to sanity. Search is busy not gaining any market share. Hotmail is still useless. Enterprise software is finding new ways to package old software, same as ever was. And gaming is actually doing pretty well.
Console gaming anyways. Microsoft took it among themselves to, what I can only very generously describe as, try and unify gaming-related services through a Xbox Live related abomination called Games for Windows Live. They started this out by shoving their "solution" down the throat of every developer who wanted to publish an Xbox 360 game for the PC.
Now, the idea makes sense. Having one account for both Xbox and PC gaming. The implmentation is where it starts hurting.
Tycho over at Penny-Arcade noticed that when logging into Games for Windows Live, the same account on Xbox Live would get knocked offline. He then taled about this issue to a Microsoft person:
I spoke to someone from Microsoft about this very thing, and they said it was interesting, but asked how it would work mechanically. Where would messages be sent? Would one take precedent over the other?
If this is the kind of issue that causes them problems then their problems are, quite frankly, richly deserved. Just have one central place where messages go and other customized views for different access points. It's not a hard thing to do, we've been using that approach for email for 25 years.
Compounding the problem is that instead of working to solve it before rolling out GfWL, they just made it impossible to log in outside of a game. Supposedly, they thought you might not notice getting kicked off Xbox Live if you start a game on your computer or laptop. Considering that they are marketing both platforms as things that go far beyond gaming, this is just cringe-inducingly stupid.
Update: This is relevant.
Last week, I decided to start on a project that I've been thinking about ever since I read this book review sometime during the early part of presidential campaign. It talked about how we could improve the elections by replacing the simplistic majority vote system with range voting. What it comes down to is that instead of picking 1 item out of a range of options, just to grade every option by itself.
It stuck with me that not even the most technology savvy political blogs and website out there used range voting for their polls. I don't know why I didn't just do it when I had the idea but I did it now, and I managed to whip up a javascript based widget that works across domains and can be placed on any website by including 1 or 2 lines of script.
I included one poll below and I hope it works across most browsers. It's just a couple of hours coding so it's hardly done and I did no cross browser testing.
This error popped up today just when I wanted to go home, and I really didn't know what to do at first.
Warning: session_start() [function.session-start]: Function spl_autoload_call() hasn't defined the class it was called for in…
I just googled it and thankfully someone else had encountered the same issue. Had I thought about it for a minute, it probably would come to me because it's entirely logical. "spl_autoload_call()" is the function symfony defines to load classes on demand. The error message indicates that the function returned without defining (via include) the class it was called to define, and that this happen during session_start, i.e. when the session data is being deserialized. Symfony creates and caches an assosiative array of all class files that apply to a given application context, instead of trying to find classes on the fly or guess their location. What happened in my case was that I hadn't defined the different session cookie names for two different applications correctly. In one application I had an object in the session which class was specific to that application. Then I switched to the other application, it tried to deserialize the same session instead of creating a new one and was unable to find the class of that object. Hence the error message.
Symfony 1.2.2 is, ironically, a bugfix release. It happens to break sfDoctrinePager. This probably slipped past because it was broken by a commit intended to fix some problem with generated code. There's tests covering that but no test for normal usage of the pager.
I filed a ticket here.
Update: Bug has been fixed for the next version.
I made the switch to sattelite TV today because cable is getting more expensive and they're slow to add HD channels. One thing I was pretty happy about was that you didn't have to pay any upfront fees for DVRs, and the Scientific Atlantic models they offered are really pretty good, although the hard drive could be a lot bigger.
Now I have Dish Networks top DVR and while the hard drive is certainly bigger, the interface, especially when it comes to setting up recordings, is a disaster. It gives you the feeling that it's very powerful, but it's really just complicated and doesn't work very well at all.
I don't know whether it's because the programmers didn't care or because they didn't feel like working around certain software patents. Whatever it is, I already miss the old interface.
To set up recording with Scientific Atlantic's DVR, you select a show from the timeline or search for it by name (if there is more than one episode for a show with a certain title, the list is collapsed to make scrolling through the result set faster) . With one click, you can then decide to record the item you selected, or all instances of this show on this channel. Very simple and straightforward. Additional options are also easy to set up. You can select to record the show only on the current channel or all channels, only record new or all episodes, only at the currently selected time or all times, etc.
Contrast that with Dish Network. I select a show from the time line. I hit one button to record only the item I selected, another button for a more complicated setup. I get a new screen, to select frenquency of recording. Another screen from there to select delete protection, start early/end late. If I want more options than that, I have to create the recording as something called Dish Pass, which is basically a custom search. It records everything that matches a set of criteria such as title, channels, frequency and resolution(!). But not time, and that where I get pissed off. You see, The Daily Show and The Colbert Report are repeated four times a day, and they are apparently all marked as new. I don't know whose fault that is, but Dish Network and Scientific Atlantic's guides both have the same problem. However, with SA's DVR I can just set it to record only at the time when it show new episodes. Easy enough, with Dish Network, I have to create a custom, time-based recording that I can't even give a title. But that means it's gonna record episodes Monday through Friday, while new episodes are on only Monday through Thurdays. And there's no way around that.
Also, there's more than one menu to do the same thing. I hate it.
Update: Toggling subtitles is a huge pain in the ass now as well. Nice font, though.
Godaddy is insufferably slow today. I wonder if 1&1 is any better.
Update: Took advantage of Dreamhosts new year's sale and got 2 years of hosting for $20. Can't wait to make the change.
Like probably everyone else, I was amused when the news broke that most 30gb Zune players died simultaneously on the morning of December 31st, 2008. I looked like a blunder of epic proportions on Microsoft's part (Epic Fail, as it's called now). However, now that more information is available it's apparent that it's not really Microsoft fault. The only thing they can be blamed for is trusting the drivers Freescale provided for their parts. It's not unreasonable to assume that a big semiconductor maker would properly unit test their drivers. That did not happen, as a look at the source code reveals.
Someone helpfully posted the source code of the driver here. The guilty loop is located at line 259:
while (days > 365)
{
if (IsLeapYear(year))
{
if (days > 366)
{
days -= 366;
year += 1;
}
}
else
{
days -= 365;
year += 1;
}
}
At first, it looks like a simple off-by-one error. If it's a leap year, and the last day in the year (366), nothing is substracted and the loop never stops. However, replacing "days > 366" with "days >= 366" is incorrect as well, because that would set day to 0. Before I give the correct solution, let's look at some more problems with this driver.
The same loop, albeit slightly modified, is used in a different part of the driver:
while (day > 365)
{
if (IsLeapYear(year))
{
numOfLeap++;
if (day > 366)
{
OALMSG(OAL_RTC&&OAL_INFO, (TEXT("Leap Year: %u"),year));
day -= 366;
year += 1;
OALMSG(OAL_RTC&&OAL_INFO, (TEXT(", Days left: %u\r\n"),day));
}
else
{
OALMSG(OAL_ERROR, (TEXT("ERROR calculate day\r\n")));
break;
}
}
else
{
OALMSG(OAL_RTC&&OAL_INFO, (TEXT("Not Leap Year: %u"),year));
day -= 365;
year += 1;
OALMSG(OAL_RTC&&OAL_INFO, (TEXT(", Days left: %u\r\n"),day));
}
}
The irony here is that although it pops out an error message when days is 366, it breaks the loop and cotinues as if nothing happened, actually creating the correct results. Here, a unit test wouldn't have shown any problems, save for the debug message.
It's a bit unclear at first whether the first day in this timestamp schema is supposed to be 1 or 0. Consider this validity check for date input:
if ((lpst->wYear < ORIGINYEAR) || (lpst->wYear > MAXYEAR)) return FALSE;if ((lpst->wMonth < 1) ||(lpst->wMonth > 12)) return FALSE;if((lpst->wDay < 0) ||(lpst->wDay > month_tab[lpst->wMonth-1])) return FALSE;if ((lpst->wHour > 23) ||(lpst->wMinute > 59) ||(lpst->wSecond > 59)) return FALSE;
This code would let day 0 pass. It also doesn't have a problem with negative hours, minutes and seconds, but that's beside the point. The #define block at the top of the source file reveals that day 1 is supposed to be the first day:
#define JAN1WEEK 2 // Jan 1 1980 is a Tuesday #define GetDayOfWeek(X) (((X-1)+JAN1WEEK)%7)
With that cleared up, the solution for the loop is that the boundary is variable, not constant. In a normal year, it needs to keep going until 365 days or less are left. In a leap year, the number is 366. Of course, since the actual year in unknown until the end of the (correct) loop, you can't simply decide that beforehand. The shortest fix would be just to break if 366 days are left in a leap year. Someone also provided this replacement for the loop:
while (days > 365+IsLeapYear(year))
{
days -= 365+IsLeapYear(year);
year++;
}
High marks for simplicity and elegance, low marks for calling the leap year check twice per loop. I propose:
while (days > (daysInYear = IsLeapYear(year) ? 366 : 365))
{
days -= daysInYear;
year++;
}
I'll be interested to see how they end up fixing it and if they decide to take on the other issues as well.
For some reason, I never have time for anything over the Christmas holidays. Blogging suffered especially. Let's fix that:
If there's one software solution I had always wanted, it's the ability to share folders across multiple machines and operating systems in a completely transparent way. That means the syncronization has to be as hands off as possible and the folder has to behave like a normal folder. I finally got my wish with Dropbox. It's entirely possible there has been a solution like that before, and I missed it. Regardless, Dropbox is perfect because it's free (for up to 2GB of storage) and clients are avaible for Windows, Mac and Linux. That's great for me because I use each one on a daily basis.
The client can currently monitor only one folder, but it comes with some file sharing capabilities. For people with security concerns, I think it should be possible to store a TrueCrypt volume in Dropbox. The client is smart enough to segment files and upload only the segments that have changed.
The next new tool in the mix is VirtualBox. VirtualBox is an open-source virtualization solution by Sun that is, again perfectly for me, available on all OS. It allows me to have a Linux server for development whenever I need it, which saves me the money of building or hosting one. It's not feasible to upload the whole server image to Drobox, but you can create a shared HDD image. I created the server image on one machine that I copied to all my machines. Then I created a 50mb (or whatever) harddrive that I copied into Dropbox and mounted in the server. It's hardly a perfect solution but it will have to do until I come up with a better solution. This way doesn't allow me to duplicate config and packages between the server images on the different machines, but at least working data will be.
And finally, Eclipse 3.4 is out and PDT 2.0 has just been released. It's still a bit rough around the edges, but Eclipse now has a vastly improved update manager. There's an irritating issue with the plugin-source manager (can't edit source URLs). PDT has finally added "Mark Occurences", which I've missed since I switched to PDT from an abandoned PHP plugin for Eclipse. It also and seems to be handling variable typing better.
All around exciting new stuff. Most of it is open source, too, and while Dropbox is not, it's built on top of Amazon Web Services. And I can't get enough of those.