progs/lecture1.scala
changeset 268 e43f7e92ba26
parent 265 59779ce322a6
child 272 da3d30ae67ec
equal deleted inserted replaced
267:9e0216756771 268:e43f7e92ba26
    35 // Collections
    35 // Collections
    36 //=============
    36 //=============
    37 List(1,2,3,1)
    37 List(1,2,3,1)
    38 Set(1,2,3,1)
    38 Set(1,2,3,1)
    39 
    39 
       
    40 // ranges
    40 1 to 10
    41 1 to 10
    41 (1 to 10).toList
    42 (1 to 10).toList
    42 
    43 
    43 (1 until 10).toList
    44 (1 until 10).toList
    44 
    45 
    45 // an element in a list
    46 // picking an element in a list
    46 val lst = List(1, 2, 3, 1)
    47 val lst = List(1, 2, 3, 1)
    47 lst(0)
    48 lst(0)
    48 lst(2)
    49 lst(2)
    49 
    50 
    50 // some alterative syntax for lists
    51 // some alterative syntax for lists
    51 
    52 
    52 1 :: 2 :: 3 :: Nil
    53 1 :: 2 :: 3 :: Nil
    53 List(1, 2, 3) ::: List(4, 5, 6)
    54 List(1, 2, 3) ::: List(4, 5, 6)
    54 
    55 
    55 // Equality is structural
    56 // Equality in Scala is structural
    56 //========================
    57 //=================================
    57 val a = "Dave"
    58 val a = "Dave"
    58 val b = "Dave"
    59 val b = "Dave"
    59 
    60 
    60 if (a == b) println("Equal") else println("Unequal")
    61 if (a == b) println("Equal") else println("Unequal")
    61 
    62 
    74 // Printing/Strings
    75 // Printing/Strings
    75 //==================
    76 //==================
    76 
    77 
    77 println("test")
    78 println("test")
    78 
    79 
    79 val tst = "This is a " + "test\n" 
    80 val tst = "This is a " ++ "test" 
       
    81 print(tst)
    80 println(tst)
    82 println(tst)
    81 
    83 
    82 val lst = List(1,2,3,1)
    84 val lst = List(1,2,3,1)
    83 
    85 
    84 
    86 
    85 println(lst.toString)
    87 println(lst.toString)
       
    88 
       
    89 println(lst.mkString)
    86 println(lst.mkString(","))
    90 println(lst.mkString(","))
    87 
    91 
    88 println(lst.mkString(", "))
    92 println(lst.mkString(", "))
    89 
    93 
    90 // some methods take more than one argument
    94 // some methods take more than one argument
    91 println(lst.mkString("{", ",", "}"))
    95 println(lst.mkString("{", ",", "}"))
    92 
    96 
       
    97 // (in this case .mkString can take no, one, 
       
    98 // or three arguments...this has to do with
       
    99 // default arguments)
    93 
   100 
    94 
   101 
    95 // Conversion methods
   102 // Conversion methods
    96 //====================
   103 //====================
    97 
   104 
    98 List(1,2,3,1).toString
   105 List(1,2,3,1).toString
    99 List(1,2,3,1).toSet
   106 List(1,2,3,1).toSet
       
   107 
   100 "hello".toList.tail
   108 "hello".toList.tail
   101 1.toDouble
   109 1.toDouble
   102 
   110 
   103 
   111 
   104 // useful list methods
   112 // useful list methods
   117 "1,2,3,4,5".split(",3,").mkString("\n")
   125 "1,2,3,4,5".split(",3,").mkString("\n")
   118 
   126 
   119 "abcdefg".startsWith("abc")
   127 "abcdefg".startsWith("abc")
   120 
   128 
   121 
   129 
   122 // Types (slide)
   130 // Types (see slide)
   123 //===============
   131 //===================
   124 
   132 
   125 /* Scala is a strongly typed language
   133 /* Scala is a strongly typed language
   126  
   134  
   127  * some base types
   135  * base types
   128 
   136 
   129     Int, Long, BigInt, Float, Double
   137     Int, Long, BigInt, Float, Double
   130     String, Char
   138     String, Char
   131     Boolean
   139     Boolean...
   132 
   140 
   133  * some compound types 
   141  * compound types 
   134 
   142 
   135     List[Int],
   143     List[Int]
   136     Set[Double]
   144     Set[Double]
   137     Pairs: (Int, String)        
   145     Pairs: (Int, String)        
   138     List[(BigInt, String)]
   146     List[(BigInt, String)]
   139     Option[Int]
   147     Option[Int]
       
   148 
       
   149  * user-defined types (later)
       
   150 
   140 */
   151 */
   141 
   152 
   142 
   153 
       
   154 // you can make the type of a value explicit
   143 val name: String = "leo"
   155 val name: String = "leo"
   144 
   156 
   145 
   157 
   146 // type errors
   158 // type errors
   147 math.sqrt("64")
   159 math.sqrt("64")
   151 // error: type mismatch;
   163 // error: type mismatch;
   152 // found   : String("64")
   164 // found   : String("64")
   153 // required: Double
   165 // required: Double
   154 // math.sqrt("64")
   166 // math.sqrt("64")
   155 
   167 
       
   168 
   156 // Pairs/Tuples
   169 // Pairs/Tuples
   157 //==============
   170 //==============
   158 
   171 
   159 val p = (1, "one")
   172 val p = (1, "one")
   160 p._1
   173 p._1
   172 def incr(x: Int) : Int = x + 1
   185 def incr(x: Int) : Int = x + 1
   173 def double(x: Int) : Int = x + x
   186 def double(x: Int) : Int = x + x
   174 def square(x: Int) : Int = x * x
   187 def square(x: Int) : Int = x * x
   175 
   188 
   176 def str(x: Int) : String = x.toString
   189 def str(x: Int) : String = x.toString
       
   190 
       
   191 incr(3)
       
   192 double(4)
   177 square(6)
   193 square(6)
       
   194 str(3)
   178 
   195 
   179 
   196 
   180 // The general scheme for a function: you have to give a type 
   197 // The general scheme for a function: you have to give a type 
   181 // to each argument and a return type of the function
   198 // to each argument and a return type of the function
   182 //
   199 //
   193 def silly(n: Int) : Int = {
   210 def silly(n: Int) : Int = {
   194   if (n < 10) n * n
   211   if (n < 10) n * n
   195   else n + n
   212   else n + n
   196 }
   213 }
   197 
   214 
       
   215 def another_silly(x: Int, y: String) : String = {
       
   216   if (x <= 12) y
       
   217   else x.toString
       
   218 }
       
   219 
       
   220 another_silly(2, "two")
       
   221 another_silly(12, "twelf")
       
   222 another_silly(20, "twenty")
       
   223 
   198 
   224 
   199 // If-Conditionals
   225 // If-Conditionals
   200 //=================
   226 //=================
   201 
   227 
   202 // - Scala does not have a then-keyword
   228 // - Scala does not have a then-keyword
   203 // - both if-else branches need to be present
   229 // - !both if-else branches need to be present!
   204 
   230 
   205 def fact(n: Int) : Int = 
   231 def fact(n: Int) : Int = 
   206   if (n == 0) 1 else n * fact(n - 1)
   232   if (n == 0) 1 else n * fact(n - 1)
   207 
   233 
   208 
   234 
   248 
   274 
   249 
   275 
   250 // Option type
   276 // Option type
   251 //=============
   277 //=============
   252 
   278 
   253 //in Java if something unusually happens, you return null
   279 //in Java if something unusually happens, you return null or something
   254 //
   280 //
   255 //in Scala you use Options instead
   281 //in Scala you use Options instead
   256 //   - if the value is present, you use Some(value)
   282 //   - if the value is present, you use Some(value)
   257 //   - if no value is present, you use None
   283 //   - if no value is present, you use None
   258 
   284 
   267 //  Try(something).getOrElse(what_to_do_in_case_of_an_exception)
   293 //  Try(something).getOrElse(what_to_do_in_case_of_an_exception)
   268 //
   294 //
   269 import scala.util._
   295 import scala.util._
   270 import io.Source
   296 import io.Source
   271 
   297 
   272 val my_url = "https://nms.imperial.ac.uk/christian.urban/"
   298 val my_url = "https://nms.kcl.ac.uk/christian.urban/"
   273 
   299 
   274 Source.fromURL(my_url).mkString
   300 Source.fromURL(my_url).mkString
   275 
   301 
   276 Try(Source.fromURL(my_url).mkString).getOrElse("")
   302 Try(Source.fromURL(my_url).mkString).getOrElse("")
   277 
   303 
   297 // much better - you record in the type that things can go wrong 
   323 // much better - you record in the type that things can go wrong 
   298 def get_contents(name: String) : Option[List[String]] = 
   324 def get_contents(name: String) : Option[List[String]] = 
   299   Try(Some(Source.fromFile(name).getLines.toList)).getOrElse(None)
   325   Try(Some(Source.fromFile(name).getLines.toList)).getOrElse(None)
   300 
   326 
   301 get_contents("text.txt")
   327 get_contents("text.txt")
   302 
   328 get_contents("test.txt")
   303 
   329 
   304 
   330 
   305 // String Interpolations
   331 // String Interpolations
   306 //=======================
   332 //=======================
   307 
   333 
   344 
   370 
   345 for (n <- (1 to 10).toList; 
   371 for (n <- (1 to 10).toList; 
   346      m <- (1 to 10).toList) yield m * n
   372      m <- (1 to 10).toList) yield m * n
   347 
   373 
   348 
   374 
       
   375 // you can assign the result of a for-comprehension
       
   376 // to a value
   349 val mult_table = 
   377 val mult_table = 
   350   for (n <- (1 to 10).toList; 
   378   for (n <- (1 to 10).toList; 
   351        m <- (1 to 10).toList) yield m * n
   379        m <- (1 to 10).toList) yield m * n
   352 
   380 
   353 println(mult_table.mkString)
   381 println(mult_table.mkString)
   424 
   452 
   425 // Why not just? Why making your life so complicated?
   453 // Why not just? Why making your life so complicated?
   426 for (c <- lst) println(c)
   454 for (c <- lst) println(c)
   427 
   455 
   428 // Aside: concurrency 
   456 // Aside: concurrency 
   429 // (ONLY WORKS OUT-OF-THE-BOX IN SCALA 2.11.8, not in SCALA 2.12)
   457 // (scala <<..parallel_collections...>> -Yrepl-class-based)
   430 // (would need to have this wrapped into a function, or
       
   431 //  REPL called with scala -Yrepl-class-based)
       
   432 for (n <- (1 to 10)) println(n)
   458 for (n <- (1 to 10)) println(n)
       
   459 
       
   460 import scala.collection.parallel.CollectionConverters._
       
   461 
   433 for (n <- (1 to 10).par) println(n)
   462 for (n <- (1 to 10).par) println(n)
   434 
   463 
   435 
   464 
   436 // for measuring time
   465 // for measuring time
   437 def time_needed[T](n: Int, code: => T) = {
   466 def time_needed[T](n: Int, code: => T) = {
   454 // - no vars, no ++i, no +=
   483 // - no vars, no ++i, no +=
   455 // - no mutable data-structures (no Arrays, no ListBuffers)
   484 // - no mutable data-structures (no Arrays, no ListBuffers)
   456 
   485 
   457 
   486 
   458 // Q: Count how many elements are in the intersections of two sets?
   487 // Q: Count how many elements are in the intersections of two sets?
       
   488 // A; IMPROPER WAY (mutable counter)
   459 
   489 
   460 def count_intersection(A: Set[Int], B: Set[Int]) : Int = {
   490 def count_intersection(A: Set[Int], B: Set[Int]) : Int = {
   461   var count = 0
   491   var count = 0
   462   for (x <- A; if (B contains x)) count += 1 
   492   for (x <- A; if (B contains x)) count += 1 
   463   count
   493   count