Visual Studio Achievements Buzz

January 26 2012

The project I’ve been working on recently finally shipped: Visual Studio Achievements.

It’s been great to see the reaction to it, including posts in Wired, Ars Technica, Life Hacker, BoingBoing, Gamasutra and more. It also sparked quite a discussion in Reddit and Slashdot. Here’s a list of all the buzz that the project has generated:

Microsoft Crossbreeds Programming Kit with Fantasy Game

Caleb Garling/Wired

January 24, 2012

http://www.wired.com/wiredenterprise/2012/01/visual-studio-achievements/

Coders, Motivate Yourself with Achievements

Logan Booker/Lifehacker Australia

January 21, 2012

http://www.lifehacker.com.au/2012/01/coders-motivate-yourself-with-achievements-for-visual-studio/

Microsoft Keeps It Old-School with a Pricey Text Adventure Game, Visual Studio 2010

Peter Bright/Ars Technica

January 20, 2012

http://arstechnica.com/microsoft/news/2012/01/microsoft-pimps-it-old-school-with-a-pricey-text-adventure-game.ars

Microsoft Text Adventure Game!

Rob Beschizza/BoingBoing

January 20, 2012

http://boingboing.net/2012/01/20/microsoft-text-adventure-game.html

Microsoft Turns Coding Into a game with New Visual Studio Plug-In

Matt Williams/Games.on.net

January 20, 2012

http://games.on.net/article/14709/Microsoft_Turns_Coding_into_a_Game_with_New_Visual_Studio_Plug-In

Microsoft to Make Programming Fun

David Stellmack/Fudzilla

January 20, 2012

http://www.fudzilla.com/index.php/home/item/25641-microsoft-to-make-programing-fun

Microsoft Corporation Adding Visual Studio

Rachael Brunelli/eMoneyDaily

January 20, 2012

http://www.emoneydaily.com/microsoft-corporation-nasdaqmsft-adding-visual-studio/69822708/

Microsoft Gamifies Visual Studio with Achievements

Mike Rose/Gamasutra

January 19, 2012

http://www.gamasutra.com/view/news/39717/Microsoft_gamifies_Visual_Studio_with_achievements.php

Microsoft Now Has Achievements for… Developers

Luke Plunkett/Kotaku

January 19, 2012

http://kotaku.com/5877391/microsoft-now-has-achievements-fordevelopers

Visual Studio Gets Achievements

Chris Duckett/TechRepublic

January 18, 2012

http://www.techrepublic.com/blog/australia/visual-studio-gets-achievements/572

Microsoft Adds Achievements to Visual Studio Software

Tom Bramwell/EuroGamer.net

January 19, 2012

http://www.eurogamer.net/articles/2012-01-19-microsoft-adds-achievements-to-visual-studio-software

Microsoft Adds Developer Achievements to Visual Studio

Nathan Brown/Edge

January 19, 2012

http://www.edge-online.com/news/microsoft-adds-developer-achievements-visual-studio

Visual Studio Achievements Program

Sue Gee/I Programmer

January 19, 2012

http://www.i-programmer.info/news/99-professional/3635-visual-studio-achievements-program.html

Microsoft Brings Achievements to Visual Studio

Earnest “Nex” Cavalli/ Escapist Magazine

January 19, 2012

http://www.escapistmagazine.com/news/view/115354-Microsoft-Brings-Achievements-To-Visual-Studio

Achievement Unlocked: Microsoft Gamifies Development

Craig Chapple/Develop

January 19, 2012

http://www.develop-online.net/news/39534/Achievement-unlocked-Microsoft-gamifies-development

Microsoft Adds Visual Studio Achievements for Developers

Laurentiu Stan/Social Barrel

January 19, 2012

http://socialbarrel.com/microsoft-adds-visual-studio-achievements-for-developers/30728/

Microsoft Announces Visual Studio Achievements Beta, A Pat on the Back for Dev

Ron/Winbeta

January 19, 2012

http://www.winbeta.org/news/microsoft-announces-visual-studio-achievements-beta-pat-back-devs

Visual Studio Achievements Program Brings Gamification to Development

Staff Writer/The Financial

January 19, 2012

http://finchannel.com/Main_News/Tech/102006_Visual_Studio_Achievements_Program_Brings_Gamification_to_Development/

Visual Studio Adds Game Mechanic to Keep Devs Engaged

Jason Cartwright/TechAU

January 19, 2012

http://www.techau.tv/blog/visual-studio-adds-game-mechanic-to-keep-devs-engaged/

Microsoft Introduces Xbox-like Achievements for Developers

Tom Warren/The Verge

January 18, 2012

http://www.theverge.com/microsoft/2012/1/18/2716215/xbox-achievements-badges-visual-studio-developers-gamification

The Coding Game: Microsoft’s Visual Studio Gets Badges, Achievements and Leaderboard

Todd Bishop/GeekWire

January 18, 2012

http://www.geekwire.com/2012/coding-fun-microsofts-visual-studio-badges-leaderboard

Channel9’s Visual Studio Achievements Now Available

Long Zheng/istartedsomething

January 18, 2012

http://www.istartedsomething.com/20120119/channel9s-visual-studio-achievements-now-available/

Microsoft Visual Studio Brings Gamification to App Development

Chris Burns/Slashgear

January 18, 2012

http://www.slashgear.com/microsoft-visual-studio-brings-gamification-to-app-development-18209774/

Microsoft Announces Visual Studio Achievements Beta

Pradeep Viswav/WMPoweruser

January 18, 2012

http://wmpoweruser.com/microsoft-announces-visual-studio-achievements-beta/

Microsoft Adds Achievements for Developers

Justin Rubio/IGN

January 18, 2012

http://www.ign.com/articles/2012/01/18/microsoft-adds-achievements-for-developers

Achievement Unlocked… For Developers

Paul Thurrott/Supersite for Windows

January 18, 2012

http://www.winsupersite.com/blog/supersite-blog-39/developer/achievement-unlocked-developers-141940

Microsoft Announces ‘Visual Studio Achievements’ for Developers

Simon LR/Techie Buzz

January 18, 2012

http://techie-buzz.com/microsoft/microsoft-announces-visual-studio-achievements-for-developers.html

Visual Studio Achievements, Now a Reality!

Rudi/While True Blog

January 18, 2012

http://blog.whiletrue.com/2012/01/visual-studio-achievements-now-a-reality/

Visual Studio Achievements Program Brings Gamification to Development

Staff Writer/Adafruit Industries Blog

January 18, 2012

http://www.adafruit.com/blog/2012/01/18/visual-studio-achievements-program-brings-gamification-to-development/

Visual Studio Achievements – The Beta Goes Live!

Alvin Ashcraft/Alvin Ashcraft’s Morning Dew

January 18, 2012

http://www.alvinashcraft.com/2012/01/18/visual-studio-achievements-the-beta-goes-live/

Visual Studio Achievements – Remember Kids They’re Just for Fun

Bill Simser/Fear and Loathing

January 18, 2012

http://weblogs.asp.net/bsimser/archive/2012/01/18/visual-studio-achievements-they-re-just-for-fun.aspx

Don’t Brag About Your Visual Studio Achievements! (Yet?)

Maarten Balliauw/Maarten Balliauw {blog}

January 18, 2012

http://blog.maartenballiauw.be/post/2012/01/18/Don%E2%80%99t-brag-about-your-Visual-Studio-achievements!-%28yet%29.aspx

Querying The Archivist API With JSON.NET

December 16 2011

Someone recently asked me for a sample of how to query The Archivist API to programmatically get a list of the top users of a given search term.

So I put a quick sample together, using the most excellent JSON.NET library’s LINQ provider for querying JSON. 

I used an archive on Wittgenstien.  To get the JSON that generated this chart, I simply append ?format=json to the URL, like this: http://archivist.visitmix.com/irhetoric/75/user?format=json  which results in the following response:

[{"Date":"\/Date(-62135596800000+0000)\/","Count":667.0,"Name":"lucasofri"},{"Date":"\/Date(-62135596800000+0000)\/","Count":439.0,"Name":"3PennyMovies"},{"Date":"\/Date(-62135596800000+0000)\/","Count":326.0,"Name":"quotemeal"},{"Date":"\/Date(-62135596800000+0000)\/","Count":260.0,"Name":"SiegenerZeitung"},{"Date":"\/Date(-62135596800000+0000)\/","Count":237.0,"Name":"lucasarrimada"},{"Date":"\/Date(-62135596800000+0000)\/","Count":236.0,"Name":"Double_bliss"},{"Date":"\/Date(-62135596800000+0000)\/","Count":175.0,"Name":"praashok"},{"Date":"\/Date(-62135596800000+0000)\/","Count":139.0,"Name":"PhilosophyQuotz"},{"Date":"\/Date(-62135596800000+0000)\/","Count":135.0,"Name":"NihilDeNada"},{"Date":"\/Date(-62135596800000+0000)\/","Count":132.0,"Name":"wilsonvoight"},{"Date":"\/Date(-62135596800000+0000)\/","Count":126.0,"Name":"imamrasyidi"},{"Date":"\/Date(-62135596800000+0000)\/","Count":117.0,"Name":"Iceburner"},{"Date":"\/Date(-62135596800000+0000)\/","Count":112.0,"Name":"emilsantosiii"},{"Date":"\/Date(-62135596800000+0000)\/","Count":111.0,"Name":"unwetterwarner"},{"Date":"\/Date(-62135596800000+0000)\/","Count":104.0,"Name":"LogicalAnalysis"},{"Date":"\/Date(-62135596800000+0000)\/","Count":102.0,"Name":"macondo83"},{"Date":"\/Date(-62135596800000+0000)\/","Count":93.0,"Name":"de_340513031"},{"Date":"\/Date(-62135596800000+0000)\/","Count":90.0,"Name":"neofibot"},{"Date":"\/Date(-62135596800000+0000)\/","Count":86.0,"Name":"hw1"},{"Date":"\/Date(-62135596800000+0000)\/","Count":83.0,"Name":"wirsiegen"},{"Date":"\/Date(-62135596800000+0000)\/","Count":82.0,"Name":"souvik_rt"},{"Date":"\/Date(-62135596800000+0000)\/","Count":79.0,"Name":"asmiather"},{"Date":"\/Date(-62135596800000+0000)\/","Count":76.0,"Name":"ogallardov"},{"Date":"\/Date(-62135596800000+0000)\/","Count":72.0,"Name":"pr0ject2501"},{"Date":"\/Date(-62135596800000+0000)\/","Count":71.0,"Name":"ggrigoriadis"}]

 

Here’s the program I wrote to parse this:

string json = string.Empty; using (WebClient webClient = new WebClient()) { json = webClient.DownloadString("http://archivist.visitmix.com/irhetoric/75/user?format=json"); } JArray result = JArray.Parse(json); foreach (JObject user in result) { Console.WriteLine((string)user["Name"] + " - " + (float)user["Count"]); } Console.ReadLine();

You can see how I simply pass the JSON to the static .Parse method hanging off the JArray class. If the root of the JSON wasn’t an array, I would have used the JObject.Parse() method. Once it is in the array, I can loop it and extract the values. You can also write LINQ queries using JSON.NET. For example, if I only wanted users whose tweet count was greater than 100, I could write this:

var greaterThan100 = from r in result where (float)r["Count"] > 100 select r; foreach (JObject user in greaterThan100) { Console.WriteLine((string)user["Name"] + " - " + (float)user["Count"]); }

Creating A Weighted Average User Defined Aggregate in StreamInsight 1.1

November 16 2011

I’ve been doing some prototyping StreamInsight lately and hit the following issue. I needed to write a weighted average so that I could roll up result sets.  Let me elaborate on the scenario.  I had a query whose HoppingWindow has a WindowSize of 1 minute.  One of the things the query returns is an average of one of the values returned by the event payload:

AvgLoadTime = win.Avg(e => e.LoadTime)

I then want to take all the results of that query and roll them up into a larger window of 1 hour. So that means writing a new query that uses the results of the first query for its calculation. But, if I were to simply take the average of the average, I’d get inaccurate results. What I need was the weighted mean.

To do so, I changed the code to look like this:

AvgLoadTime = win.Sum(e => e.AvgLoadTime * e.RecordCount)/win.Sum(e => e.RecordCount)

But when I deployed to StreamInsight 1.1 and got no love:

Microsoft.ComplexEventProcessing.Linq.QueryGenerationException: Expression '(e.Sum(e => (e.AvgLoadTime * Convert(e.RecordCount))) / Convert(e.Sum(e => e.RecordCount)))' contains more than one aggregate method call, which is not supported.

Doh. But then I got hip to user-defined aggregates. I found the documentation on this MSDN page essential and it helped me to write my extension, which looks like this:

public class WeightedAverage : CepAggregate<WqAggregate, double> { public override double GenerateOutput(IEnumerable<WqAggregate> win) { var AvgLoadTime = win.Sum(e => e.AvgLoadTime*e.RecordCount)/win.Sum(e => e.RecordCount); return AvgLoadTime; } } public static class ExtensionMethods { [CepUserDefinedAggregate(typeof(WeightedAverage))] public static double WeightedAvg(this CepWindow<WqAggregate> window) { throw CepUtility.DoNotCall(); } }

Where WqAggregate is just a class with the various fields that are returned as a result of my query.

So, I can now write this code:

AvgLoadTime = win.WeightedAvg()

Nice! I just had to deploy the .dll where I wrote the extension to the StreamInsight server and I was good to go. Now, with StreamInsight 1.2, the need to do this all goes away with but for now, this turns about to be a reasonable fix.

Dynamic Keyword and Dotfuscator = Very Unhappy

October 3 2011

I’ve been using Dotfuscator to obfuscate an assembly.  I thought all was good, but when I tried to use the obfuscate assembly, the assembly didn’t work like the unobfuscated one did and was throwing exceptions all over the place. After much debugging, I finally discovered that the use of the dynamic keyword was causing bigtime problems with Dotfucator.

Understanding what is going on with a simple sample is useful.  Say I have the following method to be obfuscated:

static void MyMethod() { int num = 1; int i = DoSomething(num); }

When obfuscated and then inspected in Reflector, here’s what it looks like:

private static void a() { int num = 1; int num2 = a(num); }

That’s what you’d expect.  But, now let’s say you change that method to use dynamic types instead of int. So it looks like this:

static void MyMethod() { dynamic num = 1; int i = DoSomething(num); }

When obfuscated and then disassembled in Reflector, here’s what you get:

private static void a() { object obj2 = 1; if (a.a == null) { a.a = CallSite<Func<CallSite, object, int>>.Create(Binder.Convert(CSharpBinderFlags.None, typeof(int), typeof(a))); } if (a.b == null) { a.b = CallSite<Func<CallSite, Type, object, object>>.Create(Binder.InvokeMember(CSharpBinderFlags.None, "DoSomething", null, typeof(a), new CSharpArgumentInfo[] { CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.IsStaticType | CSharpArgumentInfoFlags.UseCompileTimeType, null), CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.None, null) })); } int num = a.a.Target(a.a, a.b.Target(a.b, typeof(a), obj2)); }

Eek! Not only is it ugly as can be, look at how the method name DoSomething is passed as a  string to the InvokeMember method. But, DoSomething has been ofbuscated as a, so the assembly no longer has any notion of the DoSomething name for that method.

I’m not the only one who’s hit this as you can see from this post in the Dotfuscator forums.  Unfortunately, I couldn’t find a workaround other than removing the use of the dynamic keyword.

Table Storage, Continuation Tokens, Windows Azure

September 8 2011

By default, queries to table storage will return a maximum of 1000 rows, whether you are using the REST APIs or the LINQ provider.  If you want more rows, you need to get fancy.

It’s pretty easy.  Let’s say you have created some data access classes similar to how the Azure Hands On Labs and samples encourage you to do so. 

So say you’ve got a class that inherits from TableServiceContext that looks like this:

class RawDataContext : TableServiceContext { public RawDataContext (string baseAddress, StorageCredentials credentials) : base (baseAddress,credentials) { } public IQueryable<RawEntity> RawEntity { get { return this.CreateQuery<RawEntity>("RawEntity"); } } }

Well, you are going to want to change that, so your data context returns a CloudTableQuery instead.  So, now, your class should look like this:

class RawDataContext : TableServiceContext { public RawDataContext (string baseAddress, StorageCredentials credentials) : base (baseAddress,credentials) { } public CloudTableQuery<RawEntity> RawEntity { get { return this.CreateQuery<RawEntity>("RawEntity").AsTableServiceQuery(); } } }
Notice how the CreateQuery method has been appended with the AsTableServiceQuery() extension method. Notice also that the return type is CloudTableQuery instead of IQueryable.

But that’s not all. You’ll also need to make some changes when you issue your queries.  So, for example, say you have a DataSource class with a select query that looks like this:

public class RawDataSource { private static CloudStorageAccount storageAccount; private RawDataContext context; public RawDataSource() { storageAccount = CloudStorageAccount.FromConfigurationSetting("StorageConnection"); this.context = new RawDataContext(storageAccount.TableEndpoint.AbsoluteUri, storageAccount.Credentials); } public List<RawEntity> Select(string site) { var results = (from g in this.context.RawEntity where g.PartitionKey == site select g).ToList(); return results; } }

You’ll need to change that query such that it issues the Execute method off the CloudTableQuery result, like this:

public List<RawEntity> Select(string site) { var results = (from g in this.context.RawEntity.Execute() where g.PartitionKey == site select g).ToList(); return results; }

By adding the Execute method, the query will issue the continuation token on your behalf to Azure and concatenate the data to the result set, returning > 1000 rows.