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) |
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) |
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 // |