updated
authorChristian Urban <christian.urban@kcl.ac.uk>
Sun, 15 Nov 2020 13:10:43 +0000
changeset 361 f88b5cec2e5d
parent 360 e45d2890749d
child 362 1bde878ba6c9
updated
progs/lecture1.scala
progs/lecture2.scala
--- a/progs/lecture1.scala	Sat Nov 14 00:40:47 2020 +0000
+++ b/progs/lecture1.scala	Sun Nov 15 13:10:43 2020 +0000
@@ -483,16 +483,6 @@
 
 
 
-////////////
-// calculating pi 
-def f(n: BigInt) = BigDecimal(4 * n * n) / BigDecimal(4 * n * n - 1)
-
-2 * (BigInt(1) to BigInt(100000)).map(f).product
-
-(1 to 1000).sum
-(1 to 1000).product
-
-
 // Further Information
 //=====================
 
--- a/progs/lecture2.scala	Sat Nov 14 00:40:47 2020 +0000
+++ b/progs/lecture2.scala	Sun Nov 15 13:10:43 2020 +0000
@@ -1,50 +1,61 @@
 // Scala Lecture 2
 //=================
 
-// For-Comprehensions Again
-//==========================
-
-// the first produces a result, while the second does not
-for (n <- List(1, 2, 3, 4, 5)) yield n * n
-
-
-for (n <- List(1, 2, 3, 4, 5)) println(n)
-
 
 // String Interpolations
 //=======================
 
+
 def cube(n: Int) : Int = n * n * n
 
 val n = 3
 println("The cube of " + n + " is " + cube(n) + ".")
 
-println(s"The cube of ${n} is ${cube(n)}.")
+println(s"The cube of $n is ${cube(n)}.")
 
 // or even
 
-println(s"The cube of ${n} is ${n * n * n}.")
+println(s"The cube of $n is ${n * n * 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)
+//     "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}.")
+  println(s"Function called with $a and $b.")
   if (b == 0) a else gcd_db(b, a % b)
 }
 
 gcd_db(48, 18)
 
 
+
+// you can also implement your own string interpolations
+
+import scala.language.implicitConversions
+import scala.language.reflectiveCalls
+
+implicit def sring_inters(sc: StringContext) = new {
+    def i(args: Any*): String = s"\t${sc.s(args:_*)}\n"
+    def l(args: Any*): String = s"${sc.s(args:_*)}:\n"
+}
+
+// this allows you to write things like
+
+i"add ${3+2}" 
+l"some_fresh_name"
+
+
+
 // The Option Type
 //=================
 
-// in Java, if something unusually happens, you return null or 
-// raise an exception
+// 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)
@@ -54,6 +65,23 @@
 List(7,2,3,4,5,6).find(_ < 4)
 List(5,6,7,8,9).find(_ < 4)
 
+// Int:      ..., 0, 1, 2,...
+// Boolean:  true false
+//
+// List[Int]: Nil, List(_) 
+//
+// Option[Int]: None, Some(0), Some(1), ...
+// Option[...]: None, Some(_)
+
+def safe_div(x: Int, y: Int) : Option[Int] = 
+  if (y == 0) None else Some(x / y)
+
+List(1,2,3,4,5,6).indexOf(7)
+
+def my_min(ls: List[Int]) : Option[Int] = ls.minOption
+
+my_min(List(1,2,3,4))
+
 
 // better error handling with Options (no exceptions)
 //
@@ -63,37 +91,37 @@
 import scala.util._
 import io.Source
 
-val my_url = "https://nms.kcl.ac.uk/christian.urban/"
+val my_url = "https://nms.kcl.ac.uk/christian.urban2/"
 
-Source.fromURL(my_url).mkString
+Source.fromURL(my_url)("ISO-8859-1").mkString
 
-Try(Source.fromURL(my_url).mkString).getOrElse("")
+Try(Source.fromURL(my_url)("ISO-8859-1").mkString).getOrElse("")
 
-Try(Some(Source.fromURL(my_url).mkString)).getOrElse(None)
+Try(Some(Source.fromURL(my_url)("ISO-8859-1").mkString)).getOrElse(None)
 
 
 // the same for files
-Try(Some(Source.fromFile("text.txt").mkString)).getOrElse(None)
+Try(Some(Source.fromFile("test.txt")("ISO-8859-1").mkString)).getOrElse(None)
 
 
 // how to implement a function for reading 
 // (lines) something from files...
 //
 def get_contents(name: String) : List[String] = 
-  Source.fromFile(name).getLines.toList
+  Source.fromFile(name)("ISO-8859-1").getLines.toList
 
 get_contents("text.txt")
 get_contents("test.txt")
 
 // slightly better - return Nil
 def get_contents(name: String) : List[String] = 
-  Try(Source.fromFile(name).getLines.toList).getOrElse(List())
+  Try(Source.fromFile(name)("ISO-8859-1").getLines.toList).getOrElse(List())
 
 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)
+  Try(Some(Source.fromFile(name)("ISO-8859-1").getLines.toList)).getOrElse(None)
 
 get_contents("text.txt")
 get_contents("test.txt")
@@ -111,8 +139,12 @@
 Some(1).isDefined
 None.isDefined
 
+for (x <- lst) yield x.getOrElse(0)
 
-val ps = List((3, 0), (4, 2), (6, 2), (2, 0), (1, 0), (1, 1))
+
+
+val ps = List((3, 0), (4, 2), (6, 2), 
+              (2, 0), (1, 0), (1, 1))
 
 // division where possible
 
@@ -120,15 +152,18 @@
   if (y == 0) None else Some(x / y)
 }
 
+
+
 // getOrElse is for setting a default value
 
 val lst = List(None, Some(1), Some(2), None, Some(3))
 
-for (x <- lst) yield x.getOrElse(0)
+
 
 
-// a function that turns strings into numbers (similar to .toInt)
-Integer.parseInt("12u34")
+// a function that turns strings into numbers 
+// (similar to .toInt)
+Integer.parseInt("1234")
 
 
 def get_me_an_int(s: String) : Option[Int] = 
@@ -242,8 +277,6 @@
 // type of functions is for example Int => Int
 
 
-0 :: List(3,4,5,6)
-
 
 def my_map_int(lst: List[Int], f: Int => Int) : List[Int] = {
   if (lst == Nil) Nil