Panagram TDD kata

124 views
Skip to first unread message

Christian Soronellas

unread,
Mar 28, 2016, 11:10:53 AM3/28/16
to Clean Code Discussion
Hi all,

Today I wanted to practice TDD. So I went to hackerrank and picked a simple challenge: Pangrams. In short, the purpose of the exercise is to build a simple program that outputs "pangram" when a given string is a pangram (a sentence using every letter of the alphabet at least once) and "not pangram" when it's not. I started with the exercise as always but got stuck in the second test when I realized that all the tests I could think of, lead to the same point. And only I could think of one test that lead me to the solution in one big step.

For example

<?php

class PangramTest extends \PHPUnit_Framework_TestCase {
 
/** @test */
 
public function it_should_return_not_pangram_for_an_empty_string() {
    $this
->assertEquals('not pangram', isPangram(''));
 
}

 
/** @test */
 
public function it_should_return_not_pangram_for_an_string_lower_than_26() {
    $this
->assertEquals('not pangram', isPangram('a'));
 
}

 
/** @test */
 
public function it_should_return_not_pangram_for_an_string_which_doesnt_contain_letter_a() {
    $this
->assertEquals('not pangram', isPangram(str_repeat('b', 26)));
 
}

 
/** @test */
 
public function it_should_return_not_panagram_for_an_string_which_doesnt_contain_letter_b() {
    $this
->assertEquals('not panagram', isPanagram(str_repeat('a', 26)));
 
}

 
/** @test */
 
public function it_should_return_not_pangram_for_an_string_which_doesnt_contain_letter_c() {
    $this
->assertEquals('not pangram', isPangram(str_repeat('b', 26)));
 
}
}

function isPangram() {
 
return 'not pangram';
}

I could continue adding more and more tests but any of them would not allow me to change the algorithm until I add a test with all the letters from the alphabet that forces me to implement the whole algorithm at once.

/** @test */
public function it_should_return_pangram_for_an_string_which_contains_all_the_letters_in_the_alphabet() {
  $this
->assertEquals('pangram', isPangram('
The quick brown fox jumps over the lazy dog'));
}

Have any of you done this exercise before using TDD that could give me any clues?

Thanks in advance!
Christian. 

Sebastian Gozin

unread,
Apr 8, 2016, 11:50:48 AM4/8/16
to Clean Code Discussion
Hmm, I see your dilemma.

I have done the following in the past though I'm not sure this is proper TDD practice.
You could write tests for something which doesn't solve this problem but once it exists would make it easier to solve this problem.

For example,
I naively would think that if you iterate over the letters in a string you could flag each letter you encounter in some kind of table.
So you could write tests which assert each letter in the alphabet can be flagged in said table.

Then finally I presume all you have to do is check if every single entry in the table was flagged to true?

Sebastian Gozin

unread,
Apr 8, 2016, 11:55:01 AM4/8/16
to Clean Code Discussion
Thinking a bit more on it I just identified 2 problems which need to be solved for this kata.

1. a function to convert a string into a table with keys for every letter in the alphabet and a value of true if that key was present in the string (you can TDD this)
2. a function which takes a table and asserts every value is true

Funnily, the second function is pretty generic.

Sebastian Gozin

unread,
Apr 8, 2016, 12:02:42 PM4/8/16
to Clean Code Discussion
Aaaand.

A buddy of mine at the office had the following idea.

1. a function which counts the number of unique letters from the alphabet in the input
2. a function which returns true on the number 26

vivek poddar

unread,
Apr 8, 2016, 12:06:15 PM4/8/16
to clean-code...@googlegroups.com

Basically what you are doing is reducing the problem to simpler subproblems which is a great thing and this thinking is mostly done before jumping to coding either via pen paper or whiteboard but I can't see the role of TDD in it.

--
The only way to go fast is to go well.
---
You received this message because you are subscribed to the Google Groups "Clean Code Discussion" group.
To unsubscribe from this group and stop receiving emails from it, send an email to clean-code-discu...@googlegroups.com.
To post to this group, send email to clean-code...@googlegroups.com.
Visit this group at https://groups.google.com/group/clean-code-discussion.

Sebastian Gozin

unread,
Apr 8, 2016, 1:40:04 PM4/8/16
to Clean Code Discussion
Well I was reasoning that the purpose of these kata's is to practice problems we already know how to solve.
Rather than coerce TDD into exposing a solution which it can't do.
Perhaps that's the point of this kata.

So, if we know how to solve the problem through splitting it up in more manageable subproblems then the kata reverts to building muscle memory which can serve you to recognize similar patterns in other problems.

Even if the transformation priority premise suggests it can result in efficient solutions it doesn't look like it can be applied to the original problem.
It can be applied to the sub problems however.
To unsubscribe from this group and stop receiving emails from it, send an email to clean-code-discussion+unsub...@googlegroups.com.

theUniC

unread,
Apr 9, 2016, 5:23:59 AM4/9/16
to clean-code-discussion
Thanks to you all guys for your answers.

Indeed, a friend of mine pointed me out to the same reasoning and It worked pretty well. What I ended up doing was to make the alphabet a variable. And that let me build a solution incrementally.

Here I attach a link with all the test cases.


Best,
Christian.

To unsubscribe from this group and stop receiving emails from it, send an email to clean-code-discu...@googlegroups.com.
To post to this group, send email to clean-code...@googlegroups.com.
Visit this group at https://groups.google.com/group/clean-code-discussion.

--
The only way to go fast is to go well.
---
You received this message because you are subscribed to the Google Groups "Clean Code Discussion" group.
To unsubscribe from this group and stop receiving emails from it, send an email to clean-code-discu...@googlegroups.com.

Sebastian Gozin

unread,
Apr 10, 2016, 1:43:55 PM4/10/16
to Clean Code Discussion
I like the idea of passing in an alphabet to test against.
I don't think I would have set out to do something like that but I do like to pull out hard coded values and make them configuration as it makes the production code more generic.

Interesting stuff.
To unsubscribe from this group and stop receiving emails from it, send an email to clean-code-discussion+unsub...@googlegroups.com.
To post to this group, send email to clean-code...@googlegroups.com.
Visit this group at https://groups.google.com/group/clean-code-discussion.

--
The only way to go fast is to go well.
---
You received this message because you are subscribed to the Google Groups "Clean Code Discussion" group.
To unsubscribe from this group and stop receiving emails from it, send an email to clean-code-discussion+unsub...@googlegroups.com.

vivek poddar

unread,
Apr 11, 2016, 9:26:39 AM4/11/16
to clean-code...@googlegroups.com

+1 for using alphabet array.

@sebastian we would like to see some example :)

To unsubscribe from this group and stop receiving emails from it, send an email to clean-code-discu...@googlegroups.com.
To post to this group, send email to clean-code...@googlegroups.com.
Visit this group at https://groups.google.com/group/clean-code-discussion.

--
The only way to go fast is to go well.
---
You received this message because you are subscribed to the Google Groups "Clean Code Discussion" group.
To unsubscribe from this group and stop receiving emails from it, send an email to clean-code-discu...@googlegroups.com.

To post to this group, send email to clean-code...@googlegroups.com.
Visit this group at https://groups.google.com/group/clean-code-discussion.

--
The only way to go fast is to go well.
---
You received this message because you are subscribed to the Google Groups "Clean Code Discussion" group.
To unsubscribe from this group and stop receiving emails from it, send an email to clean-code-discu...@googlegroups.com.
Reply all
Reply to author
Forward
0 new messages