Watching Others Do the Same TDD Calculator Kata

by Kofi Sarfo 23. October 2009 06:17
I've been doing this String Calculator Kata whenever I've had a spare half hour before 7am and wanted to see how others did it. See the Andrew Woodward Calculator Kata and the Bobby Johnson Calculator Kata.

Differences Between Test Runners; Mouse, Monitors & Keyboard Shortcuts

by Kofi Sarfo 22. October 2009 06:20

Differences

It was more than a little odd to see tests pass using the ReSharper Test Runner but fail when using either NUnit or the as yet mystery default option (whichever is used when Test With > Debugger is selected from the context menu).

Test with DebuggerReason being that ReSharper is kind enough to run the tests in the order they appear whilst the others do so in alphabetic order. Dependencies between tests become apparent. Slaps to the forehead are delivered. We resolve to steer clear of using statics for unit testing.

Mouse

With only one monitor at work - everyone has just the one monitor so we're not too keen on standing out for being flash by having two monitors! - it would be handy having test results appear in the status bar using an ALT-T shortcut and TestDriven.NET. However, licensing! So it's tabbed Unit Test Sessions and CTRL-TAB until we're in the promise land.

Keyboard Shortcuts

Also, it turns out the the advertisement for going mouseless is true. Keeping the hands on the keyboard does indeed speed up coding. The next problem then was trying to access the Debug Tooltips (available ordinarily by hovering the mouse over variables). The solution is AutoHotkey and the script is courtesy of Rob Henry.

Bloomberg 1970s

by Kofi Sarfo 15. October 2009 19:51

Bloomberg connectivity is a riot. We submit (by FTP) a text file with an expected format using carriage return and line feed to separate data entity requests.

From C# this means shelling out to a batch file (remember DOS) which executes some Java code responsible for handling request/response. If the request is valid then one minute later a zip file is returned that contains a text file. We parse and we have a database ready data file. If the request is badly formed, however, then an error file is created on the remote FTP directory but that is never returned!

Five years ago someone asked on Willmott (serving the Quantitative Finance Community) how to connect a Java application with Bloomberg to send and receive data. Dominic Connor was kind enough to reply.

At another time, at another place we used the DLLs on the Bloomberg terminal to return the data we needed. It was fast, efficient, predictable and illegal. Good times.

Tags:

Nostalgia

Xml Namespaces I've Loved and the Nature of RSS

by Kofi Sarfo 20. September 2009 17:02

Yesterday, during yet another interview, we didn't deliver quite  the finest explanation of what an XML Namespace is. Today, we're using them to parse a Stack Overflow feed so clearly we understand them, however, if part of the question's purpose is to assess our ability to express this simple idea simply then shitehawks! #fail

Take this feed, for example, which is the RSS for a useful post on Volatile vs. Interlocked vs. lock. In order to to be able to use XPath with XDocument to retrieve the question we rely on XmlNamespaceManager.

    var xDoc = XDocument.Load("http://stackoverflow.com/feeds/question/154551");

    var xmlNamespaceManager = new XmlNamespaceManager(new NameTable());
        xmlNamespaceManager.AddNamespace("atom", "http://www.w3.org/2005/Atom");

    var postedQuestion 
        = xDoc.XPathSelectElement("/atom:feed/atom:entry/atom:summary", xmlNamespaceManager);

This is another example of Stack Overflow brilliance. The feeds are in chronological order so that we can guarantee that the first item (or entry) is the original post. Following the Volatile trail leads to a Joe Duffy post on Volatile Reads and Writes, and Timeliness. For example, he writes the C# documentation for volatile is highly misleading with reference to the following MSDN documentation:

The volatile modifier is usually used for a field that is accessed by multiple threads without using the lock statement to serialize access. Using the volatile modifier ensures that one thread retrieves the most up-to-date value written by another thread.

Unfortunately, I can't find this specific RSS item within the Technology feed and the same is true for the RSS feed for this blog. Although it's possible to score a reference to the item if it appears within the list of entries as they each have a unique ID, should the category contain too many entries then the older posts don't show up. Soon I'll show why this might matter but I digress.

The quoted paragraph above came as some surprise and a few hours reading suggests that:
  1. This stuff is hard!
  2. It would take *years* at the exclusion of a whole lotta stuff to have a legitimate claim to deep understanding of the intricacies of threading in .NET
  3. A solid handle on this C# Threading series of posts might just be enough (for now).
The real trick, however, might be recall during interview. There's definitely a theme here.

It's easier to forget the details of SQL Transaction Isolation levels (during interview)

by Kofi Sarfo 26. June 2009 00:45

So I interviewed again yesterday with a City-based asset management company you've probably not heard of but a cash rich client is exactly what we need right now. Shaking off a cold hit-hard mid-week wasn't ideal circumstance but it wasn't feeling less than fabulous that did the trick but in part, in fact, not being able to remember how each of the SQL Server Transaction Isolation levels might impact queries on the same table.

This is partly why I like interviews. Potentially embarrassing situations during which one is able to demonstrate what one cannot remember. Here's what the MSDN entry has to say about the SET TRANSACTION ISOLATION LEVEL (Transact-SQL) command which controls the locking and row versioning behavior of Transact-SQL statements issued by a connection to SQL Server. Yay.

So the story in a nutshell is that using this command it's possible, amongst other things, to allow dirty reads if that's the desired result. In order to try the code below in SQL Management Studio use one tab to run the transaction once all the necessary database objects have been created and another tab to view the results of the different isolation levels.

We create a table to use for holding some random values.

CREATE TABLE RandomLetters
(
     ID int IDENTITY(1,1) NOT NULL
    ,Letter varchar(32) NOT NULL
) 

In order to populate this table with some random values we rely on a stored procedure inspired by one over here.

CREATE PROCEDURE sp_GenerateRandomLetters
     @Length int
    ,@randomLetters varchar(32) OUT
AS
DECLARE @counter smallint
DECLARE @RandomNumber float
DECLARE @RandomNumberInt tinyint
DECLARE @CurrentCharacter varchar(1)
DECLARE @ValidCharactersLength int
DECLARE @ValidCharacters varchar(255)

SET @ValidCharacters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-=+&$'

SET @ValidCharactersLength = len(@ValidCharacters)
SET @CurrentCharacter = ''
SET @RandomNumber = 0
SET @RandomNumberInt = 0
SET @RandomLetters = ''

SET NOCOUNT ON

SET @counter = 1
WHILE @counter < (@Length + 1)
BEGIN
        SET @RandomNumber = Rand()
        SET @RandomNumberInt = Convert(tinyint, ((@ValidCharactersLength - 1) * @RandomNumber + 1))
        SELECT @CurrentCharacter = SUBSTRING(@ValidCharacters, @RandomNumberInt, 1)
        SET @counter = @counter + 1
        SET @RandomLetters = @RandomLetters + @CurrentCharacter
END

And because we're going to populate this table with more than the one record:

DECLARE @randomLetters varchar(32)
DECLARE @randomLettersCount int

SELECT @randomLettersCount = 0

WHILE (@randomLettersCount < 1000)
BEGIN
        EXEC sp_GenerateRandomLetters 12, @randomLetters OUT
        INSERT INTO RandomLetters (Letter)
        SELECT    @randomLetters
        SELECT @randomLettersCount = @randomLettersCount + 1
END

None of this is even nearly shattering. It's not meant to be. Also, the following ought to error the first time it's run.

DROP TABLE ##OriginalRandomLetters

Now let's make that table which gets dropped by the statement above.

CREATE TABLE ##OriginalRandomLetters
    (
         ID int NOT NULL
        ,Letter varchar(32) NOT NULL
    )

And we sync this global temporary table with those values in the permanent table created above

INSERT INTO ##OriginalRandomLetters
    SELECT ID, Letter
    FROM RandomLetters

Confirm that we are good.

SELECT * FROM ##OriginalRandomLetters

And back on that other tab and therefore using another connection...

BEGIN TRANSACTION

    DECLARE @RandomUpdateCount int
    DECLARE @RandomID int
    DECLARE    @randomLetters varchar(32)

    SELECT @RandomUpdateCount = 0

    SET NOCOUNT ON

    WHILE @RandomUpdateCount < 20000
    BEGIN
        SELECT @RandomID = 1 + RAND() * 999
        -- SELECT @RandomID '@RandomID'

        EXEC sp_GeneratePassword 12, @randomLetters OUT
        -- SELECT @randomLetters '@randomLetters'

        UPDATE    RandomLetters
        SET        Letter = @randomLetters
        WHERE    ID = @RandomID

        SELECT @RandomUpdateCount = @RandomUpdateCount + 1
    END

ROLLBACK TRANSACTION

And finally let's try one of these transaction isolation levels

    SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED
    SET TRANSACTION ISOLATION LEVEL READ COMMITTED
    SET TRANSACTION ISOLATION LEVEL REPEATABLE READ
    SET TRANSACTION ISOLATION LEVEL SNAPSHOT
    SET TRANSACTION ISOLATION LEVEL SERIALIZABLE

And the result of the following query will depend on the chosen isolation level.

SELECT * FROM RandomLetters

For example the READ UNCOMMITTED isolation level will allow you to see the changes being made to the values in the RandomLetters table whilst the transaction to update values is being run whereas most of the other isolation levels will cause SELECT * FROM RandomLetters to hang until the transaction is complete. In the case of SNAPSHOT there's an error: Snapshot isolation transaction failed accessing database 'WimiroDemo' because snapshot isolation is not allowed in this database. Use ALTER DATABASE to allow snapshot isolation.

I might be forgiven for not remembering all this behaviour during interview but not having a handle immediately on the correct strategy for ASP.NET paging and the 10 steps of the ASP.NET Page Life Cycle might have been forgetfulness too far. But that's what the internet is for, I say. Fingers crossed I get the gig anyway.

Tags:

SQL Server

Listening to folks talk REST whilst running 10km

by Kofi Sarfo 12. June 2009 02:24

Caught .NET Rocks show #445 with Kenn Scribner on REST. A useful discussion about REST, SOAP, the evolution of 'web services' technology and where WCF best fits in. Listen here.

Notes:

.NET Rocks talk transcript

Kiva Loans

  • Sabhuku Group

    Sabhuku Group

    Poultry

    Requested loan: $1200

    Amount raised: $0

    Harare, Zimbabwe

    to restock batches of 100 birds every two weeks.

    Loan Now »

  • Zvishandwa Group

    Zvishandwa Group

    Spare Parts

    Requested loan: $1100

    Amount raised: $0

    Juru, Zimbabwe

    to restock fan belts, filters, bearings, nuts, and tires, among other motor vehicle parts.

    Loan Now »

  • Sheila

    Sheila

    Grocery Store

    Requested loan: $700

    Amount raised: $0

    Harare, Zimbabwe

    to restock groceries for resale.

    Loan Now »

To see more entrepreneurs »

Make a loan to an entrepreneur across the globe for as little as $25. Kiva is the world's first online lending platform connecting online lenders to entrepreneurs across the globe.