95 List(1,2,3,4,3)indexOf(3)  | 
    94 List(1,2,3,4,3)indexOf(3)  | 
    96   | 
    95   | 
    97 "1,2,3,4,5".split(",").mkString("\n") | 
    96 "1,2,3,4,5".split(",").mkString("\n") | 
    98 "1,2,3,4,5".split(",3,").mkString("\n") | 
    97 "1,2,3,4,5".split(",3,").mkString("\n") | 
    99   | 
    98   | 
   100 // Types  | 
    99 // Types (slide)  | 
   101 //=======  | 
   100 //=======  | 
   102   | 
   101   | 
   103 /* Scala is a strongly typed language  | 
   102 /* Scala is a strongly typed language  | 
   104    | 
   103    | 
   105  * some base types  | 
   104  * some base types  | 
   122 println(">\n\n<") | 
   121 println(">\n\n<") | 
   123 println(""">\n<""") | 
   122 println(""">\n<""") | 
   124 println("""">\n<"""") | 
   123 println("""">\n<"""") | 
   125   | 
   124   | 
   126 /* in Java  | 
   125 /* in Java  | 
   127 val lyrics = "Baa, Baa, Black Sheep \n" +  | 
   126 val lyrics = "Sun dips down, the day has gone \n" +  | 
   128              "Have you any wool? \n" +  | 
   127              "Witches, wolves and giants yawn \n" +  | 
   129              "Yes, sir, yes sir \n" +  | 
   128              "Queen and dragon, troll and gnome \n" +  | 
   130              "Three bags full"  | 
   129              "Baddy buddies head for home"  | 
   131 */   | 
   130 */   | 
   132   | 
   131   | 
   133 val lyrics = """Baa, Baa, Black Sheep    | 
   132 val lyrics = """Sun dips down, the day has gone  | 
   134                 |Have you any wool?  | 
   133                 |Witches, wolves and giants yawn  | 
   135                 |Yes, sir, yes sir  | 
   134                 |Queen and dragon, troll and gnome  | 
   136                 |Three bags full""".stripMargin  | 
   135                 |Baddy buddies head for home""".stripMargin  | 
   137   | 
   136   | 
   138 println(lyrics)  | 
   137 println(lyrics)  | 
   139   | 
   138   | 
   140   | 
   139   | 
   141 // Pairs/Tuples  | 
   140 // Pairs/Tuples  | 
   274 // has no "yield"  | 
   273 // has no "yield"  | 
   275   | 
   274   | 
   276 for (n <- (1 to 10)) println(n)  | 
   275 for (n <- (1 to 10)) println(n)  | 
   277   | 
   276   | 
   278   | 
   277   | 
   279 // concurrency (ONLY WORKS IN SCALA 2.11.8, not in SCALA 2.12.0)  | 
   278   | 
         | 
   279   | 
         | 
   280   | 
         | 
   281   | 
         | 
   282 // concurrency (ONLY WORKS IN SCALA 2.11.8, not in SCALA 2.12)  | 
         | 
   283 //             (would need to have this wrapped into a function, or  | 
         | 
   284 //              REPL called with scala -Yrepl-class-based)  | 
   280 for (n <- (1 to 10)) println(n)  | 
   285 for (n <- (1 to 10)) println(n)  | 
   281 for (n <- (1 to 10).par) println(n)  | 
   286 for (n <- (1 to 10).par) println(n)  | 
   282   | 
   287   | 
   283   | 
   288   | 
   284 // for measuring time  | 
   289 // for measuring time  | 
   285 def time_needed[T](i: Int, code: => T) = { | 
   290 def time_needed[T](n: Int, code: => T) = { | 
   286   val start = System.nanoTime()  | 
   291   val start = System.nanoTime()  | 
   287   for (j <- 1 to i) code  | 
   292   for (i <- (0 to n)) code  | 
   288   val end = System.nanoTime()  | 
   293   val end = System.nanoTime()  | 
   289   ((end - start) / i / 1.0e9) + " secs"  | 
   294   (end - start) / 1.0e9  | 
   290 }  | 
   295 }  | 
         | 
   296   | 
   291   | 
   297   | 
   292 val list = (1 to 1000000).toList  | 
   298 val list = (1 to 1000000).toList  | 
   293 time_needed(10, for (n <- list) yield n + 42)  | 
   299 time_needed(10, for (n <- list) yield n + 42)  | 
   294 time_needed(10, for (n <- list.par) yield n + 42)  | 
   300 time_needed(10, for (n <- list.par) yield n + 42)  | 
   295   | 
   301   | 
   296   | 
   302   | 
   297   | 
   303   | 
         | 
   304 // Problems with mutability and parallel computations  | 
         | 
   305 //====================================================  | 
         | 
   306   | 
         | 
   307 def count_intersection(A: Set[Int], B: Set[Int]) : Int = { | 
         | 
   308   var count = 0  | 
         | 
   309   for (x <- A; if (B contains x)) count += 1   | 
         | 
   310   count  | 
         | 
   311 }  | 
         | 
   312   | 
         | 
   313 val A = (1 to 1000).toSet  | 
         | 
   314 val B = (1 to 1000 by 4).toSet  | 
         | 
   315   | 
         | 
   316 count_intersection(A, B)  | 
         | 
   317   | 
         | 
   318 // but do not try to add .par to the for-loop above  | 
         | 
   319   | 
         | 
   320   | 
         | 
   321 //propper parallel version  | 
         | 
   322 def count_intersection2(A: Set[Int], B: Set[Int]) : Int =   | 
         | 
   323 	A.par.count(x => B contains x)  | 
         | 
   324   | 
         | 
   325 count_intersection2(A, B)  | 
         | 
   326   | 
         | 
   327   | 
         | 
   328 //for measuring time  | 
         | 
   329 def time_needed[T](n: Int, code: => T) = { | 
         | 
   330   val start = System.nanoTime()  | 
         | 
   331   for (i <- (0 to n)) code  | 
         | 
   332   val end = System.nanoTime()  | 
         | 
   333   (end - start) / 1.0e9  | 
         | 
   334 }  | 
         | 
   335   | 
         | 
   336 val A = (1 to 1000000).toSet  | 
         | 
   337 val B = (1 to 1000000 by 4).toSet  | 
         | 
   338   | 
         | 
   339 time_needed(10, count_intersection(A, B))  | 
         | 
   340 time_needed(10, count_intersection2(A, B))  | 
         | 
   341   | 
         | 
   342   | 
         | 
   343   | 
         | 
   344   | 
   298 // Webpages  | 
   345 // Webpages  | 
   299 //==========  | 
   346 //==========  | 
   300   | 
   347   | 
   301 import io.Source  | 
   348 import io.Source  | 
   302   | 
   349   | 
   303 // obtaining a webpage  | 
   350 // obtaining a webpage  | 
   304 val url = """https://nms.kcl.ac.uk/christian.urban/"""   | 
   351 val url = """https://nms.kcl.ac.uk/christian.urban/"""   | 
   305 val url = """http://api.postcodes.io/postcodes/CR84LQ"""   | 
         | 
   306 Source.fromURL(url)("ISO-8859-1").mkString | 
   352 Source.fromURL(url)("ISO-8859-1").mkString | 
         | 
   353   | 
         | 
   354   | 
         | 
   355 // another example  | 
         | 
   356 //val url = """http://api.postcodes.io/postcodes/CR84LQ"""   | 
   307   | 
   357   | 
   308   | 
   358   | 
   309 // a function for looking up constituency data  | 
   359 // a function for looking up constituency data  | 
   310 def consty_lookup(pcode: String) : String = { | 
   360 def consty_lookup(pcode: String) : String = { | 
   311   val url = "http://api.postcodes.io/postcodes/" + pcode  | 
   361   val url = "http://api.postcodes.io/postcodes/" + pcode  | 
   348 def get_all_URLs(page: String): Set[String] =   | 
   398 def get_all_URLs(page: String): Set[String] =   | 
   349   http_pattern.findAllIn(page).map(unquote).toSet  | 
   399   http_pattern.findAllIn(page).map(unquote).toSet  | 
   350   | 
   400   | 
   351 // naive version of crawl - searches until a given depth,  | 
   401 // naive version of crawl - searches until a given depth,  | 
   352 // visits pages potentially more than once  | 
   402 // visits pages potentially more than once  | 
   353 def crawl(url: String, n: Int): Unit = { | 
   403 def crawl(url: String, n: Int) : Unit = { | 
   354   if (n == 0) ()  | 
   404   if (n == 0) ()  | 
   355   else { | 
   405   else { | 
   356     println(s"Visiting: $n $url")  | 
   406     println(s"Visiting: $n $url")  | 
   357     for (u <- get_all_URLs(get_page(url))) crawl(u, n - 1)  | 
   407     for (u <- get_all_URLs(get_page(url))) crawl(u, n - 1)  | 
   358   }  | 
   408   }  |