Archive for May, 2012

Multi-Armed Bandit in C#

After reading this fantastic blog post about how to do better than A/B testing (http://stevehanov.ca/blog/index.php?id=132), I decided to create an implementation of the algorithm in C#. As I already had a library dealing with statistical decision making on GitHub, I’ve added this functionality the nBayes library, which you can find here:

https://github.com/joelmartinez/nBayes – specifically, in the Optimization namespace.

I won’t reiterate the pros/cons, and explanation of this algorithm, as Steve does a fantastic job over on his blog … so I’ll just present the sample program I wrote to go along with it. This program uses the API to create three options (the same used in the blog post), and then proceeds to simulate users who prefer to act on one option, then partway (35%) through the exercise changing preference. And you can see how the algorithm correctly begins to primarily show the new choice about halfway through.

/// <summary>This sample program has 3 options, and will use the the optimizer
/// to run a test scenario. Two options are picked, and we will simulate user interest in one,
/// then user sentiment changing to favor the second option.</summary>
private static void TestOptimizer()
{
  var optimizer = new Optimizer();

  // define the available options
  Option[] options = new Option[] {
    Option.Named("Orange"),
    Option.Named("Green"),
    Option.Named("White")
  };
  optimizer.Add(options[0]);
  optimizer.Add(options[1]);
  optimizer.Add(options[2]);

  // pick two options, and define when user interest will change
  var firstWinner = options[2]; // white
  var secondWinner = options[1]; // green
  var switchRatio = .35f; // 35% of the way through the test set
  int tries = 100; // the test set

  for (int i = 0; i < tries; i++) {
    Option selected = optimizer.Choose().Result; // don't care about asyncrony in this particular example
    Console.WriteLine("Choosing: {0}", selected);

    // decide which chosen option 'the users' will prefer
    bool isFirstBatch = (float)tries * switchRatio > i;
    if (isFirstBatch && selected == firstWinner)
      firstWinner.IncrementSuccesses();
    else if (!isFirstBatch && selected == secondWinner)
      secondWinner.IncrementSuccesses();
  }

  Console.WriteLine("\nResults! We expect that ({0}) will have the highest success rate, and ({1}) will be in second place", secondWinner, firstWinner);
  Console.WriteLine("\nThis is the final result after {0} tries\n{1}", tries, optimizer);
}

There are multiple strategies to solve the ‘multi-armed bandit‘ problem. This particular implementation is using ‘Epsilon-Greedy’. It’s still early, and I have other ideas on how to structure the code in order to facilitate multiple strategies … but for now, let me know if you’ve got any thoughts or feedback on this bit of code. Thanks! :-)

Comments

DarkSky API Wrapper for C#

When I saw that the guys from Dark Sky were releasing an API, I knew I wanted to work with it. So I whipped up a quick C# API Wrapper for the DarkSky API.

You can find the project here on GitHub: https://github.com/joelmartinez/darksky-csharp

Currently supported platforms are: Windows Phone, iOS, and Android via MonoTouch/Mono for Android.

Usage is very simple:

using DarkSky;

...

var darksky = new DarkSky.Api(YOUR_API_KEY);
var orlando  = new Position { Latitude=28.5381f, Longitude=-81.3794f };
Task<FullForecast> response = darksky.Forecast(orlando);

response.ContinueWith(forecast => DisplayText(forecast.Result.HourSummary));
// displays something like "Rain starting in 3 Min, Stopping 30 Min Later"

Please let me know if you have any feedback either by opening an issue, emailing me, commenting on my blog, or forking the project and submitting a pull request.

Comments

The Problem with C# 5′s async/await Pattern

C# 5 brings a fantastic new feature … built-in asynchrony (not to be confused with concurrency). The compiler has added two new keywords, async and await, which allows your code to transparently change execution contexts. For example, instead of writing:

Task
  .StartNew(() => MakeSomeDecisionSlowly())
  .ContinueWith(result => ProcessResult(result));

You can simply say:

bool result = await MakeSomeDecisionSlowly();
ProcessResult(result);

While the two pieces of code are exactly equivalent, the second code is so much simpler to understand. Because you don’t really have to think about the fact that there is an asynchronous context switch going on, you are free to focus on your program’s logic, rather than worrying about manually orchestrating what tasks are doing what.

However, after using these features for several days while porting my KhanAcademy windows phone app to windows 8, I’ve come to approach them with a bit of caution. While they are great for low level IO-bound tasks, in my opinion they don’t scale well to higher level API design. A few things to watch out for:

If you use await somewhere in your code, then the containing method needs to be marked with the async keyword, and there are specific rules about return types. Namely, the method must either be void, or return Task<T>. For example, the example above would have to be in a method

public async void DoThatThing() { … }

Or, if you wanted to return the result of ‘MakeSomeDecisionSlowly’ back to the caller, it would have to look like this:

public async Task<bool> DoThatThing() { … }

Which is great, and all, but then it means that the calling method must be decorated with ‘async’ as well. If you are refactoring an existing codebase, this can have the effect of rippling up the inheritance chain with numerous (albeit small) changes … depending on the situation.

Ok, fine, maybe that’s not a huge deal; it’s kind of annoying but I can definitely deal with that kind of refactoring. The big problem I have with async/await is that outside of relatively trivial pieces of code, it can tend to wipe away many benefits of proper abstractions.

Let’s say you are implementing a remote API call, and you have several requirements:

  • Process the results if
    • You have a network connection (common mobile requirement)
    • The server is reachable (what if you’re connected at starbucks, but haven’t accepted the wifi’s terms of use?)
    • The server returns a code 200 (bugs happen)
    • The server indicates that your credentials are ok (what if the user’s password expired, or was changed by the user on your website?)
    • The server’s json response indicates a successful request
  • If any of the above conditions are false, notify the user of the problem (with specific text for the situation).

This is a very common scenario in any occasionally connected mobile application, and you can see that there are no less than five distinct decisions that need to be made during the course of an API call. If you use async/await blindly, you have two problems:

First, you are deferring these decisions to the caller … you’ll do a nice asynchronous call, and return a Task<string> with the json results; or if you’re sophisticated, a Task<T> with the results already parsed and converted to a strongly typed object. However, it’s up to the caller to handle exceptions, check for network connections, deal with individual response scenarios (logged out, invalid request, etc.). So you may end up with every call site looking like this:

if (HasConnection())
{
  try
  {
    MyObject result = await MakeRemoteAPICall();
    ProcessSuccessfulResult(result);
  }
  catch(Exception e)
  {
    ProcessError(e.Message);
  }
}
else
{
  ProcessError("No Connection");
}

Second, providing further abstractions is difficult because you are limited to a single return type. So if you want to handle all of the stated requirements for the caller, you will have to wrap up the result in a special return value that can provide some details to the user, such as ‘was it successful’, the error message if it wasn’t, and the parsed return value if it was. While the pros and cons of using error codes for return values have been debated for ages; I tend to prefer simpler return values for local APIs, since a complex return value adds an additional burden on the caller to know how to interpret the results. At best, every call site would look something like this:

Result<MyObject> value = await MakeRemoteAPICall();
if (value.WasSuccessful)
{
  ProcessSuccessfulResult(value.Result);
}
else
{
  ProcessError(value.ErrorMessage);
}

That’s a bit better than before, but still rather verbose for my taste.

I propose that the callback style of API design still has a place for situations like this. Consider the following sample:

MakeRemoteAPICall(
  result => ProcessSucessfulResult(result),
  error => ProcessError(error));

For the local consumer of this API, this is logically the same: if the call was successful do this, otherwise do that. But the caller doesn’t have to worry about all the nuances of deciding whether a call was successful or not. They can focus on how to process the results, rather than dealing with all of this ceremony. And after all, isn’t that what we’re all aiming to do, simplify our code?

I would love to hear thoughts about how this kind of code can be made even simpler. Would love to hear any opinions, for or against. Thanks!

edit: lively debate over on Reddit :) http://www.reddit.com/r/programming/comments/txhfq/the_problem_with_c_5s_asyncawait_pattern/

Comments (9)

Twilio-CSharp for MonoTouch and Android

I noticed that Twilio‘s official C# client didn’t have a version that you could use from MonoTouch and Mono for Android. So I took a few minutes, forked the project, and added some MonoDevelop projects so that you can compile for each of those two platforms.

The mono versions are using the silverlight version of the API, which uses async style methods where you pass in callbacks. There are two dependencies: RestSharp, and json.net. Though it looks like RestSharp has shed their dependency on json.net, there are still some references in the twilio code. The json.net project maintain mono specific versions … they depend on a portable library for that cross platform support. Unfortunately that means that you can’t compile it if you’re on a mac and only using monodevelop. Thankfully I found this helpful fork that did this work for me.

At the risk of  ‘pushing’ my pull request onto them, I submitted a pull request; But I made sure to word it such that I’m ok if they want to push back and ask for any changes … or maybe they don’t want to maintain a Mono version at all, in which case I’m happy to keep it in my fork. So we’ll see what happens. Please let me know if you have any feedback on this change.

As an aside, I also noticed while I was looking around github that many projects that have mono versions tend to use *.MonoTouch and *.MonoDroid for their project/solution names. It’s a subtle thing, but  Xamarin is careful not to refer to their product as MonoDroid, but Mono For Android. I wonder if this has to do with the trademarks that are owned by Lucasarts, if so I’d hate to wake up to a nice C&D in the mailbox ;)

Comments

Parse an iOS plist on Android

I was implementing a feature in the CalorieCount Android App the other day that was previously implemented in the iOS version of that same app. Just needed to show a list of timezones based on what country was selected. Not rocket science at all, but the iOS implementation was storing the data in a plist file, with a <dict> element inside. So rather than take that data and try to translate it to something more ‘android specific’ … I decided to just use the file as is. The biggest benefit was that in the future if we ever had to update the file, I could update it in place, and simply copy it over to the other platform.

So I copied the file into my xml folder, and wrote this simple parser that reads the file in, and parses it into a HashMap

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64
package cyborg;
 
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
 
import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;
 
import android.content.Context;
 
/**
* This class parses an iOS plist with a dict element into a hashmap.
*/
public class XmlMapParser {
private XmlPullParser parser;
 
public XmlMapVisitor(Context context, int xmlid) {
parser = context.getResources().getXml(xmlid);
}
 
public HashMap<String, ArrayList<String>> convert() {
HashMap<String, ArrayList<String>> map = new HashMap<String, ArrayList<String>>();
 
final String KEY = "key", STRING = "string";
try {
parser.next();
int eventType = parser.getEventType();
String lastTag = null;
String lastKey = null;
while (eventType != XmlPullParser.END_DOCUMENT) {
if (eventType == XmlPullParser.START_TAG) {
lastTag = parser.getName();
}
else if (eventType == XmlPullParser.TEXT) {
// some text
if (KEY.equalsIgnoreCase(lastTag)) {
// start tracking a new key
lastKey = parser.getText();
}
else if (STRING.equalsIgnoreCase(lastTag)) {
// a new string for the last encountered key
if (!map.containsKey(lastKey)) {
map.put(lastKey, new ArrayList<String>());
}
map.get(lastKey).add(parser.getText());
}
}
eventType = parser.next();
}
} catch (XmlPullParserException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
 
return map;
}
}
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>key1</key>
<array>
<string>one</string>
<string>two</string>
</array>
<key>key2</key>
<array>
<string>one</string>
<string>two</string>
</array>
</dict>
</plist>
view raw sample.plist This Gist brought to you by GitHub.

The way I look at it, may as well reuse what we’ve got, and spend less time yak shaving (ie. translating between platforms) … git ‘er done!

Comments