progs/lecture1.scala
changeset 200 01ee4b576eb2
parent 199 54befaf23648
child 202 f7bcb27d1940
equal deleted inserted replaced
199:54befaf23648 200:01ee4b576eb2
    61 
    61 
    62 Set(1,2,3) == Set(3,1,2)
    62 Set(1,2,3) == Set(3,1,2)
    63 List(1,2,3) == List(3,1,2)
    63 List(1,2,3) == List(3,1,2)
    64 
    64 
    65 
    65 
    66 // this applies for "concrete" values;
    66 // this applies to "concrete" values;
    67 // you cannot compare functions
    67 // you cannot compare functions
    68 
    68 
    69 
    69 
    70 // Printing/Strings
    70 // Printing/Strings
    71 //==================
    71 //==================
    82 
    82 
    83 println(lst.mkString(", "))
    83 println(lst.mkString(", "))
    84 
    84 
    85 // some methods take more than one argument
    85 // some methods take more than one argument
    86 println(lst.mkString("[", ",", "]"))
    86 println(lst.mkString("[", ",", "]"))
       
    87 
    87 
    88 
    88 
    89 
    89 // Conversion methods
    90 // Conversion methods
    90 //====================
    91 //====================
    91 
    92 
   107 List(1,2,3,4,3).indexOf(3)
   108 List(1,2,3,4,3).indexOf(3)
   108 
   109 
   109 "1,2,3,4,5".split(",").mkString("\n")
   110 "1,2,3,4,5".split(",").mkString("\n")
   110 "1,2,3,4,5".split(",3,").mkString("\n")
   111 "1,2,3,4,5".split(",3,").mkString("\n")
   111 
   112 
       
   113 "abcdefg".startsWith("abc")
       
   114 
       
   115 
   112 // Types (slide)
   116 // Types (slide)
   113 //=======
   117 //===============
   114 
   118 
   115 /* Scala is a strongly typed language
   119 /* Scala is a strongly typed language
   116  
   120  
   117  * some base types
   121  * some base types
   118 
   122 
   124 
   128 
   125     List[Int],
   129     List[Int],
   126     Set[Double]
   130     Set[Double]
   127     Pairs: (Int, String)        
   131     Pairs: (Int, String)        
   128     List[(BigInt, String)]
   132     List[(BigInt, String)]
       
   133     Option[Int]
   129 */
   134 */
   130 
   135 
   131 
   136 
   132 
   137 
   133 // Pairs/Tuples
   138 // Pairs/Tuples
   139 
   144 
   140 val t = (4,1,2,3)
   145 val t = (4,1,2,3)
   141 t._4
   146 t._4
   142 
   147 
   143 
   148 
       
   149 List(("one", 1), ("two", 2), ("three", 3))
       
   150 
   144 // Function Definitions
   151 // Function Definitions
   145 //======================
   152 //======================
   146 
   153 
   147 def incr(x: Int) : Int = x + 1
   154 def incr(x: Int) : Int = x + 1
   148 def double(x: Int) : Int = x + x
   155 def double(x: Int) : Int = x + x
   157 //  def fname(arg1: ty1, arg2: ty2,..., argn: tyn): rty = {
   164 //  def fname(arg1: ty1, arg2: ty2,..., argn: tyn): rty = {
   158 //    body 
   165 //    body 
   159 //  }
   166 //  }
   160 
   167 
   161 
   168 
       
   169 //
       
   170 // BTW: no returns!!
       
   171 // "last" line (expression) in a function determines the result
       
   172 //
       
   173 
       
   174 def silly(n: Int) : Int = {
       
   175   n * n
       
   176   n + n
       
   177 }
       
   178 
   162 
   179 
   163 // If-Conditionals
   180 // If-Conditionals
   164 //=================
   181 //=================
   165 
   182 
   166 // Scala does not have a then-keyword
   183 // - Scala does not have a then-keyword
   167 // both if-else branches need to be present
   184 // - both if-else branches need to be present
   168 
   185 
   169 def fact(n: Int) : Int = 
   186 def fact(n: Int) : Int = 
   170   if (n == 0) 1 else n * fact(n - 1)
   187   if (n == 0) 1 else n * fact(n - 1)
   171 
   188 
   172 
   189 
   209 // Option type
   226 // Option type
   210 //=============
   227 //=============
   211 
   228 
   212 //in Java if something unusually happens, you return null
   229 //in Java if something unusually happens, you return null
   213 //
   230 //
   214 //in Scala you use Option
   231 //in Scala you use Options instead
   215 //   - if the value is present, you use Some(value)
   232 //   - if the value is present, you use Some(value)
   216 //   - if no value is present, you use None
   233 //   - if no value is present, you use None
   217 
   234 
   218 
   235 
   219 List(7,2,3,4,5,6).find(_ < 4)
   236 List(7,2,3,4,5,6).find(_ < 4)
   238 
   255 
   239 
   256 
   240 // the same for files
   257 // the same for files
   241 Source.fromFile("test.txt").mkString
   258 Source.fromFile("test.txt").mkString
   242 
   259 
       
   260 // function reading something from files...
       
   261 
       
   262 def get_contents(name: String) : List[String] = 
       
   263   Source.fromFile(name).getLines.toList
       
   264 
       
   265 get_contents("test.txt")
       
   266 
       
   267 // slightly better - return Nil
       
   268 def get_contents(name: String) : List[String] = 
       
   269   Try(Source.fromFile(name).getLines.toList).getOrElse(Nil)
       
   270 
       
   271 get_contents("text.txt")
       
   272 
       
   273 // much better - you record in the type that things can go wrong 
       
   274 def get_contents(name: String) : Option[List[String]] = 
       
   275   Try(Some(Source.fromFile(name).getLines.toList)).getOrElse(None)
       
   276 
       
   277 get_contents("text.txt")
       
   278 
       
   279 
   243 
   280 
   244 // String Interpolations
   281 // String Interpolations
   245 //=======================
   282 //=======================
   246 
   283 
   247 val n = 3
   284 val n = 3
   248 println("The square of " + n + " is " + square(n) + ".")
   285 println("The square of " + n + " is " + square(n) + ".")
   249 
   286 
   250 println(s"The square of ${n} is ${square(n)}.")
   287 println(s"The square of ${n} is ${square(n)}.")
   251 
   288 
       
   289 
       
   290 // helpful for debugging purposes
       
   291 //
       
   292 //         "The most effective debugging tool is still careful thought, 
       
   293 //          coupled with judiciously placed print statements."
       
   294 //                   — Brian W. Kernighan, in Unix for Beginners (1979)
   252 
   295 
   253 
   296 
   254 def gcd_db(a: Int, b: Int) : Int = {
   297 def gcd_db(a: Int, b: Int) : Int = {
   255   println(s"Function called with ${a} and ${b}.")
   298   println(s"Function called with ${a} and ${b}.")
   256   if (b == 0) a else gcd_db(b, a % b)
   299   if (b == 0) a else gcd_db(b, a % b)
   258 
   301 
   259 gcd_db(48, 18)
   302 gcd_db(48, 18)
   260 
   303 
   261 
   304 
   262 // Asserts/Testing
   305 // Asserts/Testing
   263 //================
   306 //=================
   264 
   307 
   265 assert(gcd(48, 18) == 6)
   308 assert(gcd(48, 18) == 6)
   266 
   309 
   267 assert(gcd(48, 18) == 5, "The gcd test failed")
   310 assert(gcd(48, 18) == 5, "The gcd test failed")
   268 
   311 
   280   for (n <- (1 to 10).toList; 
   323   for (n <- (1 to 10).toList; 
   281        m <- (1 to 10).toList) yield m * n
   324        m <- (1 to 10).toList) yield m * n
   282 
   325 
   283 mult_table.sliding(10,10).mkString("\n")
   326 mult_table.sliding(10,10).mkString("\n")
   284 
   327 
   285 // the list can also be constructed in any other way
   328 // the list/set/... can also be constructed in any 
       
   329 // other way
   286 for (n <- List(10,12,4,5,7,8,10)) yield n * n
   330 for (n <- List(10,12,4,5,7,8,10)) yield n * n
   287 
   331 
   288 
   332 
   289 // with if-predicates
   333 // with if-predicates / filters
   290 
   334 
   291 for (n <- (1 to 3).toList; 
   335 for (n <- (1 to 3).toList; 
   292      m <- (1 to 3).toList;
   336      m <- (1 to 3).toList;
   293      if (n + m) % 2 == 0) yield (n, m)
   337      if (n + m) % 2 == 0) yield (n, m)
   294 
   338 
   303 for ((m, n) <- lst) yield m + n 
   347 for ((m, n) <- lst) yield m + n 
   304 
   348 
   305 for (p <- lst) yield p._1 + p._2 
   349 for (p <- lst) yield p._1 + p._2 
   306 
   350 
   307 
   351 
   308 // general pattern
   352 // general pattern of for-yield
   309 
   353 
   310 for (x <- ...) yield {
   354 for (p <- ...) yield {
   311   // potentially complicated
   355   // potentially complicated
   312   // calculation of a result
   356   // calculation of a result
   313 }
   357 }
   314 
   358 
   315 
   359 // Functions producing multiple outputs
       
   360 //======================================
       
   361 
       
   362 def get_ascii(c: Char) : (Char, Int) = (c, c.toInt)
       
   363 
       
   364 get_ascii('a')
       
   365 
       
   366 
       
   367 // .maxBy, sortBy with pairs
       
   368 def get_length(s: String) : (String, Int) = (s, s.length) 
       
   369 
       
   370 val lst = List("zero", "one", "two", "three", "four", "ten")
       
   371 val strs = for (s <- lst) yield get_length(s)
       
   372 
       
   373 strs.sortBy(_._2)
       
   374 strs.sortBy(_._1)
       
   375 
       
   376 strs.maxBy(_._2)
       
   377 strs.maxBy(_._1)
       
   378 
       
   379 
       
   380 // For without yield
       
   381 //===================
   316 
   382 
   317 // with only a side-effect (no list is produced),
   383 // with only a side-effect (no list is produced),
   318 // has no "yield"
   384 // has no "yield"
   319 
   385 
   320 for (n <- (1 to 10)) println(n)
   386 for (n <- (1 to 10)) println(n)
   323 // BTW: a roundabout way of printing out a list, say
   389 // BTW: a roundabout way of printing out a list, say
   324 val lst = ('a' to 'm').toList
   390 val lst = ('a' to 'm').toList
   325 
   391 
   326 for (i <- (0 until lst.length)) println(lst(i))
   392 for (i <- (0 until lst.length)) println(lst(i))
   327 
   393 
   328 // why not?
   394 // Why not just? Why making your life so complicated?
   329 for (c <- lst) println(c)
   395 for (c <- lst) println(c)
   330 
   396 
   331 // Aside: concurrency 
   397 // Aside: concurrency 
   332 // (ONLY WORKS OUT-OF-THE-BOX IN SCALA 2.11.8, not in SCALA 2.12)
   398 // (ONLY WORKS OUT-OF-THE-BOX IN SCALA 2.11.8, not in SCALA 2.12)
   333 // (would need to have this wrapped into a function, or
   399 // (would need to have this wrapped into a function, or
   348 val list = (1 to 1000000).toList
   414 val list = (1 to 1000000).toList
   349 time_needed(10, for (n <- list) yield n + 42)
   415 time_needed(10, for (n <- list) yield n + 42)
   350 time_needed(10, for (n <- list.par) yield n + 42)
   416 time_needed(10, for (n <- list.par) yield n + 42)
   351 
   417 
   352 
   418 
   353 // Function producing multiple outputs
   419 
   354 //=====================================
   420 // Just for "Fun": Mutable vs Immutable
   355 
   421 //=======================================
   356 def get_ascii(c: Char) : (Char, Int) = (c, c.toInt)
   422 //
   357 
   423 // - no vars, no ++i, no +=
   358 get_ascii('a')
   424 // - no mutable data-structures (no Arrays, no ListBuffers)
   359 
   425 
   360 
   426 
   361 
   427 // Q: Count how many elements are in the intersections of two sets?
   362 // .maxBy, sortBy with pairs
   428 
   363 def get_length(s: String) : (String, Int) = (s, s.length) 
   429 def count_intersection(A: Set[Int], B: Set[Int]) : Int = {
   364 
   430   var count = 0
   365 val lst = List("zero", "one", "two", "three", "four", "ten")
   431   for (x <- A; if (B contains x)) count += 1 
   366 val strs = for (s <- lst) yield get_length(s)
   432   count
   367 
   433 }
   368 strs.sortBy(_._2)
   434 
   369 strs.sortBy(_._1)
   435 val A = (1 to 1000).toSet
   370 
   436 val B = (1 to 1000 by 4).toSet
   371 strs.maxBy(_._2)
   437 
   372 strs.maxBy(_._1)
   438 count_intersection(A, B)
       
   439 
       
   440 // but do not try to add .par to the for-loop above
       
   441 
       
   442 
       
   443 //propper parallel version
       
   444 def count_intersection2(A: Set[Int], B: Set[Int]) : Int = 
       
   445   A.par.count(x => B contains x)
       
   446 
       
   447 count_intersection2(A, B)
       
   448 
       
   449 
       
   450 //for measuring time
       
   451 def time_needed[T](n: Int, code: => T) = {
       
   452   val start = System.nanoTime()
       
   453   for (i <- (0 to n)) code
       
   454   val end = System.nanoTime()
       
   455   (end - start) / 1.0e9
       
   456 }
       
   457 
       
   458 val A = (1 to 1000000).toSet
       
   459 val B = (1 to 1000000 by 4).toSet
       
   460 
       
   461 time_needed(10, count_intersection(A, B))
       
   462 time_needed(10, count_intersection2(A, B))
       
   463 
   373 
   464 
   374 // Further Information
   465 // Further Information
   375 //=====================
   466 //=====================
   376 
   467 
   377 // The Scala home page and general information is at
   468 // The Scala homepage and general information is at
   378 //
   469 //
   379 //  http://www.scala-lang.org
   470 //  http://www.scala-lang.org
   380 //	http://docs.scala-lang.org
   471 //	http://docs.scala-lang.org
   381 //
   472 //
   382 //
   473 //
   383 // It should be fairly easy to install the Scala binary and
   474 // It should be fairly easy to install the Scala binary and
   384 // run Scala on the commandline. There are also at least 
   475 // run Scala on the commandline. People also use Scala with 
   385 // four IDEs you can use with Scala:
   476 // Vim and Jedit. I currently settled on VS Code
   386 //
   477 //
   387 //  (0) Some general information about setting up IDEs
   478 //   https://code.visualstudio.com
   388 //	    with Scala support can be found at
   479 //
   389 //
   480 // There are also plugins for Eclipse and IntelliJ - YMMV.
   390 //         http://docs.scala-lang.org/getting-started.html 
   481 // Finally there are online editors specifically designed for 
   391 //
   482 // running Scala applications (but do not blame me if you lose 
   392 //
   483 // all what you typed in):
   393 //  (1) Eclipse for Scala (one big bundle)
   484 //
   394 //
   485 //   https://scalafiddle.io 
   395 //         http://scala-ide.org/download/sdk.html
   486 //   https://scastie.scala-lang.org
   396 //  
   487 //
   397 //  (2) IntelliJ (needs additional Plugins)
       
   398 //
       
   399 //         https://www.jetbrains.com/idea/
       
   400 //		   http://docs.scala-lang.org/getting-started-intellij-track/getting-started-with-scala-in-intellij.html	  
       
   401 //
       
   402 //  (3) Sublime (not free, but unlimited trial period; 
       
   403 //	    needs Scala and SublimeREPL plugin)
       
   404 //
       
   405 //         https://www.sublimetext.com
       
   406 //
       
   407 //  (4) Emacs (old-fashioned, but reliable)
       
   408 //
       
   409 //         https://www.gnu.org/software/emacs/
       
   410 //
       
   411 //      I use the old scala-tool support for Emacs distributed at
       
   412 //
       
   413 //         https://github.com/scala/scala-tool-support/tree/master/tool-support/emacs 
       
   414 //
       
   415 //      but there is also support for the newer Ensime Scala Mode
       
   416 //
       
   417 //         http://ensime.org/editors/emacs/scala-mode/   
       
   418 //   
       
   419 // There is also Scala support in the Atom editor, but my
       
   420 // experience is mixed. People also use Scala with Vim and Jedit.
       
   421 // Finally there is an online editor specifically designed for 
       
   422 // running Scala applications (but do not blame mne if you lose all 
       
   423 // what you typed in):
       
   424 //
       
   425 //      https://scalafiddle.io 
       
   426 //
       
   427 //
       
   428 //
       
   429 // All of the IDEs above support a REPL for Scala. Some of them have
       
   430 // the very nifty feature of a Scala Worksheet -- you just save your
       
   431 // file and it will be automatically evaluated and the result pasted
       
   432 // into your file. However, this way of writing Scala code never worked
       
   433 // for me. I just use the REPL.
       
   434 //
   488 //
   435 //
   489 //
   436 // Scala Library Docs
   490 // Scala Library Docs
   437 //====================
   491 //====================
   438 //
   492 //
   441 // Scala Tutorials
   495 // Scala Tutorials
   442 //
   496 //
   443 //  http://docs.scala-lang.org/tutorials/
   497 //  http://docs.scala-lang.org/tutorials/
   444 //
   498 //
   445 // There are also a massive number of Scala tutorials on youtube
   499 // There are also a massive number of Scala tutorials on youtube
   446 // and there are tons of books and free material.
   500 // and there are tons of books and free material. Google is your 
   447 //
   501 // friend.
   448 
   502 
   449 
   503 
   450 
   504 
   451 
   505 
   452 
   506 
   453 
   507 
   454 
   508 
   455 
   509 
   456 
   510 
   457 
   511 
   458 
   512 
   459 
   513 
   460 
   514 
   461 
   515 
   462 
   516