Amazon announced Kindle Unlimited, a new service that gives unlimited access to 600.000 books for $9.99/month.

The number sounds impressive, but even reading 1% of those books is close to a utopia. Underestimating and assuming that reading a book takes 1 day, reading 6.000 will take about 16 years. Moreover, so many choices can lead to SADD (Streaming Attention Deficit Disorder) – instead of reading a book from beginning to end, the reader gives up part way up and picks a new one, hoping to find something more exciting. This is a behavior observed only when the cost of change is less than the expected gain. In this case the cost is 0 (if you exclude the monthly fee) so surfing from book to book is extremely easy.

However, I’ve got excited while reading about the new service because it might help me save some money. Therefore, I’ve decided to do some math and figure out if this service is a good deal for me.

Read the rest of this post »

We recently moved in a new building that has open offices. It get pretty loud sometimes with ~10 people in the same room. I wanted something that can isolate me from the noise and since I don’t like ear plugs, I decided on noise cancellation headphones. After reading some reviews I tried Bose QuietComfort 15 and Audio-Technica ATH-ANC7b.

IMG_2104

Construction and case

Both headphones are well-built. However, ATH-ANC7b is made of better quality materials; it is sturdier and I bet it could take greater damage than Bose before breaking. Both sets have leather ear cups but the Bose ones are softer and more comfortable.

In terms of case, again the ATH-ANC7b case seems stronger; it is a rectangular case with rounded corners, nothing fancy. The Bose case has the shape of the headphones but I think that makes it less resistant to damage (more concave surfaces). Both cases have enough room to store an MP3 player, cables and extra batteries.

IMG_2101 IMG_2108 IMG_2106

Noise cancellation

This is the primary reason I got these headphones. Both of them need one AAA battery to cancel noise.

When enabled, the noise cancellation on ATH-ANC7b is pretty good. You can still hear human voices but it is able to cancel most of the background noise. The noise cancellation on Bose is… unbelievable. Enable it and you are locked in a bubble. No more noises, no nothing. It is actually scary how quite it gets - if you wear them without listening to music, you can hear the blood in your ears. But, just like ATH-ANC7b, you can still hear voices and non-background noise.

Music

I didn’t get these headphones for sound quality. Both, do a pretty good job at playing music with noise cancellation on. With noise cancellation off, Bose cannot play any sounds. It is astounding that such expensive headphones cannot be used as just headphones. That’s a very big minus for Bose.
Read the rest of this post »

The Windows Azure Web Jobs SDK is a framework that simplifies the task of adding background processing to web sites. You can get more details about it by reading the Getting Started guide or Scott Hanselman’s introduction. Scott describes the Web Jobs SDK very well: “minimal ceremony for maximum results”. The Windows Azure Web Jobs SDK (codename SimpleBatch) is a very simple framework but provides some powerful binding capabilities.

The most simple advanced binding is the blob name placeholder. It allows you to express the intent of listening to blobs in a specific container that match a specific pattern. For example, you are only interested in blobs that end with “.jpeg”, or only blobs that are prefixed with “input-” and have the extension “.txt”, or you just want the name of the blob and you do not want to bind to an Azure SDK type.

public static void Thumbnails(
    [BlobInput("images/{name}.jpeg")] Stream inputImage,
    [BlobOutput("thumbnails/{name}.jpeg")] Stream outputImage)
{
    // Code that reads the image from inputImage and writes it to outputImage
}

The function above will only be triggered by blobs in the “images” container that have the extension “.jpeg”. The value of {name} placeholder from the input will replace the {name} placeholder in the output. For example, if the input blob is “images/img123.jpeg” then {name} is “img123″ and the output image is “thumbnails/img123.jpg”.

The name placeholders can be also be used to read and write to and from the same container without triggering an infinite loop (the output retriggers the function).

public static void Thumbnails(
    [BlobInput("images/full_{name}.jpeg")] Stream inputImage,
    [BlobOutput("images/thumb_{name}.jpeg")] Stream outputImage)
{
    // Code that reads the image from inputImage and writes it to outputImage
}

The function above reads from the “images” container and writes back in the same container. However, it is only triggered by blobs suffixed with “_full.jpeg” and writes blobs that end with “_thumb.jpeg”. For example, if the input blob is “images/full_img123.jpeg”, then {name} is “img123″ and the output image is “images/thumb_img123.jpeg”.

The placeholder binding is not limited to blob output only. If you need the value of {name} in the code, you can get it by adding a parameter named “name” to your function.

public static void Thumbnails(
    [BlobInput("images/{name}_full.jpeg")] Stream inputImage,
    string name,
    [BlobOutput("images/{name}_thumb.jpeg")] Stream outputImage)
{
    // Code that reads the image from inputImage and writes it to outputImage
}

When the function above executes, the parameter “name” will have the value of the {name} placeholder. For example: if the input is “images/img123_full.jpg” then “name” has the value “img123″.

Similar binding capabilities are available for queue messages too. Assume the following queue message object:

class Order
{
    public string CustomerName {get;set;}
    public string OrderId {get;set;}
}

When a new order arrives, we are going to get the Order message from a queue and create a blob (an invoice) with the name equal to the order id. One approach is to use the IBinder interface to bind the output blob and specify the name that equals the order id. The better and simpler approach (SimpleBatch) is to bind the blob name placeholder to the queue message properties:

public static void ProcessOrder(
    [QueueInput("orders")] Order newOrder,
    [BlobOutput("invoices/{OrderId}")] TextWriter invoice)
{
    // Code that creates the invoice
}

The {OrderId} placeholder from the blob name gets its value from the OrderId property of the newOrder object. For example, newOrder is (JSON): {"CustomerName":"Victor","OrderId":"abc42"} then the output blob name is “invoices/abc42″. The placeholder is case-sensitive.

Books 2013

Jan 4th, 2014

Following last year’s tradition of writing about the books I read in the previous year, here is the list of books I read in 2013:

oneup_cover

One Up On Wall Street: How To Use What You Already Know To Make Money In

7habits_cover

The 7 Habits of Highly Effective People: Powerful Lessons in Personal Change

hp_1_cover

Harry Potter and the Philosopher’ Stone

hp_2_cover

Harry Potter and the Chamber of Secrets

hp_3_cover

Harry Potter and the Prisoner of Azkaban

hp_4_cover

Harry Potter and the Goblet of Fire

hp_5_cover

Harry Potter and the Order of the Phoenix

hp_6_cover

Harry Potter and the Half-Blood Prince

hp_7_cover

Harry Potter and the Deathly Hallows

brokengenius_cover

Broken Genius: The Rise and Fall of William Shockley

box_cover

The Box: How the Shipping Container Made the World Smaller and the World Economy Bigger

gump_cover

Forrest Gump

milio_cover

The Millionaire Mind

Which was the best? Surprisingly, the history of the shipping container is more fascinating than you would expect. The Box is a must read for every one and the learnings from it apply in the software industry too.

I am starting 2014 with two books on my reading list:

moonwalking cover

Moonwalking with Einstein: The Art and Science of Remembering Everything

song_cover

For a Song and a Hundred Songs: A Poet’s Journey Through a Chinese Prison

This is the story of a bug that was hard to reproduce. It is about the investigation and it shows how well intended code can make bugs even harder to reproduce. The bug (and the fix) is trivial. However, a combination of factors make it remarkable.

When Know Inc. starts for the first time after a clean installation, it displays a popup window with an introduction to the game. After the dialog closes it should not show up again. However, on some installations, the dialog would still appears on the second or even third game start. This would happen until a mission was started. Then, it would stop showing up no matter what. The bug was reported about a month ago and until two days ago I was not able to reproduce it.

I uninstalled the game on my phone and reinstalled it from the Store. Then I noticed that every time I start the game, I get the intro popup. On Windows Phone, if you install the game from the Store you cannot access the isolated storage where the files are stored. That can only be done for side-loaded applications. So I had the bug reproducing on my phone but no way to investigate.

I uninstalled the store version of the game and installed the developer version so I can debug. Guess what? I couldn’t reproduce it anymore. At least I knew that it is somehow reproducible on my phone. I tried to remember what I did with the store version before I noticed the bug. I opened the game… clicked the Story button… probably closed the game… opened it again… started a mission… dismissed the how to play dialog… closed the game… I knew it was reproducible, I just had to find the correct steps. Tried for an hour or so but nothing. At that point, I didn’t know that it only works on clean installations (you’ll see soon why). No luck, so that was it, no repro.

I was working on a new feature when I saw the bug again. Eureka! Repro on developer build. The first thing I did was Read the rest of this post »

New blog theme

Dec 23rd, 2013

In July 2010, I wrote my first WordPress theme from scratch. I kind of got bored of that design.  I wanted something new that is simple and allows the reader to focus on the content. Today, I stripped down the old theme and rearranged the elements. I kept only what is essential:

  • The text (duuuh). I increased the line spacing a little and changed the font.
  • Twitter feed because I’m micro blogging there a lot.
  • Links to social networks.

No more:

  • Gradients and fancy backgrounds.
  • Tag clouds et al.
  • Lots of plugins.

Let me know what you think:

Old vs new

Books 2012

Feb 3rd, 2013

Some time ago I read an article about Kindle owners reading more books than others. The author was explaining that owning a Kindle makes you read more. Owning a Kindle is definitely not the cause. I believe it is the other way around - reading more makes you buy a Kindle, therefore Kindle owners seem to read more. Anyway, the reasoning there is not the topic of this post.

In 2012, my goal was to read 1 book/quarter. I am happy to say that I managed to read three times as much.

I was taken on a fantastic journey of mysteries and discoveries through the streets of London by Sir Arthur Conan Doyle’s The Adventures of Sherlock Holmes. After that, my mind has ventured through Wonderland with the help of Lewis Carroll’s Alice’s Adventures in Wonderland. With today’s knowledge, it is easy to imagine what would be required to go to the center of the Earth. But, can you believe that Jules Verne imagined that with the knowledge of 1864? Just like most of his books, A Journey to the Center of the Earth is one fascinating reading. From the center of the Earth I went back back in 1943 to the story of a Norwegian hunted by Nazi troops. David Howarth and Stephen E. Ambrose describe the incredible story about survivorship and human spirit in We Die Alone: A WWII Epic of Escape and Endurance. Finally, I was taken closer to the present day and financial topics by David Lender’s Bull Street which is a pretty good mixture of reality and fiction about the life on Wall Street.

Read the rest of this post »

Goodbye, SkypeGadget

Nov 3rd, 2012

Five years after releasing the first version of SkypeGadget, I decided to stop supporting and developing SkypeGadget. I believe that I discontinued it about a year ago when I provided the latest update but today it is official. Starting today, Nov 3rd 2012, I will no longer offer support for SkypeGadget.

There are a few reasons behind this decision: (1) Windows 8 is out and it does not have support for gadgets. (2) Skype4COM, the library that allowed SkypeGadget to talk to Skype, is no longer supported and from what I’ve heard, it does not work with the latest version of Skype. (3) Gadgets are an old technology; the new era of live tiles is here.

Before I end, I give you the SkypeGadget memorabilia:

  • SkypeGadget’s first name was SkypeConversation.
  • It started as a contest entry. The first prize was an HTC Touch. SkypeGadget got on 6th.
  • October 27, 2007 is the date of the oldest SkypeConversation version that I have (see the screenshot). I started developing it 1-2 weeks before that date.
  • In July 2009, it reached 100.000 downloads on Gallery Live.
  • Last time I checked the Gallery Live website, before Microsoft discontinued it, there were more than 300.000 downloads.
  • On top of the numbers above, there are about 40.000 downloads from this website. I think the total number of downloads, from all places, is close to 350.000.
  • The SkypeGadget page on this website has 95.000 views.
  • SkypeGadget has less than 500 lines of code, including CSS and HTML.
  • Believe it or not, people donated REAL money. Four people donated a total of $13 (2x$5, 1x$2, 1x$1).
  • SkypeGadget was and will remain free and open-source.
  • SkypeGadget was the first ever gadget that allowed interaction with Skype. There were at least 3 other gadgets that copied my code.
  • There are people who use outdated versions of Skype just to run SkypeGadget (Thanks guys!).

You can still download SkypeGadget, I’ll keep the page up and running.

C# error CS1540

Sep 12th, 2012

There are many ways in which one could violate the rules of Object Oriented Programming in C#. Fortunately, the C# compiler is smart enough to prevent many of them, like the one in the example below. Can you  figure out why the compiler doesn’t allow the call in the last method?

abstract class BaseClass
{
    protected abstract void AMethod(BaseClass arg);
}
class Derived : BaseClass
{
    protected override void AMethod(BaseClass arg)
    {
        arg.AMethod();
    }
}

Read the rest of this post »

Guess who’s back?

Sep 9th, 2012

Yes, I am still alive :) I was too lazy to write any posts in the last months.

Stay tuned for the next technical post on Wednesday (Sept. 9, 2012) morning. Until then, here’s a picture taken from the 73rd floor of the tallest building in Seattle:

« Older Posts