Thursday, February 3, 2011

FLASH: TPP

Flash Cards: T-P Premise

I read a nice blog today exploring the Transformation Priority Premise using the flash card kata. The author did it in both lisp and C#. Let’s try it in Java.

The flash card kata is pretty straightforward. Given a set of questions and answers, ask the user each question and solicit an answer. If the answer is correct, say so and count it. If the answer is wrong show the correct answer and count the error. At the end, print the number of right and wrong answers.

The first test is wonderfully simple. Given an empty list of questions and answers, end the game immediately with a summary showing nothing right and nothing wrong.

We begin with an empty test which passes:

public class flashCardTest { @Test public void degenerateGame() throws Exception { } }

We get the test to fail by asserting the answer we want and by doing a couple of ({}–>nil) transforms. (In this case -1 is the integer equivalent of nil, e.g. a degenerate value)

public class FlashCardTest { @Test public void rightAndWrongShouldBeZeroIfGamePlayedWithNoCards() { List emptyList = new ArrayList(); playGame(emptyList); assertEquals(0, rightAnswers()); assertEquals(0, wrongAnswers()); }  private int wrongAnswers() { return -1; }  private int rightAnswers() { return -1; }  private void playGame(List flashCards) { } }

To get this to pass just need to do some (nil->constant) transforms.

private int wrongAnswers() { return 0; }  private int rightAnswers() { return 0; }

This solution is a bit ugly since it couples the test and the solution. So let’s refactor to create a class.

public class FlashCardTest { @Test public void rightAndWrongShouldBeZeroIfGamePlayedWithNoCards() { FlashCardGame flashCardGame = new FlashCardGame(); List emptyList = new ArrayList();  flashCardGame.playGame(emptyList);  assertEquals(0, flashCardGame.rightAnswers()); assertEquals(0, flashCardGame.wrongAnswers()); } }

public class FlashCardGame { public FlashCardGame() { }  int wrongAnswers() { return 0; }  int rightAnswers() { return 0; }  void playGame(List flashCards) { } }

For the next test, lets try a game with a single flash card, that the user gets right.

@Test public void rightShouldBeOneIfOneRightAnswer() { FlashCard card = new FlashCard("Q", "A"); List cards = new ArrayList(); cards.add(card);  flashCardGame.playGame(cards); assertEquals(1, flashCardGame.rightAnswers()); assertEquals(0, flashCardGame.wrongAnswers()); }

This fails of course. We can make it pass by simply incrementing the right count in playGame if the list of cards is not zero. This is a (unconditional->if) transform. That, plus a little refactoring gives us:

public class FlashCardGame { private int rightAnswers;  public FlashCardGame() { }  int getWrongAnswers() { return 0; }  int getRightAnswers() { return rightAnswers; }  void playGame(List flashCards, FlashCardTest answerer) { if (flashCards.size() != 0) rightAnswers++; } }

OK, so let’s try a wrong answer.

@Test public void wrongShouldBeOneIfOneWrongAnswer() { FlashCard card = new FlashCard("QW", "A"); List cards = new ArrayList(); cards.add(card);  flashCardGame.playGame(cards); assertEquals(0, flashCardGame.getRightAnswers()); assertEquals(1, flashCardGame.getWrongAnswers()); }  public String answerQuestion(String question) { if (question.equals("QR")) return "A"; else return "W"; }

This forced us to create the answerQuestion function that pretends to be a user answering questions. If you pass in “QR” you get the right answer “A”. If you pass in “QW” you get the wrong answer “W”. To get this test to pass we’re going to have to get this function called by playGame. We can do this by passing the test along in an argument using the Change Signature refactoring. Then we can use a (unconditional->if) transform to check the value of our new function.

public class FlashCardGame { private int rightAnswers; private int wrongAnswers;  public FlashCardGame() { }  int getWrongAnswers() { return wrongAnswers; }  int getRightAnswers() { return rightAnswers; }  void playGame(List flashCards, FlashCardTest answerer) { if (flashCards.size() != 0) { String question = flashCards.get(0).getQuestion(); if (answerer.answerQuestion(question).equals("A")) rightAnswers++; else wrongAnswers++; } } }

Of course this is hideous, so we need to refactor alot.

public interface User { String answerQuestion(String question); }  ----  public class MockUser implements User { public MockUser() { }  public String answerQuestion(String question) { if (question.equals("QR")) return "A"; else return "W"; } }  ----  public class FlashCardGame { private int rightAnswers; private int wrongAnswers;  public FlashCardGame() { }  int getWrongAnswers() { return wrongAnswers; }  int getRightAnswers() { return rightAnswers; }  void playGame(List flashCards, User user) { if (flashCards.size() != 0) { String question = flashCards.get(0).getQuestion(); String answer = user.answerQuestion(question); if (answer.equals("A")) rightAnswers++; else wrongAnswers++; } } }  ----  public class FlashCardTest { private FlashCardGame flashCardGame; private MockUser user = new MockUser();  @Before public void setUp() throws Exception { flashCardGame = new FlashCardGame(); user = new MockUser(); }  @Test public void rightAndWrongShouldBeZeroIfGamePlayedWithNoCards() { List emptyList = new ArrayList();  flashCardGame.playGame(emptyList, user);  assertEquals(0, flashCardGame.getRightAnswers()); assertEquals(0, flashCardGame.getWrongAnswers()); }  @Test public void rightShouldBeOneIfOneRightAnswer() { FlashCard card = new FlashCard("QR", "A"); List cards = new ArrayList(); cards.add(card);  flashCardGame.playGame(cards, user); assertEquals(1, flashCardGame.getRightAnswers()); assertEquals(0, flashCardGame.getWrongAnswers()); }  @Test public void wrongShouldBeOneIfOneWrongAnswer() { FlashCard card = new FlashCard("QW", "A"); List cards = new ArrayList(); cards.add(card);  flashCardGame.playGame(cards, user); assertEquals(0, flashCardGame.getRightAnswers()); assertEquals(1, flashCardGame.getWrongAnswers()); } }

Now let’s do two questions, one right and one wrong.

@Test public void countBothOneRightAndOneWrong() { List cards = new ArrayList(); cards.add(new FlashCard("QW", "A")); cards.add(new FlashCard("QR", "A"));  flashCardGame.playGame(cards, user); assertEquals(1, flashCardGame.getRightAnswers()); assertEquals(1, flashCardGame.getWrongAnswers()); }

This fails, but we can make it pass with a (if->while) transform.

void playGame(List flashCards, User user) { for (FlashCard card : flashCards) { String question = card.getQuestion(); String answer = user.answerQuestion(question); if (answer.equals("A")) rightAnswers++; else wrongAnswers++; } }

One thing left. We need to actually compare the answer in the flashcard to the response from the user.

@Test public void countThreeNewQuestionsTwoRightOneWrong() { List cards = new ArrayList(); cards.add(new FlashCard("Q1", "1")); cards.add(new FlashCard("Q2", "2")); cards.add(new FlashCard("Q3", "wrong"));  flashCardGame.playGame(cards, user); assertEquals(2, flashCardGame.getRightAnswers()); assertEquals(1, flashCardGame.getWrongAnswers()); }

We need to make a small change to the Mock.

public class MockUser implements User { public String answerQuestion(String question) { if (question.equals("QR")) return "A"; else { return question.substring(1); } } }

And now we can make this pass with a simple (expression->function) transform.

void playGame(List flashCards, User user) { for (FlashCard card : flashCards) { String question = card.getQuestion(); String answer = user.answerQuestion(question); if (answer.equals(card.getAnswer())) rightAnswers++; else wrongAnswers++; } }

There’s more to do, of course, but the plumbing is all set up, and the algorithm looks right. There were several cases where we could have used a lower transform such as (variable->assignment) but there was no need, and the algorithm came out nicely.

There is just the slightest chance that the one use of (if->while) could have been done with (statement->tail-recursion), but since this is Java, that’s probably not the best choice.

24 comments:

  1. The code blocks are not readable, they have no line breaks

    ReplyDelete
  2. Thanks for some useful tips in programming.

    Nowadays the most desired type of solutions is blackberry development that allows to develop applications for mobile phone. All of them needs to be checked by quality control testing.

    ReplyDelete
  3. Thanks for great posts. Let me mention about cheap home insurance with discounts homeowners insurance agents. Save on free rates on homeowners insurance.

    ReplyDelete
  4. Thank you for posting this great info. You have great chance to get info about online affiliate programs. The most common casino affiliate programs such as go wild affiliates and great poker rooms such as redbet affiliate.

    ReplyDelete
  5. I'm really impressed with your writing skills and also with the layout on your weblog. Either way keep up the excellent quality writing, it is rare to see a great blog like this one these days..
    www.coderstech.com
    www.codersiq.com

    ReplyDelete
  6. I have read your blog its very attractive and impressive. I like it your blog.

    Java Online Training Java EE Online Training Java EE Online Training Java 8 online training Core Java 8 online training

    Java Online Training from India Java Online Training from India Core Java Training Online Core Java Training Online Java Training InstitutesJava Training Institutes

    ReplyDelete
  7. oracle fusion financials online training at erptree.com is worlds best online training center. we have excelled in knowledge sharing through online. we have almost all country students as our subscribers for online course. 10+ years of experience we have in handling various ascent people.
    we have user friendly website where you will be provided with all the required details and Self-paced DEMO videos

    ReplyDelete
  8. Hi!!!
    Good evening!!!
    very interesting article I feel very enthusiastic while reading and the information provided in this article is so useful for me About we are providing
    If our standard training offerings do not meet your requirements, <a href=" Rainbow training institute” ></a> can develop a course or set of courses tailored to your specific needs. A custom course might include a combination of topics from several standard courses or specialized material not found in any of our standard seminars. Rainbow training institute Labs will work with your staff to design the course you need.

    ReplyDelete
  9. شركة تنظيف فلل بالرياض
    وبالطبع يكون عمل تنظيف مساجد بالرياض أكثر صعوبة، حيث أن المساجد هي بيوت الله تعالى ومن الضروري أن تبقى مفتوحة دائماً لأداء الصلوات الخمس ، وعلي الشركة إتمام مهمة تنظيف الموكيت في أسرع وقت ويتم تجفيفه أيضا حتي يصبح جاهزاً للفرش والصلاة عليه في أوقات الصلوات الخمس دون تأخير .
    شركة تنظيف منازل شرق الرياض
    شركة تنظيف منازل شمال الرياض
    شركة تنظيف منازل جنوب الرياض
    شركة تنظيف منازل غرب الرياض
    &*&*&*&*&*&*&*&
    شركة تنظيف موكيت شمال الرياض
    شركة تنظيف موكيت شرق الرياض
    شركة تنظيف موكيت غرب الرياض
    شركة تنظيف موكيت جنوب الرياض






    ReplyDelete

  10. شركة نقل عفش بالمدينة المنورة
    التنقل من مكان لاخر ليس امرا سهلا بل امر يحتاج الى جهد كبير ووقت طويل كما ان اعمال النقل تحتاج الى احتراف فى ترتيب الاولويات وتنظيم العمل حتى لا يعرقل احد الاعمال عملا اخرا ويتسبب فى تأخر واخطاء، ومن هنا فقد نحتاج الى احد المتخصصين ليكونوا عونا لنا فى هذا العمل الشاق وتكون شركة نقل اثاث بالمدينة المنورة
    هى الاختيار الانسب لنا فى وقت الحاجة حيث الاتقان فى العمل وفن الترتيب والتنظيم بالاضافة الى الكفاءة فى اعمال النقل والقدرة على الانجاز
    شركة شراء اثاث مستعمل بالمدينة المنورة

    ReplyDelete
  11. إذا كنت ترغب في الحصول على مياه نقية افضل شركة كشف تسربات بالقصيم و خالية من الجراثيم و الميكروبات فلابد ان تقوم بتوفير افضل شركة عزل خزانات بالقصيم أجود خامات العزل على الخزان و التي يتم تركيبها في الجدرا و في قاع الخزان و ذلك من اجل المحافظة افضل شركة اسطح خزانات بالقصيم على منع تعرض أشعة الشمس بشكل مباشر على المياه و تسلطها بشكل افضل شركة مكافحة حشرات بالقصيم دائم مما يؤدي إلى التغيير في الخواص الفيزيائية في مكونات المياه

    ReplyDelete
  12. لدى الصراصير جهاز استشعار شركة تنظيف بالبخار بجدة حساس جدًا موجود في قرونها مع العلم أنها شركة مكافحة حشرات بجدة لا عين لها ولا تستطيع الرؤية لكنها إن دخلت شركة تنظيف خزانات بجدة في منزل فإنها سرعان ما تهاجمه وبالتالي يصعب السيطرة شركة تنظيف شقق بجدة عليها حيث أنها تتكاثر بسرعة وبأعداد كبيرة فإذا كان منزلك به صراصير شركة مكافحة البق بجدة فمن الأفضل الاتصال بشركة متخصصة للقضاء عليها في الحال.

    ReplyDelete
  13. في البداية نحرص عبلي شركة تنظيف بالبخار بجدة ان يتم تفريغ الخزان من المياه شركة تنظيف خزانات بجدة و من بعدها نقوم بتوفير النظافة الدقيقة شركة مكافحة العتة بجدة لجميع اجزاءه الداخلية و الخارجية و من شركة مكافحة حشرات بجدة بعدها نحرص علي ان يتم اتباع افضل مواد العزل الامنة و التي شركة مكافحة النمل الابيض بجدة لا يمكن ان تلحث اي نوع من الضرر بالانسان و لهذا تواصل معنا عزيزي العميل لتجد خدمة تنظيف للخزان الخاص بالمنزل

    ReplyDelete
  14. من الممكن أن يحصل العملاء شركة تجهيز ملاعب على أفضل أنواع النجيل الصناعي التي يرغبون شركة نجيل صناعي بها و التي تتنوع بين أكثر من شكل مختلف حيث يوجد النجيل المتداخل ، النحيف و العريض شركة تنسيق حدائق أيضا و جميع تلك الأنواع متوفرة في شركة لاندسكيب بالقاهرة من أجل أن تحقق إليكم الخدمات التي ترغبون شركة تجهيزات حمامات سباحة في الحصول عليها و ذلك لأننا متميزون في مجال تركيب النجيل الصناعي و نحاول أن نلبي جميع احتياجات عملائنا

    ReplyDelete
  15. إن عرقلة الأنابيب والصرف الصحي هي تسليك مجاري بالكويت واحدة من أسوأ المشاكل التي يواجهها تسليك مجاري الكويت رب البيت ويمكن الآن حلها بسهولة من قبل أفضل الشركات لتنظيف المجاري في الكويت تسليك مجاري على أعلى مستوى ، لأن مشكلة انسداد المجاري تؤثر على وجود روائح كريهة تسليك مجاري بالكويت لا تحظى بشعبية لجميع أعضاء المنزل وتؤثر على الناس

    ReplyDelete
  16. تعتبر الواجهات شركة تنظيف بدبي من أهم الأماكن التي يجب تنظيفها على أكمل وجه، حيث أن نظافة شركة تنظيف بالشارقة الواجهات هي دليل على نظافة المنزل؛ لهذا شركة تنظيف بدبي يجب الاهتمام بها بشكل كبير وذلك من خلال شركة تنظيف فى دبي التواصل مع شركة تنظيف واجهات منازل في الشارقة شركة تنظيف بعجمان فإن الشركة سوف تتمكن من القيام بهذه المهمة مع اختلاف أنواع المنظفات

    ReplyDelete
  17. عندما يكون هناك ارتباط بين عملية التنظيف شركة تنظيف شقق بمكة وانتشار الأمراض والجراثيم شركة مكافحة حشرات بمكة يجب ان يتم التخلص من جميع الأتربة والأوساخ في المكان مثل الشقة او الفيلا او المنزل الذي نعيش بداخله شركة مكافحة حشرات بالطائف حتى يتم حماية أطفالنا من خطر الإصابة بالأمراض وتوفر شركة تنظيف منازل بمكة جميع خدمات شركة تنظيف خزانات بالطائف التنظيف سواء التنظيف العادي او خدمات غسيل شقق بمكة او غسيل منازل بمكة شركة تنظيف خزانات بمكة ومن أهم ما يتم القيام به لخروج الخدمة بصورة مشرفة أمام العملاء

    ReplyDelete
  18. نحن متخصصون في مجال التنظيف بالبخار لثقتنا شركة تنظيف بالبخار بجدة الدائمة في أن النظافة وحدها لا تكفى ويجب أن نوفر التعقيم شركة تنظيف بالبخار بمكة والتطهير معها لضمان مكان نظيف وصحي شركة تنظيف بجدة خالي تماماً من البكتريا والجراثيم خاصة شركة نقل عفش بمكة في وجود الأطفال فالبخار تقنية شديدة التأثير في قتل البكتريا والجراثيم لذلك نحرص على استخدامه ونوفر شركة تنظيف سجاد بالبخار بجدة أحدث التقنيات التي تعمل بالبخار لتقديم خدمات على مستوى عالي من الدقة والإتقان وتقوم

    ReplyDelete
  19. وقد اثبتت الدراسة والابحاث ان تلوث مياه الخزان شركة نقل عفش بجدة نتيجة المواد المصنوع منها الخزان ويعتبرافضل انواع الخزانات المصنوعة شركة تنظيف بالبخار بجدة من الحديد المجلفن او المصنوع من الزجاج وهم واقل عرضه للتلوث واغلاقه بطريقة جيدة فحرصا منا نحن شركة غسيل خزانات بالطائف شركة مكافحة حشرات بمكة على صحتنا وصحة اطفالنا يجب شركة تنظيف خزانات بالطائف تنظيف خزان المياه بصفة دورية حتى نتفادى جميع الامراض شركة تنظيف كنب بدبي ونقي اولادنا وانفسنا منها ونستخدم الخزان المصنوع من الصلب الغير قابل للصدا والمصرح به من وزارة الصحة.

    ReplyDelete
  20. يمكنك التواصل مع شركة تنظيف بدبي في أي وقت من أجل أن يقوم فريق العمال شركة تنظيف بالشارقة و الخبراء بالحضور إلى المنزل في الميعاد الذي تقوم شركة تنظيف بعجمان بتحديده حيث أن الفريق معروف بمدى التزامه بالمواعيد و الاتقان شركة تنظيف بابو ظبي في العمل فنحن نرغب في توفير الخدمة المثالية التي تمكنا من الحصول شركة تنظيف كنب بدبي على ثقة العميل الكبيرة بنا فنحن نجتهد لكي نستحق تلك الثقة بشكل مستمر

    ReplyDelete
  21. يعمل فريق الخبراء على تقديم التصاميم حجر هاشمى هيصم المختلفة الخاصة بالمطابخ أو الحمامات شركة تنظيف بدبي و يمكنك الاختيار فيما بينها و هذا من خلال حجر مايكا تسليك مجاري بالكويت الذي يعمل على توفير الدعم و القوة على الغرف الموجودة في المنزل و تتعامل الشركة رقم صباغ رخيص بالكويت معكم بأقل الاسعار و التكاليف التي فني كهرباء منازل بالكويت لا مثيل لها في أي مكان آخر

    ReplyDelete