blog.dashpoint.com

Twitter Conversations an Agile Case Study

clock December 12, 2008 04:33 by author Administrator

Twitter Conversations

From time to time Twitter Users engage in conversations. It is a royal pain to follow these conversations using the native Twitter programs including the web version of Twitter.  As an exercise I began creating an application that would allow me to follow Twitter conversations. This is the story of creating that application.

User Story
     As a Twitter user I want to be able to follow conversations between other Twitter users.

This post will accomplish two things.
1. Fulfill the requirements of the user story.
2. Create a small application that can be used by the ALT.NET/Agile/Lean community to learn numerous agile software development concepts including:  test driven development, dependency injection, how good design affects testing, etc.

Note: The second item in the list came from conversations at KaizenConf (www.kaizenconf.com  kaizenconf.pbwiki.com). These conversations centered on the need to create a learning application. I am submitting this application as a case study so that we all may learn from it.
To accomplish the story we need the following parts:

1. A mechanism for communicating with Twitter.
2. Query Twitter UserID’s based on list of screen names.
3. Query messages for each user in list of screen names.
4. Filter messages where the message content contains any of the names in the list of screen names.
The first step is to define a domain model. The following domain model represents the different elements that will help in fulfilling the requirements of the user story.

• User
    o UserID(int)
    o ScreenName(string)
    o UserName (string)
    o Followers (int)
• Message
    o MessageID(int)
    o MessageDate(string)
    o MessageContent(string)
    o UserID (int)
    o UserName(string)

Unit Tests (Part 1)
After creating the domain model began creating unit tests for my API. I decided to divide my API into two subject areas: Users and Messages. The User API is used to query Twitter User information. The Message API is used to query Twitter Status(s) aka messages. The following code is the first set of unit tests.

<TestFixture()> _
Public Class UnitTests

  <Test()> _
  Sub Should_Return_My_Following()
    Dim UserAPI As New Twitter.API.User
    Assert.That(UserAPI.GetUsers().count > 0)
  End Sub

  <Test()> _
  Sub Should_Return_Single_User()
    Dim UserAPI As New Twitter.API.User
    Assert.That(UserAPI.GetUser(UserAPI.GetMyUser().UserID.ToString).ScreenName _
       = "rodpaddock")
    End Sub

  <Test()> _
  Sub Should_Return_Single_User_ByName()
      Dim UserAPI As New Twitter.API.User
      Assert.That(UserAPI.GetUser("rodpaddock").ScreenName = "rodpaddock")
  End Sub

  <Test()> _
  Sub Should_Return_My_User()
      Dim UserAPI As New Twitter.API.User
      Dim User As Twitter.Domain.User = UserAPI.GetMyUser
      Assert.That(UserAPI.GetMyUser().ScreenName = "rodpaddock")
  End Sub

  <Test()> _
  Sub Should_Return_My_Messages()
      Dim MessageAPI As New Twitter.API.Message
      Assert.That(MessageAPI.GetMyMessages().Count > 0)
  End Sub

  <Test()> _
  Sub Should_Return_Messages_By_User()
      Dim MessageAPI As New Twitter.API.Message
      Assert.That(MessageAPI.GetUserMessages("rodpaddock").Count > 0)
  End Sub

  <Test()> _
  Sub Should_Return_Messages_From_MultipleUsers()
      Dim MessageAPI As New Twitter.API.Message
      Dim UserAPI As New Twitter.API.User
      Dim UserQuery As New List(Of Twitter.Domain.User)
      UserQuery.Add(UserAPI.GetUser("rodpaddock"))
      UserQuery.Add(UserAPI.GetUser("chriswilliams"))
      Assert.That(MessageAPI.GetMultipleUserMessages(UserQuery.ToArray).Count > 0)
  End Sub
End Class

This set of unit tests does a good job of covering our API’s and insuring they all work as planned. But the tests do have a number of design flaws. For now we’ll leave them alone and look at some of the code they are testing.

Twitter Basics

Now that you have looked at the domain model and the unit tests, take a look at the process of fulfilling these unit tests. For this exercise consider the following unit test.

<Test()> _
Sub Should_Return_Single_User_ByName()
   Dim UserAPI As New Twitter.API.User
   Assert.That(UserAPI.GetUser("rodpaddock").ScreenName = "rodpaddock")
End Sub

To fulfill the requirements of this test the following things must occur:
1. Application must connect to Twitter
2. Application must retrieve user data based on the passed in username
3. The data returned must be transformed into a usable User domain object.

The following code fulfills the requirements of this test:

Const GetUserURL As String = "http://twitter.com/users/show/<<USERID>>.json"
Public Function GetUser(ByVal id As String) As Twitter.Domain.User

    Dim Credentials As New NetworkCredential("<<YourUserName>>", "<<YourPassword>>")
    Dim Request As HttpWebRequest = _
        HttpWebRequest.Create(GetUserURL.Replace("<<USERID>>", id.ToString))
    Request.Method = "GET"
    Request.Credentials = Credentials

    Dim Response As WebResponse = Request.GetResponse
    Dim Reader As New StreamReader(Response.GetResponseStream)
    Dim Results As String = Reader.ReadToEnd

    Dim JsonSerializer As New System.Web.Script.Serialization.JavaScriptSerializer
    Dim UserObject As Object = JsonSerializer.DeserializeObject(Results)

    Return New Twitter.Domain.User With { _
       .UserID = UserObject("id"), _
       .UserName = UserObject("name"), _
       .ScreenName = UserObject("screen_name"), _
       .Followers = UserObject("followers_count")}

    End Function

This code performs the following tasks:
1. Created a  NetworkCredentials object with your Twitter user name and password. All twitter requests use basic authentication.
      Dim Credentials As New NetworkCredential("<<YourUserName>>", "<<YourPassword>>")
2. Created an HttpWebRequest based on Twitter’s REST API. This call will return data in JSON format as specified via the .json extension on the URL.
     Dim Request As HttpWebRequest = _
      HttpWebRequest.Create(GetUserURL.Replace("<<USERID>>", id.ToString))
      Request.Method = "GET"
      Request.Credentials = Credentials

3. Read data from the web request stream using a Stream Reader.
       Const GetUserURL As String = "http://twitter.com/users/show/<<USERID>>.json"
       Dim Response As WebResponse = Request.GetResponse
       Dim Reader As New StreamReader(Response.GetResponseStream)
       Dim Results As String = Reader.ReadToEnd

4. Deserialize the JSON data into an array of Name/Value pair data using the .Net JSON serializer.
       Dim JsonSerializer As New System.Web.Script.Serialization.JavaScriptSerializer
       Dim UserObject As Object = JsonSerializer.DeserializeObject(Results)
5. Turn the returned user information into a User domain object
       Return New Twitter.Domain.User With { _
         .UserID = UserObject("id"), _
         .UserName = UserObject("name"), _
         .ScreenName = UserObject("screen_name"), _
         .Followers = UserObject("followers_count")}
 
That’s pretty much how all communication works with Twitter. If you closely examine the code you will find a number of design flaws. Basically this code was developed as a spike: “Let’s see how we can pull data from Twitter”. The basic pattern: authenticate, request and parse was cut and pasted into each API call. I did this knowing that that the code (and tests) would be refactored into a proper design.

Refactoring the Code

After completing the first run through the code (getting it working) it was time to refactor. I gave myself some of goals:
1. Reduce the amount of redundant code.
2. Create a better designed set of test code (remove redundancy)
3. Prepare the code for dependency injection (current tests require internet connections)

The “authenticate and request” process received the first refactoring. This process can be pseudo coded as follows:

Given a valid set of user credentials and a REST URL return a string result.

From this pseudo code we created a Twitter communication class.

Imports System.Web
Imports System.Net
Imports System.IO

Public Class TwitterRequest
    Private UserName As String = ""
    Private Password As String = ""
    Sub New(ByVal UserName As String, ByVal Password As String)
        Me.UserName = UserName
        Me.Password = Password
    End Sub

    Function GetTwitterRequest(ByVal URL As String) As String
        Dim Credentials As New NetworkCredential(Me.UserName, Me.Password)

        Dim Request As HttpWebRequest = HttpWebRequest.Create(URL)
        Request.Method = "POST"
        Request.Credentials = Credentials

        Dim Response As WebResponse = Request.GetResponse
        Dim Reader As New StreamReader(Response.GetResponseStream)
        Dim Results As String = Reader.ReadToEnd
        Return Results

    End Function
End Class

Now we have a wrapped class that needs two items in its constructor (UserName , Password) and has a single method GetTwitterRequest(URL). The GetTwitterRequest(URL)’s job is to return a JSON string that will be used by the subsequent API call.

All of the code necessary for  communicating with Twitter is encapsulated into this class.

Next step was to refactor the User and Message API’s.  The first step involved creating a constructor that accepted a TwitterRequest object. The constructor for the Message API changed to: 

 Dim Communicator As Twitter.Communication.TwitterRequest = Nothing
 Dim JsonSerializer As New System.Web.Script.Serialization.JavaScriptSerializer

  Sub New(ByVal TwitterCommunicator As Twitter.Communication.TwitterRequest)
      Me.Communicator = TwitterCommunicator
  End Sub

These two refactorings reduced the code radically. The following code shows the new GetUser() method.


Public Function GetUser(ByVal id As String) As Twitter.Domain.User
 Dim UserObject As Object = JsonSerializer.DeserializeObject(_
   Me.Communicator.GetTwitterRequest(GetUserURL.Replace("<<USERID>>", id.ToString)))

   Return New Twitter.Domain.User With { _
      .UserID = UserObject("id"), _
      .UserName = UserObject("name"), _
      .ScreenName = UserObject("screen_name"), _
      .Followers = UserObject("followers_count")}

End Function

The code went from 10 lines of code to 2.  The same results were seen across the entire API. 
Refactoring Tests
Once the API’s were refactored  the tests were then refactored. The following code shows the new set of tests.

Imports NUnit.Core
Imports NUnit.Framework

<TestFixture()> _
Public Class UnitTests
    Dim UserAPI As Twitter.API.User = Nothing
    Dim MessageAPI As Twitter.API.Message = Nothing
    Dim Communicator As New Twitter.Communication.TwitterRequest("", "”)

    <SetUp()> _
    Sub Setup()
        Me.UserAPI = New Twitter.API.User(Me.Communicator)
        Me.MessageAPI = New Twitter.API.Message(Me.Communicator)
    End Sub

    <Test()> _
    Sub Should_Return_My_Following()
        Assert.That(UserAPI.GetUsers().Count > 0)
    End Sub

    <Test()> _
    Sub Should_Return_Single_User()
     Assert.That(UserAPI.GetUser(UserAPI.GetMyUser().UserID.ToString).ScreenName _
        = "rodpaddock")
    End Sub

    <Test()> _
    Sub Should_Return_Single_User_ByName()
        Assert.That(UserAPI.GetUser("rodpaddock").ScreenName = "rodpaddock")
    End Sub

    <Test()> _
    Sub Should_Return_My_User()
        Assert.That(UserAPI.GetMyUser().ScreenName = "rodpaddock")
    End Sub

    <Test()> _
    Sub Should_Return_My_Messages()
        Assert.That(MessageAPI.GetMyMessages().Count > 0)
    End Sub

    <Test()> _
    Sub Should_Return_Messages_By_User()
        Assert.That(MessageAPI.GetUserMessages("rodpaddock").Count > 0)
    End Sub

    <Test()> _
    Sub Should_Return_Messages_From_MultipleUsers()
        Dim UserQuery As New List(Of Twitter.Domain.User)
        UserQuery.Add(UserAPI.GetUser("rodpaddock"))
        UserQuery.Add(UserAPI.GetUser("chriswilliams"))
        Assert.That(MessageAPI.GetMultipleUserMessages(UserQuery.ToArray).Count > 0)
    End Sub
End Class

As you can see the testing class now has member variables for each API class and the <Setup()> section instantiates the APIs with the injected communication class.

User Interface

Finally a small WPF application was built to track conversations between users. The following code creates instances of the User and Message APIs, creates an array of user objects from a string (split by commas), retrieves messages for the specified users and finally queries them using LINQ to ferret out a conversation. This code is as follows:
Partial Public Class Main

    Dim UserAPI As Twitter.API.User = Nothing
    Dim MessageAPI As Twitter.API.Message = Nothing
    Dim Communicator As New Twitter.Communication.TwitterRequest("", "")

    Public Sub New()
        MyBase.New()

        Me.InitializeComponent()

        ' Insert code required on object creation below this point.
        ' Add any initialization after the InitializeComponent() call.
        Me.UserAPI = New Twitter.API.User(Me.Communicator)
        Me.MessageAPI = New Twitter.API.Message(Me.Communicator)
    End Sub

 

Private Sub cmdGetThread_Click(ByVal sender As Object, _
   ByVal e As System.Windows.RoutedEventArgs) Handles cmdGetThread.Click

        '-- create list of users from comma (,) delimited list of names in text box
        '-- TODO we should scrub this
        Dim UserQuery As New List(Of Twitter.Domain.User)
        For Each UserName As String In Me.txtCriteria.Text.Split(",")
            UserQuery.Add(UserAPI.GetUser(UserName))
        Next

        '-- get messages for these users
        Dim messages As Twitter.Domain.Message() = _
           MessageAPI.GetMultipleUserMessages(UserQuery.ToArray())

        '-- filter messages based on who is in the contents
        Dim FilteredMessages = _
           From Message _
             In messages _
         Where MatchesCriteria(Message.MessageContent, Me.txtCriteria.Text.Split(","))
        Order By Message.MessageDate Descending


        Me.lstResults.ItemsSource = FilteredMessages.ToArray
    End Sub


    Function MatchesCriteria(ByVal Content As String, _
         ByVal SearchCriteria As String()) As Boolean
        Dim llRetVal As Boolean = False
        For Each SearchString In SearchCriteria
            If Content.ToLower.Contains(SearchString) Then
                llRetVal = True
                Exit For
            End If
        Next
        Return llRetVal
    End Function

Lastly the information is displayed using the following XAML code:


<Window
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
x:Class="Main"
x:Name="Window"
Title="Main"
 xmlns:Custom="http://schemas.microsoft.com/wpf/2008/toolkit">

<Grid x:Name="LayoutRoot">
  <StackPanel Margin="0,0,0,37">
    <Button Content="Get Thread" x:Name="cmdGetThread"/>
   <TextBox Text="bellware,pandamonial,chadmyers" 
     TextWrapping="Wrap" x:Name="txtCriteria" Width="622.627"/>
    <ScrollViewer>
    <ListBox Width="Auto" Height="500"
      IsSynchronizedWithCurrentItem="True" x:Name="lstResults"    >
      <ListBox.ItemTemplate>
  <DataTemplate>
                <StackPanel>
                   <TextBlock Text="{Binding Path=MessageDate}"/>
                   <TextBlock Text="{Binding Path=UserName}"/>
                   <TextBlock Text="----------"/>
                </StackPanel>
  </DataTemplate>
 </ListBox.ItemTemplate>
 </ListBox>
</ScrollViewer>
</StackPanel>
</Grid>
</Window>

The following screen shot demonstrates a conversation that occurred today between three people I follow on Twitter:

Twitter Conversation Window 

Next Steps
There is more work to be done here. In the future posts I hope to do the following:

1. Introduce a Dependency Injection container. For this application I want to use StructureMap.
2. Introduce more mocking to remove dependencies on Twitter (maybe we can write a Twitter mock layer)
3. Further refine the design of the libraries. There’s still redundant code left we can remove.
4. Improve the UI and create some alternate UI’s with MVC  or maybe Silverlight
5. Open up the code to contributions from other developers.

Summary

What I hoped to accomplish in this post was a brief introduction to building a useful tool using the agile principles of Test Driven Development and Dependency Injection. Another goal of this post is to open a conversation on these agile principles. A lot of these practices may seem simple to a lot of the folks I blog with here but a lot of folks out there they seem foreign. I appreciate the comments.

The full code for this post can be found at www.dashpoint.com/downloads/TwitterPlayGround.Zip

Note: There are two sections where you will need to use your own username and password.

Thanks
Rodman

 



Roundtables vs. Lunch Counters

clock December 1, 2008 22:28 by author Administrator

I have a strange pet peeve. I hate rectangular tables.  It’s a strange pet peeve but its mine and I stick by it. I hate rectangular because they don’t scale. They don’t scale conversations for groups of people greater than say 6 people.  I became aware of just how much I hate rectangular tables last week. I was at QCON in San Francisco and went to dinner with some friends at a great seafood restaurant. There were 4 of us and because there were no tables available but we had to sit at the bar. The bar had 4 empty seats side by side so we took them. Dinner was great and some good conversations took place. The problem is that there were basically two conversations of two people. It would have been my preference to have one conversation with all four people involved.  I cemented my hatred further two days later at another dinner with another rectangular table.  We had a larger group (12+ people) this time.  The communication situation was marginally better for the “middle” people. A larger conversation “cluster” formed in the center with smaller satellites of communication for the “edge” people. 

Flash back two weeks earlier to Kaizen Conf. Kaizen Conf is a conference centered on concepts of continuous improvement, agile and lean software development practices. Most of the sessions I attended were large groups (some 50+) sitting in large circles having healthy and involved discussions on some healthy topics. The benefit of the structure is that everyone can see and hear everyone else.  Communication is more fluid and minimizes the “clustering” effect.  Another benefit of the roundtable structure is its channel balancing effect. No channel is more important or larger than another. There is no “head” of the circle.

I find a lot of similarity in software development practices today.  Classic waterfall development is what I call lunch counter development. Communications happen in differing stages along the lunch counter with the bulk of quality communication happening in the middle. The edge people are generally left out of the main communication and never have their concerns every really addressed. Just think of your customer sitting at one end of the table trying to communicate there needs to the other end of the table.

Now take a look at agile/lean and RAD (iterative) software development practice.  These practices are what I am seeing as round table development. It’s all about value systems. Agile/Lean/RAD developments value communication between all stakeholders at all stages of the development process. Every stakeholder has seat at the table. The cornerstone of these practices is the active communication between all constituents at all times.  Stand up meetings, iteration planning meetings, retrospectives.  All of these (and many more) practices relate to facilitating communications between project stakeholders.

The more I develop software using round table (agile/lean) methodologies and practices the more I find the lunch counter development (waterfall) detestable. Software development practices that emphasize and promote communicating down lunch counter are destined to disappoint and generally leave bad tastes in stakeholder’s mouths. This is not limited to just users being disappointed. All stakeholders are disappointed. How many developers do you know that don’t really care about their end users or the quality of their software? I take it personally when my software doesn’t work, doesn’t deliver its expected value or frustrates my end users who I truly care about. I am betting you feel the same way. Let’s not forget that it’s not just you the developer or the end user that feel the effects of software development process. Along with end users and developers; project managers, managers, executives and customers all feel the true quality of the software process.

Stories differ but legend says King Arthur created his round table to emphasize equal status among all that had a seat.  The most important aspect of any software development process is the communication of requirements. Does your company communicate down a lunch counter or do they sit at the round table?

It's been too long between blog posts so here ya go. This post will end up as my editorial in CoDe Magazine next month. I have more posts in the works related to my recent spelunking into all things agile. Stay tuned.



Using Windows Authentication with ASP.NET Web Services

clock May 22, 2008 19:55 by author Administrator

This is a simple placeholder so I have a place to look for this code again. 

exec
sp_grantlogin 'SERVERNAME\ASPNET'

exec sp_grantlogin 'NT AUTHORITY\NETWORK SERVICE' 

use forum

go

sp_revokedbaccess 'NT AUTHORITY\NETWORK SERVICE'

sp_grantdbaccess 'NT AUTHORITY\NETWORK SERVICE', 'forumuser'



Unlearn

clock May 9, 2008 11:37 by author Administrator

“You must unlearn what you have learned.”

Yoda to Luke Skywalker Empire Strikes Back 1981

I have become convinced that we are entering a new dawn of software development and we must take time to unlearn that which we know. Over the last 2 months I have been researching building business applications using Silverlight 2.0. In case you don’t know Silverlight 2.0 is a tool used to build Rich Internet Applications (RIA’s) Silverlight 1.1 (released in 2007) gave us a small glimpse of the future of RIA development.  This glimpse proved that Silverlight 1.1 was wholly lacking for business developers (it didn’t even have a button). Silverlight Version 2.0 (released at Mix 08 in Las Vegas, NV) is a different story. Silverlight 2.0 has all of the features a business developer might need. The control set includes: textboxes, buttons, watermark textboxes and, drum roll please, a DataGrid component.

During my research I began experimenting with the DataGrid. I started (in XAML) adding columns to the DataGrid’s columns collection, setting data binding attributes, column widths and header properties. I then turned to the code portion of my research and DataGrid’s ItemSource property to a list of objects. I ran the application and lo-and-behold it worked (not the first time of course but eventually).  After getting my simple grid demo working I wanted to implement a simple, but common use case. I wanted to allow the user to sort the data by clicking on the column.  Here’s how it went:

1. Look for DataGrid properties called something like “AllowSort”
2. Look for header properties that would turn this feature on.
3. Look into the documentation for the DataGrid (samples, online, etc)
4. Download and open the source code for the DataGrid (yup you read that right its available to developers)

I struck out on all accounts. It looked like I would be waiting for a new rev for this feature. I did take one more step though. I turned to my trusty search engine Google and typed in “silverilght 2.0 datagrid sort”. And look what I found: Matt Berseth (http://mattberseth.com/blog/) had already figured this out in a very creative and enlightening way. Matt’s unique solution was to put a HyperlinkButton control into the DataGrid’s Header Content property. The Header object’s Content Property is defined as Object. The normal use case for this property is to specify a string as your header. But this is Silverlight and when a property says it’s an object it’s an object. This means you can replace the header content with a Hyperlink rather than a textbox. This is where my epiphany occurred:

My typical path took me to the control itself. I searched for properties, events and even considered for a moment hacking up a hit test set of code to do this. It hadn’t occurred to me to composite some controls together to do what I wanted.  This is where I told myself I must unlearn what I know.  I must think of new and interesting ways to combine these controls to do new and interesting things.

This epiphany raised its head again over the last 2 weeks. Over the last 6 months we have started the trek down the Agile Development path. This path has included installing and researching agile development applications including:  Nant, Nunit and Subversion.  We are using Nant and Nunit to automate our testing, and in the last two weeks we moved a large quantity of our source code into a Subversion repository. It’s this last application that has provided me with another epiphany.  Source code control in Subversion is “just different” than in Visual SourceSafe (our previous source code provider).  Visual SourceSafe is a pessimistic version control system (you lock files when you check them out) Subversion is just the opposite. All files are worked on in shared mode. Meaning two developers can work on the same file at the same time. It’s up to the developer to merge changes into the development branch of code when conflicts occur. Along with a different philosophy Subversion uses different terms: In Subversion Checkout means get a fresh set of code from the repository, Import means send source code to the repository. Commit means send your changes to the repository. Visual SourceSafe had different meanings for all of these terms.

When I started using Subversion I found it difficult until I told myself what Yoda said: “You must unlearn what you have learned.” I closed the book on Visual SourceSafe and opened a new one on Subversion. I consulted the documentation to see what the Subversion philosophy is and what the terms in Subversion really mean. When I “forgot” what I knew about source code control from the VSS POV things began to become clear and the process of migrating much simpler.

In today’s development world new technologies require new thinking. You need to unlearn what you already know. To find comfort in the unlearning process, take shelter in the words of Jedi Master Obi-Wan Kenobi to Luke Skywalker: “Luke… Let go. Trust the force”. 



DevTeach Toronto 2008 = Agile Immersion

clock April 29, 2008 15:30 by author Administrator

 

If you want a good general immersion in Agile practices look no further than DevTeach (www.devteach.com)

Last DevTeach (in Vancouver) I sat through a number of Agile sessions with a fellow development partner. This parter had virtually no experience with Agile practices. After DevTeach we began discussions on implementing Agile practices in his 15+ developer shop. It was good for him to hear from other developers about their experiences with Agile.

So if you want to get your management, developers or development buddies on board with Agile then send them Toronto in May for DevTeach.

PS: You can also stay for a post-con session on Building Business Apps with Silverlight 2.0 given by me and my business partner Jim Duffy

PSS: Small conferences like DevTeach are MUCH better than large ones. Why: Because the speaker to attendee ratio is much lower and we can all interact much more…. I personally prefer small conferences over large ones.

 



OT: SilverLight 2.0 = iPhone SDK

clock March 6, 2008 15:08 by author Administrator

Maybe it's  just a coincidence but I am thinking its not.

I am at MIX 08 in Las Vegas and am eagerly awating today's keynote with Steve Ballmer and Guy Kawasaki.

Funny thing is the whole timing of it all....

1. Apple's iPhone SDK Meeting is at 1:00pm Pacific

2. MIX 08 Keynote is at 1:00pm Pacific.

3. Guy Kawasaki is the former evangelist for Apple. Heck he started the whole software/hardware platform concept.

4. Silverlight is a full functioned player on the Apple.

5. Steve Jobs hates Flash http://www.informationweek.com/blog/main/archives/2008/03/jobs_flash_not.html

We got to see that Silverlight is a player in the Nokia space. Will we be developing iPhone and iTouch apps with Silverlight? As the Apple ad's say: Imagine....

UPDATE: Oh Well! It was a fun thought for a few hours in any case. 



Public Speaking Anti Patterns

clock February 12, 2008 23:24 by author Administrator

Public  Speaking Anti-Patterns

Last week fellow CodeBetter blogger Kyle Baley wrote a blog topic called “Presentation Topics” (http://codebetter.com/blogs/kyle.baley/archive/2008/02/08/presentation-tips.aspx)

He did a good job of presenting a number of useful tips for speaking.  Well I am going take a shot here and point out a few bad habits that some of my fellow presenters have developed over the years that do nothing but piss me off because they should know better.

1.       SHUT UP AND LISTEN – I cannot tell you how many speakers I have seen that interrupt questions from the audience. 

       If you are going to allow questions in your sessions you need to shut up, listen, and let the person asking the question finish.  Don’t  interrupt!!!!  Don’t ASSume you know what the rest of the question is.

 

2.       REPEAT THE QUESTION – Whenever a question is asked:  Repeat it out loud. That dude in the back probably didn’t hear the question from the front row. 

       You need to be courteous to your audience and let them know what is happening.

 

3.       MAKE SURE YOU KNOW WHAT THE QUESTION IS -  If you don’t know what the question means or don’t understand it here’s a tip: Say this to the questioner: “Can you say that another way?”  This will help you understand what they are really asking.

 

4.       LESS IS MORE – If you have 60 slides for a 60 minute session you are not going to get to the end.  

 

5.       DON’T WRITE A BOOK – Slides are supposed to be outlines not dissertations. See #4.

 

6.       DON’T UPGRADE YOUR MACHINE - The week/day/hour/minute before your session is not the time to install that new alpha, beta, omega version.  

       Just because that beta is ready doesn’t mean your session is.  If you do this you deserve to have your shit break.

 

7.       DON’T MAKE EXCUSES - If stuff breaks in your session it’s your fault. You didn’t prepare properly. See #6 about upgrades.

 

8.       DO THE JULIA CHILD – Ever watch cooking shows. They always have one that’s done and ready to serve. You should have a copy of your sample code that runs perfectly.

      If your demo breaks you can always go to that copy.

 

9.       ARRIVE EARLY, SIT IN BACK – When you give a session you need to arrive early and check the lighting, sound, projection, etc in the room. All rooms are not created equally.  

     Check your colors, fonts, etc. Set up your machine with code on it and go sit in the last row. Can you read it? If not adjust accordingly.

 

10.   ONE FOR THE AGILE DUDES- You need to have an outline of what you are going cover.  In specifically titled sessions you need to have it planned and not do ad-hoc sessions.  

 

11.   FINISH ON TIME - At the last conference I attended there were a number of sessions that ran way long.  Don’t do this!!!  It’s RUDE! It’s RUDE to the attendee,

      RUDE to the conference coordinators and the RUDE to the next speaker.

 

12.   AND FINALLY ----- Don’t Ever Ask: “How much time do we have left” – This is my BIGGEST pet peave.  You might think it’s cute. It’s not… If you ask this in a session you are a total complete idiot. 

      If you want the real  answer to this question here it is:  “Here Mr./Ms./Mrs. speaker  let me look in the conference brochure and see what time the session with YOUR FREAKING NAME  

      on it is supposed to start and end.”  Asking this question is unprofessional and silly.  Get the point?

 

I hope this lists helps you as a speaker and attendee.

 

 



Microsoft Team Systems - Open Source Alternatives

clock December 14, 2007 12:21 by author Administrator

I am heading to a client next week to see a demo of Microsoft Team Systems. My client got a preliminary prices for implementing Team Systems.

Needless to say. Its not cheap....

I want to have a good list of open source tools that will provide the same functionality as Team Systems. Maybe we can all contribute to a feature by feature list of open source tools and use this as a reference for later...

Here's a starting list

  • Testing - Nuniut
  • CI - Cruise Control
  • Build System - Nant
  • Version Control  - SubVersion

What others should I add to the list ? Remember I need to replace all the functionality of team systems,



AltNetConf Day2 - Agile and MVC Goodness

clock October 7, 2007 10:03 by author Administrator

Day 2 went great. The group gathered for some opening remarks and immediately went into sessions.

I was a participant in a discussion group where we discussed:

Introducing Agile/Alt.Net into the work place

Passion for Agile/Alt.Net

Pragmatic a Agile/Alt.Net

Being a catalyst for Agile/Alt.Net

The room was fairly full and some great conversations took place. Here are some of the ideas thrown out and recorded in my trusty Mead notebook:

JP Boodhoo http://www.jpboodhoo.com/blog/ started with “Passion does not necessarily incite action.” We discussed the concept that just because you are passionate you still need to take action. Passion for passions sake doesn’t do anything.

One mechanism for facilitating agile adoption is to arrive with a solution in hand. Scott Bellware is famous for saying you won’t understand until you do it.   There is some truth to this. Agile is difficult to explain. It’s easier to see a readily provided solution.

Another idea is to do a month of iterations and use this as a basis for examining agile success.

Some stuff to look at:

The Agile Contract

The Pragmatic Programmer

21 Laws of Leadership

Success is always easy to sell twice.

You may need to introduce agile at a ground level. Start with one developer.  Teach them. Have them teach too.

Try lunch and learns.

More stuff to look into

Resharper

Continuious Integration

Cruise Control

Maybe you just need to do agile on a project and show the results after the fact. Returns to the statement: “success is easy to sell twice”.

That was just my notes from session 1.

Now on to Behavior Driven Development

This intent of this session IMO was to discuss what BDD is and how to use it in your development process.  I am not convinced that this session was successful as it seemed to degrade immediately.

The meeting was started off with three moderators discussing their POV of POV. It was never made clear what the hell BDD really is.  The presenters should have started off defining what BDD is. Each person pretty much immediately jumped in discussing their favorite tools for doing BDD

In any case this session did provide me with some ideas.

BDD to me looks like a way to gather requirements (stories) in a standardized way then being able to take those requirements and generate programming and acceptance tests.

Scott Bellware shows a tool called Rspec that takes requirements from Ruby code (I believe) and puts them into a friendly/easy to read web interface. The thing that struck me as cool was the way in which requirements were spelled out. Stuff like:

Registrants will receive an e-mail

When signing up the registrant will be required to provide an e-mail address.

The thing that I liked was the way they documented requirements. The language used was very cool.

Another moderator showed his tool for recording stories. This persons’ tool showed a nice structure for recording requirements (stories) in a structured way. You can then generate testing artifacts from there system.

I am not sure if this was the theme or intent. But I did come up with a concept that I would love to explore.

How do we gather requirements in a more formalized and standard way? Language is important. 

MVC and DLR (Dynamic Language Runtime) Goodness

The next sessions that I attended were the MVC and DLR Goodness sessions.

ScottGu gave a kick ass session showing the new MVC framework. I am not going to write about what we saw as numerous other bloggers have done so.  Let’s just say this is a cool framework and I cannot wait to play with it in a couple of weeks.

 

After ScottGu was done Scott Hanselman gave a good session on how DLR’s will be implemented in the new MVC framework. I have never written a line of Python or Ruby so this was an interesting session from that angle.

One thing I liked was that he showed the concepts surrounding creating your own Viewer in the new MVC framework. I can definitely see using the MVC framework when we implement WPF in our shop.

I am VERY impressed with what the Scott’s. Contrary to other opinions Microsoft seems to get this area and is taking ACTION. (See theme above <G>)

One side note: When ScottGu  gets Ray Ozzies job. Scott Bellware will go work at Microsoft for ScottGu.  I was there when it was said. I have witnesses <G>

 

 



AltNetConf Day 1 - Fishbowls Rock!

clock October 6, 2007 10:04 by author Administrator

OK so I am a newbie to Agile practices and this “conference” is a great place to become immersed in all that is Agile.

Last night was very interesting. Over 100 people gathered in one room to create this conference. The meeting started a definition of alt.net and Open Spaces.  The definition of Open Spaces is:

Whoever shows up is the right group. Whatever happens is the only thing that could have. Whenever it starts is the right time. When it's over, it's over.

A definition of bumblebees vs. butterflies was discussed. Are you a bumblebee or a butterfly?  Bumblebees go from one room to another landing and pollinating. Butterflies find a warm spot in the sun and take in their surroundings.  You can also take on different roles because of the rule of two feet:

If you feel you aren’t learning or contributing you are encouraged to use the rule of two feet. Get up and move to another place.

So after a briefing on the “rules” 100+ people introduced themselves. Lots of people from lots of places with very diverse goals for this gathering.  Scott Hanselman  http://www.hanselman.com/blog/ had one of the best intros:

Hi, I’m Scott Hanselman I hope to bring my entire 3 weeks of experience at MSFT to this meeting. My goal is to find out what we do so bad that it started a movement. 

Scott and Scott (Guthrie that is: http://weblogs.asp.net/scottgu/) are here to join the conversation. This is a great thing. Of all the people I know from MSFT that listen these two dudes do.

After the intros we learned about the concept of a fishbowl meeting. I tell you what this was one of the coolest concepts I have participated in. Basically 5 or 6 chairs are put in front of the room. One chair is left empty the others are filled with members of the meeting. The topic that started it all was what does alt.net mean to you. And then it begins. The people in the chairs begin the discussing putting for the there points. When someone wants to contribute they take the empty chair, the person that has been in a chair longest gets up. The discussion continues. There is a constant rotation of people sitting, giving a POV or comment, and getting up. I don’t know if I did this justice but a lot of cool ideas were discussed and it was rather fun.

After the completion of the fishbowl the agenda was set.  While the fishbowl was going on people were able to take 6*9 post it pads and write down an ideas for things they would like to see or discuss. Immediately after the fishbowl people with session ideas stood up and presented their idea and put that idea on grid with rooms and time slots. I think there were over 50 post its on the board. Not too bad for 100 people.  

After the agenda was put on the board people “voted” for the sessions they wanted to see by  putting their initials on the post it note. During the “voting process” endless hours of conversations happened. I was definitely a bumblebee. I flew from one small gathering to the next. From looking at a new MVC model being shown by ScottGu , discussions of UI testing with Jeremy Miller,  meeting the new editor of MSDN Magazine and countless others. This meeting is off to a great start.

The one thing that drew me to this conference was the people. This is a real community of greate people sharing great ideas. This was not a fabricated community but one that formed like all great communities do: IT JUST HAPPENED.

Now it’s off to Day 2