1 // Scala Lecture 2 |
1 // Scala Lecture 2 |
2 //================= |
2 //================= |
3 |
3 |
4 // UNFINISHED BUSINESS from Lecture 1 |
4 |
5 //==================================== |
5 |
6 |
6 // The Option Type |
7 |
7 //================= |
8 // for measuring time |
8 |
9 def time_needed[T](n: Int, code: => T) = { |
9 // in Java, if something unusually happens, you return null or |
10 val start = System.nanoTime() |
10 // raise an exception |
11 for (i <- (0 to n)) code |
11 // |
12 val end = System.nanoTime() |
12 //in Scala you use Options instead |
13 (end - start) / 1.0e9 |
13 // - if the value is present, you use Some(value) |
14 } |
14 // - if no value is present, you use None |
15 |
15 |
16 |
16 |
17 val list = (1 to 1000000).toList |
17 List(7,2,3,4,5,6).find(_ < 4) |
18 time_needed(10, for (n <- list) yield n + 42) |
18 List(5,6,7,8,9).find(_ < 4) |
19 time_needed(10, for (n <- list.par) yield n + 42) |
19 |
20 |
20 |
21 // (needs a library and 'magic' option -Yrepl-class-based) |
21 |
22 |
22 // better error handling with Options (no exceptions) |
23 |
23 // |
24 |
24 // Try(something).getOrElse(what_to_do_in_case_of_an_exception) |
25 |
25 // |
26 // Just for Fun: Mutable vs Immutable |
26 |
27 //==================================== |
27 import scala.util._ |
28 // |
28 import io.Source |
29 // - no vars, no ++i, no += |
29 |
30 // - no mutable data-structures (no Arrays, no ListBuffers) |
30 val my_url = "https://nms.kcl.ac.uk/christian.urban/" |
31 |
31 |
32 |
32 Source.fromURL(my_url).mkString |
33 // Q: Count how many elements are in the intersections of |
33 |
34 // two sets? |
34 Try(Source.fromURL(my_url).mkString).getOrElse("") |
35 |
35 |
36 def count_intersection(A: Set[Int], B: Set[Int]) : Int = { |
36 Try(Some(Source.fromURL(my_url).mkString)).getOrElse(None) |
37 var count = 0 |
37 |
38 for (x <- A; if B contains x) count += 1 |
38 |
39 count |
39 // the same for files |
40 } |
40 Try(Some(Source.fromFile("text.txt").mkString)).getOrElse(None) |
41 |
41 |
42 val A = (1 to 1000).toSet |
42 // how to implement a function for reading something from files... |
43 val B = (1 to 1000 by 4).toSet |
43 |
44 |
44 def get_contents(name: String) : List[String] = |
45 count_intersection(A, B) |
45 Source.fromFile(name).getLines.toList |
46 |
46 |
47 // but do not try to add .par to the for-loop above |
47 get_contents("test.txt") |
48 |
48 |
49 |
49 // slightly better - return Nil |
50 //propper parallel version |
50 def get_contents(name: String) : List[String] = |
51 def count_intersection2(A: Set[Int], B: Set[Int]) : Int = |
51 Try(Source.fromFile(name).getLines.toList).getOrElse(List()) |
52 A.par.count(x => B contains x) |
52 |
53 |
53 get_contents("text.txt") |
54 count_intersection2(A, B) |
54 |
55 |
55 // much better - you record in the type that things can go wrong |
56 |
56 def get_contents(name: String) : Option[List[String]] = |
57 val A = (1 to 1000000).toSet |
57 Try(Some(Source.fromFile(name).getLines.toList)).getOrElse(None) |
58 val B = (1 to 1000000 by 4).toSet |
58 |
59 |
59 get_contents("text.txt") |
60 time_needed(100, count_intersection(A, B)) |
60 get_contents("test.txt") |
61 time_needed(100, count_intersection2(A, B)) |
|
62 |
61 |
63 |
62 |
64 |
63 |
65 // For-Comprehensions Again |
64 // For-Comprehensions Again |
66 //========================== |
65 //========================== |