Code Kata 4

KataTen: Hashes vs. Classes

·Ifwe’re programming business applications in a language such as Java or C#, we’reused to constructing and using classes to manipulate our business objects. Isthis always the right way to go, or would a less formal approach serves us wellsometimes?

This week’s topic doesn’t involve a coding challenge.Instead, we’re thinking about design and tradeoffs.

Imagine that you’ve been asked to write an exportutility for a large and complex database. The export has to read data from 30or so tables (perhaps 100 columns are potentially written to each exportrecord). Some of the exported data is written exactly as read from thedatabase, but other exported data must be calculated. In addition, if certainflag fields have specific values, then additional data must be read from thedatabase to complete an export row.

The export data must obviously be correct, but theclient is also asking for a flexible solution; their world changes a lot.

One solution is to use existing business objects andexisting persistence mechanisms, and to use higher-level classes to aggregatetheir results into a form that can be used to generate export rows. This higherlevel object could perform the calculations necessary for the virtual fields,and read in additional business objects if the flag fields dictate.

An alternative solution might be to read the data row ata time into a Hash using ad-hoc queries, keying the hash on the field names. Aseparate pass could then be made to perform any necessary calculations, storingthe results back in to the same hash. Additional data could be read from thedatabase if the flag fields are set, again storing the results in the hash. Thecontents of the hash are then used to write the export record, and we loop backto do the next row.

This kata is a thought experiment. What are the topthree advantages and top three disadvantages of the two approaches? If you’rebeen using classes to hold data in your business applications, what would theimpact be if you were to switch to hashes, and vice versa? Is this issuerelated to the static/dynamic typing debate?

·Kata Eleven – Sorting it Out

Just because we need to sort something doesn’tnecessarily mean we need to use a conventional sorting algorithm.

We use sorting routines all thetime; putting customer records in to name order, arranging orders by value (andeven sorting the letters in a word back inKataSix). Most of the time we (wisely) use one of thesort routines built in to our language’s library (such as C’s qsort and Java’sjava.Collections.sort). After all, very clever folks spent a lot of timegetting these library routines tuned for speed and/or memory usage.

However, there are times when whipping up a sort ofour own can outperform these generic routines. Our challenge this week is toimplement a couple of different sorts. (However, at the risk of giving the gameaway, these sorts both have something in common).

Sorting Balls

In the Pragmatic Lottery (motto:There’s One Born Every Minute, and it MightJust Be You!), we select each week’s winning combination by drawingballs. There are sixty balls, numbered (not surprisingly, as we areprogrammers) 0 to 59. The balls are drawn by the personable, but somewhatdistracted, Daisy Mae. As a result, some weeks five numbers are drawn, whileother weeks seven, nine, or even fifteen balls make it to the winner’s rack.Regardless of the number of balls drawn, our viewers need to see the list ofwinning numbers in sorted order just as soon as possible. So, your challenge isto come up with some code that accepts each number as it is drawn and presentsthe sorted list of numbers so far. The tests might look something like:

    rack = Rack.new
    assert_equal([], rack.balls)
    rack.add(20)
    assert_equal([ 20 ], rack.balls)
    rack.add(10)
    assert_equal([ 10, 20 ], rack.balls)
    rack.add(30)
    assert_equal([ 10, 20, 30 ], rack.balls)

Sorting Characters

Our resident conspiracy expert, Dr. X, is looking forhidden messages in the collected publications of Hugh Hefner. Dr. X believesthe message is hidden in the individual letters, so rather than get distractedby the words, he’s asked us to write a program to take a block of text andreturn the letters it contains, sorted. Given the text:

  When not studying nuclear physics, Bambi likes to play
  beach volleyball.

our program would return:

  aaaaabbbbcccdeeeeeghhhiiiiklllllllmnnnnooopprsssstttuuvwyyyy

The program ignores punctuation, and maps upper caseto lower case.

Are there any ways to perform this sort cheaply, andwithout using built-in libraries?

·Kata Twelve: Best Sellers

Consider the implementation of a top-ten best sellerslist for a high volume web store.

AGedankenKatathis week: no code needed (althoughwriting short prototypes might help you come to a conclusion).

Say you’re writing code for an online site that sellsthings (something like Amazon). Your site is wildly popular, and you sellmillions of items each day.

The marketing department wants the home page todisplay a top-ten list of the best selling items over the last 24 hours, withthe list being updated each hour.

oHow would you implement this?

oAre there any changes you could ask for to make theimplementation easier?

oWhat would be the impact if they later came back andsaid:

§only update the list once per day;or

§we need the list updated in real time: each time thehome page is displayed we need the list to reflect the 24 hours up until thatpoint.

This kata might be deeper than it first appears. Youmight want to consider database vs. in-memory solutions, data structures thatallow aging, time-space tradeoffs, and the like.

·Kata Thirteen: Counting CodeLines

Counting lines of code in Java source is not quite assimple as it seems.

This week let’s write something vaguely useful: autility that counts the number of lines of actual code in a Java source file.For the purpose of this exercise, a line is counted if it contains somethingother than whitespace or text in a comment. Some simple examples:

  -   // This file contains 3 lines of code
  1   public interface Dave {
  -     /**
  -      * count the number of lines in a file
  -      */
  2     int countLines(File inFile); // not the real signature!
  3   }

and…

  -   /*****
  -   * This is a test program with 5 lines of code
  -   *  \/* no nesting allowed!
  -   //*****//***/// Slightly pathological comment ending...
  -
  1  public class Hello {
  2      public static final void main(String [] args) { // gotta love Java
  -          // Say hello
  3        System./*wait*/out./*for*/println/*it*/("Hello/*");
  4      }
  -
  5  }

Remember that Java comments are either “//” to the endof line, or “/*” to the next “*/”. The block comments do not nest. There may bemultiple /*…*/ comments on a line. Whitespace includes tabs, spaces, carriagereturns, and vertical tabs. Oh, and remember that comment start sequences thatappear inside Java strings should be ignored.

Goals of the Kata

The mixture of line-based things (single linecomments, blank lines, and so on) with the stream-based block comments can makesolutions slightly ugly. While coding your solution, consider the structure ofyour code, and see how well it fits the structure of the problem. As with mostof these kata, consider coding multiple alternative implementations. Does whatyou learned on the first tries affect your approach to subsequent ones?

·Kata Fourteen: Tom Swift UnderMilk Wood

Trigrams can be used to mutate text into new, surreal,forms. But what heuristics do we apply to get a reasonable result?

As a boy, one of my treats was go to the shops on aSaturday and spend part of my allowance on books; for a nine-year old, I hadquite a collection of Tom Swift and Hardy Boys. Wouldn’t it be great to be ableto create more and more of these classic books, to be able to generate a newTom Swift adventure on demand?

OK, perhaps not. But that won’t stop us trying. Icoded up a quick program to generate some swash-buckling scientific adventureon demand. It came up with:

…it was in the wind that waswhat he thought was his companion. I think would be a good one and accordinglythe ship their situation improved. Slowly so slowly that it beat the band!You’d think no one was a low voice. “Don’t take any of the elements and theinventors of the little Frenchman in the enclosed car or cabin completelyfitted up in front of the gas in the house and wringing her hands. “I’m surethey’ll fall!”She looked up at them. He dug a mass of black vapor which it hadrefused to accept any. As for Mr. Swift as if it goes too high I’ll warn youand you can and swallow frequently. That will make the airship was shootingupward again and just before the raid wouldn’t have been instrumental incapturing the scoundrels right out of jail.”

Stylistically, it’s Victor Appleton meets DylanThomas. Technically, it’s all done with trigrams.

Trigram analysis is very simple. Look at each set ofthree adjacent words in a document. Use the first two words of the set as akey, and remember the fact that the third word followed that key. Once you’vefinished, you know the list of individual words that can follow each two wordsequence in the document. For example, given the input:

  I wish I may I wish I might

You might generate:

    "I wish" => ["I", "I"]
    "wish I" => ["may", "might"]
    "may I"  => ["wish"]
    "I may"  => ["I"]

This says that the words “I wish” are twice followedby the word “I”, the words “wish I” are followed once by “may” and once by“might” and so on.

To generate new text from this analysis, choose anarbitrary word pair as a starting point. Use these to look up a random nextword (using the table above) and append this new word to the text so far. Thisnow gives you a new word pair at the end of the text, so look up a potentialnext word based on these. Add this to the list, and so on. In the previousexample, we could start with “I may”. The only possible next word is “I”, sonow we have:

   I may I

The last two words are “may I”, so the next word is“wish”. We then look up “I wish”, and find our choice is constrained to another“I”.

   I may I wish I

Now we look up “wish I”, and find we have a choice.Let’s choose “may”.

   I may I wish I may

Now we’re back where we started from, with “I may.”Following the same sequence, but choosing “might” this time, we get:

   I may I wish I may I wish I might

At this point we stop, as no sequence starts “Imight.”

Given a short input text, the algorithm isn’t toointeresting. Feed it a book, however, and you give it more options, so theresulting output can be surprising.

For this kata, try implementing atrigram algorithm that generates a couple of hundred words of text using abook-sized file as input. ProjectGutenbergis a good source of online books (TomSwift and His Airship ishere).Be warned that these files have DOS line endings (carriage return followed bynewline).

Objectives

Kata’s are about trying something many times. In thisone, what we’re experimenting with is not just the code, but the heuristics ofprocessing the text. What do we do with punctuation? Paragraphs? Do we have toimplement backtracking if we chose a next word that turns out to be a dead end?

I’ll fire the signal and thefun will commence…

·Kata Sixteen: Business Rules

How can you tame a wild (and changing) set of busine***ules?

Imagine you’re writing an order processing applicationfor a large company. In the past, this company used a fairly random mixture ofmanual and ad-hoc automated business practices to handle orders; they now wantto put all these various ways of hanadling orders together into one whole: yourapplication. However, they (and their customers) have come to cherish thediversity of their business rules, and so they tell you that you’ll have tobring all these rules forward into the new system.

When you go in to meet the existing order entry folks,you discover that their business practices border on chaotic: no two productlines have the same set of processing rules. To make it worse, most of therules aren’t written down: you’re often told something like “oh, Carol on thesecond floor handles that kind of order.”

During first day of meetings, you’ve decided to focuson payments, and in particular on the processing required when a payment wasreceived by the company. You come home, exhausted, with a legal pad full ofrule snippets such as:

oIf the payment is for a physical product, generate apacking slip for shipping.

oIf the payment is for a book, create a duplicatepacking slip for the royalty department.

oIf the payment is for a membership, activate thatmembership.

oIf the payment is an upgrade to a membership, applythe upgrade.

oIf the payment is for a membership or upgrade, e-mailthe owner and inform them of the activation/upgrade.

oIf the payment is for the video “Learning to Ski,” adda free “First Aid” video to the packing slip (the result of a court decision in1997).

oIf the payment is for a physical product or a book,generate a commission payment to the agent.

oand so on, and so on, for seven long, yellow pages.

And each day, to your horror, you gather more and morepages of these rules.

Now you’re faced with implementing this system. The rulesare complicated, and fairly arbitrary. What’s more, you know that they’re goingto change: once the system goes live, all sorts of special cases will come outof the woodwork.

Objectives

How can you tame these wild business rules? How canyou build a system that will be flexible enough to handle both the complexityand the need for change? And how can you do it without condemming yourself toyears and years of mindless support?

点赞