Carolina Code Camp 2014

05 May

Carolina Code Camp Logo

Last Saturday I attended my first local code camp since moving to Asheville: Carolina Code Camp. This event is held annually in the Charlotte area. It is presented by the Enterprise Developers Guild and held in a wonderful facility at the Levine Campus of Central Piedmont Community College.


The organization and energy of the event impressed, and the attendees were very engaged. I look forward to participating in future events.

I presented two sessions; the slides and code are available below.

Unlocking the Power of Object-Oriented C#

Slides (10 MB)

Code (838 K)

Data-Driven UIs in XAML Applications

Slides (2 MB)

Code (8.25 MB)

As usual, no warranty is provided, express or implied.

Attendees, please feel free to contact me if you have any questions about the demo code (jay at codequota dot com).

posted @ Monday, May 05, 2014 11:23 PM | Feedback (2)

Orlando Code Camp 2014

22 Mar

The quota is established: Orlando Code Camp slides and code once a year.

A great event, as always; a lot of talented presenters. My own presentation on data-driven UIs was a new one and I look forward to presenting this session again with some refinements.

Data-Driven UIs in XAML Applications

Slides (3.3 MB)

Code (8.2 MB - contains images)


As usual, no warranty is provided, express or implied.
The slide deck is not likely to be useful outside of the presentation context. The code does contain some interesting bits, in particular the expression-based generic view-models and fast-reflection extensions. Also of possible use the are the dynamic forms, based on JSON definitions, for exposing/configuring new backend features without redeploying.
posted @ Saturday, March 22, 2014 4:31 PM | Feedback (0)

Orlando Code Camp 2013 Presentations

16 Mar

The great people behind the Orlando .NET User Group (ONETUG) put on another terrific Orlando Code Camp event today. A host of really talented speakers from the local area and all around North America presented on a great array of topics.

I was pleased to have the opportunity to deliver two presentations, and will be attaching the slides and source code below by tomorrow. Please feel free to contact me if you are looking for any additional information or resources from the talk.

If you attended either talk and can take a minute to rate it or leave a comment, please do so at SpeakerRate.


Unlocking the Power of Object-Oriented C#

Slides (9.2 MB)

Code (785 KB)

Keyboard Fu & Automation Zen

Slides (5.4 MB)

posted @ Saturday, March 16, 2013 4:39 PM | Feedback (0)

ONETUG Supports GiveCamp Orlando

28 Oct

Our inaugural GiveCamp event in 2011 was part of "[Inter-]National GiveCamp," where 16 GiveCamps across the US and UK were held over the same weekend, and we received a lot of support from Microsoft and national sponsorships arranged through Microsoft and GiveCamp.org.

There are a lot of GiveCamps happening again in October this year, including ours and another 4 this weekend, but there is no coordinated effort to secure sponsorship on a collective level.

Our planning committee--Richard Salogub, in particular--has been working hard to pick up that slack by seeking support from both local businesses and national brands. We have been fortunate to receive the support of many businesses in the form of prizes for our volunteers, as well as financial sponsorship from CenturyLink, Telerik, ComponentOne, and AgileThought, and food donations from Miller's Ale House, Cold Stone Creamery, and Dunkin' Donuts (all on University Boulevard).

Our greatest source of support, however, has been a local resource: the Orlando .NET User Group. ONETUG is committed as an organization to supporting and growing the developer community in Central Florida, and has made a huge impact in our ability to pull off the GiveCamp event.

ONETUG logo

I have been a professional developer for 5 years now, and have been a regular attendee of ONETUG's monthly meetings at Orlando City Hall for almost as long. My professional path has been shaped in profound ways by my attendance at a few key presentations at ONETUG. In fact, I now work on a team with one of those presenters -- a position that I found through ONETUG's job page.

I want to personally thank the board of ONETUG (several of whom are already very involved in GiveCamp planning and execution) for their support of GiveCamp and the community at large.
posted @ Sunday, October 28, 2012 1:17 PM | Feedback (0)

GiveCamp.Orlando Returns October 26-28 2012

08 Aug

GiveCamp logo

Our 2nd annual GiveCamp.Orlando event is slated for October 26-28, 2012. We are fortunate to again be hosted by Full Sail University.

If you missed GiveCamp last year, or aren't sure what GiveCamp is all about, we have all the information you need at http://givecamporlando.org.

Basically, it is an opportunity for you as a designer, developer or other technology professional to use your skills to give back -- supporting local non-profits by developing top-notch custom solutions that help them achieve their missions.

Keep up-to-date by following us on Twitter and Facebook.
posted @ Wednesday, August 08, 2012 12:57 AM | Feedback (0)

Western North Carolina .NET Developers Guild

29 Jul

I had the privilege to visit with and present to the Western North Carolina .NET Developer's Guild this month during a vacation in Asheville.

I'd like to thank Tracy and everyone at WNC for their hospitality and the opportunity.

If you attended the presentation and would like any of the demo code, please send me an E-mail and I'll be happy to provide it: jay at codequota dot com.
posted @ Sunday, July 29, 2012 3:33 PM | Feedback (0)

Slides and Code from Orlando Code Camp 2012

01 Apr

My friend, Patrick Roeper, and I presented "Taking Control of WCF" yesterday at Orlando Code Camp 2012.

For those who attended, thank you! We hope you got something useful out of it, and that the concepts will help you start fighting back.

To the guy who said "restart Visual Studio!" when we had difficulty with our first demo solution, you were right. I reopened that solution afterward and added those service references without a hitch.

If you have any feedback you'd like to leave on the presentation, I'll appreciate your rating and comments on SpeakerRate.

Without further ado, the slides and code:
Taking Control of WCF Slide Deck (1.2 MB)
Taking Control of WCF Demo Code (187 KB)

We've plugged in a bit of dummy data (AdventurePerksDataContext) to remove the dependency of having an AdventureWorks SQL database running, and have turned off the Audit feature. If you turn on Auditing (via Audit=true when applying the ServiceExtensionsAttribute), audit records will be written to c:\wcfaudit.txt.

As Patrick mentioned, this code was written for demonstration purposes, to show how you can understand and take control of the communication framework using design principles with which you are already familiar. It is neither intended nor recommended for a production environment. It would probably get you fired.
posted @ Sunday, April 01, 2012 12:11 PM | Feedback (0)

Readable bool

16 Mar

The advent of .NET 4.0 has meant good things for code readability by way of named parameters. For all but the least motivated among us, obscure things like:

var employee = new Employee("John Doe", 23, true, false);

can become

var employee = new Employee(
    name: "John Doe",
    age: 23,
    isActive: true,
    isExempt: false);

Now we know exactly what we are doing when we pass those cryptic values, especially the booleans.

I work on a project that interfaces with a handful of external APIs, each with slightly different capabilities. These external providers are finite in number, and any change to the supported providers or capabilities of those providers requires some work in one or more translation modules, so we are not concerned with having the capabilities of each provider data-driven. Given these conditions, we define capabilities in code, passing in a value for each API provider capability as we construct the Provider object.

Important to note is that this class became not only a way to programmatically inspect the capabilities of a given API provider, but a human-readable reference document for looking up the capabilities of each provider when questions arose.

At first, it looked something like this:

FooProvider = new ApiProvider("Foo", true, false);
BarProvider = new ApiProvider("Bar", false, false);
BazProvider = new ApiProvider("Baz", true, true);

We could easily see from the constructor for ApiProvider that the first boolean parameter corresponded to canCancel and the second to canUpdate.

As we implemented support for more API providers, however, the number of nuances increased and the capabilities list increased as well. Time for named parameters.

FooProvider = new ApiProvider("Foo", canCancel: true, canUpdate: false, canReplayFeed: false, canLock: false);
BarProvider = new ApiProvider("Bar", canCancel: false, canUpdate: true, canReplayFeed: false, canLock: true);
BazProvider = new ApiProvider("Baz", canCancel: true, canUpdate: true, canReplayFeed: true, canLock: false);
FunkProvider = new ApiProvider("Funk", canCancel: true, canUpdate: true, canReplayFeed: true, canLock: false);

The named parameters help, but things are starting to get out of hand. We could break each capability out into its own line, but then it becomes difficult to compare the capabilities of each API provider, because each is separated by a considerable number of lines of code.

To mitigate this, we started by declaring constant bool members--all true--for each capability.

private const bool CanCancel = true;
private const bool CanUpdate = true;
private const bool CanReplayFeed = true;
private const bool CanLock = true;

We then passed these values in to our constructor instead of using named parameters, negating the value where the capability is not supported:

FooProvider = new ApiProvider("Foo", CanCancel, !CanUpdate, !CanReplayFeed, !CanLock);
BarProvider = new ApiProvider("Bar", !CanCancel, CanUpdate, !CanReplayFeed, CanLock);
BazProvider = new ApiProvider("Baz", CanCancel, CanUpdate, CanReplayFeed, !CanLock);
FunkProvider = new ApiProvider("Funk", CanCancel, CanUpdate, CanReplayFeed, !CanLock);

The effect is somewhat cleaner, and gives a relatively clear view of the capabilities of each provider.

This can be further enhanced by putting meaningful comments on each of the "readable bool" constants to give some hints via Intellisense:

a tool-tip shows more information about the meaning of the capability setting

This is a technique to pass meaningfully named bool arguments with or without .NET 4.0, optionally with some additional, descriptive metadata.

As when passing unnamed boolean arguments, however, it is critical that the values be ordered properly: there is no constraint against passing CanReplayFeed as the canCancel argument, for example.


tags: ,
posted @ Friday, March 16, 2012 1:06 AM | Feedback (0)

Secretly Sequential if-Blocks

14 Feb

There is a class of algorithm that always just feels off in its implementation, which typically takes the shape of a sequence of if blocks. In some cases, each subsequent if statement has to re-examine what happened in the previous.

As an example, consider the requirement to display a DateTime or TimeSpan in the format "11h 3m 55s", where no hour is displayed when the number of hours is 0 ("15m 9s"), no minutes displayed when the number of minutes is 0 ("59s") and nothing displayed if there are no seconds, except that if any of the preceding values is non-zero, we display subsequent values even if zero ("2h 0m 0s").

Definitely manageable, but not as straightforward as we'd like:

public static string FormatDisplayTime(DateTime time)
{
  var stringBuilder = new StringBuilder();

  var hasHours = time.Hour > 0;
  if (hasHours)
  {
    stringBuilder.Append(time.Hour).Append("h ");
  }

  var hasMinutes = time.Minute > 0;
  if (hasHours || hasMinutes)
  {
    stringBuilder.Append(time.Minute).Append("m ");
  }

  if (hasHours || hasMinutes || time.Second > 0)
  {
    stringBuilder.Append(time.Second).Append("s");
  }

  return stringBuilder.ToString();
}

 

Secretly sequential

The interesting thing about this--and it isn't immediately obvious--is that we are secretly dealing with a sequence.

I use the term "secretly sequential" lightly. It is natural that any series of if-blocks is crafted as a sequence -- the boolean logic simply doesn't work otherwise. What I'm talking about here are cases where the subjects of those if-blocks can actually be re-framed as a sequence.

So, we have 3 items in our sequence (hours, minutes, seconds), and we want to skip items until we find one that is non-zero. From that point on, we will print all items regardless of value.

Wow - this sounds like a job for LINQ.

 

Enter LINQ

We will have to restructure the problem as a sequence, though:

public static string FormatDisplayTime(DateTime dateTime)
{
  var dateParts = new Dictionary<string, int>
    {
      {"h ", dateTime.Hour},
      {"m ", dateTime.Minute},
      {"s", dateTime.Second}
    };
  return dateParts
    .SkipWhile(x => x.Value == 0)
    .Aggregate("", (s, x) => s + x.Value + x.Key);

In a nutshell, we set up our values and just skip over them until we find one with a non-zero value. From then on, we concatenate the value and the "h", "m", or "s" until we have gone over all items in the sequence and have our fully constructed time format.

 

Concatenation? What about StringBuilder?

You can use StringBuilder with Aggregate; it just gets a bit long-winded for my taste:

return dateParts
  .SkipWhile(x => x.Value == 0)
  .Aggregate(new StringBuilder(),
    (sb, x) => sb.Append(x.Value).Append(x.Key),
    sb => sb.ToString());

 

What about performance?

As you might expect, the cost of instantiating the Dictionary<TKey, TValue> outweighs the multiple evaluations in the "normal" implementation. At reasonable volume, the difference is indiscernible to negligible, but at 1 million consecutive invocations the difference is pronounced.

This is a not-uncommon tradeoff when using LINQ: sacrifice a bit of performance in favour of brevity, clarity and maintainability.

 

In conclusion

Whether you feel the LINQ solution is appropriate, better, or utter nonsense, I think it is a valuable exercise to recognize that some algorithms are "secretly sequential" and may lend themselves to being re-framed and solved as sequences.


tags: , ,
posted @ Tuesday, February 14, 2012 5:19 PM | Feedback (2)

Iterator Blocks and Side Effects

13 Feb

Sometimes leveraging side-effects in methods or even properties seems like a clever way to keep our code concise, but this often results in bugs and almost always comes at the cost of maintainability.

Avoiding side effects is especially important in the context of iterator blocks.

Consider the following method:

public IEnumerable<Customer> GetOrLoad(IEnumerable<int> customerIds)
{
    foreach (var id in customerIds)
    {
        Customer found = null;
        if(!_innerCache.TryGetValue(id, out found))
        {
            found = PerformLookup(id);
            _innerCache.Add(id, found);
        }

        yield return found;
    }
}


To a caller, this method just returns IEnumerable<Customer>; there is no immediate indicator that the method is implemented as an iterator block (using the yield keyword). The signature of the method suggests that we are dealing with a cache of Customer objects, keyed on an int identifier, and that if we pass in some IDs they'll either be returned from the cache or else some kind lookup will be performed and the result will then be cached.

On the one hand, the naming is decent: "GetOrLoad" gives us a clue that we aren't just drawing from the cache -- that we might be loading some data. However, that same hint suggests that we could use the same method as a means of loading items into the cache.

So, we do some work when the application is initializing in order to prime the cache:

public void PreloadCustomerCacheForSalesPerson(SalesPerson salesPerson)
{
    _cache.FindOrLookup(salesPerson.CustomerIds);
}

We know that the GetOrLoad() method is going to look up any values not already in cache, and add them. We aren't concerned here with the Customer objects that the method will return.

The problem is that we've gone through all this work to prime the cache for our salespeople, but the cache is still completely empty.

We were relying on the knowledge that this method will look up Customers that aren't already cached, but because the method is implemented as an iterator (therefore lazy-evaluated) and we never iterate over the result set, the body of the GetOrLoad() method is never invoked.

tags: , ,
posted @ Monday, February 13, 2012 6:14 PM | Feedback (0)