001    package example;
002    
003    /**
004     * The class to demonstrate ComTest as a test and design tool.
005     * In this example we have side effect that makes
006     * the testing a bit more complex.
007     * 
008     * Suppose our problem is to do some linguistic research 
009     * and find what are the most popular three first vowels from
010     * every verse in Finish national poetry Kalevala.
011     * The first song of Kalevala begins like:
012     * <pre>
013     * Mieleni minun tekevi, aivoni ajattelevi
014     * lähteäni laulamahan, saa'ani sanelemahan,
015     * sukuvirttä suoltamahan, lajivirttä laulamahan.
016     * Sanat suussani sulavat, puhe'et putoelevat,
017     * kielelleni kerkiävät, hampahilleni hajoovat.
018     * </pre>
019     * At the beginning we will need to read the file kalevala.txt
020     * and then take every verse and extract there 3 first vowels. 
021     * To extract the 3 first vowels we might need a function
022     * extract3FirstVowels(s).  But to make it a bit more generic
023     * we may send the number 3 as a parameter.  And to make it more general
024     * we might send also the list of chars to extract as a parameter.
025     * So we need a function extractChars(s,n,letters)
026     * @author vesal
027     * @version 8.6.2010
028     *
029     */
030    public class TakeCharsReady {
031    
032            /**
033             * Take from s the n first chars that are in the list of letters and return them.
034             * @param s where to take letters
035             * @param n how many letters to take at max
036             * @param letters set of letters we are looking
037             * @return n first chars belonging to set letters
038             * 
039             * @example
040             * <pre name="test">
041             *   StringBuilder s = new StringBuilder("Mieleni minun tekevi");
042             *   extractChars(s,3,"aeiouyåäö") === "iee"; s.toString() === "Mlni minun tekevi"; 
043             *   extractChars(s,3,"xyz") === "";          s.toString() === "Mlni minun tekevi"; 
044             *   extractChars(s,4,"klmn") === "Mlnm";     s.toString() === "i inun tekevi"; 
045             *   extractChars(s,4,"e") === "ee";          s.toString() === "i inun tkvi"; 
046             * </pre>
047             * 
048             * @example
049             * <pre name="test">
050             *   StringBuilder s;
051             *   s = new StringBuilder($s);
052             *   extractChars(s,$n,$letters) === $result; s.toString() === $left;
053             *   
054             *            $s              | $n | $letters    | $result  | $left
055             *   -------------------------------------------------------------------------------  
056             *     "Mieleni minun tekevi" |  3 | "aeiouyåäö" | "iee"    | "Mlni minun tekevi" 
057             *     ---                    |  3 | "xyz"       | ""       | "Mlni minun tekevi" 
058             *     ---                    |  4 | "klmn"      | "Mlnm"   | "i inun tekevi" 
059             *     ---                    |  4 | "e"         | "ee"     | "i inun tkvi" 
060             * </pre>
061             */
062            public static String extractChars(StringBuilder s, int n, String letters) {
063                    StringBuilder result = new StringBuilder();
064                    String uletters = letters.toUpperCase();
065                    int i = 0;
066                    while ( i < s.length() && result.length() < n ) {
067                            char c = s.charAt(i);
068                            if ( uletters.indexOf(Character.toUpperCase(c)) >= 0 ) { // found the letter
069                                    result.append(c);
070                                    s.deleteCharAt(i);
071                            } else { // not found, move to the next one
072                                    i++;
073                            }
074                    }
075                    
076                    return result.toString();
077            }
078            
079            /**
080             * @param args not used
081             */
082            public static void main(String[] args) {
083                    StringBuilder s = new StringBuilder("Mieleni minun tekevi");
084                    String vowels3 = extractChars(s,3,"aeiouyåäö");
085                    System.out.println("Three first vovels are " + vowels3 + " and there are left " + s);
086            }
087    
088    }