diff -r 54befaf23648 -r 01ee4b576eb2 progs/lecture1.scala --- a/progs/lecture1.scala Thu Nov 08 23:42:03 2018 +0000 +++ b/progs/lecture1.scala Fri Nov 09 01:08:43 2018 +0000 @@ -63,7 +63,7 @@ List(1,2,3) == List(3,1,2) -// this applies for "concrete" values; +// this applies to "concrete" values; // you cannot compare functions @@ -86,6 +86,7 @@ println(lst.mkString("[", ",", "]")) + // Conversion methods //==================== @@ -109,8 +110,11 @@ "1,2,3,4,5".split(",").mkString("\n") "1,2,3,4,5".split(",3,").mkString("\n") +"abcdefg".startsWith("abc") + + // Types (slide) -//======= +//=============== /* Scala is a strongly typed language @@ -126,6 +130,7 @@ Set[Double] Pairs: (Int, String) List[(BigInt, String)] + Option[Int] */ @@ -141,6 +146,8 @@ t._4 +List(("one", 1), ("two", 2), ("three", 3)) + // Function Definitions //====================== @@ -159,12 +166,22 @@ // } +// +// BTW: no returns!! +// "last" line (expression) in a function determines the result +// + +def silly(n: Int) : Int = { + n * n + n + n +} + // If-Conditionals //================= -// Scala does not have a then-keyword -// both if-else branches need to be present +// - Scala does not have a then-keyword +// - both if-else branches need to be present def fact(n: Int) : Int = if (n == 0) 1 else n * fact(n - 1) @@ -211,7 +228,7 @@ //in Java if something unusually happens, you return null // -//in Scala you use Option +//in Scala you use Options instead // - if the value is present, you use Some(value) // - if no value is present, you use None @@ -240,6 +257,26 @@ // the same for files Source.fromFile("test.txt").mkString +// function reading something from files... + +def get_contents(name: String) : List[String] = + Source.fromFile(name).getLines.toList + +get_contents("test.txt") + +// slightly better - return Nil +def get_contents(name: String) : List[String] = + Try(Source.fromFile(name).getLines.toList).getOrElse(Nil) + +get_contents("text.txt") + +// much better - you record in the type that things can go wrong +def get_contents(name: String) : Option[List[String]] = + Try(Some(Source.fromFile(name).getLines.toList)).getOrElse(None) + +get_contents("text.txt") + + // String Interpolations //======================= @@ -250,6 +287,12 @@ println(s"The square of ${n} is ${square(n)}.") +// helpful for debugging purposes +// +// "The most effective debugging tool is still careful thought, +// coupled with judiciously placed print statements." +// — Brian W. Kernighan, in Unix for Beginners (1979) + def gcd_db(a: Int, b: Int) : Int = { println(s"Function called with ${a} and ${b}.") @@ -260,7 +303,7 @@ // Asserts/Testing -//================ +//================= assert(gcd(48, 18) == 6) @@ -282,11 +325,12 @@ mult_table.sliding(10,10).mkString("\n") -// the list can also be constructed in any other way +// the list/set/... can also be constructed in any +// other way for (n <- List(10,12,4,5,7,8,10)) yield n * n -// with if-predicates +// with if-predicates / filters for (n <- (1 to 3).toList; m <- (1 to 3).toList; @@ -305,14 +349,36 @@ for (p <- lst) yield p._1 + p._2 -// general pattern +// general pattern of for-yield -for (x <- ...) yield { +for (p <- ...) yield { // potentially complicated // calculation of a result } +// Functions producing multiple outputs +//====================================== +def get_ascii(c: Char) : (Char, Int) = (c, c.toInt) + +get_ascii('a') + + +// .maxBy, sortBy with pairs +def get_length(s: String) : (String, Int) = (s, s.length) + +val lst = List("zero", "one", "two", "three", "four", "ten") +val strs = for (s <- lst) yield get_length(s) + +strs.sortBy(_._2) +strs.sortBy(_._1) + +strs.maxBy(_._2) +strs.maxBy(_._1) + + +// For without yield +//=================== // with only a side-effect (no list is produced), // has no "yield" @@ -325,7 +391,7 @@ for (i <- (0 until lst.length)) println(lst(i)) -// why not? +// Why not just? Why making your life so complicated? for (c <- lst) println(c) // Aside: concurrency @@ -350,87 +416,75 @@ time_needed(10, for (n <- list.par) yield n + 42) -// Function producing multiple outputs -//===================================== -def get_ascii(c: Char) : (Char, Int) = (c, c.toInt) - -get_ascii('a') - +// Just for "Fun": Mutable vs Immutable +//======================================= +// +// - no vars, no ++i, no += +// - no mutable data-structures (no Arrays, no ListBuffers) -// .maxBy, sortBy with pairs -def get_length(s: String) : (String, Int) = (s, s.length) +// Q: Count how many elements are in the intersections of two sets? + +def count_intersection(A: Set[Int], B: Set[Int]) : Int = { + var count = 0 + for (x <- A; if (B contains x)) count += 1 + count +} -val lst = List("zero", "one", "two", "three", "four", "ten") -val strs = for (s <- lst) yield get_length(s) +val A = (1 to 1000).toSet +val B = (1 to 1000 by 4).toSet + +count_intersection(A, B) + +// but do not try to add .par to the for-loop above + -strs.sortBy(_._2) -strs.sortBy(_._1) +//propper parallel version +def count_intersection2(A: Set[Int], B: Set[Int]) : Int = + A.par.count(x => B contains x) + +count_intersection2(A, B) + -strs.maxBy(_._2) -strs.maxBy(_._1) +//for measuring time +def time_needed[T](n: Int, code: => T) = { + val start = System.nanoTime() + for (i <- (0 to n)) code + val end = System.nanoTime() + (end - start) / 1.0e9 +} + +val A = (1 to 1000000).toSet +val B = (1 to 1000000 by 4).toSet + +time_needed(10, count_intersection(A, B)) +time_needed(10, count_intersection2(A, B)) + // Further Information //===================== -// The Scala home page and general information is at +// The Scala homepage and general information is at // // http://www.scala-lang.org // http://docs.scala-lang.org // // // It should be fairly easy to install the Scala binary and -// run Scala on the commandline. There are also at least -// four IDEs you can use with Scala: -// -// (0) Some general information about setting up IDEs -// with Scala support can be found at -// -// http://docs.scala-lang.org/getting-started.html -// -// -// (1) Eclipse for Scala (one big bundle) +// run Scala on the commandline. People also use Scala with +// Vim and Jedit. I currently settled on VS Code // -// http://scala-ide.org/download/sdk.html -// -// (2) IntelliJ (needs additional Plugins) -// -// https://www.jetbrains.com/idea/ -// http://docs.scala-lang.org/getting-started-intellij-track/getting-started-with-scala-in-intellij.html -// -// (3) Sublime (not free, but unlimited trial period; -// needs Scala and SublimeREPL plugin) -// -// https://www.sublimetext.com -// -// (4) Emacs (old-fashioned, but reliable) +// https://code.visualstudio.com // -// https://www.gnu.org/software/emacs/ -// -// I use the old scala-tool support for Emacs distributed at -// -// https://github.com/scala/scala-tool-support/tree/master/tool-support/emacs -// -// but there is also support for the newer Ensime Scala Mode +// There are also plugins for Eclipse and IntelliJ - YMMV. +// Finally there are online editors specifically designed for +// running Scala applications (but do not blame me if you lose +// all what you typed in): // -// http://ensime.org/editors/emacs/scala-mode/ -// -// There is also Scala support in the Atom editor, but my -// experience is mixed. People also use Scala with Vim and Jedit. -// Finally there is an online editor specifically designed for -// running Scala applications (but do not blame mne if you lose all -// what you typed in): +// https://scalafiddle.io +// https://scastie.scala-lang.org // -// https://scalafiddle.io -// -// -// -// All of the IDEs above support a REPL for Scala. Some of them have -// the very nifty feature of a Scala Worksheet -- you just save your -// file and it will be automatically evaluated and the result pasted -// into your file. However, this way of writing Scala code never worked -// for me. I just use the REPL. // // // Scala Library Docs @@ -443,8 +497,8 @@ // http://docs.scala-lang.org/tutorials/ // // There are also a massive number of Scala tutorials on youtube -// and there are tons of books and free material. -// +// and there are tons of books and free material. Google is your +// friend.