--- 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.