Tuesday, November 15, 2011

Choen the counterBot

I'm pretty excited... both my kids seem interested in computers and what you can do with them. My daughter, especially, is very interested in learning bits and pieces about programming. My son is interested, but not so much in the nuts & bolts of programming. He is interested in numbers and performance, though. They're both young, though... he's in 1st grade, and she's in 2nd.

She's expressed some interest in programming before. Last time we talked about application design... she got extremely ambitious and drew about twenty pages of "designs" (hand-drawn mock-ups of screens) for games that she wanted to create. (Essentially knock-offs of games she's played on favorite websites like PBS Kids and Pixie Hollow.)

More recently, she was using my computer, and discovered that when she's logged into my computer on her account, she has access to Visual Studio Express. When she asked what it was, I told her it was tools to write programs, and she just lit up. Immediately, she wanted to start working on a simple UI that mimics a math program she uses at school.

I started to realize, however, that she needs to learn more of the basics before we dive into a full fledged user interface. I started to think about some of the earliest programs I learned to write.

Back when I was in 4th grade, I got my hands on an Apple II, and one of the first programs I learned to write on it was a program that accepted two numbers (start and finish) and simply scrolled out a count between them.

Nowadays, we have object oriented programming, and C#, but I wanted to try to keep it simple and understandable for her. I decided that we would create a "counter-bot" class, and we would create an instance of it named whatever she wanted it to be named (She decided on Choen (pronounced more like Cohen)).

Today, we got the basics of the counterBot class written, and wrote a short program to create an instance of it, initialize it, and start counting, sending the numbers out to the screen. A countBot has beginAt, finishAt, countBy properties, and Start, Count, GetCurrentNumber and isFinished commands.

Here's the code:
counterBot.cs:
--------------------------------------------------------
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Choen_the_counterBot
{
    class counterBot
    {
        public int beginAt;
        public int finishAt;
        public int countBy = 1;
        private int currentNumber;
    
        public void Start()
        {
            currentNumber = beginAt;
        }

        public int GetCurrentNumber()
        {
            return currentNumber;
        }

        public void Count()
        {
            currentNumber = currentNumber + countBy;
        }

        public bool isFinished()
        {
            bool result=false;
            if (currentNumber > finishAt)
            {
                result = true;
            }
            return result;
        }

    }
}

--------------------------------------------------------


and here's the console Main method in program.cs:
--------------------------------------------------------
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace Choen_the_counterBot
{
    class Program
    {
        static void Main(string[] args)
        {
            counterBot Choen = new counterBot();
            Choen.beginAt = 0;
            Choen.finishAt = 2000000;

            Choen.Start();
            DateTime startTime = DateTime.Now;
            
            while (!Choen.isFinished())
            {
                Console.WriteLine(Choen.GetCurrentNumber());
                Choen.Count();
            }
            
            Console.WriteLine("Finished counting from " 
                + Choen.beginAt.ToString() 
                + " to " 
                + Choen.finishAt.ToString()
                + " by " 
                + Choen.countBy 
                + "'s in " 
                + (DateTime.Now - startTime)
                       .Seconds.ToString() 
                + " seconds!");
      
            Console.ReadKey();
        }
    }
}


--------------------------------------------------------


I got a bit fancy and added the timer code to see how long it took. Together, my son, daughter, and I watched Choen the counterBot count out various scenarios, and got as ambitious as watching it count from zero to two million. In order to get my son's interest, I added the timer to see how long it took. We discovered that my computer can count from zero to two million, "out loud" (showing the numbers on the screen) in 52 seconds. If we hid the console writes, it could do it in less than a second.

Next time we play with it, we'll write a graphic UI (a windows form) and hook Choen the counter bot up to it.

Friday, March 11, 2011

Code Generation

I've been evangelizing code generation since the work I did at Providus / FRS Global...

One of my arguements on the topic got published by Edgewater...

I love the picture on it... :)

Friday, March 4, 2011

SharePoint Saturday NH

I'm psyched to be a part of the founding and building of SharePoint Saturday for New Hampshire. It's a part of the Granite State SharePoint Users Group (follow twitter @NHSharePointUG ) or check us out on Linked-IN.

Stay tuned for more info.... lots of exciting stuff happening for the SharePoint community in NH.

Edit: May have jumped the gun on this a bit... the site may not be publicly accessible... yet. I'll update this post when it's made public.

Friday, April 24, 2009

Infrastructure Agility via Cloud Technology

I'm honored to have just been published on Edgewater's public blog...

It's bit about managing infrastructure agility. The basic idea is architecting your infrastructure so that you can push off parts to different clouds when you need to, for any of a multitude of reasons. The idea goes a bit beyond virtualization.

Check it out:

http://edgewatertech.wordpress.com/2009/04/24/best-practice-cloud-computing/

Workstation Virtualization

I've been having fun (ya, really... fun!) with MS VPC 2007 SP1 lately.

I've put some VM's on a portable USB disk. USB2 isn't the best connection, but it's workable. It does a few things... adds a spindle to the system config, offloading that overhead from the main disk.

An external disk also means the VM is "portable". I can launch the VM on my laptop or any other host system (like my home system) without any significant difficulty. Even better, by having the VPC config files on the host, rather than on the external disk, you can tune VM settings (like memory and network connectivity) for optimal conditions on the host system.

One other nice time-saver is differencing disks. You can create a "base" virtual hard disk, and create VHD's that are deltas of the base... by doing this, you can create a primary configuration, and then create several machines that inherit that basic config. It came in very handy for a recent product evaluation... I just created a base VM roughly according to what the client expects to host the system on, and then created VMs based on that for each product I wanted to evaluate.

Another nice feature is virtual assist hardware. At first, I didn't know my ThinkPad had it, but it turns out to be a BIOS setting. Flip that on, do a cold boot, and VM performance is visibly better. I knew of some of the other features from past experience with MS VPC 2005, but the hardware acceleration is new to me. (Ironically, my newer home desktop, a 64-bit monster with huge RAM doesn't support the hardware assist... performance isn't a problem, there, tho. )

One more trick: enable the Undo disk option... It put another layer of protection on your VM, allowing you snap a line on your VM at a point in time that you can back-out to. The cool part about this is that the Undo disk is created as a temporary file on the host system, (typically on the primary system drive). This distributes load across the spindles even more, which further improves run-time performance. The downside: when it comes time to commit the undo, it can take a while.

I still love the idea, going forward, of putting client dev environments on a config like this... Not only does it create a nice level of separation between client system configurations, but when you get your hands on better hardware, migration is not an issue.

Wednesday, February 18, 2009

Reading SharePoint Lists into an ADO.Net DataTable, Updated

I've been integrating processes with SharePoint lists for some time now. I made a post back in September '08 about how to pull a SharePoint list into an ADO.NET DataTable.

A very kind reader contributed a much appreciated simplified solution. It actually worked for general cases, but didn't solve a fundamental problem (one of the reasons I posted my version of the code to begin with): What if you have a column with odd characters in the name, like "EntityA.Property1"?

Unfortunately, ADO.NET imports columns with certain character encodings as DBNull. I suspect this might be a bug, but the example below shows a very simple WPF form that uses the basic technique with a slight variation to work around the issue:

using System;
using System.Collections.Generic;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;
using data = System.Data;
using xml = System.Xml;
namespace WindowsApplication1
{
///
/// Interaction logic for Window1.xaml
///

public partial class Window1 : System.Windows.Window
{


public Window1()
{
InitializeComponent();
}


public void OnLoaded(object sender, RoutedEventArgs args)
{
SharePointLists.
Lists listsService = new WindowsApplication1.SharePointLists.Lists();
listsService.Url =
"http://spsite/_vti_bin/lists.asmx";
listsService.Proxy =
null;
listsService.UseDefaultCredentials =
true;
xml.
XmlNode listData =
listsService.GetListItems(
"Test List",
default(string),
null,
null,
default(string),
null,
default(string));

//Takes care of columns with names like "EntityA.Property1", gets rid of "ows_" prefix:
listData.InnerXml = listData.InnerXml.Replace(
"_x002e_", "_").Replace("ows_", "");

data.DataSet listDataSet = new data.DataSet();
xml.
XmlNodeReader listDataReader = new xml.XmlNodeReader(listData);
listDataSet.ReadXml(listDataReader);
CollectionViewSource dataObj = (CollectionViewSource)Resources["Data"];
dataObj.Source =
new data.DataView(listDataSet.Tables[1]);

}
}
}


Here's the XAML component:

<
Window x:Class="WindowsApplication1.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="WindowsApplication1" Height="300" Width="300"
Loaded="OnLoaded"
>

<
Window.Resources>
<
CollectionViewSource x:Key="Data" />
</
Window.Resources>

<
Grid DataContext="{StaticResource Data}">
<
ListBox ItemsSource="{Binding}" DisplayMemberPath="EntityA_Property1"/>
</
Grid>

</
Window>

Wednesday, February 4, 2009

WORKAROUND: Misconfigured Windows-Integrated Authentication for Web Services

In trying to drive a process from a SharePoint list, I ran across a problem...

I couldn't create a web reference in my C# project due to some really weird problem... In the "Add web reference" wizard, I entered my URL, and was surprised by a pop-up titled "Discovery Credential", asking me for credentials for the site.

Since I was on the local domain and had "owner" permissions to the site, I thought I would just waltz in and get the WSDL.

Ok, so it wants creds... I gave it my own.

Negative...!?!?

After a few attempts and access denied errors, I hit Cancel, and was rewarded by, of all things, the WSDL display... but I still couldn't add the reference.

After quite a bit of wrestling, it turns out there was an authentication provider configuration problem. The site was configured to use Kerberos authentication, but the active directory configuration was not set up correctly. (I believe it needed someone to use SetSPN to update the Service Principal Name (SPN) for the service.)

One way to resolve the problem was to set the authentication provider to NTLM, but in my case, I didn't have, (and wasn't likely to get) that configuration changed in the site (a SharePoint Web Application) I really needed access to.

In order to make it work, I had to initially create my reference to a similar, accessible site.

(e.g. http://host/sites/myaccessiblesite/_vti_bin/lists.asmx )

Then, I had to initialize the service as such, in code:




private void InitWebService()
{
System.Net.AuthenticationManager.Unregister("Basic");

System.Net.AuthenticationManager.Unregister("Kerberos");

//System.Net.AuthenticationManager.Unregister("Ntlm");

System.Net.AuthenticationManager.Unregister("Negotiate");

System.Net.AuthenticationManager.Unregister("Digest");



SmokeTestSite.Lists workingLists = new SmokeTest.SmokeTestSite.Lists();

workingLists.Url = "http://host/sites/mybrokensite/_vti_bin/lists.asmx";

workingLists.UseDefaultCredentials = true;

workingLists.Proxy = null;

lists = workingLists;
}


What this accomplishes is it unregisters all authentication managers in your application domain. (This can only be done once in the same app domain. Attempts to unregister the same manager more than once while the program's running will throw an exception.)

So by having all the other authentication managers disabled in the client, the server would negotiate and agree on Ntlm authentication, which succeeds.