Fix image URLs to relative paths, add code block fencing

This commit is contained in:
2026-05-10 02:57:23 +00:00
parent 71da91c571
commit d42561616f
16 changed files with 547 additions and 187 deletions
+5 -2
View File
@@ -6,16 +6,19 @@ published: true
---
Hi, Im James Kolpack, and Im a code-aholic.
#### Where Im from
Ever since I was a kid Ive been programming at various degrees of sophistication.  Being a child of the 80s, I started with Basic (of the [GW variety](http://en.wikipedia.org/wiki/GW-BASIC) on a [8086 based IBM](http://en.wikipedia.org/wiki/IBM_Personal_System/2)) with a dash of [Logo](http://en.wikipedia.org/wiki/Logo_%28programming_language%29) and [batch scripting](http://en.wikipedia.org/wiki/Batch_file).  Later in college I became learned in [Pascal](http://en.wikipedia.org/wiki/Pascal) and then [C](http://en.wikipedia.org/wiki/C_%28programming_language%29) and the trials and tribulations of [memory management](http://en.wikipedia.org/wiki/Malloc) and [complex data structures](http://en.wikipedia.org/wiki/Tree_%28data_structure%29).  I loved the ability to solve interesting problems by the clever assembly of instructions to be executed on a computer.  It was a bit of a power trip, really - “Pow, I just made a program that can find the optimal combination of items to fill a [knapsack in psuedo-polynomial time](http://en.wikipedia.org/wiki/Knapsack_problem#Dynamic_programming_solution).”  This capability does not, I discovered, transcend one-to-one to “real-world” power but youve got to [![LegoMan_bigger](http://popcyclical.com/content/binary/WindowsLiveWriter/Introducing_90B9/LegoMan_bigger_thumb.png)](http://popcyclical.com/content/binary/WindowsLiveWriter/Introducing_90B9/LegoMan_bigger_2.png)do what you can with what youve got.
Ever since I was a kid Ive been programming at various degrees of sophistication.  Being a child of the 80s, I started with Basic (of the [GW variety](http://en.wikipedia.org/wiki/GW-BASIC) on a [8086 based IBM](http://en.wikipedia.org/wiki/IBM_Personal_System/2)) with a dash of [Logo](http://en.wikipedia.org/wiki/Logo_%28programming_language%29) and [batch scripting](http://en.wikipedia.org/wiki/Batch_file).  Later in college I became learned in [Pascal](http://en.wikipedia.org/wiki/Pascal) and then [C](http://en.wikipedia.org/wiki/C_%28programming_language%29) and the trials and tribulations of [memory management](http://en.wikipedia.org/wiki/Malloc) and [complex data structures](http://en.wikipedia.org/wiki/Tree_%28data_structure%29).  I loved the ability to solve interesting problems by the clever assembly of instructions to be executed on a computer.  It was a bit of a power trip, really - “Pow, I just made a program that can find the optimal combination of items to fill a [knapsack in psuedo-polynomial time](http://en.wikipedia.org/wiki/Knapsack_problem#Dynamic_programming_solution).”  This capability does not, I discovered, transcend one-to-one to “real-world” power but youve got to [![LegoMan_bigger](../media/WindowsLiveWriter/Introducing_90B9/LegoMan_bigger_thumb.png)](../media/WindowsLiveWriter/Introducing_90B9/LegoMan_bigger_2.png)do what you can with what youve got.
As for the name of the blog, “popcyclical”, its a dual homage to my interest in cyclical relationships and, of course, popsicles.  It also references my moniker “poprhythm” which I was given many years ago for my ever-loving devotion to excellent music.
#### Where Im going
On this blog I will be exploring ideas and issues that are relevant to me at the given time.  As a developer employed at a small shop, [![100px-Directed_graph_with_back_edge.svg](http://popcyclical.com/content/binary/WindowsLiveWriter/Introducing_90B9/100px-Directed_graph_with_back_edge.svg_thumb_1.png)](http://popcyclical.com/content/binary/WindowsLiveWriter/Introducing_90B9/100px-Directed_graph_with_back_edge.svg_4.png)the focus is guaranteed to wander over time.  For any given week, I may be highly invested in any number of   topics.  This may include : [upcoming features](http://msdn.microsoft.com/en-us/library/dd264736%28VS.100%29.aspx) of programming languages, [graph algorithm design and application](http://www.codeplex.com/quickgraph/), [development tooling](http://www.jetbrains.com/resharper/), [data mining](http://en.wikipedia.org/wiki/Data_mining), [system architecture](http://martinfowler.com/books.html), [user experience](http://mitpress.mit.edu/catalog/item/default.asp?tid=5393&ttype=2), [natural language processing](http://opennlp.sourceforge.net/), [semantic web](http://en.wikipedia.org/wiki/Semantic_Web), [test driven development](http://en.wikipedia.org/wiki/Test-driven_development), [statistics](http://www.r-project.org/), [data management](http://en.wikipedia.org/wiki/Database), … these and many others are all fair game.  As of today, the technologies Im working in from day to day are [C#](http://msdn.microsoft.com/en-us/vcsharp/aa336809.aspx) on the [.NET](http://www.microsoft.com/NET/) framework, [ASP.NET MVC](http://www.asp.net/%28S%28d35rmemuuono1wvm1gsp2n45%29%29/mvc/) and [jQuery](http://jquery.com/), [WCF](http://msdn.microsoft.com/en-us/netframework/aa663324.aspx), and a [variety](http://www.microsoft.com/sqlserver/2008/en/us/default.aspx) of [database](http://www.oracle.com/database/berkeley-db/xml/index.html) [engines](http://www.mysql.com/).
On this blog I will be exploring ideas and issues that are relevant to me at the given time.  As a developer employed at a small shop, [![100px-Directed_graph_with_back_edge.svg](../media/WindowsLiveWriter/Introducing_90B9/100px-Directed_graph_with_back_edge.svg_thumb_1.png)](../media/WindowsLiveWriter/Introducing_90B9/100px-Directed_graph_with_back_edge.svg_4.png)the focus is guaranteed to wander over time.  For any given week, I may be highly invested in any number of   topics.  This may include : [upcoming features](http://msdn.microsoft.com/en-us/library/dd264736%28VS.100%29.aspx) of programming languages, [graph algorithm design and application](http://www.codeplex.com/quickgraph/), [development tooling](http://www.jetbrains.com/resharper/), [data mining](http://en.wikipedia.org/wiki/Data_mining), [system architecture](http://martinfowler.com/books.html), [user experience](http://mitpress.mit.edu/catalog/item/default.asp?tid=5393&ttype=2), [natural language processing](http://opennlp.sourceforge.net/), [semantic web](http://en.wikipedia.org/wiki/Semantic_Web), [test driven development](http://en.wikipedia.org/wiki/Test-driven_development), [statistics](http://www.r-project.org/), [data management](http://en.wikipedia.org/wiki/Database), … these and many others are all fair game.  As of today, the technologies Im working in from day to day are [C#](http://msdn.microsoft.com/en-us/vcsharp/aa336809.aspx) on the [.NET](http://www.microsoft.com/NET/) framework, [ASP.NET MVC](http://www.asp.net/%28S%28d35rmemuuono1wvm1gsp2n45%29%29/mvc/) and [jQuery](http://jquery.com/), [WCF](http://msdn.microsoft.com/en-us/netframework/aa663324.aspx), and a [variety](http://www.microsoft.com/sqlserver/2008/en/us/default.aspx) of [database](http://www.oracle.com/database/berkeley-db/xml/index.html) [engines](http://www.mysql.com/).
#### I can use your help
@@ -10,15 +10,15 @@ Interacting with your computer using a mouse-driven GUI makes many tasks quick a
**Its a matter of keeping up with your thoughts**. Suppose some series of tasks takes 20 seconds with a mouse but you can accomplish the same tasks in 12 seconds using the keyboard. The big deal isnt that youve saved 8 seconds; the big deal is that youre more likely to finish your tasks before you lose the thought that motivated them.
I interact with the[![Tilda - Console Launcher Hot Key](http://popcyclical.com/content/binary/images/ConsoleLauncherHotKeyTilda_66F3/tilda_console_thumb.png)](http://popcyclical.com/content/binary/images/ConsoleLauncherHotKeyTilda_66F3/tilda_console.png) file system on a very regular basis.  I havent measured this, but I bet Ill open Windows Explorer (or [xplorer²](http://www.zabkat.com/)) at least two or three times for every hour Im at the computer.  Im forever poking around for documents and restructuring directories so that theyll be easier to find next time.  Many times Ill want to execute a command line statement in the path that Im browsing.  There are [several](http://www.burgaud.com/open-command-window-here/) [different](http://www.microsoft.com/windowsxp/downloads/powertoys/xppowertoys.mspx) [strategies](http://code.kliu.org/cmdopen/) for getting a “Open Command Prompt Here” to the explorer context menu, but they all require a right-click (or [simulating one with the keyboard](http://www.ehow.com/how_8219_click-using-keyboard.html)).  Theres an easier way.
I interact with the[![Tilda - Console Launcher Hot Key](../media/images/ConsoleLauncherHotKeyTilda_66F3/tilda_console_thumb.png)](../media/images/ConsoleLauncherHotKeyTilda_66F3/tilda_console.png) file system on a very regular basis.  I havent measured this, but I bet Ill open Windows Explorer (or [xplorer²](http://www.zabkat.com/)) at least two or three times for every hour Im at the computer.  Im forever poking around for documents and restructuring directories so that theyll be easier to find next time.  Many times Ill want to execute a command line statement in the path that Im browsing.  There are [several](http://www.burgaud.com/open-command-window-here/) [different](http://www.microsoft.com/windowsxp/downloads/powertoys/xppowertoys.mspx) [strategies](http://code.kliu.org/cmdopen/) for getting a “Open Command Prompt Here” to the explorer context menu, but they all require a right-click (or [simulating one with the keyboard](http://www.ehow.com/how_8219_click-using-keyboard.html)).  Theres an easier way.
A couple years ago I read an article on [instructables](http://www.instructables.com) about a [“Drop Down”, Quake-style command prompt for Windows](http://www.instructables.com/id/%22Drop-Down%22%2c-Quake-style-command-prompt-for-Window/).  The project uses [AutoHotKey](http://www.autohotkey.com/) to launch and hide a console window using a keyboard shortcut.  Neat!  It works great, except that it always dumps you in the your %HOMEPATH%.  Ive taken the script and upgraded it to navigate directly to the currently open path in Windows Explorer its name is **Tilda**.
For example Ive got an explorer window open in C:\console\UnxUtils\usr\local\wbin and I want to string some of those juicy unix command line utilities together.  I can now simply do **Win**+**~**, and Ive got a new console instance in the right place.  As with the original, it will minimize/maximize the console window on subsequent usage of the key combination. 
For example Ive got an explorer window open in `C:\console\UnxUtils\usr\local\wbin` and I want to string some of those juicy unix command line utilities together.  I can now simply do **Win**+**~**, and Ive got a new console instance in the right place.  As with the original, it will minimize/maximize the console window on subsequent usage of the key combination. 
I have this nasty habit of navigating around the file system when Im using Windows Explorer.  After running some unix commands, I might have a hankering to run MSBuild.exe (ok, probably not, but who knows?).  I could tediously type the path, or, I could have Tilda automatically enter it for me.  From the new path in Windows Explorer, I type a combination **Win**+**Shift**+**~** and the chdir command gets sent to the current console window.[![Tilda - chdir](http://popcyclical.com/content/binary/images/ConsoleLauncherHotKeyTilda_66F3/tilda_chdir_thumb.png)](http://popcyclical.com/content/binary/images/ConsoleLauncherHotKeyTilda_66F3/tilda_chdir.png)
I have this nasty habit of navigating around the file system when Im using Windows Explorer.  After running some unix commands, I might have a hankering to run MSBuild.exe (ok, probably not, but who knows?).  I could tediously type the path, or, I could have Tilda automatically enter it for me.  From the new path in Windows Explorer, I type a combination **Win**+**Shift**+**~** and the `chdir` command gets sent to the current console window.[![Tilda - chdir](../media/images/ConsoleLauncherHotKeyTilda_66F3/tilda_chdir_thumb.png)](../media/images/ConsoleLauncherHotKeyTilda_66F3/tilda_chdir.png)
Please note that Im using (and recommend) [Console](http://sourceforge.net/projects/console/) as a command line window host.  **Tilda** is currently set to use this, but the script can be easily modified to use cmd.exe or whichever console window host you prefer.
Please note that Im using (and recommend) [Console](http://sourceforge.net/projects/console/) as a command line window host.  **Tilda** is currently set to use this, but the script can be easily modified to use `cmd.exe` or whichever console window host you prefer.
**Tilda **- open and close a console window using a hot key.  Automatically navigates to the currently open explorer window.  Save some trips to the mouse and make getting to the command line easier.
@@ -7,24 +7,35 @@ published: true
I was recently tasked to add server-and-client-side form validation for an ASP.NET MVC site - which already uses in-place editing courtesy [Jeditable](http://www.appelsiini.net/projects/jeditable).  I really like the field editing experience that Jeditable provides it makes form entry in the browser interactive, is fairly straightforward to integrate, and its adaptable to many scenarios.  It does not, however, have any validation mechanism built in. 
Our project already used [jQuery Validate](http://bassistance.de/jquery-plugins/jquery-plugin-validation/) for a few forms by using the HTML class definitions like adding class=”required phone” to an INPUT element.  This works great, but doesnt provide any server-side validation tie-in.
Our project already used [jQuery Validate](http://bassistance.de/jquery-plugins/jquery-plugin-validation/) for a few forms by using the HTML class definitions like adding `class=”required phone”` to an `INPUT` element.  This works great, but doesnt provide any server-side validation tie-in.
Earlier this year, I remembered having seen a [presentation](http://speakerrate.com/talks/1218-useful-jquery-tips-tricks-and-plugins-with-asp-net-mvc) by [Elijah Manor](http://elijahmanor.com/) who mentioned using [xVal](http://xval.codeplex.com/) for robust server and client side validation. And with the news that [MVC 2 will have a built in validation technique similar to xVal](http://haacked.com/archive/2009/10/01/asp.net-mvc-preview-2-released.aspx), it was an easy decision to start investigating this library.
[xVal](http://xval.codeplex.com/) is a pretty easy to get integrated.  The first step is to decorate the model with validation rules Ive decided to use .NET frameworks [DataAnnotations](http://msdn.microsoft.com/en-us/library/system.componentmodel.dataannotations.aspx), which ends up looking like:public class ValidateViewModel
[xVal](http://xval.codeplex.com/) is a pretty easy to get integrated.  The first step is to decorate the model with validation rules Ive decided to use .NET frameworks [DataAnnotations](http://msdn.microsoft.com/en-us/library/system.componentmodel.dataannotations.aspx), which ends up looking like:
```
public class ValidateViewModel
{
[Required(ErrorMessage = "This string is required")]
public string StringRequired { get; set; }
[Range(13, 100, ErrorMessage = "Must be between 13 and 100")]
public double DoubleRange13_100 { get; set; }
}public class ValidatedController
}
```
```
public class ValidatedController
{
public ViewResult Index()
{
return View(new ValidateViewModel());
}
}<%@ Page Language="C#" Inherits="System.Web.Mvc.ViewPage<ValidateViewModel>" %>
}
```
```
<%@ Page Language="C#" Inherits="System.Web.Mvc.ViewPage<ValidateViewModel>" %>
<asp:Content ContentPlaceHolderID="MainContent" runat="server">
<% using(Html.BeginForm()) {%>
<%= Html.ValidationSummary() %>
@@ -38,7 +49,12 @@ Earlier this year, I remembered having seen a [presentation](http://speakerrate.
<%} %>
</asp:Content>
To validate this ViewModel server side, we use a [DataAnnotationsValidationRunner](http://blog.codeville.net/2009/01/10/xval-a-validation-framework-for-aspnet-mvc/) like the one in xVals documentation:[AcceptVerbs(HttpVerbs.Post)]
```
To validate this ViewModel server side, we use a [DataAnnotationsValidationRunner](http://blog.codeville.net/2009/01/10/xval-a-validation-framework-for-aspnet-mvc/) like the one in xVals documentation:
```
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult Update(ValidateViewModel model)
{
try {
@@ -54,7 +70,11 @@ public ActionResult Update(ValidateViewModel model)
return ModelState.IsValid ? RedirectToAction("Completed")
: (ActionResult) View();
}public static class DataAnnotationsValidationRunner
}
```
```
public static class DataAnnotationsValidationRunner
{
private static IEnumerable<ErrorInfo> GetErrors(object instance)
{
@@ -74,9 +94,16 @@ public ActionResult Update(ValidateViewModel model)
}
}
```
*Aside: the project uses the *[*Active record pattern*](http://en.wikipedia.org/wiki/Active_record_pattern)* via *[*Castle ActiveRecord*](http://www.castleproject.org/activerecord/index.html)* for data access without an intermediate business-logic layer.  For this case, the rules are defined on the ViewModel and are validated in the controller.  This does add some noise in the actions Im definitely interested in other methods for handling this. Such as - perhaps the validation could be placed inside the ViewModel?*
The next step is to add client-side validation.  [xVal](http://xval.codeplex.com/)s built-in [jQuery Validate](http://bassistance.de/jquery-plugins/jquery-plugin-validation/) rule generator makes this ridiculously simple just reference jquery.validate.js and xVal.jquery.validate.js in the view, and then this single line:<%= Html.ClientSideValidation<ValidateViewModel>() %>
The next step is to add client-side validation.  [xVal](http://xval.codeplex.com/)s built-in [jQuery Validate](http://bassistance.de/jquery-plugins/jquery-plugin-validation/) rule generator makes this ridiculously simple just reference `jquery.validate.js` and `xVal.jquery.validate.js` in the view, and then this single line:
```
<%= Html.ClientSideValidation<ValidateViewModel>() %>
```
The rules defined in the ViewModel will now be validated client side and enforced for server side actions.  This works great for a statically defined HTML form, but I learned that integrating with [Jeditable](http://www.appelsiini.net/projects/jeditable)s dynamic inline forms to be not so straight forward.
@@ -5,7 +5,10 @@ slug: jquery-validate-and-jeditable-part-2
published: true
---
When using [Jeditable](http://www.appelsiini.net/projects/jeditable), there is no form element to bind [jQuery Validate](http://bassistance.de/jquery-plugins/jquery-plugin-validation/) rules with.  Instead, when an editable element is clicked or activated, it dynamically creates a new form and input element and destroys them after the user is done editing.  For the ViewModel from [Part 1](/2010/01/01/jQueryValidateAndJeditablePart1.aspx), the View might be rendered like so for [Jeditable](http://www.appelsiini.net/projects/jeditable):<%@ Page Language="C#" Inherits="System.Web.Mvc.ViewPage<ValidateViewModel>" %>
When using [Jeditable](http://www.appelsiini.net/projects/jeditable), there is no form element to bind [jQuery Validate](http://bassistance.de/jquery-plugins/jquery-plugin-validation/) rules with.  Instead, when an editable element is clicked or activated, it dynamically creates a new form and input element and destroys them after the user is done editing.  For the ViewModel from [Part 1](/2010/01/01/jQueryValidateAndJeditablePart1.aspx), the View might be rendered like so for [Jeditable](http://www.appelsiini.net/projects/jeditable):
```
<%@ Page Language="C#" Inherits="System.Web.Mvc.ViewPage<ValidateViewModel>" %>
<asp:Content ContentPlaceHolderID="MainContent" runat="server">
<% using(Html.BeginForm()) {%>
<%= Html.ValidationSummary() %>
@@ -20,8 +23,12 @@ When using [Jeditable](http://www.appelsiini.net/projects/jeditable), there is n
</div>
<%} %>
</asp:Content>
```
[xVal](http://xval.codeplex.com/)s ClientSideValidation<TViewModel>() used in [Part 1](/2010/01/01/jQueryValidateAndJeditablePart1.aspx) wont work to validate this.  The reason?  It generates a script that binds validation directly to the form elements on page load.  The rendered script looks for the ViewModel looks like:<script type="text/javascript">
[xVal](http://xval.codeplex.com/)s `ClientSideValidation<TViewModel>()` used in [Part 1](/2010/01/01/jQueryValidateAndJeditablePart1.aspx) wont work to validate this.  The reason?  It generates a script that binds validation directly to the form elements on page load.  The rendered script looks for the ViewModel looks like:
```
<script type="text/javascript">
xVal.AttachValidator(null,
{"Fields":[
{
@@ -52,8 +59,12 @@ xVal.AttachValidator(null,
}
]}, {})
</script>
```
The rules are in the xVals StandardJSON format and the AttachValidator function (in xVal.jquery.validate.js) scans the DOM and attaches [jQuery Validate](http://bassistance.de/jquery-plugins/jquery-plugin-validation/) rules as attributes to the matched input elements.  Since [Jeditable](http://www.appelsiini.net/projects/jeditable) doesnt create these elements until theyre actively being edited, the rules have nothing to attach to since they dont exist yet.  Fortunately, [jQuery Validate](http://bassistance.de/jquery-plugins/jquery-plugin-validation/) provides several strategies for defining the rules.  In addition to being able to attach attributes to the input elements, the rules can be placed in a separate data structure.  [jQuery Validate](http://bassistance.de/jquery-plugins/jquery-plugin-validation/) refers to these as “static rules”.  Instead of attaching the xVal rule set directly to the elements, it can be adapted to the static rule set that [jQuery Validate](http://bassistance.de/jquery-plugins/jquery-plugin-validation/) can use directly.  The structure for the ViewModel rules will look like: {
The rules are in the xVals StandardJSON format and the `AttachValidator` function (in `xVal.jquery.validate.js`) scans the DOM and attaches [jQuery Validate](http://bassistance.de/jquery-plugins/jquery-plugin-validation/) rules as attributes to the matched input elements.  Since [Jeditable](http://www.appelsiini.net/projects/jeditable) doesnt create these elements until theyre actively being edited, the rules have nothing to attach to since they dont exist yet.  Fortunately, [jQuery Validate](http://bassistance.de/jquery-plugins/jquery-plugin-validation/) provides several strategies for defining the rules.  In addition to being able to attach attributes to the input elements, the rules can be placed in a separate data structure.  [jQuery Validate](http://bassistance.de/jquery-plugins/jquery-plugin-validation/) refers to these as “static rules”.  Instead of attaching the xVal rule set directly to the elements, it can be adapted to the static rule set that [jQuery Validate](http://bassistance.de/jquery-plugins/jquery-plugin-validation/) can use directly.  The structure for the ViewModel rules will look like:
```
{
rules: {
StringRequired: {
required: true
@@ -73,16 +84,26 @@ The rules are in the xVals StandardJSON format and the AttachValidator functi
}
}
I've adapted some javascript to do this conversion - it's available [here](http://popcyclical.com/content/binary/images/jQueryValidateandJeditable_E71E/xValRuleAdapter.js).  To get the ViewModels rules into this format for javascript consumption, this line is added:<script type="text/javascript">
```
I've adapted some javascript to do this conversion - it's available [here](../media/images/jQueryValidateandJeditable_E71E/xValRuleAdapter.js).  To get the ViewModels rules into this format for javascript consumption, this line is added:
```
<script type="text/javascript">
var validateOptions
= convertXvalToValidateOptions(
<%= Html.ClientSideValidationRules<ValidateViewModel>()%>
);
</script>
```
 
To get these attached to form elements as soon as the user activates them, [Jeditable](http://www.appelsiini.net/projects/jeditable)s “plugin” feature is utilized:$(function() { // <- on document ready
To get these attached to form elements as soon as the user activates them, [Jeditable](http://www.appelsiini.net/projects/jeditable)s “plugin” feature is utilized:
```
$(function() { // <- on document ready
// register plugin with Jeditable to tie in jQuery Validate
$.editable.types['text'].plugin = bindValidate;
@@ -122,18 +143,20 @@ function jeditableValidate(settings, self) {
return $('form', self).valid();
}
```
With this glue in place, the form elements will now be validated with the rules defined in the ViewModel.  All fields valid:
[![jQueryValidateJeditable1](http://popcyclical.com/content/binary/images/jQueryValidateandJeditable_E71E/jQueryValidateJeditable1_thumb.png)](http://popcyclical.com/content/binary/images/jQueryValidateandJeditable_E71E/jQueryValidateJeditable1.png)
[![jQueryValidateJeditable1](../media/images/jQueryValidateandJeditable_E71E/jQueryValidateJeditable1_thumb.png)](../media/images/jQueryValidateandJeditable_E71E/jQueryValidateJeditable1.png)
…and here after both have invalid values:
[![jQueryValidateJeditable2](http://popcyclical.com/content/binary/images/jQueryValidateandJeditable_E71E/jQueryValidateJeditable2_thumb.png)](http://popcyclical.com/content/binary/images/jQueryValidateandJeditable_E71E/jQueryValidateJeditable2.png)
[![jQueryValidateJeditable2](../media/images/jQueryValidateandJeditable_E71E/jQueryValidateJeditable2_thumb.png)](../media/images/jQueryValidateandJeditable_E71E/jQueryValidateJeditable2.png)
A few notes:
- Any additional options to be sent to [jQuery Validate](http://bassistance.de/jquery-plugins/jquery-plugin-validation/) can be attached to the validateOptions object. Ive used this to place all error messages into a separate errorLabelContainer (like [here](http://stackoverflow.com/questions/61456/mvc-net-jquery-validation)).
- Any additional options to be sent to [jQuery Validate](http://bassistance.de/jquery-plugins/jquery-plugin-validation/) can be attached to the `validateOptions` object. Ive used this to place all error messages into a separate `errorLabelContainer` (like [here](http://stackoverflow.com/questions/61456/mvc-net-jquery-validation)).
- I feel that AttachValidator function in xVal.jquery.validate.js from could become more loosely coupled by separating the rule conversion from the DOM element attachment.
- I feel that AttachValidator function in `xVal.jquery.validate.js` from could become more loosely coupled by separating the rule conversion from the DOM element attachment.
I think both of these jQuery libraries provide a great benefit when creating interactive and helpful forms.  Kudos to [Jörn Zaefferer](http://bassistance.de/) and [Mika Tuupola](http://www.appelsiini.net/) for the good work.  xVal is likewise an excellent library thanks to [Steve Sanderson](http://www.codeplex.com/site/users/view/SteveSanderson).
@@ -10,30 +10,45 @@ From [ASP.NET MVC in Action](http://www.manning.com/palermo/) section 4.4.1:
*Views are difficult to unit test, so we want to keep them as thin as possible. … Notice in [the View Model] that all of the properties are strings. Well have the [properties] properly formatted before this view model object is placed in view data. This way, the view need not consider the object, and it can format the information properly.*
To facilitate the formatting between the Domain Model and the View Model, a few of [AutoMapper](http://www.codeplex.com/AutoMapper)s features may be utilized. Heres a DomainModel containing a CurrencyProperty which will needed to formatted for human consumption:public class DomainModel
To facilitate the formatting between the Domain Model and the View Model, a few of [AutoMapper](http://www.codeplex.com/AutoMapper)s features may be utilized. Heres a `DomainModel` containing a `CurrencyProperty` which will needed to formatted for human consumption:
```
public class DomainModel
{
public decimal CurrencyProperty { get; set; }
}
```
Now, here is a ViewModel which will be used to transport the formatted value to the View:public class ViewModel
Now, here is a `ViewModel` which will be used to transport the formatted value to the View:
```
public class ViewModel
{
///<summary>Currency Property - formatted as $#,###.##</summary>
public string CurrencyProperty { get; set; }
}
```
####
#### Mapping from Domain Model to View Model
[AutoMapper](http://www.codeplex.com/AutoMapper) provides an easy way to create a mapping between two object types.  For particular tweaks for individual property mappings, the ForMember method can be used like:///<summary>Setup mapping between domain and view model</summary>
[AutoMapper](http://www.codeplex.com/AutoMapper) provides an easy way to create a mapping between two object types.  For particular tweaks for individual property mappings, the `ForMember` method can be used like:
```
///<summary>Setup mapping between domain and view model</summary>
static ViewModel()
{
// map dm to vm
Mapper.CreateMap<DomainModel, ViewModel>()
.ForMember(vm => vm.CurrencyProperty, mc => mc.AddFormatter<CurrencyFormatter>());
}
```
This sets up a mapping between the DomainModel and ViewModel and additionally applies a custom formatter for CurrencyProperty.  The formatter must implement the IValueFormatter interface like so:public class CurrencyFormatter : IValueFormatter
This sets up a mapping between the DomainModel and `ViewModel` and additionally applies a custom formatter for CurrencyProperty.  The formatter must implement the IValueFormatter interface like so:
```
public class CurrencyFormatter : IValueFormatter
{
///<summary>Formats source value as currency</summary>
public string FormatValue(ResolutionContext context)
@@ -41,32 +56,49 @@ This sets up a mapping between the DomainModel and ViewModel and additionally ap
return string.Format(CultureInfo.CurrentCulture, "{0:c}", context.SourceValue);
}
}
```
…and a simple conversion constructor on the ViewModel:/// <summary> Creates the view model from the domain model.</summary>
…and a simple conversion constructor on the `ViewModel`:
```
/// <summary> Creates the view model from the domain model.</summary>
public ViewModel(DomainModel domainModel)
{
Mapper.Map(domainModel, this);
}
Now, neither the Controller or View need concern about any formatting and can stay focused on orchestrating and layout:public ViewResult Index()
```
Now, neither the Controller or View need concern about any formatting and can stay focused on orchestrating and layout:
```
public ViewResult Index()
{
var model = new DomainModel{CurrencyProperty = 19.95m};
var viewModel = new ViewModel(model);
return View(viewModel);
}<%@ Page Language="C#" Inherits="System.Web.Mvc.ViewPage<ViewModel>" %>
}
```
```
<%@ Page Language="C#" Inherits="System.Web.Mvc.ViewPage<ViewModel>" %>
<asp:Content ContentPlaceHolderID="MainContent" runat="server">
<% using(Html.BeginForm()) {%>
<%= Html.TextBoxFor(m=>m.CurrencyProperty)%>
<%} %>
</asp:Content>
```
*Aside: TextBoxFor is an upcoming ASP.NET MVC 2 feature thats available today in MVC Futures or the RC.  Check out *[*Matts post*](http://www.trycatchfail.com/blog/post/2009/12/11/My-best-%28or-worst%29-MVC-hack-to-datehellip3b.aspx)* for some neat stuff.*
*Aside: `TextBoxFor` is an upcoming ASP.NET MVC 2 feature thats available today in MVC Futures or the RC.  Check out *[*Matts post*](http://www.trycatchfail.com/blog/post/2009/12/11/My-best-%28or-worst%29-MVC-hack-to-datehellip3b.aspx)* for some neat stuff.*
#### Mapping from View Model back to Domain Model
So now the formatted value is being rendered but how do we go about the reverse trip back to the server?  First, to define an action:[AcceptVerbs(HttpVerbs.Post)]
So now the formatted value is being rendered but how do we go about the reverse trip back to the server?  First, to define an action:
```
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult Index(ViewModel viewModel)
{
var model = new DomainModel();
@@ -75,22 +107,35 @@ public ActionResult Index(ViewModel viewModel)
// ... return a view or action result
}
```
*Aside: for validating that what the user enters is in the correct format, see *[*another post about jQuery Validate here*](/2010/01/01/jQueryValidateAndJeditablePart1.aspx)*.*
… and a Map method on the ViewModel:public void MapTo(DomainModel domainModel)
… and a `Map` method on the `ViewModel`:
```
public void MapTo(DomainModel domainModel)
{
Mapper.Map(this, domainModel);
}
```
But this mapping will fail without first creating a definition back from the ViewModel to the Model.  In the ViewModels static constructor: // from vm to dm
But this mapping will fail without first creating a definition back from the `ViewModel` to the Model.  In the `ViewModel`s static constructor:
```
// from vm to dm
Mapper.CreateMap<ViewModel, DomainModel>()
.ForMember(dm => dm.CurrencyProperty,
mc => mc
.ResolveUsing<CurrencyResolver>()
.FromMember(vm => vm.CurrencyProperty));
This utilizes another [AutoMapper](http://www.codeplex.com/AutoMapper) method - ResolveUsing - which can be used to get the string property back to a decimal.  The ValueResolver<TSource,TDestination> is defined like so:public class CurrencyResolver : ValueResolver<string, decimal>
```
This utilizes another [AutoMapper](http://www.codeplex.com/AutoMapper) method - ResolveUsing - which can be used to get the string property back to a decimal.  The `ValueResolver<TSource,TDestination>` is defined like so:
```
public class CurrencyResolver : ValueResolver<string, decimal>
{
///<summary>Parses source value as currency</summary>
protected override decimal ResolveCore(string source)
@@ -99,6 +144,8 @@ This utilizes another [AutoMapper](http://www.codeplex.com/AutoMapper) method -
}
}
```
#### Conclusions
There may be more elegant ways to accomplish formatting for MVC Views, but this method is quite workable.  In particular, I can imagine utilizing [DataAnnotationss DisplayFormatAttribute](http://msdn.microsoft.com/en-us/library/system.componentmodel.dataannotations.displayformatattribute.aspx) to decorate the Model or ViewModel and the framework automagically applying the formatting while rendering the View.
@@ -6,67 +6,107 @@ published: true
---
Being a [Resharper](http://www.jetbrains.com/resharper/) user for the past 5 years, I had to jump on opportunity to [try out the publicly released beta for the new 5.0 version](http://www.jetbrains.com/resharper/beta/beta.html?utm_source=jetbrains-dotnet-outlook4&utm_medium=resharper5beta-page&utm_campaign=resharper5beta).  Im currently using Visual Studio 2008, but Ill be glad to have the updated VS2010 support from Resharper once its released.  As for the changes in this major revision, Im excited to try out new code inspections, LINQ integration improvements, and native NUnit integration.
### Installation
- [![Resharper5BetaInstallComplete](http://popcyclical.com/content/binary/images/Resharper5BetaImpressions_7EC3/Resharper5BetaInstallComplete_thumb.png)](http://popcyclical.com/content/binary/images/Resharper5BetaImpressions_7EC3/Resharper5BetaInstallComplete.png)Install was quick and easy.  It uninstalled the version 4.5 and questioned me about killing a task that was getting in the way.
- [![Resharper5BetaInstallComplete](../media/images/Resharper5BetaImpressions_7EC3/Resharper5BetaInstallComplete_thumb.png)](../media/images/Resharper5BetaImpressions_7EC3/Resharper5BetaInstallComplete.png)Install was quick and easy.  It uninstalled the version 4.5 and questioned me about killing a task that was getting in the way.
- Starting Resharper, Im greeted with a “License to version 4.0 is not acceptable”.  This is troubling in two ways:
- The license that I bought is for 4.5 C# Edition.
- Why does a beta need a license?
[![Resharper5BetaLicense](http://popcyclical.com/content/binary/images/Resharper5BetaImpressions_7EC3/Resharper5BetaLicense_thumb.png)](http://popcyclical.com/content/binary/images/Resharper5BetaImpressions_7EC3/Resharper5BetaLicense.png)
[![Resharper5BetaLicense](../media/images/Resharper5BetaImpressions_7EC3/Resharper5BetaLicense_thumb.png)](../media/images/Resharper5BetaImpressions_7EC3/Resharper5BetaLicense.png)
- For now, using “free evaluation” this seems to do the trick.
- As expected, the [AgentSmith plugin](http://www.agentsmithplugin.com/) is no longer installed (duh), but an updated version is available on their site.
### New Features
Id like to be pretty thorough in acquainting myself with the enhancements, so Ill touch on each of them from the [list here](http://blogs.jetbrains.com/dotnet/2009/10/resharper-50-overview/).
- **Structure Patterns** [![image](http://popcyclical.com/content/binary/images/Resharper5BetaImpressions_7EC3/image_thumb.png)](http://popcyclical.com/content/binary/images/Resharper5BetaImpressions_7EC3/image.png)
- Custom built code refactorings.  This could be a godsend for [brownfield development](http://en.wikipedia.org/wiki/Brownfield_%28software_development%29) enabling project-wide cleanup for stinky “[code smells](http://en.wikipedia.org/wiki/Code_smell)”.  The real power is in the “Placeholder” templating its much like the Live Templates but for refactoring.  The image onthe right has a pattern that I made to change from timeSpan to happyHour.  Needless to say, this is trivial (and useless!), but Im readily awaiting the next time I find a [code smell](http://en.wikipedia.org/wiki/Code_smell) I cant live with.
- **Structure Patterns** [![image](../media/images/Resharper5BetaImpressions_7EC3/image_thumb.png)](../media/images/Resharper5BetaImpressions_7EC3/image.png)
- Custom built code refactorings.  This could be a godsend for [brownfield development](http://en.wikipedia.org/wiki/Brownfield_%28software_development%29) enabling project-wide cleanup for stinky “[code smells](http://en.wikipedia.org/wiki/Code_smell)”.  The real power is in the “Placeholder” templating its much like the Live Templates but for refactoring.  The image onthe right has a pattern that I made to change from `timeSpan` to `happyHour`.  Needless to say, this is trivial (and useless!), but Im readily awaiting the next time I find a [code smell](http://en.wikipedia.org/wiki/Code_smell) I cant live with.
- **Project Refactoring and Dependencies View**
- Ive been waiting for the ability to mass-rename namespaces.  Resharper5 : check. 
- So what does “Project Refactoring” mean?  Does a project have a bunch of types declared in the same files?  After a few clicks, they can all moved into their own:[![image](http://popcyclical.com/content/binary/images/Resharper5BetaImpressions_7EC3/image_thumb_3.png)](http://popcyclical.com/content/binary/images/Resharper5BetaImpressions_7EC3/image_3.png)
[![image](http://popcyclical.com/content/binary/images/Resharper5BetaImpressions_7EC3/image_thumb_4.png)](http://popcyclical.com/content/binary/images/Resharper5BetaImpressions_7EC3/image_4.png) 
- So what does “Project Refactoring” mean?  Does a project have a bunch of types declared in the same files?  After a few clicks, they can all moved into their own:[![image](../media/images/Resharper5BetaImpressions_7EC3/image_thumb_3.png)](../media/images/Resharper5BetaImpressions_7EC3/image_3.png)
[![image](../media/images/Resharper5BetaImpressions_7EC3/image_thumb_4.png)](../media/images/Resharper5BetaImpressions_7EC3/image_4.png) 
- Dependency View is basically “find usages by project” which could certainly be useful for larger solutions. 
- **Call Tracking, Value Tracking**
- Examines method, variable, field or property usage through the solution and finds where its being generated or called from, as well as the opposite - where its being used.  Its the static-analysis version of the call stack.
[![image](http://popcyclical.com/content/binary/images/Resharper5BetaImpressions_7EC3/image_thumb_5.png)](http://popcyclical.com/content/binary/images/Resharper5BetaImpressions_7EC3/image_5.png)
[![image](../media/images/Resharper5BetaImpressions_7EC3/image_thumb_5.png)](../media/images/Resharper5BetaImpressions_7EC3/image_5.png)
- **Internationalization**
- Ive never worked on a project using [Internationalization](http://en.wikipedia.org/wiki/Internationalization_and_localization), but its bound to happen sooner than later. Resharper 5 adds the ability to move string to resource files as well as refactoring and inspection to support multiple languages.
- **ASP.NET**
- [![image](http://popcyclical.com/content/binary/images/Resharper5BetaImpressions_7EC3/image_thumb_6.png)](http://popcyclical.com/content/binary/images/Resharper5BetaImpressions_7EC3/image_6.png)Syntax highlighting!  Check it out - unused namespaces inside ASP.NET markup will now appear grayed out, just as they do in source code.
- [![image](../media/images/Resharper5BetaImpressions_7EC3/image_thumb_6.png)](../media/images/Resharper5BetaImpressions_7EC3/image_6.png)Syntax highlighting!  Check it out - unused namespaces inside ASP.NET markup will now appear grayed out, just as they do in source code.
- Templates for ASP.NET:
[![image](http://popcyclical.com/content/binary/images/Resharper5BetaImpressions_7EC3/image_thumb_7.png)](http://popcyclical.com/content/binary/images/Resharper5BetaImpressions_7EC3/image_7.png)
[![image](../media/images/Resharper5BetaImpressions_7EC3/image_thumb_7.png)](../media/images/Resharper5BetaImpressions_7EC3/image_7.png)
- **ASP.NET MVC**
- [![image](http://popcyclical.com/content/binary/images/Resharper5BetaImpressions_7EC3/image_thumb_8.png)](http://popcyclical.com/content/binary/images/Resharper5BetaImpressions_7EC3/image_8.png)View name autocomplete from the controller, as well as navigation to and from actions.
- [![image](../media/images/Resharper5BetaImpressions_7EC3/image_thumb_8.png)](../media/images/Resharper5BetaImpressions_7EC3/image_8.png)View name autocomplete from the controller, as well as navigation to and from actions.
- … and navigation to Views.  **Shift+Click** on a view name to jump there:
[![image](http://popcyclical.com/content/binary/images/Resharper5BetaImpressions_7EC3/image_thumb_9.png)](http://popcyclical.com/content/binary/images/Resharper5BetaImpressions_7EC3/image_9.png)
[![image](../media/images/Resharper5BetaImpressions_7EC3/image_thumb_9.png)](../media/images/Resharper5BetaImpressions_7EC3/image_9.png)
- *Aside: Our project has some calls to HtmlHelper.RenderPartial(“<ViewName>”) called inside of a class instantiated with an instance of HtmlHelper (its a Helper for HtmlHelper). Resharper cant resolve these names… but I wouldnt expect it to.*
- **IntelliSense Changes**
- In addition to performance improvements, completion can now done using abbreviated names based on [CamelHumps](http://animals.howstuffworks.com/mammals/question104.htm):
 [![image](http://popcyclical.com/content/binary/images/Resharper5BetaImpressions_7EC3/image_thumb_10.png)](http://popcyclical.com/content/binary/images/Resharper5BetaImpressions_7EC3/image_10.png)
- [![image](http://popcyclical.com/content/binary/images/Resharper5BetaImpressions_7EC3/image_thumb_11.png)](http://popcyclical.com/content/binary/images/Resharper5BetaImpressions_7EC3/image_11.png)**Bookmarks**
 [![image](../media/images/Resharper5BetaImpressions_7EC3/image_thumb_10.png)](../media/images/Resharper5BetaImpressions_7EC3/image_10.png)
- [![image](../media/images/Resharper5BetaImpressions_7EC3/image_thumb_11.png)](../media/images/Resharper5BetaImpressions_7EC3/image_11.png)**Bookmarks**
- Set and jump to bookmarks with quick keystrokes.  **Ctrl+Shift+[0-9]** to set, and **Ctrl+[0-9]** jump back.  **Ctr+~**  to see which bookmarks are available:
 [![image](http://popcyclical.com/content/binary/images/Resharper5BetaImpressions_7EC3/image_thumb_12.png)](http://popcyclical.com/content/binary/images/Resharper5BetaImpressions_7EC3/image_12.png)
 [![image](../media/images/Resharper5BetaImpressions_7EC3/image_thumb_12.png)](../media/images/Resharper5BetaImpressions_7EC3/image_12.png)
- **Upgrade to LINQ**
- Now this is pretty slick parses a foreach loop and its innards and [translates it to a single LINQ statement](http://blogs.jetbrains.com/dotnet/2009/12/resharper-50-preview-loops-2-linq/):
[![image](http://popcyclical.com/content/binary/images/Resharper5BetaImpressions_7EC3/image_13.png)](http://popcyclical.com/content/binary/images/Resharper5BetaImpressions_7EC3/image_19.png)
[![image](../media/images/Resharper5BetaImpressions_7EC3/image_13.png)](../media/images/Resharper5BetaImpressions_7EC3/image_19.png)
- **New and Improved Code Inspections**
- So, JetBrains says theyve added a bunch of new code inspections Im counting a little over 100 C# Context Actions in 5.0, where as 4.5 had closer to 80.  There appear to be some LINQ related ones in there. Theyve also called out that it can now highlight errors in XML comments (something which the [AgentSmith](http://www.agentsmithplugin.com/) plugin already did quite well).
- [![image](http://popcyclical.com/content/binary/images/Resharper5BetaImpressions_7EC3/image_thumb_13.png)](http://popcyclical.com/content/binary/images/Resharper5BetaImpressions_7EC3/image_14.png)**Native NUnit Support**
- [![image](../media/images/Resharper5BetaImpressions_7EC3/image_thumb_13.png)](../media/images/Resharper5BetaImpressions_7EC3/image_14.png)**Native NUnit Support**
- To be honest, Ive been using the previous Resharper versions NUnit support without complaint.  Im thinking that the that the improvements are “under the hood” it works just as well now as it did before.
- **XML Formatting**
- Inspection and refactoring support - “Reorder attributes” and “Collapse Empty Tag”, for instance.
[![image](http://popcyclical.com/content/binary/images/Resharper5BetaImpressions_7EC3/image_thumb_14.png)](http://popcyclical.com/content/binary/images/Resharper5BetaImpressions_7EC3/image_15.png)[![image](http://popcyclical.com/content/binary/images/Resharper5BetaImpressions_7EC3/image_thumb_15.png)](http://popcyclical.com/content/binary/images/Resharper5BetaImpressions_7EC3/image_16.png)  
- [![image](http://popcyclical.com/content/binary/images/Resharper5BetaImpressions_7EC3/image_thumb_16.png)](http://popcyclical.com/content/binary/images/Resharper5BetaImpressions_7EC3/image_17.png)**External Sources**
[![image](../media/images/Resharper5BetaImpressions_7EC3/image_thumb_14.png)](../media/images/Resharper5BetaImpressions_7EC3/image_15.png)[![image](../media/images/Resharper5BetaImpressions_7EC3/image_thumb_15.png)](../media/images/Resharper5BetaImpressions_7EC3/image_16.png)  
- [![image](../media/images/Resharper5BetaImpressions_7EC3/image_thumb_16.png)](../media/images/Resharper5BetaImpressions_7EC3/image_17.png)**External Sources**
- This promises to add navigation to referenced libraries that before could only be accessed at the higher namespace-class-method  level via Visual Studios Object Browser.  I poked around a bit on JetBrains site looking how to configure the symbol locations, but it doesnt seem to be documented yet.  Perhaps it might need to have the symbols locations populated in VS->Options->Debugging-Symbols, but perhaps not.
### Surprises
- Transparently imported settings from 4.5 horray!  Appears to be able to use the 4.5.resharper shared solution settings
- [![image](http://popcyclical.com/content/binary/images/Resharper5BetaImpressions_7EC3/image_thumb_17.png)](http://popcyclical.com/content/binary/images/Resharper5BetaImpressions_7EC3/image_18.png)Running “Find Usages” on a class is taking much longer in previous version it was instantaneous, now it appears to be scrounging through files instead of an index (could be External sources feature?)
- [![image](../media/images/Resharper5BetaImpressions_7EC3/image_thumb_17.png)](../media/images/Resharper5BetaImpressions_7EC3/image_18.png)Running “Find Usages” on a class is taking much longer in previous version it was instantaneous, now it appears to be scrounging through files instead of an index (could be External sources feature?)
- Quick navigate to Type/Filename/Symbol now match partial names no more needing to put in a “*” to match wildcards.
- In the day or two Ive been using it, I dont think Ive encountered any crashes.  This is a good thing the [multitude of errors being automatically reported](http://www.jetbrains.net/jira/browse/RSRP) seem to be going to good use.
### Wish List
- Javascript.  Being a dynamic language and all, itd be pretty difficult to implement the full set of navigation and refactoring helpers Resharper provides for C# and VB.  But oh, wouldnt it be slick if it could.
- Community sharing for code-style and and structure patterns. Theres already preference and template sharing with team members via a shared settings file. The next evolution is to extend this to the cloud and create a public library to exchange ideas with all Resharper users.
For every one of the new features Ive encountered in the past couple of days, Im sure there are two or three that I havent stumbled over yet.  Thats a great thing about this product utilizing a small subset of its features can greatly [streamline development and increase productivity](http://blog.briandicroce.com/2008/05/12/the-case-for-resharper-in-the-enterprise/).  Even after years of use, I am still happily surprised to discover new facets of the tool I hadnt noticed or investigated before.
@@ -8,6 +8,7 @@ published: true
As software developers we are forever scheming on ways to increase the quality of our software.  Its a great feeling when customers are enjoying some bit of code that you wrote, so making it even better next time is a worthwhile goal.  In contrast, Ive observed at a number of [SaaS](http://en.wikipedia.org/wiki/Software_as_a_service) development shops have a **lack of quality** when it comes to the **delivery mechanics**.  Its as if once the software is written, the development effort is over and its time to tediously prepare for the deployment ceremony.  What I want to write about is the deployment process itself theres a whole other topic relating to deployment project management which includes tracking changes, scheduling perhaps another day on that.
The fact is that many software shops will deploy their services manually.  This may (hopefully) include **multiple environments** for development, QA, staging, and finally production.  Deployments will have checklists looking something like:
- Log into target machine.
- Shut down service.
- Copy updated binaries.
@@ -15,14 +16,23 @@ The fact is that many software shops will deploy their services manually.  This
- Restart service.
- Repeat for every target.
If the application has data/schema updates, it could be added as another step in the deployment process.  Likewise, in a multi-target environment there may be preliminary steps for switching out the targets from an application pool.  Finally, in the case of a software emergency, a working roll-back strategy is essential.  A few points:
- **Deployment is time consuming**
- While each step may only take a few minutes, together it can add up to a significant chunk of a work day.  Multiply that by the target count for the environment - lather, rinse, repeat.
- **Steps are error prone**
- A missed or botched step may not be noticed until its time to turn on the service or worse, afterwards.  Theres a lot of click-click-typedy-typedy-clicking with not a lot of feedback.
- **None of the steps actually require human interaction**
- I have never seen a deployment plan where all of the steps and details were not known before hand.  If the plan is not 100% deterministic, its probably more of a deployment *idea*** **and should be re-thunkd.
Automating the deployment seems like a no-brainer.  [Ayende Rahien makes his views clear](http://ayende.com/Blog/archive/2008/09/08/Requirements-101-Have-an-automated-deployment.aspx) -
>
@@ -30,15 +40,25 @@ Automating the deployment seems like a no-brainer.  [Ayende Rahien makes his vi
But how to get from source code to having it automatically deployed?  It takes a bit of setup, but its well worth the effort for a project in active development.  Heres one potential dataflow:
 [![Service Development Workflow](http://popcyclical.com/content/binary/images/AutomatedServiceDeploymentWorkflow_1325C/ServiceDevelopmentWorkflow_thumb.png)](http://popcyclical.com/content/binary/images/AutomatedServiceDeploymentWorkflow_1325C/ServiceDevelopmentWorkflow.png)
 [![Service Development Workflow](../media/images/AutomatedServiceDeploymentWorkflow_1325C/ServiceDevelopmentWorkflow_thumb.png)](../media/images/AutomatedServiceDeploymentWorkflow_1325C/ServiceDevelopmentWorkflow.png)
- **Code gets written for the project and placed in source control**
- All code needs to be in source control no exceptions!
- All code needs to be in source control no exceptions!
- **Continuous integration triggers a build**
- **Builds artifacts are created by the build server**
- For reliable builds, its important to have a [dedicated build machine](http://blog.ianuy.com/2009/06/07/the-importance-of-a-dedicated-build-machine/) - [magical or not](http://www.codinghorror.com/blog/2004/12/the-magical-build-machine.html)
- For reliable builds, its important to have a [dedicated build machine](http://blog.ianuy.com/2009/06/07/the-importance-of-a-dedicated-build-machine/) - [magical or not](http://www.codinghorror.com/blog/2004/12/the-magical-build-machine.html)
- **Project configurations for each potential target**
- This includes setting environmental variables and injecting any content needed to make the code run correctly once it is deployed
- This includes setting environmental variables and injecting any content needed to make the code run correctly once it is deployed
- **Automated Deployment**
- This is essentially a scripted equivalent of the manual deployment process
- This is essentially a scripted equivalent of the manual deployment process
There are many open source and commercially available technologies catering to each of these functions Ill dig into a few of them in some future posts.  In broad terms, its a worthwhile endeavor to have an **end-to-end software delivery process**.  Its a guarantee that your time and energy are kept focused on doing whats important developing software!
@@ -7,4 +7,4 @@ published: true
I just posted an article on [CodeProject](http://www.codeproject.com) about a generalized code block which can be used in a common scenario for simple performance benchmarking.  Check out ["Simplified Performance Counters for Timed Operations" here](http://www.codeproject.com/KB/dotnet/simpleperfcounters.aspx)…
[![OperationPerformanceCounter_AddCounters](http://popcyclical.com/content/binary/images/SimplifiedPerformanceCountersin.NET_E293/OperationPerformanceCounter_AddCounters_thumb.png)](http://popcyclical.com/content/binary/images/SimplifiedPerformanceCountersin.NET_E293/OperationPerformanceCounter_AddCounters.png) [![OperationPerformanceCounter_OperationsPerSecond](http://popcyclical.com/content/binary/images/SimplifiedPerformanceCountersin.NET_E293/OperationPerformanceCounter_OperationsPerSecond_thumb.png)](http://popcyclical.com/content/binary/images/SimplifiedPerformanceCountersin.NET_E293/OperationPerformanceCounter_OperationsPerSecond.png) [![OperationPerformanceCounter_AverageDuration](http://popcyclical.com/content/binary/images/SimplifiedPerformanceCountersin.NET_E293/OperationPerformanceCounter_AverageDuration_thumb.png)](http://popcyclical.com/content/binary/images/SimplifiedPerformanceCountersin.NET_E293/OperationPerformanceCounter_AverageDuration.png)
[![OperationPerformanceCounter_AddCounters](../media/images/SimplifiedPerformanceCountersin.NET_E293/OperationPerformanceCounter_AddCounters_thumb.png)](../media/images/SimplifiedPerformanceCountersin.NET_E293/OperationPerformanceCounter_AddCounters.png) [![OperationPerformanceCounter_OperationsPerSecond](../media/images/SimplifiedPerformanceCountersin.NET_E293/OperationPerformanceCounter_OperationsPerSecond_thumb.png)](../media/images/SimplifiedPerformanceCountersin.NET_E293/OperationPerformanceCounter_OperationsPerSecond.png) [![OperationPerformanceCounter_AverageDuration](../media/images/SimplifiedPerformanceCountersin.NET_E293/OperationPerformanceCounter_AverageDuration_thumb.png)](../media/images/SimplifiedPerformanceCountersin.NET_E293/OperationPerformanceCounter_AverageDuration.png)
@@ -5,17 +5,24 @@ slug: programming-language-misuse
published: true
---
Im feeling a bit guilty about some code I wrote:using (new OperationTimer("MyOperation", this))
Im feeling a bit guilty about some code I wrote:
```
using (new OperationTimer("MyOperation", this))
{
// ... complete operation
}
```
This innocent looking C# snippet is hiding a tricky secret - the using statement is being misused (no pun intended).  The [documentation defines the intended usage clearly](http://msdn.microsoft.com/en-us/library/yh598w02%28VS.80%29.aspx):
This innocent looking C# snippet is hiding a tricky secret - the `using` statement is being misused (no pun intended).  The [documentation defines the intended usage clearly](http://msdn.microsoft.com/en-us/library/yh598w02%28VS.80%29.aspx):
using Statement
Defines a scope, outside of which an object or objects will be disposed.
The problem?  The notion of “object disposal” is being hijacked!  In your garden variety [IDisposable](http://msdn.microsoft.com/en-us/library/system.idisposable.aspx) implementation, youd be dealing with an [external resource that needs to be released](http://msdn.microsoft.com/en-us/library/fs2xkftw.aspx) before the object can be removed from memory.  Instead, Im using it to time a block of code like so:class OperationTimer : IDisposable
The problem?  The notion of “object disposal” is being hijacked!  In your garden variety [`IDisposable`](http://msdn.microsoft.com/en-us/library/system.idisposable.aspx) implementation, youd be dealing with an [external resource that needs to be released](http://msdn.microsoft.com/en-us/library/fs2xkftw.aspx) before the object can be removed from memory.  Instead, Im using it to time a block of code like so:
```
class OperationTimer : IDisposable
{
private readonly string _operationName;
private readonly ITimable _obj;
@@ -35,20 +42,29 @@ The problem?  The notion of “object disposal” is being hijacked!  In your
_obj.OnOperationCompleted(_operationName, _stopwatch.Elapsed);
}
}
```
The constructor starts a timer and the Dispose() method stops it and reports the elapsed time.  (*aside: if youre interested in how Im using the timer, check out my previous article *[*Simplified Performance Counters*](http://popcyclical.com/2010/03/21/SimplifiedPerformanceCountersInNET.aspx)) There are certainly other ways to accomplish this same behavior, but they lack the elegance of a neatly scoped code block.  Its arguably an acceptable way to repurpose the language.  In fact, the ASP.NET MVC authors saw fit to use it in a similar fashion with the [BeginForm helper](http://msdn.microsoft.com/en-us/library/dd410596.aspx).  The only “resource” it disposes of is to render a closing </form> tag.
The constructor starts a timer and the `Dispose()` method stops it and reports the elapsed time.  (*aside: if youre interested in how Im using the timer, check out my previous article *[*Simplified Performance Counters*](http://popcyclical.com/2010/03/21/SimplifiedPerformanceCountersInNET.aspx)) There are certainly other ways to accomplish this same behavior, but they lack the elegance of a neatly scoped code block.  Its arguably an acceptable way to repurpose the language.  In fact, the ASP.NET MVC authors saw fit to use it in a similar fashion with the [BeginForm helper](http://msdn.microsoft.com/en-us/library/dd410596.aspx).  The only “resource” it disposes of is to render a closing `</form>` tag.
My question is: **When does repurposing language constructs turn from “acceptable language use” to a “dirty trick”, or worse, “illegible line noise”**?
It seems like a slippery slope.  One instance that I dont care for is controlling execution flow by-way-of logical operator precedence in most C-like languages:expression1 && expression2 || expression3
It seems like a slippery slope.  One instance that I dont care for is controlling execution flow by-way-of logical operator precedence in most C-like languages:
Which is equivalent to:if (expression1)
```
expression1 && expression2 || expression3
```
Which is equivalent to:
```
if (expression1)
expression2
else
expression3
```
This takes advantage of the order of evaluation in a logical statement it is assumed (correctly) that expression2 will never be evaluated if expression1 is evaluated as false, and instead, expression3 will get to run.  Likewise, if the first two evaluate to true, the truth value is known for the statement and expression3 is never evaluated. This is clearly not the intended usage which the language designers had in mind, but it works, and it saves any keywords from being written.
This takes advantage of the order of evaluation in a logical statement it is assumed (correctly) that `expression2` will never be evaluated if `expression1` is evaluated as false, and instead, `expression3` will get to run.  Likewise, if the first two evaluate to true, the truth value is known for the statement and `expression3` is never evaluated. This is clearly not the intended usage which the language designers had in mind, but it works, and it saves any keywords from being written.
Some truly beautiful code has been written by way of hijacking the language.  For instance, [heres a program that will calculate the value of pi using an ascii circle](http://www.cise.ufl.edu/~manuel/obfuscate/pi.c).  Truly neat - but also completely useless from a software development standpoint.
What do you think?  Should I just get over my guilt about repurposing IDisposable?  Or, should I be true to the original intent of the language and find another way?
What do you think?  Should I just get over my guilt about repurposing `IDisposable`?  Or, should I be true to the original intent of the language and find another way?
@@ -11,10 +11,12 @@ Digging around in some code circa 6 months ago I discovered a method that I had
Luckily, that behavior wasnt being used anywhere in my project (yet!), but still, it was essentially a land mine waiting for someone to trip it.  My first reaction was “shame on them for posting that without testing it!”  Of course, this code didnt end up in my project because of the author.  It was I who blindly accepted and given it the “its from the internet!”-stamp-of-approval.
Lessons learned today:[![itsfromtheinternet](http://popcyclical.com/content/binary/images/fd79eac90e05_13202/itsfromtheinternet_thumb.png)](http://popcyclical.com/content/binary/images/fd79eac90e05_13202/itsfromtheinternet.png)
Lessons learned today:[![itsfromtheinternet](../media/images/fd79eac90e05_13202/itsfromtheinternet_thumb.png)](../media/images/fd79eac90e05_13202/itsfromtheinternet.png)
- Trust is earned, not given.
- Source code becomes trusted by-way-of thorough unit and functional testing.
- Do not trust untested code from the internet.
- Do not trust untested code from your own keyboard even more so at least on the internet its likely that someone else has reviewed it.
Ive written the author a friendly note with a simple fix its better to diffuse that bomb than let it get somebody else!
+4 -4
View File
@@ -7,10 +7,10 @@ published: true
This last week I gave two presentations at [CodeStock 2010](http://codestock.org/).  Thanks to everyone attended my sessions, hope you got something out of them, and thanks to the [CodeStock organizers](http://www.vinull.com/) for all your hard work.  Heres some content from the presentations:
[Parallel Computing in .NET 4 and VS 2010 - Presentation](http://popcyclical.com/content/binary/images/CodeStock2010_A334/ParallelComputing_VS2010.pptx)
[Parallel Computing in .NET 4 and VS 2010 - Code](http://popcyclical.com/content/binary/images/CodeStock2010_A334/ParallelComputing_VS2010_code.zip)
[Parallel Computing in .NET 4 and VS 2010 - Presentation](../media/images/CodeStock2010_A334/ParallelComputing_VS2010.pptx)
[Parallel Computing in .NET 4 and VS 2010 - Code](../media/images/CodeStock2010_A334/ParallelComputing_VS2010_code.zip)
[Introduction to Windows PowerShell - Presentation](http://popcyclical.com/content/binary/images/CodeStock2010_A334/Intro_To_PowerShell.pptx)
[Introduction to Windows PowerShell - Code](http://popcyclical.com/content/binary/images/CodeStock2010_A334/Intro_To_PowerShell_code.zip)
[Introduction to Windows PowerShell - Presentation](../media/images/CodeStock2010_A334/Intro_To_PowerShell.pptx)
[Introduction to Windows PowerShell - Code](../media/images/CodeStock2010_A334/Intro_To_PowerShell_code.zip)
+1 -1
View File
@@ -5,7 +5,7 @@ slug: poem-for-resharper
published: true
---
*With tongue implementation injected dynamically into cheek object*[![ReShephard](http://popcyclical.com/content/binary/images/PoemforReSharper_F225/ReShephard.jpg)](http://www.jetbrains.com/resharper/)…
*With tongue implementation injected dynamically into cheek object*[![ReShephard](../media/images/PoemforReSharper_F225/ReShephard.jpg)](http://www.jetbrains.com/resharper/)…
ReSharper is my shepherd,
I shall not want;
@@ -5,18 +5,42 @@ slug: splitting-pascalcamel-case-with-regex-enhancements
published: true
---
In [Jon Galloways](http://weblogs.asp.net/jgalloway/) [Splitting Camel Case with RegEx](http://weblogs.asp.net/jgalloway/archive/2005/09/27/426087.aspx) blog post, he introduced a simple regular expression replacement which can split “ThisIsInPascalCase” into “This Is In Pascal Case”.  Heres the original code:output = System.Text.RegularExpressions.Regex.Replace(
In [Jon Galloways](http://weblogs.asp.net/jgalloway/) [Splitting Camel Case with RegEx](http://weblogs.asp.net/jgalloway/archive/2005/09/27/426087.aspx) blog post, he introduced a simple regular expression replacement which can split “ThisIsInPascalCase” into “This Is In Pascal Case”.  Heres the original code:
```
output = System.Text.RegularExpressions.Regex.Replace(
input,
"([A-Z])",
" $1",
System.Text.RegularExpressions.RegexOptions.Compiled).Trim();
Simple and effective.  Matches any capital letters and inserts a space before them.  But theres room for improvement.  First, the call to String.Trim() to remove any spaces potentially added if the first letter is uppercase this can be handled with a [“Match if prefix is absent” group](http://msdn.microsoft.com/en-us/library/az24scfc.aspx#grouping_constructs) containing the “beginning of line” character ^.  This prevents any matches from occurring on the first character, which eliminates the need for the String.Trim() call.  The formal name for this grouping construct is “Zero-width negative lookbehind assertion”, but just think of it as “if you see whats in here, dont match the next thing”. (?<!^)([A-Z])
```
Next - theres a potential issue with how acronyms get handled with this.  Given this fictional book title: “WCFForNoobs” the split will occur on each uppercase letter resulting in “W C F For Noobs”.  The fix is simple, though require that uppercase letters be followed by a lowercase: (?<!^)([A-Z][a-z])
Simple and effective.  Matches any capital letters and inserts a space before them.  But theres room for improvement.  First, the call to `String.Trim()` to remove any spaces potentially added if the first letter is uppercase this can be handled with a [“Match if prefix is absent” group](http://msdn.microsoft.com/en-us/library/az24scfc.aspx#grouping_constructs) containing the “beginning of line” character `^`.  This prevents any matches from occurring on the first character, which eliminates the need for the `String.Trim()` call.  The formal name for this grouping construct is “Zero-width negative lookbehind assertion”, but just think of it as “if you see whats in here, dont match the next thing”.
…Now itll result in “WCF For Noobs” (arent we all!).  But now it wont add a space before the acronym for “LearnWCFInSixEasyMonths”, the result will be “LearnWCF In Six Easy Months”.  No problem add an alternate match for a lowercase letter coming before the uppercase letter.  The replace pattern makes this more difficult we dont want the space to go before the lowercase letter, we want it between the lowercase and the first capital letter of the acronym.  RegEx can handle this with another lookbehind match group “Match prefix but exclude it” - (?<=).  This allows the match to occur on the lowercase-uppercase pair, but only the uppercase portion will get matched, so when it comes time to run the replacement, the space will get inserted between the two letters.  By itself, thatll look like this: ((?<=[a-z])[A-Z])
```
(?<!^)([A-Z])
```
Great!  But this needs to be combined with previous expression.  Easy accomplished with an either/or match using the vertical bar “or” construct: (?<!^)([A-Z][a-z]|(?<=[a-z])[A-Z])
Next - theres a potential issue with how acronyms get handled with this.  Given this fictional book title: “WCFForNoobs” the split will occur on each uppercase letter resulting in “W C F For Noobs”.  The fix is simple, though require that uppercase letters be followed by a lowercase:
```
(?<!^)([A-Z][a-z])
```
…Now itll result in “WCF For Noobs” (arent we all!).  But now it wont add a space before the acronym for “LearnWCFInSixEasyMonths”, the result will be “LearnWCF In Six Easy Months”.  No problem add an alternate match for a lowercase letter coming before the uppercase letter.  The replace pattern makes this more difficult we dont want the space to go before the lowercase letter, we want it between the lowercase and the first capital letter of the acronym.  RegEx can handle this with another lookbehind match group “Match prefix but exclude it” - `(?<=)`.  This allows the match to occur on the lowercase-uppercase pair, but only the uppercase portion will get matched, so when it comes time to run the replacement, the space will get inserted between the two letters.  By itself, thatll look like this:
```
((?<=[a-z])[A-Z])
```
Great!  But this needs to be combined with previous expression.  Easy accomplished with an either/or match using the vertical bar “or” construct:
```
(?<!^)([A-Z][a-z]|(?<=[a-z])[A-Z])
```
The example “LearnWCFInSixEasyMonths” will now be split into “Learn WCF In Six Easy Months”.  These same techniques can be used for additional splits perhaps on numbers or underscores.  More generally, [lookbehind and lookahead are great tools](http://www.regular-expressions.info/lookaround.html) to have in your RegEx toolbelt.
@@ -19,31 +19,50 @@ What is the largest square number formed by any member of such a pair?
This is what Id consider a pretty good puzzle the elements (a word list and square numbers) are easy enough to grasp, the way theyre related together is unique for this scenario, and an effective solution does not immediately pop into mind.  Well, it didnt pop into *my *mind, at least.  So where to begin?
Many of the problems (at least the ones Ive solved so far) on Project Euler involve a few common steps to reach a solution:
- **Generate a set of input values for the problem** usually this will be a large set of potential values, such as all the prime numbers below 10,000,000, or in this case, 16K of words and a bunch of square numbers.
- Given these inputs, **build an algorithm that can test for the solution**.
- **Add constraints to reduce the size of the input set** so that the solution can quickly be found.  On modern hardware, this is usually under 1 second but anything under a minute is [considered kosher](http://projecteuler.net/about).
### Input Values
The input values are easy here theyve provided the word list, and a sequence of square numbers should be trivial.  First, reading the word list.  Instead of placing the words each on a new line, the file instead contains a single line formatted like:
> "A","ABILITY","ABLE","ABOUT","ABOVE","ABSENCE"...
>
Ok so itll take a little parsing.  No problem.let words =
```
"A","ABILITY","ABLE","ABOUT","ABOVE","ABSENCE"...
```
Ok so itll take a little parsing.  No problem.
```
let words =
System.IO.File.ReadAllLines(@"words.txt")
|> Array.collect (fun line -> line.Split(','))
|> Array.map (fun w -> w.Replace("\"", "").ToLower())
```
This loads the line from the file, splits the words by commas, and removes the quotations… and I threw in making the words lowercase since I hate having my puzzles constantly shouting at me.  A little aside for the language particulars: the |> is the magical-looking-but-actually-quite-simple [pipeline operator](http://msdn.microsoft.com/en-us/magazine/cc164244.aspx#S6) it passes the output from the function on the left to be input for the function on the right. And the fun > is [F# syntax for lambda expressions](http://msdn.microsoft.com/en-us/library/dd233201.aspx).  At the end of the pipeline comes a simple array containing the parsed words.
This loads the line from the file, splits the words by commas, and removes the quotations… and I threw in making the words lowercase since I hate having my puzzles constantly shouting at me.  A little aside for the language particulars: the `|>` is the magical-looking-but-actually-quite-simple [pipeline operator](http://msdn.microsoft.com/en-us/magazine/cc164244.aspx#S6) it passes the output from the function on the left to be input for the function on the right. And the `fun >` is [F# syntax for lambda expressions](http://msdn.microsoft.com/en-us/library/dd233201.aspx).  At the end of the pipeline comes a simple array containing the parsed words.
 
So for the rest of the input - the square numbers.  F# has the means to generate an infinite sequence which can then be sliced and diced to get at the bits that are needed.  The perfect squares can be generated with:let allSquares =
So for the rest of the input - the square numbers.  F# has the means to generate an infinite sequence which can then be sliced and diced to get at the bits that are needed.  The perfect squares can be generated with:
```
let allSquares =
Seq.unfold(fun (square,odd) -> Some(square, (square+odd, odd+2))) (0,1)
```
The square numbers are “[unfolded](http://msdn.microsoft.com/en-us/library/ee340363.aspx)” that is, each element is calculated based on the result from the previous element, like youd do with.  Square numbers have a [property where they can be generated by as the sum of a list of successive odd numbers](http://en.wikipedia.org/wiki/Square_number#Properties). The [tuple](http://msdn.microsoft.com/en-us/library/dd233200.aspx) of (0,1) on the far right is fed in as an initial value, with 0 being the first “square” number and 1 being the first odd number.  At each step of the unfold, the odd number is increased by 2, and the square number is calculated by the adding the previous odd number. So, the (square,odd) tuples being computed will look like:(0,1),(1,3),(4,5),(9,7),(16,9), with only the squares being captured as output.  Works for me!
The square numbers are “[unfolded](http://msdn.microsoft.com/en-us/library/ee340363.aspx)” that is, each element is calculated based on the result from the previous element, like youd do with.  Square numbers have a [property where they can be generated by as the sum of a list of successive odd numbers](http://en.wikipedia.org/wiki/Square_number#Properties). The [tuple](http://msdn.microsoft.com/en-us/library/dd233200.aspx) of `(0,1)` on the far right is fed in as an initial value, with `0` being the first “square” number and `1` being the first odd number.  At each step of the unfold, the odd number is increased by 2, and the square number is calculated by the adding the previous odd number. So, the (square,odd) tuples being computed will look like:`(0,1),(1,3),(4,5),(9,7),(16,9)`, with only the squares being captured as output.  Works for me!
As with most simple-yet-effective bits of code, this one went through a couple of refinements before nailing it.  The first pass looked like this:Seq.unfold(fun i -> Some(i, i + 1)) 0
As with most simple-yet-effective bits of code, this one went through a couple of refinements before nailing it.  The first pass looked like this:
```
Seq.unfold(fun i -> Some(i, i + 1)) 0
|> Seq.map (fun i -> i*i)
```
…where the squares are generated in two steps instead of one. The first bit unfolds all the natural numbers from 0 to infinity (or more likely, maxint), and the second part maps these each by squaring them.  It produces the same result, but is less elegant because it uses more moving pieces.
@@ -51,14 +70,21 @@ Thats all the input this problem should require next, to design the…
### Success Algorithm
A useful bit of the Project Euler problem descriptions is that they usually include an example which can be used as a test case for a solution algorithm. Here theyve provided:care, race // <- anagrams map to
1296, 9216 // <- squares
A useful bit of the Project Euler problem descriptions is that they usually include an example which can be used as a test case for a solution algorithm. Here theyve provided:
…with a replacement dictionary of (c,1),(a,2),(r,9),(e,6).  Its important to note that the anagrams and squares might be symmetric, where the numbers can be swapped (i.e. (c,9),(a,2),(r,1),(e,6) works as well), but there are cases (such as the final answer) where this doesnt hold.
```
care, race // <- anagrams map to
1296, 9216 // <- squares
```
…with a replacement dictionary of `(c,1),(a,2),(r,9),(e,6)`.  Its important to note that the anagrams and squares might be symmetric, where the numbers can be swapped (i.e. `(c,9),(a,2),(r,1),(e,6)` works as well), but there are cases (such as the final answer) where this doesnt hold.
To devise an algorithm to test for an answer, the first step is to think it over before doing any typing.  Its better to have some notion of a strategy than to rush in with the codes.  I struggle with adhering to this its just too easy to think “Im so good, Ill just figure it out as I program.”  Ive found its more productive to get away - get a pen and some paper and start sketching ideas, take a walk, etc.  Therell be plenty of time to work through all the details in code, but its best to go in with a plan a vague or even an incorrect strategy is better than none at all.
For this problem, I started with the idea of comparing each letter of the first word with the first square number, building a replacement dictionary while iterating through them.  If a valid replacement dictionary for the first set is found, it would then be tested against the second word-square-number pair. Writing in algorithm in F# meant I could treat the words as lists and iterate them using a common combination of recursive function calls and pattern matching.let rec getReplacementDictionary (sToT, tToS) (source, target) =
For this problem, I started with the idea of comparing each letter of the first word with the first square number, building a replacement dictionary while iterating through them.  If a valid replacement dictionary for the first set is found, it would then be tested against the second word-square-number pair. Writing in algorithm in F# meant I could treat the words as lists and iterate them using a common combination of recursive function calls and pattern matching.
```
let rec getReplacementDictionary (sToT, tToS) (source, target) =
match source, target with
// have already seen this exact mapping -> skip it
| s::ss, t::tt when Map.containsKey s sToT && (Map.find s sToT) = t
@@ -76,28 +102,45 @@ For this problem, I started with the idea of comparing each letter of the first
| [], [] -> Some(sToT, tToS)
| _ -> raise(System.ArgumentException("words not equal length"))
Ive named the variables “source” and “target” theyll get passed the word and the number, respectively.  They are “matched” against conditions using the patterns seen on each line following the pipe “|” character.  The easiest of these to grasp is near the end “| [], [] > Some(sToT, tToS)“ which matches two empty lists, indicating that the words have been completely checked and that there is a valid dictionary.  For the dictionary itself, I found that it was necessary to keep tabs on both the source-to-target values (sToT) as well as the target-to-source (tToS) values.  A bi-directional mapping structure would be ideal, but it would have been more effort to construct that than to fudge it with an extra variable.  If there is a better way to handle this, Id be interested to hear it… 
```
At any rate, the result of this function will either be a failure - with the None value - or with the completed dictionary(s) the Some(sToT, tToS).  Testing it against “care” and “1296” produces the expect result:> getReplacementDictionary (Map.empty, Map.empty) ("care" |> List.ofSeq, "1296" |> List.ofSeq);;
Ive named the variables “source” and “target” theyll get passed the word and the number, respectively.  They are “matched” against conditions using the patterns seen on each line following the pipe “`|`” character.  The easiest of these to grasp is near the end `| [], [] > Some(sToT, tToS)`“ which matches two empty lists, indicating that the words have been completely checked and that there is a valid dictionary.  For the dictionary itself, I found that it was necessary to keep tabs on both the source-to-target values (sToT) as well as the target-to-source (tToS) values.  A bi-directional mapping structure would be ideal, but it would have been more effort to construct that than to fudge it with an extra variable.  If there is a better way to handle this, Id be interested to hear it… 
At any rate, the result of this function will either be a failure - with the None value - or with the completed dictionary(s) the Some(sToT, tToS).  Testing it against “care” and “1296” produces the expect result:
```
> getReplacementDictionary (Map.empty, Map.empty) ("care" |> List.ofSeq, "1296" |> List.ofSeq);;
val it : (Map<char,char> * Map<char,char>) option =
Some
(map [('a', '2'); ('c', '1'); ('e', '6'); ('r', '9')],
map [('1', 'c'); ('2', 'a'); ('6', 'e'); ('9', 'r')])
```
…and changing a digit in the number to one of the already mapped digits results (Im using 1292 which repeats the 2) in a failure:> getReplacementDictionary (Map.empty, Map.empty) ("care" |> List.ofSeq, "1292" |> List.ofSeq);;
…and changing a digit in the number to one of the already mapped digits results (Im using 1292 which repeats the 2) in a failure:
```
> getReplacementDictionary (Map.empty, Map.empty) ("care" |> List.ofSeq, "1292" |> List.ofSeq);;
val it : (Map<char,char> * Map<char,char>) option = None
```
To test this dictionary against the second group, “race” and “9216”, the original function may be reused because all of the character mappings will have been seen in the first group and they will simply be verified via the first pattern.  let dict = getReplacementDictionary (Map.empty, Map.empty) ("care" |> List.ofSeq, "1296" |> List.ofSeq)
To test this dictionary against the second group, “race” and “9216”, the original function may be reused because all of the character mappings will have been seen in the first group and they will simply be verified via the first pattern. 
```
let dict = getReplacementDictionary (Map.empty, Map.empty) ("care" |> List.ofSeq, "1296" |> List.ofSeq)
getReplacementDictionary dict.Value ("race" |> List.ofSeq, "9216" |> List.ofSeq);;
val dict : (Map<char,char> * Map<char,char>) option =
Some
(map [('a', '2'); ('c', '1'); ('e', '6'); ('r', '9')],
map [('1', 'c'); ('2', 'a'); ('6', 'e'); ('9', 'r')])
```
This is making an assumption that the input words are anagrams of each other this is an OK assumption to make for now.  Indeed, it can be even assumed that the input data may be filtered for anagrams Ill cover that in the next section.
I noticed that this could be further streamlined by simply appending the words and the numbers together, since that is more-or-less what is occurring when calling it twice.  And in that case, the function no longer needs to return the mapping dictionary just a simple boolean indicating if a valid dictionary can be applied to the input.   So, the function can be modified as follows, making sure to rename it:let rec hasReplacementDictionary (sToT, tToS) (source, target) =
I noticed that this could be further streamlined by simply appending the words and the numbers together, since that is more-or-less what is occurring when calling it twice.  And in that case, the function no longer needs to return the mapping dictionary just a simple boolean indicating if a valid dictionary can be applied to the input.   So, the function can be modified as follows, making sure to rename it:
```
let rec hasReplacementDictionary (sToT, tToS) (source, target) =
match source, target with
| s::ss, t::tt when Map.containsKey s sToT && (Map.find s sToT) = t
-> hasReplacementDictionary (sToT, tToS) (ss, tt)
@@ -109,13 +152,18 @@ I noticed that this could be further streamlined by simply appending the words a
-> hasReplacementDictionary (Map.add s t sToT, Map.add t s tToS) (ss, tt)
| [], [] -> true
| _ -> raise(System.ArgumentException("words not equal length"))
```
and run a test:> let los = List.ofSeq
and run a test:
```
> let los = List.ofSeq
let s = List.append (List.ofSeq "care") (List.ofSeq "race")
let t = List.append (List.ofSeq "1296") (List.ofSeq "9216");;
> hasReplacementDictionary (Map.empty, Map.empty) (s, t);;
val it : bool = true
```
Success!  Now, having all the necessary input and a valid algorithm, it would be possible to test every possibly combination of inputs to find the correct answer. 
@@ -125,15 +173,22 @@ Project Euler problems are usually infeasible to answer without a computer.  (T
How many combinations of the input data could there be, anyway?  Theres a total of 1,786 words ranging in length from 1 to 14 characters, which leads to ~3.2 million combinations of just the words.  My script to calculate the count of all square numbers under 14 digits ran out of memory, but it turns out only up to 9 digit squares are needed.  There are 31,623 of those.  The number of combinations would be 1,7862 × 31,6232 ≈ 3.2E15.  Thats several thousand billion got to keep filtering or itll take a year!
The next obvious step is to pair up the anagrams and discard the rest of the words.  A simple way to do this is to alphabetically sort each character in each word and group together the ones that are exactly the same.  For example “care” and “race” will both map to “acer” neat trick!  Heres the codelet groupAnagrams ws =
The next obvious step is to pair up the anagrams and discard the rest of the words.  A simple way to do this is to alphabetically sort each character in each word and group together the ones that are exactly the same.  For example “care” and “race” will both map to “acer” neat trick!  Heres the code
```
let groupAnagrams ws =
ws
// sort by characters in each string and then glue them back together
|> Seq.groupBy (Array.ofSeq >> Array.sort >> (fun cs -> new string(cs)))
// take only the anagrams - where the number of words is greater than one
|> Seq.map snd
|> Seq.filter (Seq.length >> ((<) 1))
```
This is a great first step but its not quite enough.  I want all the pairs of anagrams and there are cases where there are more than 2 words that all have the same letters.  For example, “post”, “spot” and “stop” will all group together.  What I need is combinations of all the pairs so Ill end up with (“post”, “spot”), (“spot”, stop”), and (“post”, “stop”).  Fortunately, I had already borrowed/stolen a generic combination function that [Tomas had posted on Stack Overflow](http://stackoverflow.com/a/4495708/99492).let combinations size set =
This is a great first step but its not quite enough.  I want all the pairs of anagrams and there are cases where there are more than 2 words that all have the same letters.  For example, “post”, “spot” and “stop” will all group together.  What I need is combinations of all the pairs so Ill end up with (“post”, “spot”), (“spot”, stop”), and (“post”, “stop”).  Fortunately, I had already borrowed/stolen a generic combination function that [Tomas had posted on Stack Overflow](http://stackoverflow.com/a/4495708/99492).
```
let combinations size set =
let rec combinations acc size set = seq {
match size, set with
| n, x::xs ->
@@ -142,17 +197,27 @@ This is a great first step but its not quite enough.  I want all the pai
| 0, [] -> yield acc
| _, [] -> () }
combinations [] size (set |> List.ofSeq)
```
Now I can run all the whole list of anagram groups through the combinations algorithm and produce a single list of anagram pairs:let pairwiseTuples =
Now I can run all the whole list of anagram groups through the combinations algorithm and produce a single list of anagram pairs:
```
let pairwiseTuples =
Seq.collect (
combinations 2
>> Seq.map (fun l -> l.[0], l.[1])
)
And indeed it does its job:[|("cat", "act"); ... ("race", "care");
```
And indeed it does its job:
```
[|("cat", "act"); ... ("race", "care");
...
("spot", "post"); ("stop", "post"); ("stop", "spot");
...|]
```
Running the words through this results in 44 pairs of anagrams with the lengthiest pair being 9 letters long ("reduction", "introduce"). This is starting to sound reasonable to process and its where I got stuck for a bit.  Looping through all of the squares for each pair still seems computationally prohibitive. 
@@ -5,19 +5,23 @@ slug: full-on-rainbow-spirograph-using-html5-and-coffeescript
published: true
---
![rainbowspirograph](http://popcyclical.com/content/binary/Windows-Live-Writer/HTML5-full-spectrum-spirograph_BBD7/rainbowspirograph.png)
![rainbowspirograph](../media/Windows-Live-Writer/HTML5-full-spectrum-spirograph_BBD7/rainbowspirograph.png)
So intense. We've heard how HTML5's canvas element will provide device-independent in-browser graphics and now I want a taste! After seeing some [magnificent](http://www.spielzeugz.de/html5/liquid-particles.html) [demos](http://peterned.home.xs4all.nl/demooo/), I started wondering what the plumbing looks like.  I haven't touched any graphical code since maybe 1994 in [QBasic](http://en.wikipedia.org/wiki/QBASIC), so come along with me as I learn.
Also, I'm giving [CoffeeScript](http://coffeescript.org/) a spin. I saw a presentation by [Daniel Mohl](https://twitter.com/#!/dmohl) at [Codestock](http://codestock.org/) a few weeks ago and thought it was fantastic. You write in a terse-clean-"modern" language and get the functionally equivalent JavaScript out the other end.  So long to writing function(){...} every three lines! Much of the syntax is based on Ruby, so it's an easy language to read - I'll comment on any syntax that isn't immediately obvious.
Also, I'm giving [CoffeeScript](http://coffeescript.org/) a spin. I saw a presentation by [Daniel Mohl](https://twitter.com/#!/dmohl) at [Codestock](http://codestock.org/) a few weeks ago and thought it was fantastic. You write in a terse-clean-"modern" language and get the functionally equivalent JavaScript out the other end.  So long to writing `function(){...}` every three lines! Much of the syntax is based on Ruby, so it's an easy language to read - I'll comment on any syntax that isn't immediately obvious.
But the important question is - what to draw?  I follow a few graphic design blogs and remember seeing some neat [geometric patterns](http://veerle.duoh.com/design/article/illustrator_full_spectrum_spirograph) on [veerle's blog](http://veerle.duoh.com) done in Adobe Illustrator. These were inspired by the kaleidoscopic artwork of [Andy Gilmore](http://crowquills.com/) check them out, some of the pieces are kind of hypnotic. The specific creation that motivated Veerle's tutorial can be [seen here](http://crowquills.com/1061691/06-30-2008). It has a beautiful simplicity. As Veerle mentions - we don't want to make an exact replica, but instead use some of the patterns as a starting point of something original.![HTML5 arc](http://popcyclical.com/content/binary/Windows-Live-Writer/HTML5-full-spectrum-spirograph_BBD7/arc_3.png)
But the important question is - what to draw?  I follow a few graphic design blogs and remember seeing some neat [geometric patterns](http://veerle.duoh.com/design/article/illustrator_full_spectrum_spirograph) on [veerle's blog](http://veerle.duoh.com) done in Adobe Illustrator. These were inspired by the kaleidoscopic artwork of [Andy Gilmore](http://crowquills.com/) check them out, some of the pieces are kind of hypnotic. The specific creation that motivated Veerle's tutorial can be [seen here](http://crowquills.com/1061691/06-30-2008). It has a beautiful simplicity. As Veerle mentions - we don't want to make an exact replica, but instead use some of the patterns as a starting point of something original.![HTML5 arc](../media/Windows-Live-Writer/HTML5-full-spectrum-spirograph_BBD7/arc_3.png)
The absolute first step is to draw a circle, just like it was in the Illustrator tutorial by Veerle. Well, part of a circle. I found it easiest to get the desired results using an "arc".  This is a term that simply means "a specific section along the side of the circle".  What this entails for the HTML5 canvas is specifying the center point of the circle, the radius, and the angles at the start and end the arc.  My trigonometry knowledge has deteriorated over the years (if it ever existed to begin with) but this is pretty simple. The right-most point on the circle has an angle of 0π, travelling clockwise to the bottom-most point is .5π, the left-most has 1π, up to the top at 1.5π, and a full circle is (of course) 2π.  To draw a full circle, you'd type in `context.arc(0,0,radius,0,Math.PI * 2)`.  *Note: the angles I learned in school were oriented counterclockwise, yet most of the examples I've seen for HTML5 canvas are clockwise most likely because the y-axis increases in a downward direction instead of up.  I'll keep it clockwise here.*
The absolute first step is to draw a circle, just like it was in the Illustrator tutorial by Veerle. Well, part of a circle. I found it easiest to get the desired results using an "arc".  This is a term that simply means "a specific section along the side of the circle".  What this entails for the HTML5 canvas is specifying the center point of the circle, the radius, and the angles at the start and end the arc.  My trigonometry knowledge has deteriorated over the years (if it ever existed to begin with) but this is pretty simple. The right-most point on the circle has an angle of 0π, travelling clockwise to the bottom-most point is .5π, the left-most has 1π, up to the top at 1.5π, and a full circle is (of course) 2π.  To draw a full circle, you'd type in context.arc(0,0,radius,0,Math.PI * 2).  *Note: the angles I learned in school were oriented counterclockwise, yet most of the examples I've seen for HTML5 canvas are clockwise most likely because the y-axis increases in a downward direction instead of up.  I'll keep it clockwise here.*
### Access the HTML5 Canvas using CoffeeScript
But what's this context, you ask? I might have lied about the first step the super-absolute first step will be to set up the HTML5 canvas object so that we can draw on it.  Here's a complete example of a using CoffeeScript in a script tag with the in-browser compiler to accomplish this.<!DOCTYPE html>
But what's this context, you ask? I might have lied about the first step the super-absolute first step will be to set up the HTML5 canvas object so that we can draw on it.  Here's a complete example of a using CoffeeScript in a script tag with the in-browser compiler to accomplish this.
```
<!DOCTYPE html>
<html>
<head>
<title>Full on rainbow Spirograph</title>
@@ -50,9 +54,14 @@ But what's this context, you ask? I might have lied about the first step the
<!-- https://github.com/jashkenas/coffee-script/raw/master/extras/coffee-script.js -->
<!-- coffee-script.js goes AFTER all the CoffeeScript. -->
<script type="text/javascript" src="scripts/coffee-script.js"></script>
</html>![HTML5 canvas example](http://popcyclical.com/content/binary/Windows-Live-Writer/HTML5-full-spectrum-spirograph_BBD7/canvas_1.png)
</html>
```
![HTML5 canvas example](../media/Windows-Live-Writer/HTML5-full-spectrum-spirograph_BBD7/canvas_1.png)
This generates a page containing a dark 300x300 rectangle with "#myCanvas" written in white. This is great for kicking the tires, but the script is getting compiled down to JavaScript each time the page loads.  It's preferable to compile it ahead of time.  With a little tooling this process becomes nearly transparent.  In Visual Studio a great option is the [Web Workbench extension by Mindscape](http://www.mindscapehq.com/products/web-workbench).  It automatically compiles your CoffeeScript (and [Sass](http://sass-lang.com/) and [LESS](http://lesscss.org/)) scripts each time the file is saved. After making this change, the code now looks like...<!DOCTYPE html>
This generates a page containing a dark 300x300 rectangle with "#myCanvas" written in white. This is great for kicking the tires, but the script is getting compiled down to JavaScript each time the page loads.  It's preferable to compile it ahead of time.  With a little tooling this process becomes nearly transparent.  In Visual Studio a great option is the [Web Workbench extension by Mindscape](http://www.mindscapehq.com/products/web-workbench).  It automatically compiles your CoffeeScript (and [Sass](http://sass-lang.com/) and [LESS](http://lesscss.org/)) scripts each time the file is saved. After making this change, the code now looks like...
```
<!DOCTYPE html>
<html>
<head>
<title>Full on rainbow Spirograph</title>
@@ -63,6 +72,9 @@ This generates a page containing a dark 300x300 rectangle with "#myCanvas" writt
<canvas id="myCanvas"></canvas>
</body>
</html>
```
```
# CoffeeScript_Compiled.coffee
canvasSize = 300
@@ -78,6 +90,9 @@ $ ->
ctx.fillStyle = 'white'
ctx.fillText("#myCanvas", 80, 150)
```
```
// CoffeeScript_Compiled.js
(function() {
var canvasSize;
@@ -97,10 +112,14 @@ $ ->
});
}).call(this);
```
### Circular
Now that the canvas is ready to draw on let's get back to that arc. Like from the Illustrator tutorial, I'm aiming to make a leaf-like object that can be duplicated around a central axis.  First I'll create the right side of the leaf.# cache the math stuff
Now that the canvas is ready to draw on let's get back to that arc. Like from the Illustrator tutorial, I'm aiming to make a leaf-like object that can be duplicated around a central axis.  First I'll create the right side of the leaf.
```
# cache the math stuff
pi = Math.PI
cos = Math.cos
sin = Math.sin
@@ -123,43 +142,62 @@ $ ->
# fill it in with a color
ctx.fillStyle = '#fdf6e3'
ctx.fill()
```
The first bits are again to set up the canvas context I'll omit those from now on.  The first line of interest contains the [translate](http://www.html5canvastutorials.com/advanced/html5-canvas-transform-translate-tutorial/) function this reorients the context to the specified point.  Anything drawn on the canvas afterwards will treat this point as the center.  Here I pass in size/2, size/2 - which makes the center of the canvas the 0,0 coordinate.
The first bits are again to set up the canvas context I'll omit those from now on.  The first line of interest contains the `[translate](http://www.html5canvastutorials.com/advanced/html5-canvas-transform-translate-tutorial/)` function this reorients the context to the specified point.  Anything drawn on the canvas afterwards will treat this point as the center.  Here I pass in `size/2, size/2` - which makes the center of the canvas the `0,0` coordinate.
The next line computes a radius based off the size of the canvas I simply did a fourth of the canvas dimensions so that it would fit with room to spare.
Next comes the definition of the arc's shape or the path that the arc will make. The first step is a call to [beginPath](http://www.html5canvastutorials.com/tutorials/html5-canvas-paths/)().  This is done so that the first point of the arc it is drawn as the beginning of the shape.  If I had drawn anything else on the canvas before this (which I actually have more on that later), it would continue the previous path, drawing a line between that last piece and the arc.  I've found it's easier to explicitly begin and close the path rather than to assume it's a fresh canvas especially when you start composing more complex drawings.
Next comes the definition of the arc's shape or the path that the arc will make. The first step is a call to `[beginPath](http://www.html5canvastutorials.com/tutorials/html5-canvas-paths/)()`.  This is done so that the first point of the arc it is drawn as the beginning of the shape.  If I had drawn anything else on the canvas before this (which I actually have more on that later), it would continue the previous path, drawing a line between that last piece and the arc.  I've found it's easier to explicitly begin and close the path rather than to assume it's a fresh canvas especially when you start composing more complex drawings.
Finally the actual call to [arc](http://www.html5canvastutorials.com/tutorials/html5-canvas-arcs/)! Since we've translated the canvas to center point we're passing in the 0,0 coordinate so that the circle gets drawn in the exact middle.  Next comes the radius variable which we've already defined. Now comes the tricky bit the beginning and end angles of the arc. Going back to the circle schematic I'm defining the beginning point slightly past the top (to the right), and the end point slightly before the bottom (to the left).  By "slightly", I mean by 0.2 for each side.  Multiply these values by π, and it's ready to be drawn! Oh and the final parameter indicates that it should be drawn counter-clockwise. Completely assembled, the call looks like arc(0, 0, radius, 1.7 * pi, .3 * pi, false)
Finally the actual call to `[arc](http://www.html5canvastutorials.com/tutorials/html5-canvas-arcs/)`! Since we've translated the canvas to center point we're passing in the `0,0` coordinate so that the circle gets drawn in the exact middle.  Next comes the radius variable which we've already defined. Now comes the tricky bit the beginning and end angles of the arc. Going back to the circle schematic I'm defining the beginning point slightly past the top (to the right), and the end point slightly before the bottom (to the left).  By "slightly", I mean by `0.2` for each side.  Multiply these values by π, and it's ready to be drawn! Oh and the final parameter indicates that it should be drawn counter-clockwise. Completely assembled, the call looks like `arc(0, 0, radius, 1.7 * pi, .3 * pi, false)`
Finally, a fillStyle is specified as a color using hex RGB and the arc is drawn by calling [fill](http://www.html5canvastutorials.com/tutorials/html5-canvas-shape-fill/)(). Voila!![spriospectrum-arc](http://popcyclical.com/content/binary/Windows-Live-Writer/HTML5-full-spectrum-spirograph_BBD7/spriospectrum-arc_3.png)Arc
Finally, a `fillStyle` is specified as a color using hex RGB and the arc is drawn by calling `[fill](http://www.html5canvastutorials.com/tutorials/html5-canvas-shape-fill/)()`. Voila!![spriospectrum-arc](../media/Windows-Live-Writer/HTML5-full-spectrum-spirograph_BBD7/spriospectrum-arc_3.png)Arc
Well... that seems like a lot of work to draw something so trivial!  It'll get more interesting in a little bit...
### Leafy
The first half of the leaf has been drawn now for the other half.  There are a number of ways to go about this I'll go over a few that I've found.  In this first pass, we'll simply draw another arc on the opposite side of the circle.ctx.beginPath()
The first half of the leaf has been drawn now for the other half.  There are a number of ways to go about this I'll go over a few that I've found.  In this first pass, we'll simply draw another arc on the opposite side of the circle.
```
ctx.beginPath()
ctx.arc(0, 0, radius, 1.7 * pi, .3 * pi, false)
ctx.arc(0, 0, radius, .7 * pi, 1.3 * pi, false)
ctx.closePath()![spriospectrum-doubleArc](http://popcyclical.com/content/binary/Windows-Live-Writer/HTML5-full-spectrum-spirograph_BBD7/spriospectrum-doubleArc_3.png)Double Arc
ctx.closePath()
```
![spriospectrum-doubleArc](../media/Windows-Live-Writer/HTML5-full-spectrum-spirograph_BBD7/spriospectrum-doubleArc_3.png)Double Arc
Ok not a bad start.  This time I draw the same arc on the right as before and then continue on with a second call to arc on the left side of the circle arc(0, 0, radius, .7 * pi, 1.3 * pi, false).  The only differences are the start and end angle.  Going clockwise, the first arc goes from 1.7π to .3π, and then the second arc continues at .7π and ends at 1.3π.  Filling in this path produces the shape seen above.
Ok not a bad start.  This time I draw the same arc on the right as before and then continue on with a second call to `arc` on the left side of the circle `arc(0, 0, radius, .7 * pi, 1.3 * pi, false)`.  The only differences are the start and end angle.  Going clockwise, the first arc goes from 1.7π to .3π, and then the second arc continues at .7π and ends at 1.3π.  Filling in this path produces the shape seen above.
The obvious problem is all that extra space in the middle of the circle it's definitely not leafy so it's got to go! I'll start over with just the arc on the right side.  To allow us to easily figure out where the leaf will go, it'll be good to have an easy-to-spot anchor point. For this, I chose the bottom bottom-most point of the leaf which which will be located at 0,0. All that's needed is a bit of maths.
The obvious problem is all that extra space in the middle of the circle it's definitely not leafy so it's got to go! I'll start over with just the arc on the right side.  To allow us to easily figure out where the leaf will go, it'll be good to have an easy-to-spot anchor point. For this, I chose the bottom bottom-most point of the leaf which which will be located at `0,0`. All that's needed is a bit of maths.
![arctrig](http://popcyclical.com/content/binary/Windows-Live-Writer/HTML5-full-spectrum-spirograph_BBD7/arctrig_20528432-e657-466d-81ef-808a0cfaaf5f.png)It's clear to see that the bottom-most point of the arc is below-and-right to the canvas center point.  To do this, we'll move the coordinates for the center of the circle up and to the left. But how much? To calculate, we'll use a little trig.  The coordinates on a circle can be calculated, given the angle θ, with x = cos(θ) and y = sin(θ). So, the offset for x will be -cos(.3π) * radius and for y will be -sin(.3π) * radius...ctx.arc(
![arctrig](../media/Windows-Live-Writer/HTML5-full-spectrum-spirograph_BBD7/arctrig_20528432-e657-466d-81ef-808a0cfaaf5f.png)It's clear to see that the bottom-most point of the arc is below-and-right to the canvas center point.  To do this, we'll move the coordinates for the center of the circle up and to the left. But how much? To calculate, we'll use a little trig.  The coordinates on a circle can be calculated, given the angle θ, with `x = cos(θ)` and `y = sin(θ)`. So, the offset for x will be `-cos(.3π) * radius` and for y will be `-sin(.3π) * radius`...
```
ctx.arc(
-cos(.3 * pi) * radius,
-sin(.3 * pi) * radius,
radius, 1.7 * pi, .3 * pi, false)![spriospectrum-arcBottomOrigin](http://popcyclical.com/content/binary/Windows-Live-Writer/HTML5-full-spectrum-spirograph_BBD7/spriospectrum-arcBottomOrigin_8fb6af10-c844-4f68-8d5f-fb668291949d.png)Arc with Bottom at Origin
radius, 1.7 * pi, .3 * pi, false)
```
![spriospectrum-arcBottomOrigin](../media/Windows-Live-Writer/HTML5-full-spectrum-spirograph_BBD7/spriospectrum-arcBottomOrigin_8fb6af10-c844-4f68-8d5f-fb668291949d.png)Arc with Bottom at Origin
Success!  Now the same process for the left-side...ctx.arc(
Success!  Now the same process for the left-side...
```
ctx.arc(
-cos(.7 * pi) * radius,
-sin(.7 * pi) * radius,
radius, .7 * pi, 1.3 * pi, false)![spriospectrum-leaf](http://popcyclical.com/content/binary/Windows-Live-Writer/HTML5-full-spectrum-spirograph_BBD7/spriospectrum-leaf_c72b70ca-0fd0-43c8-ae98-1f99ed85f3d9.png)Leaf
radius, .7 * pi, 1.3 * pi, false)
```
![spriospectrum-leaf](../media/Windows-Live-Writer/HTML5-full-spectrum-spirograph_BBD7/spriospectrum-leaf_c72b70ca-0fd0-43c8-ae98-1f99ed85f3d9.png)Leaf
### Rotate
Another way to skin this cat is to use the rotate() function to spin the canvas around. Now I'll try drawing the first arc, flipping the context, and then drawing the exact same arc.drawArc = ->
Another way to skin this cat is to use the `rotate()` function to spin the canvas around. Now I'll try drawing the first arc, flipping the context, and then drawing the exact same arc.
```
drawArc = ->
ctx.arc(
-cos(.3 * pi) * radius,
-sin(.3 * pi) * radius,
@@ -169,9 +207,14 @@ ctx.beginPath()
drawArc()
ctx.rotate(pi) # rotate by half a circle
drawArc()
ctx.closePath()![spriospectrum-arcRotate](http://popcyclical.com/content/binary/Windows-Live-Writer/HTML5-full-spectrum-spirograph_BBD7/spriospectrum-arcRotate_1fabafd4-53c2-43c2-82bd-dc872e009905.png)Rotated Arc
ctx.closePath()
```
![spriospectrum-arcRotate](../media/Windows-Live-Writer/HTML5-full-spectrum-spirograph_BBD7/spriospectrum-arcRotate_1fabafd4-53c2-43c2-82bd-dc872e009905.png)Rotated Arc
Kind of neat looking but it obviously didn't turn out quite right.  It rotated around the center and ended up both vertically and horizontally on the opposite side.  This can be fixed with some additional translation...startAngle = 1.7 * pi
Kind of neat looking but it obviously didn't turn out quite right.  It rotated around the center and ended up both vertically and horizontally on the opposite side.  This can be fixed with some additional translation...
```
startAngle = 1.7 * pi
endAngle = .3 * pi
drawArc = -> ctx.arc(0, 0, radius, startAngle, endAngle, false)
@@ -182,11 +225,16 @@ drawArc()
ctx.rotate(pi)
ctx.translate(-cos(endAngle) * radius * 2, 0)
drawArc()
ctx.closePath()![spriospectrum-leafRotate](http://popcyclical.com/content/binary/Windows-Live-Writer/HTML5-full-spectrum-spirograph_BBD7/spriospectrum-leafRotate_83bef149-6e97-4ff4-9197-f7581acd5c17.png)Rotated Arc for Leaf
ctx.closePath()
```
![spriospectrum-leafRotate](../media/Windows-Live-Writer/HTML5-full-spectrum-spirograph_BBD7/spriospectrum-leafRotate_83bef149-6e97-4ff4-9197-f7581acd5c17.png)Rotated Arc for Leaf
This time I'm drawing the arc at 0,0 and doing a translate before the first arc, and a rotate and translate before the second arc.  It turns out to look the same the leaf before, but the code gets a bit more muddy.  I prefer the previous implementation if this is what it takes.  Also notice that I've added a few variables to capture the start and end angles this will be important in just a little bit...
This time I'm drawing the arc at `0,0` and doing a `translate` before the first arc, and a `rotate` and `translate` before the second arc.  It turns out to look the same the leaf before, but the code gets a bit more muddy.  I prefer the previous implementation if this is what it takes.  Also notice that I've added a few variables to capture the start and end angles this will be important in just a little bit...
But first, you may have noticed that the height of the leaf, from bottom to top, is *some* length, but *what* exact length is not immediately obvious.  It'd be helpful to be able to define the leaf by a given height...height = size/2
But first, you may have noticed that the height of the leaf, from bottom to top, is *some* length, but *what* exact length is not immediately obvious.  It'd be helpful to be able to define the leaf by a given height...
```
height = size/2
arcDelta = .2
arcAngles =
start: (1.5 + arcDelta) * pi,
@@ -208,9 +256,11 @@ ctx.arc(
-sin(arcAngles.start) * radius,
radius, arcAngles.start, arcAngles.end, false)
ctx.closePath()![spriospectrum-leafHeight](http://popcyclical.com/content/binary/Windows-Live-Writer/HTML5-full-spectrum-spirograph_BBD7/spriospectrum-leafHeight_ebfa3ea8-4ee8-4f8a-8549-2d2b23ac75c4.png)Leaf using height
ctx.closePath()
```
![spriospectrum-leafHeight](../media/Windows-Live-Writer/HTML5-full-spectrum-spirograph_BBD7/spriospectrum-leafHeight_ebfa3ea8-4ee8-4f8a-8549-2d2b23ac75c4.png)Leaf using height
So, to compute the desired radius given for a given height, you can divide that height by the ratio between the center point and the leaf's bottom, sin(endPoint), multiplied by 2 to account for the top half:  radius = height / (sin(arcAngles.end) * 2)
So, to compute the desired radius given for a given height, you can divide that height by the ratio between the center point and the leaf's bottom, sin(endPoint), multiplied by 2 to account for the top half:  `radius = height / (sin(arcAngles.end) * 2)`
Also note that I'm trying the rotate again, except I'm just repositioning the center point of the second arc instead doing that messy translate.  This allows the leaf to be defined by only one set of start and end angles which get reused in the second arc.
@@ -218,7 +268,10 @@ Finally, I've added another variable, arcDelta, to capture the offset between th
### Composing
Now to the fun stuff the process to draw a leaf can now be encapsulated and we can start drawing neat patterns.  Let's make a class for the leaf.class Leaf
Now to the fun stuff the process to draw a leaf can now be encapsulated and we can start drawing neat patterns.  Let's make a class for the leaf.
```
class Leaf
constructor: (height, @fillStyle = '#fdf6e3', arcDelta = .2) ->
@arcAngles =
start: (1.5 + arcDelta) * pi,
@@ -247,7 +300,11 @@ Now to the fun stuff the process to draw a leaf can now be encapsulated and
ctx.fillStyle = @fillStyle
ctx.fill()
ctx.restore() var Leaf;
ctx.restore()
```
```
var Leaf;
Leaf = (function() {
Leaf.name = 'Leaf';
@@ -279,17 +336,26 @@ Now to the fun stuff the process to draw a leaf can now be encapsulated and
return Leaf;
})();
```
I've added the compiled JavaScript for comparison to the right.  This is where [CoffeeScript](http://coffeescript.org) starts to spread its wings.  The [class definition](http://coffeescript.org/#classes) is much neater the prototype functions are taken care of, the this repetitive-keystroke-injury-waiting-to-happen is replaced with @, you've got default values for arguments and this is just scratching the surface.  So, now that we can easily draw some leaves...ctx.translate(size/2, size) #bottom center
I've added the compiled JavaScript for comparison to the right.  This is where [CoffeeScript](http://coffeescript.org) starts to spread its wings.  The [class definition](http://coffeescript.org/#classes) is much neater the prototype functions are taken care of, the `this` repetitive-keystroke-injury-waiting-to-happen is replaced with `@`, you've got default values for arguments and this is just scratching the surface.  So, now that we can easily draw some leaves...
```
ctx.translate(size/2, size) #bottom center
leaves = [
new Leaf(size, '#c3d5eb')
new Leaf(size/9 * 8, '#648dcf', .25)
new Leaf(size/5 * 4, '#12204d', .3)
new Leaf(size/2, 'white', .35)
]
leaf.draw() for leaf in leaves![spriospectrum-leafObject](http://popcyclical.com/content/binary/Windows-Live-Writer/HTML5-full-spectrum-spirograph_BBD7/spriospectrum-leafObject_064d4632-b88d-4cec-98f2-8b6783fa571a.png)Leaf Object
leaf.draw() for leaf in leaves
```
![spriospectrum-leafObject](../media/Windows-Live-Writer/HTML5-full-spectrum-spirograph_BBD7/spriospectrum-leafObject_064d4632-b88d-4cec-98f2-8b6783fa571a.png)Leaf Object
Now we're cooking with gas!  (badum-ching - I'll be here all week) The next step is to draw the spirograph from the Illustrator tutorial...class SpiroLeaves
Now we're cooking with gas!  (badum-ching - I'll be here all week) The next step is to draw the spirograph from the Illustrator tutorial...
```
class SpiroLeaves
constructor: (leafCount, radius, arcDelta = 1/10) ->
@rotateAngle = (pi*2)/leafCount
hsla = (i) -> "hsla(#{i/leafCount*360}, 100%, 50%, .2)"
@@ -306,23 +372,28 @@ Now we're cooking with gas!  (badum-ching - I'll be here all week) The next ste
ctx.globalCompositeOperation = "lighter"
spiroLeaves = new SpiroLeaves(18, size / 2)
spiroLeaves.draw(ctx)![spriospectrum-spiroLeaves](http://popcyclical.com/content/binary/Windows-Live-Writer/HTML5-full-spectrum-spirograph_BBD7/spriospectrum-spiroLeaves_73187dbe-bd48-4666-b4be-3f5e451c3c2b.png)Full on rainbow spirograph
spiroLeaves.draw(ctx)
```
![spriospectrum-spiroLeaves](../media/Windows-Live-Writer/HTML5-full-spectrum-spirograph_BBD7/spriospectrum-spiroLeaves_73187dbe-bd48-4666-b4be-3f5e451c3c2b.png)Full on rainbow spirograph
A few notes...
- The SpiroLeaves constructor takes...
- leafCount which is how many leaves you want to be drawn... it is used to calculate the angle to rotate between each leaf - @rotateAngle = (pi*2)/leafCount
- leafCount which is how many leaves you want to be drawn... it is used to calculate the angle to rotate between each leaf - `@rotateAngle = (pi*2)/leafCount`
- radius which is simply passed as the height for each leaf
- arcDelta which how "skinny" or "squat" the leaves will be. Can be values between 0 and .5, with the larger the value, the skinnier.
- The hue of each leaf is calculated this function - hsla = (i) -> "hsla(#{i/leafCount*360}, 100%, 50%, .2)". This produces a gradient hue between 0 and 360, with 100% saturation, 50% lightness, and an alpha value of .2.  Read more [here at w3.org](http://www.w3.org/wiki/CSS/Properties/color/HSLA).
- The hue of each leaf is calculated this function - `hsla = (i) -> "hsla(#{i/leafCount*360}, 100%, 50%, .2)"`. This produces a gradient hue between 0 and 360, with 100% saturation, 50% lightness, and an alpha value of .2.  Read more [here at w3.org](http://www.w3.org/wiki/CSS/Properties/color/HSLA).
- Before drawing, the context is set to [globalCompositeOperation](http://mudcu.be/journal/2011/04/globalcompositeoperation/) = "lighter" so that the colors in overlapping leaves will reinforce each other.
- Before drawing, the context is set to `[globalCompositeOperation](http://mudcu.be/journal/2011/04/globalcompositeoperation/) = "lighter"` so that the colors in overlapping leaves will reinforce each other.
Finally let's do something really cool and animate this.  I'll draw two overlapping copies of the SpiroLeaves slowly rotating in opposite directions.spiroLeaves = new SpiroLeaves(18, size)
Finally let's do something really cool and animate this.  I'll draw two overlapping copies of the SpiroLeaves slowly rotating in opposite directions.
```
spiroLeaves = new SpiroLeaves(18, size)
i = 0
drawFrame = ->
@@ -343,17 +414,26 @@ drawFrame = ->
ctx.restore()
i += 1
setInterval drawFrame, 25![spriospectrum-spiroSpin](http://popcyclical.com/content/binary/Windows-Live-Writer/HTML5-full-spectrum-spirograph_BBD7/spriospectrum-spiroSpin_thumb.gif)Spin It
setInterval drawFrame, 25
```
![spriospectrum-spiroSpin](../media/Windows-Live-Writer/HTML5-full-spectrum-spirograph_BBD7/spriospectrum-spiroSpin_thumb.gif)Spin It
Nice! I've made a [jsfiddle](http://jsfiddle.net) with this code setup feel free to tinker and make something of your own.  [Here's the link](http://jsfiddle.net/poprhythm/g2WMu/).  Also, if you'd like to bring your CPU to its knees, make the canvas full screen.
This is my first foray into both HTM5 Canvas and CoffeeScript and I'm simply sharing what I've learned.  So, please feel free to make any corrections and/or suggestions.
---
HTML5 Canvas resources: [HTML5 Canvas Tutorials](http://www.html5canvastutorials.com/), [HTML5 Canvas Cheat Sheet](http://blog.nihilogic.dk/2009/02/html5-canvas-cheat-sheet.html)
CoffeeScript resources:  [CoffeeScript.org](http://coffeescript.org/), [CoffeeScript Cookbook](http://coffeescriptcookbook.com/), [The Little Book of CoffeeScript](http://arcturo.github.com/library/coffeescript/)
P.S. I had mentioned that I had already drawn something on the canvas before the leaves.  This would be the grid pattern here's the code:# draws a nice grid on the canvas
---
P.S. I had mentioned that I had already drawn something on the canvas before the leaves.  This would be the grid pattern here's the code:
```
# draws a nice grid on the canvas
drawGrid = (ctx, styles) ->
line = (x1,y1,x2,y2) ->
ctx.beginPath()
@@ -386,3 +466,4 @@ $ ->
ctx.fillStyle = '#002b36'
ctx.fillRect(0,0,size,size)
drawGrid(ctx, ['#657b83','#29434C','#073642','#073642'])
```
@@ -5,24 +5,35 @@ slug: traveling-salesman-problem-visualization
published: true
---
![Traveling Salesman Problem Excerpt](http://popcyclical.com/content/binary/Windows-Live-Writer/Traveling-Salesman-Problem-Visualization_11F14/Untitled-2_3.jpg)
![Traveling Salesman Problem Excerpt](../media/Windows-Live-Writer/Traveling-Salesman-Problem-Visualization_11F14/Untitled-2_3.jpg)
Over the last 9 weeks I've had the pleasure of being enrolled in the [Discrete Optimization](http://www.coursera.org/course/optimization) course at [Coursera](http://www.coursera.org) taught by [Pascal Van Hentenryck](https://www.coursera.org/instructor/~256). I had previously taken several of other massive open online courses (MOOCs), but this was the most challenging and rewarding. The key ingredients of this course were the unquestionable enthusiasm by its instructor and assistants, who created an excellent series of lectures and were personally involved at every step, as well as a game-like grading system, where the better your algorithm, the better your grade. It was rather intense! None of the programming assignments are issued with a well-defined strategy for creating a solution. Instead, the lectures cover various types of techniques and tools to be implemented and tinkered with by the students. Another interesting feature of the course is that all of the lectures and assignments are available from the first day. Most courses impose a schedule of lectures and assignments to be watched and completed on a week-by-week basis. The open structure of Discrete Optimization had me feeling a bit bewildered at first. They do provide a suggested study plan, so I (mostly) stuck with that and was able to make steady progress throughout the course.
One of the topics that resonated with many of the students, myself included, was that of [Local Search](http://en.wikipedia.org/wiki/Local_search_(optimization)). It's an idea that's easy to conceptualize and program, yet very powerful. I implemented a Local Search solution for the Traveling Salesmen Problem and, along the way, added some code to visualize some of the larger solutions. It looked pretty cool to see so many points connected together by a continuous route. I began experimenting with animating the algorithm as it finds a solution. Later, the professor's assistant (AKA graciously-answering-forum-questions-[Carleton Coffrin](http://www.coffr.in/)) put out a call for the students to create visualizations of various heuristics that can be used to solve TSP. Here is my contribution it displays [Greedy algorithm](http://en.wikipedia.org/wiki/Greedy_algorithm), [Local Search](http://en.wikipedia.org/wiki/Local_search_(optimization)), and [Simulated annealing](http://en.wikipedia.org/wiki/Simulated_annealing) strategies for a group of US cities. Traveling Salesman Problem Visualization
---
Ive seen some interest in knowing how this was created. Here are the steps:
- I wanted to use some "real" map data to help illustrate the problem.  From a list of cities from [geonames.org](http://www.geonames.org/export/), filtered by country and population to generate data sets
- Ran these through my TSP solver from the Discrete Optimization course assignment, collecting the intermediate routes as improvements are made
- Generated a metric ton of still images to illustrate the transitions between the routes - this involves:
- translating the points and lines onto a bitmap
- "tweening" many frames between each route to provide smooth transitions. I tried several different "easing functions" but ended up with something like "easeInOutQuad" shown on this [Easing Functions](http://easings.net/) page
- … also generate images for the distance and temperature
- Imported these as numbered frames into Adobe Premiere Elements - I don't use anything fancy, just the text, some cross-dissolve transitions, and alter the speed of the frames - the same could likely be done with open source editors ( [VLMC](http://www.videolan.org/vlmc/)?)
- The map of the US is a "flat" Mercator projection so that the latitude and longitude coordinates from the city list will show up in approximately the correct location - it's from here: [Mercator Projection.svg](http://commons.wikimedia.org/wiki/File:Mercator_Projection.svg)
- ... and then a bunch of slicing and dicing and mixing and matching inside the video editor to "tell the story"
The code was done in .NET heres some pseudo-code used to generate the animation:minX, minY = points.Minimum(X), points.Minimum(Y)
The code was done in .NET heres some pseudo-code used to generate the animation:
```
minX, minY = points.Minimum(X), points.Minimum(Y)
maxX, maxY = points.Maximum(X), points.Maximum(Y)
w = maxX - minX
h = maxY - minY
@@ -67,3 +78,4 @@ Translate(point)
EaseInOut(x)
(x*x)/(x*x + (1 - x)*(1 - x))
```