progs/lecture1.scala
changeset 200 01ee4b576eb2
parent 199 54befaf23648
child 202 f7bcb27d1940
--- 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.