Thursday, February 28, 2013

shopping

I've spent about $2,000 this week buying new software for my laptop. I own legitimate copies of Visual Studio Professional 2012 and Adobe Photoshop CS6 now. The modern Visual Studio is grey. The modern Photoshop is very dark grey! This follows a $2,500esque Dell purchase for an XPS Windows 8 Laptop with touch screen and a copy of Microsoft Office 2013. That is enough spending for now.

I may not know much about WinForms but I sure know how to hack.

Application.Restart(); will close and refresh/reopen a WinForms app and that's one way to refresh the data in all of the tabs. :P

Wednesday, February 27, 2013

observer pattern name

foo and bar are "listening" for fubar to "act" in this example, hence the name

Super Simple Observer Pattern Example

I keep destroying my own blog postings by accident. I wrote a really cool one about four animals being poisioned by a nuclear explosion which served as an example of the observer pattern. It is gone now. I offer the following instead. First take in these three classes:

  1. namespace FubarApp.Objects
    {
       public class Foo
       {
          public bool IsAltered { get; set; }
          
          public Foo()
          {
             IsAltered = false;
          }
          
          public void UpdateAlteredState(bool value)
          {
             IsAltered = value;
          }
       }
    }
     
  2. namespace FubarApp.Objects
    {
       public class Bar
       {
          public bool IsAltered { get; set; }
          
          public Bar()
          {
             IsAltered = false;
          }
          
          public void UpdateAlteredState(bool value)
          {
             IsAltered = value;
          }
       }
    }
     
  3. using System;
    namespace FubarApp.Objects
    {
       public class Fubar
       {
          public Action AlterationStateUpdater;
       }
    }
     

Alright, here they are in action! (pun intended)

using FubarApp.Objects;
using Microsoft.VisualStudio.TestTools.UnitTesting;
namespace FubarApp.Tests
{
   [TestClass]
   public class UnitTest
   {
      [TestMethod]
      public void Test()
      {
         
//start as false
         Foo foo = new Foo();
         Bar bar = new Bar();
         Assert.AreEqual(foo.IsAltered, false);
         Assert.AreEqual(bar.IsAltered, false);
         
         
//still false
         Fubar fubar = new Fubar();
         fubar.AlterationStateUpdater = foo.UpdateAlteredState;
         fubar.AlterationStateUpdater += bar.UpdateAlteredState;
         Assert.AreEqual(foo.IsAltered, false);
         Assert.AreEqual(bar.IsAltered, false);
         
         
//no longer false
         fubar.AlterationStateUpdater(true);
         Assert.AreEqual(foo.IsAltered, true);
         Assert.AreEqual(bar.IsAltered, true);
      }
   }
}

.designer.cs is one of two patterns I've seen for partial classes

The other shape I have seen has a partial class made by a code generation tool, such as a T4 template, and then a separate partial class of a human hand for extending the code generated stuff. The second file has to be independent as otherwise the code generation tool would overwrite the human crafted stuff upon updates.

Tuesday, February 26, 2013

Modify the startup list in Windows 8!

I figured out how to disable McAfee on my new laptop. I largely used this as my guide.

  1. I moved my cursor to the lower right corner so that the Windows 8 charm bar would appear, then I clicked on the "Search" icon. I found the "Command Prompt" icon in the sea of icons which appeared and I right-clicked upon it and then picked "Pin to taskbar" which put an icon for the "Command Prompt" on the taskbar at my desktop.
  2. I opened the Command Prompt from my taskbar at my desktop and typed "services.msc" which spawned a window titled "Services" where I...
    • I found the items that started with "McAfee" and, one-by-one, right-clicked upon them and picked "Properties" from the menu which appeared.
    • Another dialog box spawned for each item. Each box had four tabs. The "General" tab had a "Startup type" drop down and I set its value to "Disabled" in the instances where I could change its value which was not all instances.
    • I clicked "OK" at each of the "General" tabs.
  3. I opened the Command Prompt from my taskbar at my desktop and typed "msconfig" which spawned a window titled "System Configuration" where I...
    • Went to the "Startup" tab and clicked on the link for "Open Task Manager" which opened the "Startup" tab in a new window dubbed "Task Manager"
    • I right-clicked on "McAfee Security Center" and selected the "Disable" option.
  4. I restarted and on the other side of the restart there was no more McAfee!

bunk history

Don't mistake the dates here as history. The database could have been made from a .bat file that came from another database that has the history.

Object Explorer Details

"Object Explorer" is a very common, friendly pane found under the "View" menu in Microsoft SQL Server Management Studio, however, did you know that the "View" menu also holds "Object Explorer Details" which when opened side-by-side with "Object Explorer" will give you specs on the thing you have selected at "Object Explorer!" For example, click on "Stored Procedures" under "Programmability" under a database at "Object Explorer" to see a list of the stored procedures at "Object Explorer Details" where there will be a column for "Create Date" and also one for "Date Last Modified" (you have to unhide this column) which should help you see what has changed recently.

Make someone an administrator in Windows 7.

  1. right-click on "My Computer" or the comparable icon and pick "Manage"
  2. at the Computer Management pane that appears navigate to: Computer Management (Local) > System Tools > Local Users and Groups > Groups
  3. right-click on the "Administrators" group and select "Add to Group..." from the menu which appears
  4. add individuals here at the "Administrators Properties" window which pops up

Get the touch screen keyboard for Windows 8.

at: Charm Bar > Settings > Keyboard

Without touching the screen, access the charm bar in Windows 8.

I like the charm bar, but I am smudging the screen with my fingers. There is a solution! If I move my cursor to the far lower right of the screen the charm bar will appear!

Monday, February 25, 2013

Haters Gonna Hate Marissa

What rock stars we developers are! There aren't enough of us to go around and we know it. We can demand high salaries for playing with our vaporware file cabinets all day long and the perks don't stop there. We are such princesses that we don't see why we shouldn't be able to just stay at home one day and week while still getting paid. Don't our employers know how special we are?

I saw news break at cnn.com today that Marissa Mayer, the CEO of Yahoo, is putting an end to the silly work-from-home thing that poisons productivity at her company. A quote from her is: "To become the absolute best place to work, communication and collaboration will be important, so we need to be working side-by-side," to which I agree, philosophy-wise, completely. And yet, I checked Twitter for reactions by searching for "marissa" to find what I expected: Most of us are spoiled.

Sigh. Well, there are two ways this can go for Marissa and either way the haters are gonna hate.

  1. Marissa turns Yahoo around. This is not an easy undertaking. I don't know why she picked a sick company to jump to from Facebook to begin with. Maybe she likes the Herculean challenge. This will really make her if she pulls it off. It is not going to be easy. She is going to ruffle a lot of feathers in making tough choices just like this one.
  2. Marissa fails and Yahoo fails. As it all goes badly all of her tough choices are pointed to as examples of what a buffoon she was. She drove off all of the good people with her insistence that employees actually put on clothes when they work. Damn her.

Hmmm... there is always room for character assassination, believe me. Consider this guy:

Good:

  • fought and won the first world war, and especially so by trying to stay out of it
  • gave us income tax which IS better than tariffs
  • created the Federal Reserve
  • envisioned the League of Nations, a forerunner for modern day NATO
  • monopoly-busting stuff includes the Federal Trade Commission
  • child labor laws

Bad:

  • 19th century era opinions of black people, women, and immigrants

Well, we won't be making any statues of Woody any time soon. What a loser! It can be the same thing (fate) for Marissa too if our community chooses it. Haters gonna hate.

Update a table of contents in Microsoft Word.

Right-click on the TOC and pick "Update Field." You will then have to pick either the option for "Update page numbers only" or "Update entire table." The later update should be reflective of both the moves you made to the headings and the new headings you've added.

Sign the ClickOnce manifests

The checkbox for "Sign the ClickOnce manifests" under the "Signing" tab under the set of tabs one sees in Visual Studio 2010 when right-clicking upon a project and selecting "Properties" is where one turns on and off the requirement for a signing certificate. The certificates offer security if you use them. This seems to an article on as much.

restarting after a shutdown

The /r here is for restarting after a shutdown.

Sunday, February 24, 2013

Set the home page in Google Chrome.

There are two different places to do this under Settings. One is at "On startup" where you should select the option for "Open a specific page or set of pages" and then use the "Set pages" link by it to define the page while the other is at the "Show Home button" checkbox under "Appearance" (check it) where there will also be a link you must click to define what the Home button does.

prep work for TypeScript

I saw Shawn Weisfeld speak on TypeScript at the Dallas Day of Dot Net convention. He offered these links for getting started:

  1. http://www.typescriptlang.org/
  2. http://visualstudiogallery.msdn.microsoft.com/07d54d12-7133-4e15-becb-6f451ea3bea6

The second link gives a .vsix file. Hmmm. I think I am going to punt on setting this up until I can get the new laptop (which arrived yesterday) prepped.

Saturday, February 23, 2013

restoring the missing hotspot to an iPhone 4S

it is at: Settings > General > Network > Personal Hotspot

Addendum 9/9/2015: It should normally just be at: Settings > Personal Hotspot

estimating

I saw Steve McConnell of Code Complete fame who is also the CEO of Construx speak on estimating, the hardest challenge I've faced in technology, at AgileAustin on Wednesday night. Code Complete is an industry-revered treatise on software development not unlike Fred Brooks' The Mythical Man-Month, which I do not mention randomly. Mr. McConnell suggested that Brooks' Law of "adding manpower to a late software project makes it later" is not a reality in disciplined agile projects. This law is detailed in The Mythical Man-Month. My mother, Susan Jaeschke, worked for IBM for 33 years from 1969 to 2002 and she read Brooks' book, which I haven't, when it was brand new as Mr. Brooks worked at big blue like her at the same time. She has told me that one of the analogies in the book is that while it takes a woman nine months to have a baby it is a mistake to believe that one may put nine women together on a team to make a baby in one month. Naturally this speaks to the hero knowledge problem and how someone new to a team, not holding the hero knowledge, struggles to stay relevant. I suppose Fred Brooks saw a waste of time in ramping up others who are not already the hero. I've worked on two different Agile teams with hero knowledge problems. I get it, yet Steve McConnell envisions a light at the end of the tunnel for this pain point. The burn down chart shown with him in the photo I took here showed off his vision. He saw actual rate of process pulling away from desired rate of progress in a performance-decaying, worsening way initially upon adding new team members and then, ultimately, a correction in which the actual rate of progress bends back to come closer to the desired, impossibly-consistent rate of progress which is based on a fixed, estimated number of story points to be completed per sprint and represented by a diagonal line across time denoting how much work is left to be done and when it will be done. (Actually development is represented by a draw-as-you-go line which starts out at the same point as the diagonal line and then typically strays to the left of it as less gets done in a sprint than expected.) The word "late" in Brooks' Law was where Mr. Connell saw a problem. He felt that the projects Fred Brooks saw as almost done were anything but and thus Mr. Brooks was disappointed in what became of adding team members, but not because the team members were not performing. On the other hand, if a project was almost done, then adding more team members does not really make sense in Mr. Connell's model either where there is going to be some initial disorientation. I cannot help but read into Fred Brooks from Mr. Connell's perspective and believe that the projects were not almost done but instead that was just what management wanted to believe. If there had really been a light at the end of the tunnel there would not have been a reactionary demand for more resources. As complexity grows it often grows exponentially harder to make progress (especially so if you are fighting an anti-pattern) and thus a team near a finish line may really be merely halfway through an undertaking. There is a lot more to speak to in estimations for an Agile team than this resources quirk however. Estimating is not non-Agile and when teams see estimating from a we-hate-it-as-we-are-Agile perspective then they are apt to alienate management and make management hate Agile. Early successes of Agile in small projects have reinforced the we-should-not-do-estimates thing when the reality is that bigger projects have bigger demands.

Businesses do have finite plans and demand estimates for:
  1. Cost
  2. Schedule
  3. Functionality
There are three possible sources to collect estimate data from:
  1. Your Industry
  2. Your Organization
  3. Your Project

Clearly the third data source is better than the second which is itself much better than the first. As you start a project you will not have project data to draw from and as you build from Waterfall requirements (and this is the way Steve McConnell recommended to go) initially you will estimate correctly perhaps thirty percent of the time. Mr. McConnell asserted that in one to two years a team may be estimating correctly ninety to one hundred percent of the time however. It helps to practice and it helps to have the project data that you will eventually accumulate. Do not try to estimate a velocity until you have done a couple of sprints as then you may really see what your velocity actually is based upon what has gotten done. You do need to estimate however. Iterative development maybe a tremendous benefit but iterative requirements are a negative. A business would rather you were wrong than vague. If you plant a stake in the ground and then ultimately have to move the stake, well that is better than "I dunno" -flavored apathy.

The slide above shows a funnel of progressively dying ambiguity and waste by way of bad estimates (the yellow) which Mr. Connell envisions a successful project to have. You have to be a third of the way into the funnel before you are really hitting your stride in estimating the stories you are going to do (the green) and the stories you are not going to do (the red) in the name of bringing your burn down chart’s draw-as-you-go line back towards its diagonal line. (Those are my terms for the lines. :P) You have to be a third of the way into the funnel before you may use project data for estimates. Before you may get to that point, the following five legs of the project must be successfully bridged in chronological order:

  1. Initial Product Definition
  2. Approved Product Definition
  3. Requirements Specification
  4. Product Design Specification
  5. Detailed Design Specification

Wow! Wow! Waterfall! You do not want just anyone writing specifications. You need trained requirements workers. Software Requirements by Karl Wiegers was recommended by Steve McConnell as the best book on this topic.

Exception handling in JavaScript needs your love.

JavaScript exceptions cannot be captured selectively by way of subtype as is the convenient nature of C#. Instead one has to globally capture all potential exceptions and then make sense of them. If the exception you catch is not of the shape you hoped to filter for, then you will have to handle that what-do-I-do-with-this-thing-now problem with logic in your code. Captured exceptions unfortunately vary in mannerisms across different browser types, but the two properties that every JavaScript exception is going have are name and message:

function whatever() {
   try {
      freakout;
   }
   catch(error) {
      alert(error.name);
      alert(error.message);
   }
}

 
 

The alert for name above came back with "ReferenceError" for me in Firefox 16.0.2, Chrome 26.0.1410.12, and Safari 5.1.2 (7534.52.7) and "TypeError" in Internet Explorer 9.0.8112.16421 while the alert for message was "freakout is not defined" in Firefox and Chrome, "'freakout' is undefined" in Internet Explorer, and "can't find variable: freakout" in Safari. Clearly, the art of exception wrangling in JavaScript is not trivial. It is going to take some doing to make sense of errors and decide if they are something which you know you can handle within your application without stopping it (throw a modal to the screen with a message) or something you've not prepared for (let the application crash). You do need to take up the challenge however. Do not try to use an analysis tool like JSHint to find all possible errors for you or some other placebo to tell yourself that you write bug-free code. You're not that good. This was the subject of the first half of a talk by Lon Ingram of Waterfall Mobile (at AustinJS Tuesday night) which dovetailed into an overview of a testing tool he wrote called Reanimator which is named after the 1980s horror film. (When something crashes, Reanimator will simulate the nondeterministic user inputs, captured to a log, that led to the crash, on the other side of predefined initial state, in an attempt to reanimate the series of steps that led to the issue.)

How to catch: Mr. Ingram was not keen on catching exceptions from within a callback as he felt that any error messages one might get in callbacks were likely to be vague and thus worth little as they would not reveal the chain of events leading up to the callback. Instead, the actor who kicks off the asynchronous process which will hopefully fire off a callback is the better candidate for a try/catch block dress fitting. If a promise has a fail handler, then the fail handler could be referenced when throwing an error from a callback and, yes, this would be an exception to the rule just suggested. Also, window.onerror is the last line of defense for catching. Use it! For me, the variables captured in the example below behaved wildly different in all four of the browsers mentioned above. While url and lineNumber gave what you'd expect in Internet Explorer, Chrome, and Firefox, they didn't work in Safari where undefined was returned for url and 0 was returned for lineNumber. Again, only name and message are universal across all browsers. Internet Explorer gave the same thing it gave in the above example for message for error while Chrome, Firefox, and Safari instead gave a concatenation of name and message. Chrome’s was the strangest with "Uncaught ReferenceError: freakout is not defined" in contrast to Firefox's "ReferenceError: freakout is not defined" where the later browser didn't feel the need to append an extra word in advance of the beginning of the name/message concatenation. In Safari, I got: "ReferenceError: can't find variable: freakout"

window.onerror = function myErrorHandler(error, url, lineNumber) {
   alert(error);
   alert(url);
   alert(lineNumber);
}
function whatever() {
   freakout;
}

 
 

What to do with what you caught: You should probably send errors back to your own record keeping so that you'll know what your users and fighting out in the wild. When you build a database of this stuff, there will obviously be a lot of duplicates. You could try to "fingerprint" bugs to drop those which are not unique, but then again the duplicates and the metrics they offer may not necessarily be a bad thing. Suggested ways to send stuff back to yourself include:

  1. Largely invisible to the user, you could be serializing error messages and sending them back to yourself via AJAX. If you go this route you will want to get users to check a checkbox on a legal agreement given that you are collecting their information.
  2. Upon error, you could present a form to a user to complete to submit the error message back to home base. The form should be largely pre-populated with the data you wish to give to yourself, however this approach also allows users to type up their own commentary and hand it to you.
  3. You could give a user a mailto href link to click to send the data you want back to you by way of email. There may be a 2K cap on how much may be sent by a mailto link (depends on the browser) so this approach has some restraints. If you want to use a tool like stacktrace.js to capture the call stack from the point where you call an asynchronous function and then follow that up by handing yourself the serialized stack trace... this is NOT the best of the three options for you.

 
 

What to tell your users: It is best to communicate the errors of expected shapes back to the users. Tell the users what the bug was, how to report it, how much data was lost, and what they should do next. Should they just refresh the browser and try again?

Friday, February 22, 2013

C# cookies

Create a cookie:

HttpCookie myCookie = new HttpCookie("MyCookie");
myCookie["Content"] = "Hello World";
myCookie.Path = "/Support";
myCookie.Expires = DateTime.Now.AddDays(1d);
Response.Cookies.Add(myCookie);

 
 

Go fishing for it later on:

HttpCookie myCookie = new HttpCookie("MyCookie");
myCookie = Request.Cookies["MyCookie"];
if (myCookie != null)
{
   Label1.Text = myCookie["Content"];
}

Make Beyond Compare stop thinking files are different due to having different dates.

Session > Session Settings... > Comparison ...is where one may uncheck the "Compare timestamps" checkbox is Beyond Compare to make Beyond Compare stop thinking files are different due to having different dates.

Thursday, February 21, 2013

dynamic method calls in C#

Here is some more dynamic magic from C# 4.0 in a Nutshell. Consider these four classes:

  1. using System.Dynamic;
    namespace DynamicGunk.Objects
    {
       public class TourettesPatient : DynamicObject
       {
          public string Scream()
          {
             return "Aaaaaaaaaahhhhhhhhhhhhh!!!!!!!";
          }
       }
    }
     
  2. namespace DynamicGunk.Objects
    {
       public class EncephalitisLethargicPatient
       {
          public string SayNothing()
          {
             return "";
          }
       }
    }
     
  3. namespace DynamicGunk.Objects
    {
       public class IceCreamVan
       {
          public IceCreamCone GiveIceCreamToThoseWhoScream(dynamic person)
          {
             string vocalization = person.Scream();
             if (vocalization == "Aaaaaaaaaahhhhhhhhhhhhh!!!!!!!")
             {
                return new IceCreamCone();
             } else {
                return null;
             }
          }
       }
    }
     
  4. namespace DynamicGunk.Objects
    {
       public class IceCreamCone
       {
       }
    }
     

 
 

Here is the magic. This test passes! We may call the Scream method from within IceCreamVan as shown above if we are handing in a TourettesPatient.

using DynamicGunk.Objects;
using Microsoft.VisualStudio.TestTools.UnitTesting;
namespace DynamicGunk.Tests
{
   [TestClass]
   public class UnitTest
   {
      [TestMethod]
      public void Test()
      {
         TourettesPatient jack = new TourettesPatient();
         EncephalitisLethargicPatient jill = new EncephalitisLethargicPatient();
         IceCreamVan van = new IceCreamVan();
         IceCreamCone treat = van.GiveIceCreamToThoseWhoScream(jack);
         Assert.AreNotEqual(treat, null);
      }
   }
}

 
 

If we hand jill to van instead of jack, we do not get a failing test however, we end up with a test that throws an exception (as there is no Scream method on EncephalitisLethargicPatient to call). We have to alter IceCreamVan to make the jill scenario not blow up on us.

namespace DynamicGunk.Objects
{
   public class IceCreamVan
   {
      public IceCreamCone GiveIceCreamToThoseWhoScream(dynamic person)
      {
         try
         {
            string vocalization = person.Scream();
            if (vocalization == "Aaaaaaaaaahhhhhhhhhhhhh!!!!!!!")
            {
               return new IceCreamCone();
            }
         }
         catch
         {
         }
         return null;
      }
   }
}

 
 

This test will fail.

using DynamicGunk.Objects;
using Microsoft.VisualStudio.TestTools.UnitTesting;
namespace DynamicGunk.Tests
{
   [TestClass]
   public class UnitTest
   {
      [TestMethod]
      public void Test()
      {
         TourettesPatient jack = new TourettesPatient();
         EncephalitisLethargicPatient jill = new EncephalitisLethargicPatient();
         IceCreamVan van = new IceCreamVan();
         IceCreamCone treat = van.GiveIceCreamToThoseWhoScream(jill);
         Assert.AreNotEqual(treat, null);
      }
   }
}

 
 

The sort of exception swallowing we used here to make the two very different types that GiveIceCreamToThoseWhoScream may consume both manageable is pretty dirty. I am still trying to figure out the best sort of pattern for this sort of thing.

Pass variables to a C# console application.

...at the multifield "Start Options" fill-in-the-blank box at the Debug tab under the properties for a console project in Visual Studio 2012. Separate strings with spaces. They will populate the args array here in Program.cs:

static void Main(string[] args)
{
   string ourFirstArguement = args[0];
   Console.WriteLine(ourFirstArguement);
   Console.ReadLine();
}

a sproc with a brass padlock on it

If you are browsing the Stored Procedures under Programmability for a database in Microsoft SQL Server Management Studio and you see a sproc with a brass padlock on it, that means that the sproc isn't a sproc at all, but is instead a CLR object which may be called as one might call a sproc.

twenty minutes

This suggests that a Session in ASP.NET will last 20 minutes and has a link to this which offers a jQuery hack for keeping Session alive.

change the Author property in Microsoft Word

In Microsoft Word 2010 at: File > Info ...will be listed metadata for a given word document such as "Title" and "Author" and you may click on these items here to doctor them up.

Wednesday, February 20, 2013

Manhandle user inputs in a C# console app.

Today I made a silly console app that converts Fahrenheit values to Celsius values.

using System;
using Temperature_Calculator.Core;
namespace TemperatureCalculator
{
   class Program
   {
      static void Main(string[] args)
      {
         Console.Write("Type a number and then press enter: ");
         string concatenatedKeystrokes = "";
         ConsoleKeyInfo currentKeystroke;
         do
         {
            currentKeystroke = Console.ReadKey(true);
            concatenatedKeystrokes = Filter.Interpret(currentKeystroke,
                  concatenatedKeystrokes);
         }
         while (currentKeystroke.Key != ConsoleKey.Enter);
         Console.WriteLine("\r\n");
         Console.WriteLine(concatenatedKeystrokes + " in Fahrenheit converted to Celsius
               is...");
         Console.WriteLine(Converter
               .ToCelsius(Convert.ToDouble(concatenatedKeystrokes)));
         Console.WriteLine("\r\n");
         Console.WriteLine("Press any key to exit.");
         Console.ReadLine();
      }
   }
}

 
 

I teased a lot of the logic out to two static classes. The most interesting of which was this one, based upon this, which interprets user inputs and restricts them to digits and backspaces.

using System;
namespace Temperature_Calculator.Core
{
   public static class Filter
   {
      public static string Interpret(ConsoleKeyInfo keystroke, string history)
      {
         if (keystroke.Key != ConsoleKey.Backspace)
         {
            history = Add(keystroke, history);
         } else {
            history = Backspace(history);
         }
         return history;
      }
      
      private static string Add(ConsoleKeyInfo keystroke, string history)
      {
         double dummyDigit = 0;
         bool isDigit = double.TryParse(keystroke.KeyChar.ToString(), out dummyDigit);
         if (isDigit)
         {
            history += keystroke.KeyChar;
            Console.Write(keystroke.KeyChar);
         }
         return history;
      }
      
      private static string Backspace(string history)
      {
         if (history.Length > 0)
         {
            history = history.Substring(0, (history.Length - 1));
            Console.Write("\b \b");
         }
         return history;
      }
   }
}

 
 

Less interesting is...

namespace Temperature_Calculator.Core
{
   public class Converter
   {
      public static double ToCelsius(double fahrenheitValue)
      {
         double alteration = SubtractThirtyTwo(fahrenheitValue);
         alteration = MultiplyByFive(alteration);
         alteration = DivideByNine(alteration);
         return alteration;
      }
      
      private static double SubtractThirtyTwo(double value)
      {
         return value - 32;
      }
      
      private static double MultiplyByFive(double value)
      {
         return value * 5;
      }
      
      private static double DivideByNine(double value)
      {
         return value / 9;
      }
   }
}

 
 

Note that I did not make the Converter class static itself. It is only a "static" class in that it holds static methods. It is not truly a static class and I could just jam stuff like this into it:

public double LatestValue { get; set; }
 
public void SetState(double fahrenheitValue)
{
   LatestValue = ToCelsius(fahrenheitValue);
}

 
 

I could then use the instance method and the getsetter like so:

Converter converter = new Converter();
converter.SetState(Convert.ToDouble(concatenatedKeystrokes));
Console.WriteLine(converter.LatestValue);

Beyond Compare may be used to push files to a server.

  1. You will need to map a drive to the folder at a server where you wish to deploy to. (To do so, first share the folder by right-clicking on the folder and selecting "Properties." Next, navigate to the Sharing tab and click the "Share..." button. Finally, to map a drive, right-click on "My Computer" or the comparable desktop icon and select "Map network drive...")
  2. Open up Beyond Compare and select Folder Compare.
  3. Put the path to your local files in the empty dropdown list at the top left and the drive letter for the share, followed by a colon and a backslash, at the top right.
  4. Click the tan arrow at the right of the left drowndown list. This will allow you to see the files in both environments.
    • Blue files exist in one environment but not the other.
    • Red files exist in both environments but are more current where they are red.
  5. Right-click on files at the left and pick "Copy to Right" to deploy them. You should turn red items to neutral black in this manner.

Tuesday, February 19, 2013

Learn the 8 keys to a successful Windows 8 application

This was talk by Daniel Egan at the Dallas Day of Dot Net convention. The talk centered around the suggestion that it is a great time to jump into building apps for Windows 8 in contrast to the more saturated market of apps for iOS. The most interesting thing he mentioned was charms. This is a bar that will appear from the right and offers globally available commands for specific apps. There is always a Settings charm for an app for example, or at least there should be. Just as we are used to apps having a File dropdown menu in Windows 7 we should get used to having a Settings charm.

Monday, February 18, 2013

Beyond Compare by Scooter Software

...is a tool for comparing differences in files that have code in them. Go get it at: http://www.scootersoftware.com/

You may accept changes and push them up to a file share from within Beyond Compare.

Razor markup for MVC model-binding isn't too painful.

The first line of code in a View should give the type for the model like so:

@model Tuple<Guid, Guid>

 
 

Once you have a model, you may then fish for things inside of it with the usual dot syntax like so:

@Model.Item1 and @Model.Item2

 
 

Outside of the view, my Controller looks like this:

using System;
using System.Web.Mvc;
namespace GuidExperiment.Controllers
{
   public class HomeController : Controller
   {
      public ActionResult Index()
      {
         Guid foo = Guid.NewGuid();
         Guid bar = new Guid();
         Tuple<Guid,Guid> guidModel = new Tuple<Guid, Guid>(foo, bar);
         return View(guidModel);
      }
   }
}

Guid.NewGuid() versus new Guid() in C#

  1. Here... Guid foo = Guid.NewGuid(); ...the foo variable will end up with a "real" Guid in it like 20cc2758-cdcf-48ab-ae06-7ab34c4df8d5 with random characters. The Guid will be different each time.
  2. But here... Guid bar = new Guid(); ...the bar variable will end up with the same string of zeros every time. 00000000-0000-0000-0000-000000000000 will be the value. There is no randomization.

Sunday, February 17, 2013

Make a Windows Store app!

I saw Ryan Lowdermilk speak on designing Windows Store Apps for Windows 8 over a lunch break on the second day of the Dallas Day of Dot Net convention this year. He offered eight traits for a Windows 8 application:

  1. Microsoft-style Design
  2. Fast and Fluid
  3. Snap and Scale Beautifully
  4. Use the Right Contracts
  5. Invest in a Great Tile
  6. Feel Connected and Alive
  7. Roam to the Cloud
  8. Embrace Microsoft Design Patterns

 
 

The first bullet point speaks to the creative theme of Windows 8 which used to be called Metro until Metro AG threatened a lawsuit. Ryan spoke to how the brain works by breaking things up into chunks and chunks things into up to four subsets. He also spoke to the rule of thirds. If one has an image and it were broken into nine boxes like so:

     
     
     

 
 

...one should ideally line up the most interesting content along one of the midgrid lines instead of just trying to center the subject. Don't take away discoverability. It is alright to let someone wonder what happens if they click on something. In contrast, it is a mistake to make every clickable hotspot look like a button. Typically, navigation goes at the top bar and commands go at the bottom bar. These bars appear if one moves a mouse pointer there and are otherwise not to be seen, maximizing screen real-estate. Hide or grey-out submit buttons until all required form fields are completed. You can either make an app that has a flat pattern (think the forward and next pagination of Internet Explorer) or one where you may dive down to a second or third tier. There is a feature called Symantic Zoom which is available when a box with a hyphen in it appears at the lower right. The icon will allow for opening new content for the content at hand. One semantically zooms into deeper content. What should be given and how this will grow into a standardized expectation of experience is yet to be defined. Touch is a first class feature in Windows 8.

get rid of Price Peep malware at Internet Explorer

Go to: Tools > Manage add-ons ...turn off everything! It masquerades as something legitimate here.

Saturday, February 16, 2013

This is a C# example of the visitor pattern which could offend PETA.

I have learned about the visitor pattern in C# 4.0 in a Nutshell's 19th chapter which is on C#'s dynamic keyword. I am revamping what I did here to use the visitor instead of the observer pattern to give an example. This is story of four animals which are affected in different ways by visiting the site of a thermonuclear explosion:

  1. an asp named Lucifer,
  2. a bug named Gregor (winking at Kafka),
  3. a cat named Felix,
  4. and a dog named Spot.

 
 

This test passes:

[TestMethod]
public void Visiting_SiteOfThermonuclearExplosion_Should_Affect_Animals()
{
   Asp lucifer = new Asp();
   Bug gregor = new Bug();
   Cat felix = new Cat();
   Dog spot = new Dog();
   
   Assert.AreEqual(lucifer.IsHiding, false);
   Assert.AreEqual(lucifer.IsSickly, false);
   
   Assert.AreEqual(gregor.IsHiding, true);
   Assert.AreEqual(gregor.IsSickly, false);
   
   Assert.AreEqual(felix.IsHiding, false);
   Assert.AreEqual(felix.IsSickly, false);
   
   Assert.AreEqual(spot.IsHiding, false);
   Assert.AreEqual(spot.IsSickly, false);
   Assert.AreEqual(spot.IsRoamingTheCountrysideFoamingAtTheMouth, false);
   
   SiteOfThermonuclearExplosion siteOfThermonuclearExplosion =
         new SiteOfThermonuclearExplosion();
   lucifer = siteOfThermonuclearExplosion.WelcomeVisitor(lucifer);
   gregor = siteOfThermonuclearExplosion.WelcomeVisitor(gregor);
   felix = siteOfThermonuclearExplosion.WelcomeVisitor(felix);
   spot = siteOfThermonuclearExplosion.WelcomeVisitor(spot);
   
   Assert.AreEqual(lucifer.IsHiding, false);
   Assert.AreEqual(lucifer.IsSickly, true);
   
   Assert.AreEqual(gregor.IsHiding, false);
   Assert.AreEqual(gregor.IsSickly, true);
   
   Assert.AreEqual(felix.IsHiding, true);
   Assert.AreEqual(felix.IsSickly, true);
   
   Assert.AreEqual(spot.IsHiding, false);
   Assert.AreEqual(spot.IsSickly, true);
   Assert.AreEqual(spot.IsRoamingTheCountrysideFoamingAtTheMouth, true);
}

 
 

What preceded was the whole of our story for Lucifer, Gregor, Felix, and Spot. Perhaps we should step through it again, slowly. There are two chapters to our story:

  1. In chapter one, our heroes are born.
    Asp lucifer = new Asp();
    Bug gregor = new Bug();
    Cat felix = new Cat();
    Dog spot = new Dog();
    Assert.AreEqual(lucifer.IsHiding, false);
    Assert.AreEqual(lucifer.IsSickly, false);
    Assert.AreEqual(gregor.IsHiding, true);
    Assert.AreEqual(gregor.IsSickly, false);
    Assert.AreEqual(felix.IsHiding, false);
    Assert.AreEqual(felix.IsSickly, false);
    Assert.AreEqual(spot.IsHiding, false);
    Assert.AreEqual(spot.IsSickly, false);
    Assert.AreEqual(spot.IsRoamingTheCountrysideFoamingAtTheMouth, false);
     
  2. In chapter two, our antagonist is visited by our heroes.
    SiteOfThermonuclearExplosion siteOfThermonuclearExplosion =
          new SiteOfThermonuclearExplosion();
    lucifer = siteOfThermonuclearExplosion.WelcomeVisitor(lucifer);
    gregor = siteOfThermonuclearExplosion.WelcomeVisitor(gregor);
    felix = siteOfThermonuclearExplosion.WelcomeVisitor(felix);
    spot = siteOfThermonuclearExplosion.WelcomeVisitor(spot);
    Assert.AreEqual(lucifer.IsHiding, false);
    Assert.AreEqual(lucifer.IsSickly, true);
    Assert.AreEqual(gregor.IsHiding, false);
    Assert.AreEqual(gregor.IsSickly, true);
    Assert.AreEqual(felix.IsHiding, true);
    Assert.AreEqual(felix.IsSickly, true);
    Assert.AreEqual(spot.IsHiding, false);
    Assert.AreEqual(spot.IsSickly, true);
    Assert.AreEqual(spot.IsRoamingTheCountrysideFoamingAtTheMouth, true);
     

 
 

Let's talk through who our actors are. First off, our villain is defined as so:

using WhosWatchingMe.Core.Animals;
namespace WhosWatchingMe.Core
{
   public class SiteOfThermonuclearExplosion :
         SiteOfThermonuclearExplosionHelper<Animal>
   {
      protected override Animal GiveRadiationSickness(Animal animal)
      {
         animal.IsSickly = true;
         return animal;
      }
      
      protected override Animal GiveRadiationSickness(Dog dog)
      {
         dog.IsRoamingTheCountrysideFoamingAtTheMouth = true;
         dog.IsHiding = false;
         return base.GiveRadiationSickness(dog);
      }
   }
}

 
 

Our villain has an assistant. It would be possible to skip making this parent if one were to skip using the override keyword. SiteOfThermonuclearExplosion would take a mildly different shape in such a scenario. It would work akin to the way the example here does its thing. I'll get into why I decided not to go this way in a moment.

namespace WhosWatchingMe.Core.Animals
{
   public abstract class SiteOfThermonuclearExplosionHelper<T> where T : Animal
   {
      public T WelcomeVisitor<T>(T animal)
      {
         animal = GiveRadiationSickness((dynamic)animal);
         return (T)animal;
      }
      
      protected abstract T GiveRadiationSickness(Animal animal);
      protected virtual T GiveRadiationSickness(Dog dog)
      {
         return GiveRadiationSickness((Animal)dog);
      }
   }
}

 
 

Once again our four animals are:

  1. an asp named Lucifer,
    namespace WhosWatchingMe.Core.Animals
    {
       public class Asp : Animal
       {
          public Asp()
          {
          }
       }
    }

    Asp is our easiest object. Asp is a truly bland implementation of Animal. Lucifer will act as any Animal would by default. Gregor, Felix, and Spot are also of types inheriting from Animal as well, yet they behave differently which must mean that their types of Animal must do more than the Asp subclass of Animal which brings no polymorphism (overriding) to the base shape. Animal is where things gets interesting. The base class looks like so:
    namespace WhosWatchingMe.Core
    {
       public abstract class Animal
       {
          public virtual bool IsHiding { get; set; }
          public virtual bool IsSickly { get; set; }
          
          public Animal()
          {
             IsHiding = false;
             IsSickly = false;
          }
       }
    }

    Animal carries getsetters for IsHiding and IsSickly and its constructor sets both as false. Lucifer starts our story neither hiding nor sickly. He never hides, but he does end up sick. How so? SiteOfThermonuclearExplosion sets IsSickly to true!
     
  2. a bug named Gregor (winking at Kafka),
    namespace WhosWatchingMe.Core.Animals
    {
       public class Bug : Animal
       {
          public override bool IsSickly
          {
             get
             {
                return base.IsSickly;
             }
             set
             {
                base.IsSickly = value;
                if (value)
                {
                   IsHiding = false;
                } else {
                   IsHiding = true;
                }
             }
          }
          
          public Bug()
          {
             IsHiding = true;
          }
       }
    }

    Bug has a constructor which makes it hide by default, the opposite of the default behavior Animal's constructor imposes. Bug also overrides the IsSickly getsetter on Animal to offers some additional behavior. Whenever a bug gets sick it stops hiding. If it gets better it will start hiding again. Gregor starts our story both hiding and healthy and ends up sick and exposed.
     
  3. a cat named Felix,
    namespace WhosWatchingMe.Core.Animals
    {
       public class Cat : Animal
       {
          public override bool IsSickly
          {
             get
             {
                return base.IsSickly;
             }
             set
             {
                base.IsSickly = value;
                IsHiding = value;
             }
          }
          
          public Cat()
          {
          }
       }
    }

    Cat is more complicated than Asp but not as complicated as Bug. It overrides the IsSickly state and there makes the IsHiding state match the IsSickly state. Felix does not hide and is not sick at the beginning of our story. Once he gets sick, he also hides as he is a Cat.
     
  4. and a dog named Spot.
    namespace WhosWatchingMe.Core.Animals
    {
       public class Dog : Animal
       {
          public bool IsRoamingTheCountrysideFoamingAtTheMouth { get; set; }
          
          public Dog()
          {
             IsRoamingTheCountrysideFoamingAtTheMouth = false;
          }
       }
    }

    Dog has an additional getsetter which its constructor sets to false. The magic around the dynamic keyword in SiteOfThermonuclearExplosion and SiteOfThermonuclearExplosionHelper allows for the Dog type to be cherry-picked in lieu of the Animal type to allow for setting the getsetter which Animal does not have. Spot begins life not hiding, feeling fine, and not deranged. Upon visiting the site of a nuclear explosion he becomes sick and goes berserk.
     

 
 

If we wanted to throw away SiteOfThermonuclearExplosionHelper then the last method in SiteOfThermonuclearExplosion would have to look like this:

protected Animal GiveRadiationSickness(Dog dog)
{
   dog.IsRoamingTheCountrysideFoamingAtTheMouth = true;
   dog.IsHiding = false;
   dog.IsSickly = true;
   return dog;
}

 
 

Honestly, in keeping with this we would likely have a method like so:

protected Dog GiveRadiationSickness(Dog dog)
{
   dog.IsRoamingTheCountrysideFoamingAtTheMouth = true;
   dog.IsHiding = false;
   dog.IsSickly = true;
   return dog;
}

 
 

Alas, if we just double-type the code for the base class effect we are guilty of breaking the don't repeat yourself rule. I should have seen this when I wrote this but I did not. I have this in the other blog posting:

public override void AdsorbRadiation()
{
   this.IsSickly = true;
   this.IsHiding = false;
   this.IsRoamingTheCountrysideFoamingAtTheMouth = true;
}

 
 

It should be this instead:

public override void AdsorbRadiation()
{
   base.AdsorbRadiation();
   this.IsHiding = false;
   this.IsRoamingTheCountrysideFoamingAtTheMouth = true;
}

 
 

The visitor is perhaps supposed to be the actor doing the manipulation and not the actors getting manipulated. I'm not sure. I might have that semantically backwards. I forgive myself though.

MVVM is the Model-View-ViewModel Pattern.

This suggests that Martin Fowler came up with it, that the view model translates real data into DTOesque presentation data, and that WPF projects may use it.

The dynamic keyword allows one to cherry pick more specific types when applicable.

Here I wrote one of my first experimentations with dynamic upon beginning Chapter 19 of C# in a Nutshell. With every page I read I am more impressed. In learning a little more, I made this change to the Adder class I wrote before:

namespace Whatever.Objects
{
   public static class Adder
   {
      public static T Add<T> (T originalValue, T addendum)
      {
         dynamic combo = (dynamic) originalValue + addendum;
         return (T) combo;
      }
      
      public static string Add(string originalValue, string addendum)
      {
         string combo = originalValue + " " + addendum;
         return combo;
      }
   }
}

 
 

Now concatenation will end up with hello world in it instead of helloworld without a space, well, that is if the code in my example could compile. This is pretty amazing! When using dynamic to resolve a type, dynamic will fall over to more specific types if such types are available!

Friday, February 15, 2013

Test exceptions.

I need a way to pull all of the TextBox types from a web form and then check their contents for questionable items which could be used in cross-site scripting attacks:

public static void FailIfDangerous(List<TextBox> textBoxes, string connectionString)
{
   List<string> textBoxValues = (from textBox in textBoxes where textBox.Text != null
         select textBox.Text).ToList();
   Dictionary<int, string> blacklist = UseSelectStoredProcedure(connectionString);
   foreach (string textBoxValue in from blacklistItem in blacklist from textBoxValue in
         textBoxValues where textBoxValue.ToLower().Contains(
         blacklistItem.Value.ToLower()) select textBoxValue)
   {
      throw new System.InvalidOperationException("Cannot pass " + textBoxValue + " as
            it has content that falls inside of the blacklisted content for prevention of
            cross-site scripting attacks.");
   }
}

 
 

I wrote the code snippet above which I am testing like so:

[TestMethod]
public void happy_pass_test_passes()
{
   
//Arrange
   TextBox foo = new TextBox() { Text = "foo" };
   TextBox bar = new TextBox() { Text = "bar" };
   TextBox baz = new TextBox() { Text = "baz" };
   TextBox qux = new TextBox();
   List<TextBox> textBoxes = new List<TextBox>() { foo, bar, baz, qux };
   string exception = null;
   
   
//Act
   try { SanityChecker.FailIfDangerous(textBoxes, connectionString); }
   catch (InvalidOperationException e) { exception = e.Message; }
   
   
//Assert
   Assert.AreEqual(exception, null);
}
 
[TestMethod]
public void happy_fail_test_passes()
{
   
//Arrange
   TextBox foo = new TextBox() { Text = "foo" };
   TextBox bar = new TextBox() { Text = "bar" };
   TextBox baz = new TextBox() { Text = "baz" };
   TextBox qux = new TextBox() { Text = "ascii" };
   List<TextBox> textBoxes = new List<TextBox>() { foo, bar, baz, qux };
   string exception = null;
   
   
//Act
   try { SanityChecker.FailIfDangerous(textBoxes, connectionString); }
   catch (InvalidOperationException e) { exception = e.Message; }
   
   
//Assert
   Assert.AreEqual(exception, "Cannot pass ascii as it has content that falls inside of the
         blacklisted content for prevention of cross-site scripting attacks.");
}

 
 

HP Fortify was reporting some security holes to do with passing values in forms and Response.Redirect implementations for which there was little cure. Our security consultant suggested that the bugs could go unfixed if we were to use a blacklisting means to make sure potential values for cross-site scripting attacks were not passed in form fields and a whitelisting means to make sure that Response.Redirect only passed to legitimate URLs legitimate URL line variables. In the case of the inbound form values causing Fortify bugs, many such errors may be curtailed by rewriting direct SQL as stored procedures with parameterized inputs, HOWEVER, when data comes back out of the database and binds to a GridView type there is the opportunity for HTML pushed in through user inputs to be malicious.

get all the textboxes in a web form

List<TextBox> textBoxes = form1.Controls.Cast<Control>().Where(control =>
      control.GetType() == typeof (TextBox)).Cast<TextBox>().ToList();

combing through one's browser cache

I have managed to screw up and destroy the blog posting I wrote on Casey Watson speaking on Azure at Monday's Austin .NET User Group. In my frustration I found tools for combing through one's browser cache for Chrome and IE.

Addendum on 2/16/2013: I have decided that I am now mad enough about losing my notes on Casey Watson's Azure talk to try to recreate some of them. Alright, here we go. Azure is Microsoft's cloud stuff. (Think of Amazon or Heroku for Ruby or Rackspace cloud.) This is the front door and this is a calculator for pricing. Anyways...

  • IaaS is Infrastructure as a Service. This allows one to spin up VMs (virtual machines) in the cloud. The VMs cannot be copied about and one has to run all of one's updates one's self. This approach to cloudlife offers the most control, but also comes with the delicate-little-snowflake problem.
  • PaaS is Platform as a Service. PaaS is built on IaaS. Here one makes canned copies of VMs. An app straddling the VMs can scale up, in terms of platform, to use other copies and thus the canning is crucial. Software updates for the operating systems are automatic and the operating systems do not strictly have to be Windows-flavored. There are options for Linux and Ubuntu. There are also options for spinning up MSSQL and mySQL databases in the cloud. When developing an app for an Azure environment that straddles numerous VMs, one should not use Session. It is better to either go stateless or use Azure's goofy way of emulating Session.
  • SaaS is Software as a Service. SaaS is built on PaaS. To make a really terrible analogy, this is akin to having a shared hosting environment in which one may shove up an app to a holding place and get it running there while one does not have any control over the operating system's settings or that of the web server within the operating system. There are some canned starting points for apps. There is an ASP.NET Web API template and there is also a Drupal template. These are examples of "web roles" while "worker roles" in contrast are processes that may live in SaaS environments that kick off scheduled jobs or watch for activities to happen before kicking off scheduled jobs.

CSUpload is a tool for pushing a VM up to Azure from one's laptop. At Azure, one may monkey with the VM and pull it back down via another tool called Capture. VMs come down as VHD (virtual hard disk) files and then they have to somehow be cast back to VMs. From C# one may interact with Azure ServiceBus and also Azure Storage Services (get Azure Storage Libraries from NuGet).

Thursday, February 14, 2013

Chris Love on Web Performance optimization for Modern Web Applications

<link rel="shortcut-icon" href="/favicon.ico" />

...is a very important tag! It is not a tag to just not include. Instagram made the mistake of not implementing this tag and ended up having a horror story because of it. If you do not have a favicon, a browser will look for it nonetheless and this will slow down your site even more when it is being hammered with hits. Instagram alleviated the majority of its latency pains during one struggle by just adding this tag to its HTML. This is one of many helpful optimizations that Chris Love suggested in a talk on web optimizations on Saturday at the Dallas Day of Dot Net convention. Other tidbits:

  • Optimizing for the web helps SEO.
  • Minimize 3rd party scripts. It is OK to have Google analytics by itself perhaps, but not JavaScript for five different analytics packages. The marketers that think this helps you do not realize that it in fact hurts you by slowing down your site and thus discouraging visitors.
  • Local storage adds less weight than cookies. It is quicker.
  • Image sprites are cool.

I will end with offering that Chris heavily encouraged that JavaScript not be kept in blobs within HTML itself. It should be pulled out to .js files. Blocks of code in HTML load as the page loads and ultimately slow down the loading of a page. The .js files load asynchronously as needed. We talked about how to get around the problem of an inability for variables from C# to bubble up into JavaScript without having JavaScript directly in a view or web form as clearly C# cannot be injected into a .js file. Chris suggested that the dynamic content could populate hidden form fields from which it might be grabbed by JavaScript in a .js file. Here is an example of the sort of clean up we discussed. Below is an MVC view from the code I wrote for this:

<h4>AJAJ-style "AJAX" in progressive record loading:</h4>
<div id="records">
   <div class='altout'>
      <div class='in'>License Number</div>
      <div class='in'>Expiration Date</div>
      <div class='in'>Must Wear Glasses?</div>
   </div>
</div>
@Html.Partial("Next", "Three")
<script type="text/javascript">
   $(function () {
      var collection = new Array();
      collection.length = @ViewBag.OneThirdOfRecordCount;
      var counter = 0;
      $(collection).each(function () {
         $('#records').animate({ opacity: "1" }, 100, function () {
            $.ajax({
               type: "POST",
               url: '/Ajax/GetPageOfRegisteredDriverRecordSet/' + counter,
               dataType: 'json',
               success: function (result) {
                  $.each(result, function(index, value) {
                     var html = "<div class='out'>";
                     html = html + "<div class='in'>" + value.Id + "</div>";
                     html = html + "<div class='in'>" + value.Date + "</div>";
                     html = html + "<div class='in'>" + value.Bool + "</div>";
                     html = html + "</div>";
                     $('#records').append(html);
                  });
                }
            });
            counter = counter + 3;
         });
      });
   });
</script>

 
 

I refactored it to be like so:

<h4>AJAJ-style "AJAX" in progressive record loading:</h4>
<div id="records">
   <div class='altout'>
      <div class='in'>License Number</div>
      <div class='in'>Expiration Date</div>
      <div class='in'>Must Wear Glasses?</div>
   </div>
</div>
<input type="hidden" value="@ViewBag.OneThirdOfRecordCount" id="hidden"/>
@Html.Partial("Next", "Three")
<script src="@Url.Content("~/Scripts/progressivelyloadrecords.js")"
      type="text/javascript"></script>

 
 

progressivelyloadrecords.js is a new file containing:

$(function () {
   var collection = new Array();
   collection.length = $('#hidden').val();
   var counter = 0;
   $(collection).each(function () {
      $('#records').animate({ opacity: "1" }, 100, function () {
         $.ajax({
            type: "POST",
            url: '/Ajax/GetPageOfRegisteredDriverRecordSet/' + counter,
            dataType: 'json',
            success: function (result) {
               $.each(result, function (index, value) {
                  var html = "<div class='out'>";
                  html = html + "<div class='in'>" + value.Id + "</div>";
                  html = html + "<div class='in'>" + value.Date + "</div>";
                  html = html + "<div class='in'>" + value.Bool + "</div>";
                  html = html + "</div>";
                  $('#records').append(html);
               });
            }
         });
         counter = counter + 3;
      });
   });
});

 
 

I was pleasantly surprised I didn't have to use parseInt() on the value I grabbed out of the hidden form field.

Wednesday, February 13, 2013

use dynamic to add nonspecific types in C# 4.0

I'm getting into the 4.0 part of C# 4.0 in a Nutshell (a book I'm reading), and I don't mean Tuples. I mean dynamic! I didn't see what was so special about dynamic below until I tried to somehow strip it out. There is no way else to do the addition of two instances of T.

namespace Whatever.Objects
{
   public static class Adder
   {
      public static T Add<T> (T originalValue, T addendum)
      {
         dynamic combo = (dynamic) originalValue + addendum;
         return (T) combo;
      }
   }
}

 
 

If we use the static method like so...

int foo = 13;
int bar = 42;
string baz = "hello";
string qux = "world";
int sum = Adder.Add(foo, bar);
string concatenation = Adder.Add(baz, qux);
DateTime timeToFreakOut = Adder.Add(baz, qux);

 
 

...then we should expect...

  1. sum would end up with 55 inside of it if this code could compile
  2. concatenation would end up with helloworld inside of it if this code could compile
  3. timeToFreakOut makes it so the code cannot compile as the type to assign to is not consistent with the types handed in

dev, UAT and production versions of asmx web services

What if you want to set up different versions of the asmx web service your web site uses for the different environments your web site is instantiated in such as development, the user acceptance testing staging grounds, and the live, real thing web site? This seems somewhat painful. There is no way to designate what URL the asmx points to from Web.config as best as I can tell. I do not see a way to have an appSetting in XML in Web.config bubble up to the XML the .disco, .discomap, or .wsdl XML files of an amsx web service. I guess you could include three different asmx web services and swap between them in C# based upon a Web.config setting, but that would also be... ghetto. I think you have to conceptualize the web service as its own app and test it independently. The only hack I have for this problem so far is to change the hosts file of an environment running an app to reroute a URL a web service is to be found at elsewhere and to do the environmental swapping one might otherwise do at Web.config at one's hosts file at the different servers for dev, UAT, and production.

Tuesday, February 12, 2013

Session doesn't use cookies.

The server remembers who you are at the browser until you close the browser.

Monday, February 11, 2013

Sunday, February 10, 2013

Continuous Delivery

  1. Design
  2. Develop
  3. Test
  4. Release
  5. Design
  6. Develop
  7. Test
  8. Release
  9. Design
  10. Develop
  11. Test
  12. Release
  13. etc.

...this loop is continuous delivery. If you are only looping Design/Develop/Test without the Release piece then you may be doing continuous integration, but continuous delivery entails having the Release step in the cycle to ensure the users are living the new code instead of being "protected" from it. This was the subject of a talk by Jimmy Bogard at the Dallas Day of Dot Net convention yesterday. In this model something is "done" when it is in production. This model throws away the following distinctions:

  1. done
  2. done, done
  3. done, done, done

...in which the first means that the developers are done, the second means that the product owners have checked off on it, and the three-peat suggests that the feature that is done has made it into production. The boundaries and distinctions for the three versions of done stem from a realization that it may not be easy to get from one variety of done to another. If you do need the distinction of the three varieties of done, that may highlight a problem. Ideally, it shouldn't be that painful to get something into production. Jimmy asserted that Facebook has new hires develop a feature and get it into production the first day one is on the job as part of its onboarding process. The longer one delays being at "done" the longer a feature goes unproven and the more painful it gets to get it to done. If there is a hurdle to bridge in getting a feature into production that makes a team hesitant to push, as much suggests a problem. Really any pain point suggests a problem. "If something hurts, do it more often" was a rule reiterated. If things are painful, it is only by doing them more often that a team deals with the pain. Don't hide from pain. This is the premise behind the third of the seven rules Jimmy offered for a repeatable, reliable process for releasing software to eliminate the need for the three versions of done:

  1. automate almost everything
  2. keep almost everything in source control
  3. bring the pain forward
  4. build quality in
  5. done means released
  6. everyone is responsible
  7. continuous improvement

(The "almost" in the second rule means that configuration-specifics are exempt and the final rule demands a culture in which individuals recognize a need to a fix a problem when something goes wrong.)

About half of the talk was on the continuous integration (automate almost everything) technologies. There was some stuff I was familiar with, such as Tarantino, and other stuff I was less familiar with. I have been in TFSland for the last four stints of employment and have not yet used Git for source control. If I were using Git, when I made a commit via a Powershell command line (example > git push origin master), I could kick off a process at TeamCity, a build server agent, which could then deploy via a Psake script (that is what the stuff in the picture above is) to a production environment, if the build didn't break due to an inability to compile code or a failing test. I've not used TeamCity or Powershell yet either. The CI stuff is still, to me, something neat that I hope someone else in the room can do. (I'm still, and may always be, a junior developer.) Azure can also watch a Git repository and kick off a push to another environment upon a change. The Init task below will wipe clean and recreate a database. You will want to do this before running every integration test that interfaces with the database.

You will also want to have test-specific/test-friendly data on hand when running integration tests. This is likely a different dataset than the data you might hold for just browsing the site or showing it off in a demo. No problem. You can have both. Psake configurations allow for different preparations in different environments. Use Psake to prep data one way for testing and another for demos.

I am used to having a src folder for source code and a lib folder for .dlls and other supporting stuff at the root of what I might check into source control for any one application. Jimmy had five folders. Beyond lib, the src folder was renamed to code and there was also a build folder, a LatestVersion folder, and a psakev4 folder which I suppose is for psake scripts. I think LatestVersion was what the name implied while build was a temporary build-to place with contents perpetually being destroyed and recreated. Jimmy added a new field to a database schema via Tarantino as part of an example of a new feature and then rolled it out. When rolling such a change out to production you have to ask yourself about how you will handle backwards compatibility. Will rows of data without the field...

  1. become illegitimate?
  2. be allowed to legitimate without the data point?
  3. be redacted to keep a dummy value?

The Tarantino means of note-keeping for SQL scripts makes easy deploying only the deltas (differences or discrepancies between two versions) of SQL scripts (which make up the whole of schema) in the name of making surgical updates to existing schemas without dropping all of the tables and starting fresh.

I'm OK

This year I attended, for the second time, the Dallas Day of Dot Net convention, or, well, I attended the half of it that fell on a Saturday as I had to work during the half that fell on a Friday. Typing this, I'm now fifteen days out from my exwife's death and I'm in a better place to type up actual blog entries on the stuff I saw instead of the crazy notes I gave eight days ago from the HTML5.tx convention. I'm OK.

There is going to be a series of blog postings from me on each of the talks I saw. They will not all come today and some may even take a backseat (in terms of my documentation) to the talk I'll see tomorrow at the Austin .NET User Group. I'll try to type up notes on Jimmy Bogard's talk next (today). I left him for last the last year and then by the time I went to type up notes, my notes no longer made sense to me. He gave a great talk on NServiceBus that I did not retain.

OK Tom, stop babbling.

Richard Campbell of .NET Rocks fame gave a talk called "Saving the World in 60 Minutes: The Humanitarian Toolbox" in which he suggested a digital path to volunteerism. http://humanitariantoolbox.net/ is a forum where geeks may volunteer their time towards building for charities and comparable organizations. Even if you are replacing that old, 1998 web site with Drupal, you are helping! Charities need this stuff. I interfaced with Austin's Family Connections quite a bit before its demise and gained an appreciation for how tight the budget for web development may be in the nonprofit space. Such enterprises could indeed benefit from digital volunteerism. The most interesting thing in Richard's talk was a fact he gave: "I'm OK" is the most common text message. This really comes out in crisis situations. He had worked on an app that allowed one to easily broadcast "I'm OK" from a cell phone and have it cascade to social media, email lists, etc. Cool stuff.

I want to end with two pictures from eight days ago at HTML5.tx. I have decided they are too awesome not to share. The first is Jesse Cravens speaking on The Internet of Things:

Below are Paul Herrera and William J. Moner having a dialog in the "Background in Bullshit" open space. If you are good at "Where's Waldo" you may also see Cori Drew in this photo.

I'm OK.