Friday, December 30, 2011

Romo robot control library for WP7

After seeing the Romo smartphone robot on Kickstarter some time ago, I was hooked. I wanted one. And I wanted to program for it myself, on my Windows Phone! So I pledged a certain amount of money for the limited edition one - gotta have the T-shirt too - and waited for the Kickstarter results...



And then it was a landslide (they raised $114796!), and around Christmas I received my robot. It happened to be limited edition number 42 and all, pleasing my inner nerd immensely. To get to work!

In fact, I had contacted the guys at Romotive to ask about the sounds needed to drive the robot. The evening before FedEx would deliver, I had a first draft of a library and an app with some simple buttons. When the Romo arrived, this code immediately drove the Romo robot flawlessly, without any changes needed. That certainly was cool.

Today after the last day at work, I met up with some of the WP7NL crew. This first demo received some great reactions and some good suggestions too. Turns out the Romo base reacts to volume as well as sound frequencies. So I reworked the library to allow you to use this to not only control forward/backward motion and left/right rotation but variable speed for both as well.

When the library is done and tested, which means having written and published at least one Romo WP7 app myself, I plan to publish it open source on Codeplex and make the binaries available (nice reason to get into NuGet) as soon as possible. And then, order yourself a Romo, and get programming robots!

Keep watching this space for more info!

Friday, November 25, 2011

Command & Conquer, Distimo style

Just a quick post, reacting to a comment by Tijmen after tweeting about the cool Command & Conquer style competitor map by Distimo.

Data for the following map (click on it for a larger version) is from the last month. It uses colors to show which of the WP7 apps I designated as competitors for my Klout Tile app (which should be all of the Klout apps out there right now..) have the highest ranking within the Social category in that country:


Interesting, huh? Especially since the other newcomer (from France, and currently only biggest there) shows the most information from the Klout API at the moment. Really should push out v1.1 of my Klout Tile app soon: it shows more data, should be more stable and cuts back on the "review begging" that was a bit excessive in v1.0 (with a daily recurring reminder). At least my app is still the only one with a Live Tile for your score.

My goal: get the whole world blue. ;-)

Update: Since posting this, another Klout app started showing your score on a live tile. So the "blue earth" goal doesn't seem like it'll be happening soon, as I am currently busy on other WP7 apps (one of which actually has a fixed deadline).

Tuesday, November 8, 2011

The perfect way to ask for a WP7 App Review...?

Today I got a mention on Twitter I really liked about the way I implemented "review begging" in my latest Windows Phone 7 app. I do it using the following code:

using System;
using Microsoft.Phone.Scheduler;

/* ...part of AboutPage.asmx.cs... */

public static void ResetReviewReminder(KloutSettings settings)
{
  const string name = "ReviewReminder";
  Action removeReminder = () => {
    if (ScheduledActionService.Find(name) != null)
      ScheduledActionService.Remove(name);
  };
#if DEBUG
  removeReminder();
  settings.UsedReviewButton = false;
#endif
  if (settings.UsedReviewButton)
  {
    removeReminder();
  }
  else
  {
    ScheduledAction reminder = ScheduledActionService.Find(name);
    if (reminder == null)
    {
      reminder = new Reminder(name)
      {
        Title = "How do you like me so far?",
        Content = "Would you mind using the about dialog " +
        "(tap here if Klout Tile is not running) " +
        "and writing a review?",
        NavigationUri = new Uri("/AboutPage.xaml", UriKind.Relative),
        RecurrenceType = RecurrenceInterval.Weekly,
        ExpirationTime = DateTime.Now.AddMonths(1),
      };
      if (System.Diagnostics.Debugger.IsAttached)
      {
        reminder.BeginTime = DateTime.Now.AddMinutes(5);
      }
      else
      {
        DateTime x = DateTime.Now.AddDays(7);
        reminder.BeginTime = new DateTime(x.Year, x.Month, x.Day, 12, 0, 0);
      }
      ScheduledActionService.Add(reminder);
    }
  }
}

What does this do?

That's an easy question to answer: if the application settings object (which is persisted in isolated storage) flags that the user has already used the review ApplicationBar button (in Klout Tile that's the star button in the About page), then any review reminder that is found is silently deleted. If however, the user has not used the review button in the About page yet and no existing reminder is found, it creates a new review reminder.

This reminder asks the user what she thinks about the app and also includes a NavigationUri that points to the About page. It is set to recur weekly for a maximum of about a month, starting three days from now. I think this is a reasonable "beg" period and frequency. (You can adjust as you see fit, of course.)

How do I use it?

Each time the Klout Tile app is started, I call AboutPage.ResetReviewReminder() once. This means that, if this is the first time the user starts the app, the user will be reminded three days later to please go add a review.

Apart from this I have the following code in my About page to handle the user clicking review button:

private void ReviewButton_Click(object sender, EventArgs e)
{
  var settings = KloutSettings.Load();
  settings.UsedReviewButton = true;
  settings.Save();
  ResetReviewReminder(settings);
  var review = new Microsoft.Phone.Tasks.MarketplaceReviewTask();
  review.Show();
}

This makes sure that when the user does click on the review button, any reminder that exists will be deleted and no more reminders will ever be (re)created in the future.

Some of the advantages

A lot of Windows Phone apps ask the user for a review. Some have buttons, which the user can easily choose/forget to (n)ever tap. Some wait a bit and ask the user for a review using a MessageBox with Ok/Cancel buttons, but this can be annoying for the user, as there is no "Not right now." option. Also, if the user installs your app, runs it onces and never uses it again, the code to show this message box will never get executed.

Using a system reminder like the code above does gives the following advantages:

  • We are able to show the user a review reminder, even if they only start the app once and never come back to it again. (Unless they uninstall it, of course.)
  • The review reminder is stored with other system reminders (like the ones from the Calendar), so they can be shown at any time, even if when the app is not running.
  • You do not need to use a background task to get this behavior, so even if the user disables your background task (which they can) the reminder will pop up.
  • If the reminder pops up at a time that is not convenient for the user, she can just snooze it, like any other reminder.
  • The user still has a way to just dismiss the reminder, but as it is a daily repeating one, it should pop up the next day (for a maximum of two weeks after first start).
  • When the reminder pops up while the app is not running, tapping the reminder opens the correct page inside the app directly to easily let the user initiate a review scenario. (For bonus points, the URI and About page could be changed so that when the user enters by tapping the reminder, the Microsoft.Phone.Tasks.MarketplaceReviewTask is executed directly, eliminating one further step!)
  • Finally, when the user uses the review button in the About page on their own, the reminder (whether already shown before or not) is silently deleted so the user is not bothered with our "review begging" ever again.

So I think using a Reminder to do you "review begging" might be the perfect solution. What do you think?

Friday, October 28, 2011

Capturing Console output without interfering with it

Recently I've had to tackle the following problem: given an existing .NET console application, send the commandline output to an email address when the application is finished. Sounded reasonably simple, right? And in the end it was.

Options...

The key to making this work is finding out that the .NET implementation of System.Console has access to the normal stdin, stdout and stderr console streams wrapped in a TextWriter.

If you then find out that Console has methods like SetOut()for changing the TextWriters that are used for this, you have way of capturing text that the existing console application writes out using Console.Writeline() and related methods so you can email it.

...that leave existing output as it

But wait, functionality for the application should remain the same, so this output should stilll remain visible on the console too. Here design patterns come to our aid, in this case the Decorator pattern. The class we need is the following:

using System;
using System.IO;
using System.Text;

namespace peSHIr
{
  public class StringBufferPassthroughWriter : TextWriter
  {
     private TextWriter wrapped;
     private StringBuilder buffer;

     public StringBufferPassthroughWriter(TextWriter wrap)
     {
        wrapped = wrap;
        buffer = new StringBuilder();
     }

     public override Encoding Encoding { get { return wrapped.Encoding; } }
     public override void Write(string value) { wrapped.Write(value); buffer.Append(value); }
     public override void WriteLine(string value) { wrapped.WriteLine(value); buffer.AppendLine(value); }
     public override void WriteLine() { wrapped.WriteLine(); buffer.AppendLine(); }

     public string Buffer { get { return buffer.ToString(); } }
  }
}

What does the above class do? Well, not very much. All it does is decorate another TextWriter. That is: it derives from TextWriter, taking another TextWriter in its constructor which it stores, and then it simply passes through all method calls that write elementary pieces of text to the stored TextWriter. This makes sure it does not interfere with whatever that other TextWriter would normally be doing.

And it does one extra thing: keep an instance of a StringBuilder as well, and also fill this from the same overridden methods. Finally, our new TextWriter decorator supplies a read-only property to get at the stored string in the StringBuilder buffer.

How to use this

It should now probably be fairly obvious now how to actually "insert" this decorator in our existing console application to enable it to send an email with its complete output without interfering with that same output. I'll show a simple "before" and "after" comparison of the Main() method for the application.

Before

using System;

static int Main(string[] args)
{
  // Application code, calling Console.WriteLine() etc.
  return 0;
}

After

using System;
using peSHIr;

// Actual EmailSuperUser() method omitted as
// exercise for the reader... ;-)

static int Main(string[] args)
{
  using (var output = new StringBufferPassthroughWriter(Console.Out))
  {
    Console.SetOut(output);
    // Application code, calling Console.WriteLine() etc.
    EmailSuperUser(output.Buffer);
  }
  return 0;
}

And that is basically all. Hope you enjoyed this little code sample.

(For more information on how to write the EmailSuperUser method, see this Scott Guthrie blogpost and/or the System.Net.Mail documentation.)

Sunday, September 25, 2011

Ich bin ein Asperger...

Looking back, I've always thought of myself as an outsider. Always had the feeling something was wrong with me. Or maybe all those other people around me were different than I was; like they had a little secret that nobody had ever told me, because they possibly though that I "just knew" like everybody else. Because it was normal for them.

This until recently undefinable feeling has always had a great impact on my life. I was that calm, forward, studious child. That child that could perfectly entertain itself. With a book for instance; in my mind I've always been able to read. That child that never bothered anyone.

In school I usually found the lessons to be fun and interesting. I did regret the fact that all these other students, who in general didn't seem to care for it all one bit, had to be there as well. I didn't live that far away from school, so when there was a gap in the curriculum of the day - even if it was just one hour - I got on my bike and went home. What else could I do, with all those other kids, when there was nothing to do at school? I was then better off riding home to drop off some of the school books I would no longer need that day, for instance.

After studying computer science at Utrecht University, a period I basically allowed to happen to me like it was "just another school", meaning that the traditional college student life all but completely passed me by, I moved out on my own and started working as a computer programmer. I was perfectly work focused. Alone and deeply unhappy. Without knowing why.

Just as in the previous years when interacting with other people, interacting with colleages and clients at work sometimes resulted in problems. Often these small or even large conflicts with people came as a complete surprise to me. Looking back they were almost always caused by breakdowns in non-verbal communication. I had for instance said something that I thought to be factually true, but I had done this in such a way that the other person felt attacked or even insulted to the bone.

Anyway, I won't be including any more personal details. I might do so later, when both my readers and me are interested in me writing down more. At the moment I do not feel like it, and want to get back to the title of this text and how I came to write it. What I do want to add is that one of the best things that ever happened to me is my wife Rona. I would not know what to do without her..

Asperger


Quite a number of years ago I first heard or read about Asperger Syndrome, a development disorder that's part of the so-called autisme spectrum. This means it is in fact a light form of autism. I never thought it would be relevant to myself in any way. Also, the many coaches I have spent time with over the years (often through work) to help with myself and my problems at work, my melancholic moods or my unrest have apparently never thought about this possibility. Or if they did, they never let me know.

Recently Asperger has maybe gotten a bit more attention because the (not only with me) very popular Sheldon Cooper from The Bing Bang Theory exhibits many of the typical symptoms. Also, a short Twitter discussion with a group of programmers I know mentioned an online Asperger test, that startled me a bit with the high resulting score when I answered the questions in gest.

All this resulted in me buying the book Asperger Marriage a couple of weeks ago. On the 19th of september I eventually read it completely in one go; I just could not put it down. Even though the individual detailed differences between myself and the main character in this book describing the marriage between Asperger Chris and his wife Gisela are enormous - every person is different - for most of the book I had the distinct feeling the book was about me. I recognized so many of it that literally seemed to be about me. A strange and not at all pleasant experience...

Now what?


Therefore I am now convinced that I suffer of Asperger Syndrome. Although suffer is by no means the right word: it also brings me great advantages and makes me who I am. Thus I do not believe that I would want it gone even if that were possible.

For now I am therefore not inclined to have my auto-diagnosis checked by a professional in the field. After all: based on what I now know about Asperger and about myself an actual medical diagnosis would change nothing: there is no cure (even if I would want one) and no real practically useful help that would mean anything to me. The only thing I can do is to continue to adapt and develop, and learn to cope with the handicap that I apparently have. Subconsciously I have been at this for decades, and in certain areas I have become quite good at it, even if this is or perhaps always will be a conscious effort.

I am glad that my problems and feeling of "being different" at least for myself have a name now. This is also the reason I wrote this text: Asperger is part of me, and I would like people to know that. Not to gain any positive advantages or use it as an excuse, but to give it a place, for me.

Well, to be honest I might want to use it as a reference. As part of an apology for instance, in a situation where my social handicap again unwittingly cause a conflict because the tricks I picked up to deal with people in a way they consciously or unconsciously expect of me have failed. Believe me: I can only get better at this.

The coming weeks I will have enough to read: lots of books have been written on this subject and also weblogs like Life with Aspergers, which I instantly added to Google Reader. I think the book "Pretending to be normal" is now on the top of my reading list, because just the title alone seems so very much to fit the feeling I've been having for years.

Everyone who knows me and have found me to act strangely or even rude in certain situations: I hope you now have an idea of the potential reason why and also why I cannot always help myself, even if I wanted. Everyone who knows me and is now thinking "But I never once noticed anything like that!" I would like to thank very much for the enormous compliment. All other readers I want to thank for taking the trouble to read this.

Thank you.

(This is an English translation of the original Dutch blogpost. I wanted to have this introductory information in English too. Any possible future posts on this subject will likely be Dutch only.)

Sunday, September 18, 2011

Fire-and-forget background code execution

Finally, time for some code again.

In the course of writing some Windows Phone 7 apps for the Apps for Noord-Holland competition I've just hacked together a tiny class that wraps the BackgroundWorker class for one simpe case: you want a bit of code to execute in the background, fire-and-forget style:

var loadData = new peSHIr.BackgroundHelper(() =>
{
    // load something
    // load something else
    // and that's it, basically
});

So you're not really interested in giving the BackgroundWorker an argument, getting progress information, supporting cancellation, receiving a result or even when exactly the code is done running (by getting an event). You just want it to start now and eventually have it be done.

If you want/need this, here's a simple utility class you can use:

using System;
using System.ComponentModel;

namespace peSHIr
{
    public class BackgroundHelper
    {
        private Action work;
        private DoWorkEventHandler start;
        private RunWorkerCompletedEventHandler finish;
        private BackgroundWorker worker;

        public BackgroundHelper(Action executeInBackground)
        {
            work = executeInBackground;
            start = new DoWorkEventHandler(DoWork);
            finish = new RunWorkerCompletedEventHandler(WorkCompleted);
            worker = new BackgroundWorker();
            worker.DoWork += start;
            worker.RunWorkerCompleted += finish;
            worker.RunWorkerAsync();
        }

        private void DoWork(object sender, DoWorkEventArgs e)
        {
            if (work != null) work();
        }

        private void WorkCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            worker.DoWork -= start;
            worker.RunWorkerCompleted -= finish;
            worker = null;
            start = null;
            finish = null;
        }

        public bool IsBusy
        {
            get {
                return work != null && worker != null ? worker.IsBusy : false;
            }
        }
    }
}

Be sure to keep your multi-threading in order, though. So if the code stores something, use appropriate locking. Or if you access GUI elements, go through the proper Dispatcher. But that almost goes without saying, right? Also, error handling for the code you give this class is obviously left as an excercise for the reader. ;-)

Enjoy!

Friday, September 9, 2011

"Hey, what's up with the daily tweet to @twitter @support...?"

My Twitter followers are bound to know I have some bones to pick with Twitter lately. For one, I really don't like the treacle like performance of #NewTwitter compared to #OldTwitter (even in Chrome, not just in IE8 and IE9). But this post is not about that.
Recently I have been starting to post (almost) daily tweets asking Twitter to support Mobypicture. As some people are bound to frown on this, I thought I'd write this blog post to explain why I do this, and when I plan to stop doing it.

My problem

Around the time I started these daily tweets, Twitter started rolling out their new "Recent Images" media gallery. This shows the most recent images a user tweeted (includes old style retweets, or course) on their profile and includes a link to a complete grid of such images.
While I think this is cool feature, I really did not like that only a couple of image publish websites are included in this view, like: TwitPic, PhotoBucket and yfrog, while the service that I use (the Dutch Mobypicture) is not included.
This means, that what Twitter calls "Recent Images by @peSHIr" on my profile, does not include any of my recent images, but only images by others that I happened to tweet a link to at one time. This is not what I want, obviously. I would like my Moby images to show up in this view. Or, if that is (currently) not possible, I want to disable the new image gallery so it does not show up on my profile.

So, ask the parties involved

To that end, I started tweeting my request. I also DM'ed Twitter Support and MobyPicture with more background information on my request. I have received a number of replies to this. For one thing, Moby replied they cannot help me put their images into the Twitter gallery (obviously).
Twitter seems to have misinterpreted my original request for "Moby support", and quite stoically referred me to the Moby support page. Nice one, Twitter; show us you care about your users... ;-) So I changed my daily request a bit, based on this responses.
Then, after more clarification by DM, I received the following DM response from Twitter:
You can turn off media here: https://support.twitter.com/articles/20169200-media-settings-and-best-practices
After asking around by DM some more, Twitter admitted this is not a response my question on how to disable the media gallery so it doesn't show up on my profile any more. Their eventual response to that (in two DMs) was this:
We appreciate your request and feedback and will share it with the rest of the team. Unfortunately the recent imaged gallery won't be removed from your profile unless you don't have any images posted in your Tweets. Sorry! https://support.twitter.com/articles/20169409

So, that's it?

So, in the meantime, even though I thanked Twitter support for they rather promptly responses, I feel screwed. Unless I go back and delete all tweets that include a supported image link in them, I'm "stuck" with the image gallery on my profile, a feature I would really like when it would include my Moby images. And I am not going to hunt down those tweets and delete them.
Also, even though as far as I can remember the inline media display in #NewTwitter at one time showed images posted on Mobypicture, with the (again originally 2 part DM) reply from Twitter support, it seems clear my Moby images are not expected to show up in my media gallery any time soon (or ever):
You're welcome. And again, as moby is not an official media partner of ours, we don't show their images in the details pane it's possible that we will consider a partnership in the future, but for now we are not affiliated. Thanks!

So, the world is stuck with my daily tweet

I feel I have no other course of action left, than continue my daily tweet asking for Mobypicture support in the current Twitter webinterface...
So, unless my images show up in my Twitter media gallery (or possibly until I get a way to turn it off so it does not show up on my profile any more) I will be repeating that daily tweet, reminding Twitter that I have not given up asking for this support.
If you use Mobypicture and Twitter as well, I want to ask you to do the same or RT my daily reminder. If enough people do so, it might be a reason for Twitter to start including these images.
Hopefully this blogpost clarifies the reason for that annoying daily tweet. And thank you for reading this far! ;-)

Monday, August 15, 2011

3D Masters app has more downloads than expected

As we know the App Hub download statistics take a couple of days to get processed, so it took a while to get going for my 3D Masters app. However, even though it seems to start trailing off a bit at the moment, so far there have only been a couple of days the app was not downloaded somewhere:

My other application only has about 40 downloads total (and none in the time frame shown above, hence the flat start of the cumulative line). And that one has been published since early november 2010!

Also, I would expect the actual target demographic for the app to not be heavy Windows Phone 7 users yet. So you can understand how I'm over the moon with these download numbers. ;-)

Update, early Januari 2012: still only a handful to go until the 400 downloads mark; that's almost additional 200 added in two months. Is that the word of mouth going around during the holiday season? New Nokia phones and advertising? I will try to get a graph out of the whole time it was published some time soon. And I really need to get cracking on the update for next July, when the 3D Masters 2012 event will be in Venlo again.

Wednesday, July 20, 2011

Quick WP7 app development

I have often wondered, with the certification process of a centrally controlled online application database and store principle that is often used right now, if fast reactions to events in the form of a new app were still possible. After all, you cannot quickly hack something together and put it on a website so people can install and use it.

While this post is by no means a thorough treatise of this subject, it does offer one concrete example that shows quick development turn-around is indeed still possible in a centralized store arrangement.

This past week has been a bit of rollercoaster for me, building and deploying a Windows Phone 7 app with background information for the 3D Masters 2011. As a bit of background, I'll sketch a timeline of how this app came to be. All times shown are in 24h CEST and approximate, accurate to within maybe half an hour. Here goes:

  • Fri, Juli 15th, 18:30: Meet friends for diner in Haarlem, before seeing the final Harry Potter.
  • 19:00: Received an mail from 3D Masters about availability of an iPhone app for the event.
  • 20:00: After emailing back and forth a bit with Jeff Barringer during diner, I decided to try and write a WP7 equivalent.
  • 20:50: Harry Potter begins, or rather: ends... ;-)
  • Sat, Juli 16th, 7:00: I start a new blank WP7 solution in VS2010 and get to work.
  • 22:00: Made nice progress. Basic app structure, icons, panorama background, start of About screen and the complete interactive map section are done. Made good progress on starting to capture the manoeuvre and pilot data from the 3DX website into two included XML files. I did do some grocery shopping along the way, so I maybe put in about 13 hours or so.
  • Sun, Juli 17th, 10:00: I return to my 3D Masters solution. Manually getting all the data into the two XML files took relatively long time (most of it during the end of todays session), but I also wrote basic ViewModels, ListBox data templates in my panorama control and all the plumbing needed to get selecting en showing the two detail pages to work. Luckily, showing the external descriptions and the movies just took one Task object each given the URLs in the data I had. ;-)
  • Mon, Juli 18th, 0:30: After completing the XML data and quickly tombstoning the show panorama item (so you return to the one you left after going into detail pages), I call it a night and try to submit my app to the App Hub. With some break time (had to leave that chair some time during the day), I put in about another 13 hours of development time.
  • 1:30: Then I found out that submitting new apps to App Hub was broken, possibly related to the scheduled down time that was announced for monday and is no doubt related to not only the new functionality that has shown up in App Hub, but to the approach of Mango as well. Very frustrated, I gave up, and went to bed.
  • 6:00: Up early for work. Tried to submit again, and got the XAP file and all the meta data in. Dreading that this might be too late, I went to work.
  • 20:00: Saw that app submission status was "Testing in progress".
  • 22:00: Noticed that the App Hub was showing the "down for maintenance" message.
  • Tue, Juli 19th, 17:00: Saw that my blog post was linked from the 3D Masters website, App Hub was back up and the status of my app was now "Certified", which is not mentioned in the App Hub forum thread about possible states.
    Fearing the app might not make it to Marketplace in time for the event, I at least made the XAP available so people with developer unlocked devices could sideload it at least, would that turn out to be the case.
  • 21:30: I noticed an email from the WP7 Marketplace Developer Support telling me there had been a problem processing my app submission. When I checked App Hub however, the status had now moved to Published, leaving me well confused.
  • Wed, Juli 20th (=today), 6:00: I was able to find my app in Marketplace on my phone and download and install it. Victory!
  • 11:00: Started to write this blog post, as I think this whole story might be interesting to some of the WP7 developers out there. Please don't be shy in the comments if you think it is. ;-)
  • Fri, Juli 22nd, 9:00: Start of the 3D Masters event that will end the next sunday around 17:00 in Venlo, NL. Will I see you there on saturday, perhaps?
  • 11:00: Thanks for all your interest; this turns out to be my most popular post since I did that Samsung Omnia Qwerty review two years ago. ;-)
  • Mon, 15th of August: Download numbers seem to start trailing off around 60 downloads.
  • Early november: In fact, the download graph from publishing the app until now seems to have an almost constant derivative until now, just having reached the 200 download mark.
  • Fri, 24th of August 2012: Unbelievable, really. Even though I missed the 3D Masters 2012 deadline (the app still shows hardcoded data from the 2011 event right now), the download graph keeps on going up steadily, now at around 2500 downloads and about 100 active users daily (according to Flurry statistics). Possible this active user bases keeps coming back to watch the movies while practising?

So yes, there you have it. Even though I do not recommend anybody to do this on a regular basis, if you really need to and you maybe get a bit lucky with the time your app takes to run the certification procedure you can have very quick new app results!

In this case that means: some 26 hours of development time, starting a week before app was needed, about 4½ days (or 108 hours) from inception of the endeavour to having the app on my phone, downloaded from Marketplace.

Q.E.D. (now, when was that vacation again...?)

(Oh, and lots of ideas for version 1.1 of course, for the next 3D Masters and other 3DX events...)

Monday, July 18, 2011

MetalScroll for VS2010?

Anyone who, like myself, loved MetalScroll in VisualStudio, knows that with WPF VS2010 it doesn't work anymore. However, there is an alternative: go to Tools, Extension Manager right now and install the Productivity Power Tools for VisualStudio if you haven't already. The Enhanced Scrollbar that is included will probably do what you want.

Next to the Full Map Mode shown above, it has two other modes you can easily switch to using a context menu. There are also some options for the scrollbar that you'll find in the usual place: the ever expanding VS Options dialog.

I think I actually like the Scroll Bar Mode best, as it looks most like a normal scrollbar with usefull pixel pointers on it. Switching to Full Map Mode is always just a right click away when I really need it.

Windows Phone app for the 3D Masters!

Friday night, while having diner with friends before seeing the final Harry Potter movie, I got an email from the 3D Masters organizers that there was an iPhone app containing all kind of useful information.

Of course, this would be of no use to me, as I have a Windows Phone. So I wrote an email asking about the availability of a WP7 app with the same information, asking if it would be ok if I were to write one myself.

Reactions to this were very positive, so I set out to work on it the following morning. At the moment (early monday morning), the app is finished, waiting to be uploaded into the App Hub. Which, unfortunately seems to do nothing but give me errors...

Around 6:00: The next morning the uploading seemed to work. I really hope that the 3D Masters app will still have enough time to pass testing and appear in the Marketplace before the actual event it is supposed to be used at starts, which is in (now) four days.

Around 22:00: Later that same evening the App Hub was down for announced maintenance. Last status update I saw for the 3D Masters app submission was "Testing in progress". This was around 20:00. I will track the progress of the App Hub update and wonder why I will be able to get a status update again...

Tuesday the 19th, around 17:00: Great to see that we are linked from the 3D Master website now. Thanks, Jeff!

However, it is not at all certain that the app will be online in the WP7 Marketplace in time for this weekend; it's status has been "Certified" now for quite a number of hours. As a workaround, I'm making the XAP file available, so anyone with a developer unlocked WP7 device can sideload and already use it right now. So have a look, and be ready for the coming weekend no matter what happens in the certification process.

Tuesday the 19th, around 21:30: Strangly enough, App Hub status now says "Published", even though I got an email saying "We were unable to process the application submission for [app]. An error has occurred with your submission. [etc]", telling me to check the App Hub website.

Wednesday the 20th, around 6:00: I found my app in Marketplace and installed it. If you don't see it yet, that's probably because of the CDN technology that is involved. I know it can take up to even a couple of days before everyone actually see the app in their Marketplace app on their phone. So, unless you get very unlucky with CDN issues, you should be able to use the 3D Masters Windows Phone 7 app this weekend!

Enjoy it, and see you next saturday in Venlo!

Thursday, June 30, 2011

Easily exclude generated proxies from your code coverage

This is just a quick heads-up that many of you might already know about: partial classes easily enable you to add an attribute to an existing class by just adding an empty partial class definition for the same class in another source code location that just has that attribute on it.

Adding an attribute like this can be used to exclude the generated code of a webservice proxy from unit test code coverage by adding a DebuggerNonUserCode attribute to the relevant classes, like so:

// Add DebuggerNonUserCode attribute to generated
// proxy classes to exclude it from code coverage.

namespace Your.ServiceProxy.Namespace
{
 using System.Diagnostics;
 [DebuggerNonUserCode] public partial class YourWebService { }
 [DebuggerNonUserCode] public partial class SomeServiceDto { }
 [DebuggerNonUserCode] public partial class AnotherServiceDto { }
 // et cetera
}

As long as the service keeps using the same classnames, this solution even enables you to regenerate your proxy without losing the code coverage exclusion of the proxy (if you put this code in place not touched on regeneration).

Nifty, huh? ;-)

Monday, May 2, 2011

My take on using var in C#

The discussion seems to pop up from time to time among C# programmers: To var? Or not to var...? I know my take on the matter, but I never took the time to write it down. Luckily, Eric Lippert seems to have done this for me; I don't think I could agree more with his take. As seems to be the case rather often, come to think of it..

Tuesday, April 19, 2011

Mango = Layar, Skype, and almost too much to name...

Just a quick YAY! After the recent MIX reveals it seems like my Layar wish will come true with Mango! Now I'm "just" waiting for a resolution of the Google (Maps) vs Bing (Maps) situation in the Netherlands.

DevDays 2011

Yes, it is almost time: the 2011 edition of the Dutch DevDays. That's why the rest of this blog post will be in Dutch. My apologies to any international readers.

Zoals je op dit moment (het attending logo zal later waarschijnlijk wel weer verdwijnen) hiernaast kunt zien ben ik er ook weer bij. Kleine tip wat betreft dat logo: de Beleef pagina waar je de HTML snippet kunt krijgen voor je eigen logo bevat een fout. De image URL begint met ./images in plaats van met http://www.techdays.nl/images. Beetje slordig, maar gelukkig makkelijk te corrigeren.

Mijn persoonlijke agenda zal waarschijnlijk best een hoop op die van Joost lijken: veel Windows Phone, zeker na MIX met alle nieuwe aankondigingen. Een daadwerkelijke definitieve keuze maak ik waarschijnlijk zoals altijd pas op de dag zelf.

Tot in het World Forum in Den Haag!

Friday, March 11, 2011

#7slp = SevenSteps #wp7dev LAN Party

LAN Party kick-offYesterday I was at the Dutch Windows Phone 7 LAN party, "and all I got was this damn T-shirt." ;-)

It was a great day, in which the Dutch Windows Phone 7 developer community tried to come together with dozens of developers/designers to create a WP7 app from scratch. For some more information (including some killer images), please check out my description in Dutch or the English machine-translation made possible by a Google server farm.

Wednesday, March 2, 2011

Syntax highlighting is (finally!) back on this blog...

After recently changing the look of my blog not only did I lose my Google Analytics code from the template, but also the inclusion of Syntax Highlighter. I added analytics back earlier, but hadn't come round to putting source highlighting back into place. This has now been done, and all source code posted while highlighting was gone now has the needed brush class in place again. Hopefully this will make you enjoy reading code on this weblog even better.

Example code for SplitUp(), on infinite sequence! ;-)

I've received some positive reactions to my previous post, in which I gave source code of a lazy implementation of a SplitUp() function that could be used for paging an IEnumerable<T>.

However, I also got comments that example code on how you could use this would be nice. I had been thinking about that - also to show off exactly how the SplitUp() code is lazy and what actually happens if you use it - but decided to leave it out. That was mainly because I myself already knew; it just wasn't a goal of that previous blog post for me. Personally I'm not that much of a "need to see it work in an example" kind of guy, you know? Plus, blog posts take a bit of time. ;-)

Having said that, I can now give you this example, which should be self-explanatory if you run the following code in a console app project that includes the source from the previous blog code as well. Hope you enjoy it; as always all comments are welcome!

namespace SplitUpExample
{
  using System;
  using System.Linq;
  using System.Collections.Generic;
  using peSHIr.Utilities;

  class Program
  {
    static bool TraceDataCreation;
        
    static Action<string> println = text => Console.WriteLine(text);
    static Action<string> print = text => Console.Write(text);
    static Action newline = () => Console.WriteLine();

    static void Main(string[] args)
    {
      newline();
      println("* How can SplitUp() be used for paging");
      TraceDataCreation = false;
            
      var allData = TestData(64);
      var pagedData = allData.SplitUp(7);
      foreach (var page in pagedData)
      {
        print("Page:");
        foreach (int i in page)
        {
           print(" ");
           print(i.ToString());
        }
        newline();
      }

      newline();
      println("* And is it really lazy?");
      TraceDataCreation = true;
            
      println("Calling SplitUp() on infinite sequence now");
      var pagedInfinity = TestData().SplitUp(4);

      println("Retrieving first page now");
      var page1 = pagedInfinity.ElementAt(0);
            
      println("Retrieving third page now");
      var page3 = pagedInfinity.ElementAt(2);
            
      Action<string,int,int> results = (text,sum,count)
        => Console.WriteLine("{0}: {1}, {2}", text, sum, count);

      println("Showing results:");
      results("First page", page1.Sum(), page1.Count());
      results("Third page", page3.Sum(), page3.Count());
      println("So yes, SplitUp() is lazy like LINQ! ;-)");

#if DEBUG
      newline();
      println("(Key to quit)");
      Console.ReadKey();
#endif
    }

    static IEnumerable<int> TestData(int n)
    {
      return TestData().Take(n);
    }

    static IEnumerable<int> TestData()
    {
      // WARNING: this returns an infinite sequence!
      // Or at least: until int overflows... ;-)
      int i = 0;
      while (true)
      {
        if (TraceDataCreation)
          Console.WriteLine("Yielding {0}", i);
        yield return i++;
      }
    }

  }

}

Thursday, February 24, 2011

Example of C# lazy, functional programming: SplitUp()

I seem to be on a bit of roll here regarding extension methods. They are by no means a silver bullet, but this method is a nice LINQ-like lazy method on a generic sequence that is a perfect fit. I think it nicely illustrates how you can write your own such functional methods that are usable like LINQ methods that are part of the .NET framework, and have some of the same characteristics.

This SplitUp() extension method takes a sequence and splits it up into subsequences that each have a maximum length. For instance, you can split a sequence (list, collection, array, etc.) of 64 integers into an enumerable sequence of List<int> instances of lengths 10, 10, 10, 10, 10, 10 and 4 by calling SplitUp(10) on it.

Here is the source:

namespace peSHIr.Utilities
{
 using System;
 using System.Linq;
 using System.Text;
 using System.Collections.Generic;

 /// <summary>Utility code for working with sequences</summary>
 public static class SequenceUtility
 {
  /// <summary>Split up sequence of items</summary>
  /// <typeparam name="T">Item type</typeparam>
  /// <param name="input">Input sequence</param>
  /// <param name="n">Maximum number of items per sublists</param>
  /// <returns>Sequence of lists with a maximum
  /// of <paramref name="n"/> items</returns>
  /// <remarks>Might need a suppression of code analysis rule
  /// CA1006 because of the nested generic type in the method
  /// signature.</remarks>
  public static IEnumerable<IEnumerable<T>>
   SplitUp<T>(this IEnumerable<T> input, int n)
  {
   // Non-lazy error checking
   if (input == null) throw new ArgumentNullException("input");
   if (n < 1) throw new ArgumentOutOfRangeException("n", n, "<1");
   return SplitUpLazy(input, n);
  }

  private static IEnumerable<IEnumerable<T>>
   SplitUpLazy<T>(IEnumerable<T> input, int n)
  {
   // Lazy yield based implementation
   var list = new List<T>();
   foreach (T item in input)
   {
    list.Add(item);
    if (list.Count == n)
    {
     yield return list;
     list = new List<T>();
    }
   }
   if (list.Count > 0) yield return list;
   yield break;
  }
 }
}

As you can see, the SplitUp function behaves like built in LINQ functions because its implementation is split up (pun intented...). The public variant basically just does argument checking, so you get the ArgumentExceptions on improper use immediately when calling the method, while the private actual implementation uses yield statements to implement the actual splitting of the input sequence into lists of at most n elements.

This mirrors the implementation of LINQ methods, as shown in the very informative Edulinq blog series on their implementation by Jon Skeet, the so called superuser of stackoverflow.com.

I hope you find this extra illustration of this technique informative, or at least find the method itself useful. Personally I have used it for splitting up sequences of input records from a file into batches for processing by a web service that had a maximum request size. I would love to hear what you have used it for, so all comments are welcome.

(Added later: For those of you that like to have working pieces of example code to play with for code nuggets like this, please check out my next blog post.)

Wednesday, February 23, 2011

Safely set NumericUpDown control value

Very quick post about an extension method on the NumericUpDown control I once put to great use. It's small, quick, simple, needs the System.Windows.Forms and System namespaces, but can be of great use. Enjoy:

public static void SafeValue(this NumericUpDown c, decimal value)
{
   c.Value = Math.Max(c.Minimum, Math.Min(value, c.Maximum));
}

The principle will no doubt work on similar controls for WPF/Silverlight or other controls - like sliders - that at least have a value that is constrained by properties and might give exceptions if you try to set the value to an illegal value.