progs/lecture2.scala
changeset 316 8b57dd326a91
parent 310 335079d938aa
child 317 607ceabeeffc
--- a/progs/lecture2.scala	Sat Nov 09 22:04:53 2019 +0000
+++ b/progs/lecture2.scala	Mon Nov 11 13:24:12 2019 +0000
@@ -1,64 +1,63 @@
 // Scala Lecture 2
 //=================
 
-// UNFINISHED BUSINESS from Lecture 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
-}
+// The Option Type
+//=================
+
+// in Java, if something unusually happens, you return null or 
+// raise an exception
+//
+//in Scala you use Options instead
+//   - if the value is present, you use Some(value)
+//   - if no value is present, you use None
 
 
-val list = (1 to 1000000).toList
-time_needed(10, for (n <- list) yield n + 42)
-time_needed(10, for (n <- list.par) yield n + 42)
-
-// (needs a library and 'magic' option -Yrepl-class-based)
-
+List(7,2,3,4,5,6).find(_ < 4)
+List(5,6,7,8,9).find(_ < 4)
 
 
 
-// Just for Fun: Mutable vs Immutable
-//====================================
+// better error handling with Options (no exceptions)
+//
+//  Try(something).getOrElse(what_to_do_in_case_of_an_exception)
 //
-// - no vars, no ++i, no +=
-// - no mutable data-structures (no Arrays, no ListBuffers)
+
+import scala.util._
+import io.Source
+
+val my_url = "https://nms.kcl.ac.uk/christian.urban/"
+
+Source.fromURL(my_url).mkString
+
+Try(Source.fromURL(my_url).mkString).getOrElse("")
+
+Try(Some(Source.fromURL(my_url).mkString)).getOrElse(None)
 
 
-// Q: Count how many elements are in the intersections of 
-//    two sets?
+// the same for files
+Try(Some(Source.fromFile("text.txt").mkString)).getOrElse(None)
+
+// how to implement a function for reading something from files...
 
-def count_intersection(A: Set[Int], B: Set[Int]) : Int = {
-  var count = 0
-  for (x <- A; if B contains x) count += 1 
-  count
-}
+def get_contents(name: String) : List[String] = 
+  Source.fromFile(name).getLines.toList
 
-val A = (1 to 1000).toSet
-val B = (1 to 1000 by 4).toSet
-
-count_intersection(A, B)
+get_contents("test.txt")
 
-// but do not try to add .par to the for-loop above
-
+// slightly better - return Nil
+def get_contents(name: String) : List[String] = 
+  Try(Source.fromFile(name).getLines.toList).getOrElse(List())
 
-//propper parallel version
-def count_intersection2(A: Set[Int], B: Set[Int]) : Int = 
-  A.par.count(x => B contains x)
+get_contents("text.txt")
 
-count_intersection2(A, B)
-
+// 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)
 
-val A = (1 to 1000000).toSet
-val B = (1 to 1000000 by 4).toSet
-
-time_needed(100, count_intersection(A, B))
-time_needed(100, count_intersection2(A, B))
+get_contents("text.txt")
+get_contents("test.txt")