/** Example of AncTree. Immutable, using scala's "case classes". * We'll be non-O.O., and have 'static' methods `size`, `contains`, etc. */ // >>>IDE: IF an IDE is requiring one file to be one "compilation unit", uncomment the next line (1 of 3): // object dummyObjectContainerForMyAncTreeStuff { // Everything in this entire file is now contained inside the singleton object `dummyObjectContainerForMyAncTreeStuff`; // you can run `scalac` to compile, and then `scala dummyObjectContainerForMyAncTreeStuff` (in th esame // way that you run `javac [someFile].java` and then `java [someClassName]` abstract sealed class AncTree case class Unknown() extends AncTree case class Child( name :String, yob :Int, eye :String, ma :AncTree, pa :AncTree ) extends AncTree /** Return the size of `t` -- the number of `Child`s anywhere inside `t`. */ def size( t :AncTree ) :Int = t match { // If you get "error: expected class or object definition", see ">>>IDE" comments. case Unknown() => 0 case Child(_,_,_,m,p) => 1 + size(m) + size(p) } /** Return all the names in `t` as a list-of-strings. */ def changeName( t :AncTree, target :String, repl :String ) :AncTree = t match { case Unknown() => unk case Child(n,y,e,m,p) => Child( if (n==target) then repl else n, y, e, changeName(ma, target, repl), changeName(pa, target, repl) ) } /** Return all the names in `t` as a list-of-strings. */ def allNames( t :AncTree ) :List[String] = t match { case Unknown() => new List(); case Child(n,_,_,m,p) => allNames(m).add(n).appendAll(allNames(pa)) } //************************ a lowbrow testing framework ************************/ private var testNum : Int = 0 private var spaceNum : Int = 0 private val groupSize = 5 private val lineSize = 10*groupSize def test( actual:Any, expected:Any ) : Unit = { testNum += 1 spaceNum += 1 if (actual.equals(expected)) System.out.printf(".") else { System.out.printf("!") System.err.printf("TEST #%d FAILED:\n%s\nnot equal to expected\n%s\n", testNum : Integer, actual.toString(), expected.toString()) } if (spaceNum%groupSize==0) { System.out.printf(" ") } if (spaceNum%lineSize==0 ) { System.out.printf("\n"); spaceNum=0 } } def printTestMsg( msg:String ) : Unit = { System.out.printf( "%s%s\n", if (spaceNum!=0) "\n" else "", msg ) spaceNum = 0 } //************************ end lowbrow testing framework ************************/ //************************ run tests ************************/ // >>>IDE: IF an IDE is requiring one file to be one "compilation unit", uncomment the next line (2 of 3): //def main( args :Array[String] ) : Unit = { printTestMsg("Starting tests") val unk = Unknown() val jackie = Child("Jackie", 1926, "brown", unk, unk) val marge = Child("Marge", 1956, "blue", jackie, unk) val abe = Child("Abe", 1920, "blue", unk, unk ) val mona = Child("Mona", 1929, "brown", unk, unk ) val homer = Child("Homer", 1955, "brown", mona, abe) val bart = Child("Bart", 1979, "brown", marge, homer) test( size(Unknown()), 0 ) test( size(jackie), 1 ) test( size(marge), 2 ) test( size(homer), 3 ) test( size(bart), 6 ) test( changeName(unk, "Joseph", "Joey"), unk) test( changeName(jackie, "Joseph", "Joey"), jackie) test( changeName(jackie, "Jackie", "Jack"), Child("Jack", 1926, "brown", unk, unk)) test( changeName( Child("Joseph", 50, "blue", Child("Amy", 50, "blue", Child("Joseph", 50, "blue", unk, unk), Child("Joey", 50, "blue", unk, unk)), Child("Joseph", 50, "blue", unk, unk)), "Joseph", "Joey"), Child("Joey", 50, "blue", Child("Amy", 50, "blue", Child("Joey", 50, "blue", unk, unk), Child("Joey", 50, "blue", unk, unk)), Child("Joey", 50, "blue", unk, unk)) ) test( (all-names unk) []) test( (all-names jackie), ["Jackie"] ) test( (all-names marge).sort(), ["Jackie", "Marge"].sort() ) test( (all-names homer).sort(), ["Mona", "Homer", "Abe"].sort() ) test( (all-names bart).sort(), ["Jackie", "Marge", "Bart", "Mona", "Homer", "Abe"].sort() ) printTestMsg("Finished tests") // >>>IDE: IF an IDE is requiring one file to be one "compilation unit", uncomment the next line (3 of 3): //}} /** * @author ibarland * @version 2019-Apr-04 * @license: CC-BY 4.0 -- you are free to share and adapt this material * for any purpose, provided you include appropriate attribution. * https://creativecommons.org/licenses/by/4.0/ * https://creativecommons.org/licenses/by/4.0/legalcode * Including the source material's URL satisifies "appropriate attribution". */