Docs - Catecbol

26 may. 2017 - val majadito=PlatoTipico("majadito","Santa Cruz") majao == majadito ... case class Municipio(nombre:String,prov:Provincia) extends Region.
1MB Größe 5 Downloads 79 vistas
Catecbol www.catecbol.com

Capacitación Tecnológica Científica para Bolivia facebook.com/catecbol

@catecbol

Fundamentos de Scala Jean-Paul Calbimonte University of Applied Sciences and Arts Western Switzerland, HES-SO

La unión es la fuerza

[email protected]

Jean-Paul Calbimonte Formación académica: • Ingeniería de Sistemas: Universidad Católica Boliviana, Bolivia • Master en Informática: École Polytechnique Fédérale de Lausanne EPFL, Suiza

• Doctorado en Inteligencia Artificial: Universidad Politécnica de Madrid, España Experiencia:

• Investigador adjunto, University of Applied Sciences and Arts Western Switzerland • Postdoctorado, École Polytechnique Fédérale de Lausanne EPFL, Suiza • Software dev: pirAMide informatik, medspazio, Cochabamba Área de Investigación: • Procesamiento de streams, RDF streams, ingeniería ontológica, e-Health

http://jeanpi.org

Fundamentos de Scala

¿Qué es Scala? sintaxis concisa

lenguaje escalable

corre en JVM

tipos estáticos

compatible con Java abstracción concurrencia, multi-hilos

orientado objetos + funcional

ecosistema Scala

Scala: ideas básicas 1. todo valor es un objeto

2. toda funcion es un valor

Scala combina ambos paradigmas

Scala: un vistazo

Prueba Scala en línea ahora mismo!

http://tinsmith.herokuapp.com/

Scala: expresiones y tipos cada expresión es una función que resulta en un valor 1 //> res0: Int(1) = 1 true //> res1: Boolean(true) = true 2+3 //> res2: Int(5) = 5 2.4+3 //> res3: Double(5.4) = 5.4 math.Pi //> res4: Double(3.141592653589793) = 3.141592653589793 math.log(1) //> res5: Double = 0.0 "cadena" //> res6: String("cadena") = cadena "cadena" + 4 //> res7: String = cadena4 3/0 //> java.lang.ArithmeticException: / by zero

cada valor tiene un tipo de dato, e.g. Int, String

2+3

//> res2: Int(5) = 5

Scala: diseccionando una expresión 2+3

//> res2: Int(5) = 5 se puede escribir como:

2.+(3) objeto

//> res8: Int(5) = 5 argumento

método

"34".toInt < 20 //> res9: Boolean = false

Scala: valores y variables se infiere

val num=3 //> num : Int = 3 el tipo println(num) //> 3 val texto="catecbol" //> texto : String = catecbol val num2:Int=3 //> num2 : Int = 3 val mix="texto"+34+true //> mix : String = texto34true declaración explícita

var num3=3 num3 = 5 // no se puede reasignar un val ❌num2 = 5 // no se puede reasignar con otro tipo ❌num3 = "texto"

Scala: funciones (s:String) => "cadena" + s

//> res0: String => String =

función anónima

cuerpo de la parámetro función val sumarPi = (num:Int) => Pi+num //> sumarPi : Int => Double = sumarPi(23) //> res1: Double = 26.141592653589793 val puede ser una función

val calcular=(n1:Int,n2:Double) => { val n3=n1*n2 n3*5 } //> calcular : (Int,Double) => Double = calcular(3,4.5) //> res2: Double = 67.5

Scala: colecciones val arr1=Array(3,5,6,4) //> arr1 : Array[Int] = Array(3, 5, 6, 4) val arr2=Array(Array(5,4,2) Array(3,2,4), Array(1,5,4)) arr1(2) arr2.flatten

//> res0: Int = 6 //> res1: Array[Int] = Array(5,4,2,3,2,4,1,5,4)

val arr3=ArrayBuffer(3,2,4) //> scala.collection.mutable.ArrayBuffer[Int] arr3+=4 //> res2: ArrayBuffer(3, 2, 4, 4)

Scala: colecciones val map1=Map("cbba"->"Cochabamba", "lp" ->"La Paz", "tri" ->"Trinidad")

map1("cbba") //> res3: String = Cochabamba map1.getOrElse("abc", "ninguno") //> res4: String = ninguno

val bol=("bol","Bolivia") val chi=("chi","Chile") val arg=("arg","Argentina")

Seq(bol,chi,arg).toMap map1.asJava

//> res5: scala.collection.immutable .Map[String,String] //> res6: java.util.Map[String,String]

Scala: listas List(1,3,5,6,9) Seq(3,6,8,9) (1 to 6) (0 until 10)

//> res0: List[Int] = List(1, 3, 5, 6, 9) //> res1: Seq[Int] = List(3, 6, 8, 9) //> res2: Range(1, 2, 3, 4, 5, 6) //> res3: Range(0, 1, 2, 3, 4, 5, 6, 7, 8, 9)

val lista=(1 to 5) //> lista: Range(1, 2, 3, 4, 5) lista.filter(i => i res4: Vector(1, 2, 3) lista.filter(i=>i%2==0) //> res5: Vector(2, 4) lista.map(i=>i*2) //> res6: Vector(2, 4, 6, 8, 10) lista.sum //> res7: Int = 15 lista.foreach(i => println(s"*$i*")) //| *2* //| *3* //| *4* //| *5*

//> *1*

Scala: listas

val lista2=List(3,5.6,45,"hola",34.5,"chau")

lista2.head //> res8: Any = 3 lista2.take(3) //> res9: List[Any]=List(3, 5.6, 45) "adios" :: lista2 //> res10: List(adios, 3, 5.6, 45, hola, 34.5, chau)

List(20,30) ::: List(40,50) //> res11: List(20, 30, 40, 50) lista2.map { case s:String=>"*" case _ => "+" } //> res12: = List(+, +, +, *, +, *)

Scala: cadenas val s1="cadena" s1.split('a')

//> s1 : String = cadena //> res0: Array[String] = Array(c, den)

val s2=s"$s1 es un string"

//> s2 : String = cadena es un string

val num=34.56 //> num : Double = 34.56 val s3=f"$s1 y un valor de $num%2.1f" //> s3 : String = cadena y un valor de 34.6 val s4="""cadena de varias líneas"""

//> s4 : String = cadena de //| varias //| líneas

Scala: cadenas "ab,cd,ef;gh;ij".split(",|;") //> res1: Array[String] = Array(ab, cd, ef, gh, ij)

val r="[a-z]+".r //> r : scala.util.matching.Regex = [a-z]+

r.findFirstIn("2653abc7878") match { case Some(patron)=>patron } abc

//> res2: String =

Scala: clases class Banda(nombre:String,genero:String) val kjarkas=new Banda("Kjarkas","folclore") class Musico(val nombre:String,banda:Banda) { def cantar(cancion:String)={ println(s"♫♫ $cancion ♫♫") } } val elmer=new Musico("Elmer Hermosa",kjarkas) elmer.cantar("bolivia") println(elmer.nombre) println(elmer.banda)

//> ♫♫ bolivia ♫♫ //> Elmer Hermosa

Scala: clases class Instrumento(nombre:String,esAutoctono:Boolean=false){ override def toString= s"El instrumento: $nombre" }

val charango=new Instrumento("charango",true) val bajo=new Instrumento("bajo") println(bajo)

//> El instrumento: bajo

Scala: traits trait Artista{ val nombre:String val edad:Int } class Cantante(val nombre:String, val edad:Int, val discos:Int) extends Artista class Actor(val nombre:String,val edad:Int,val peilculas:Int) extends Artista val luzmila=new Cantante("Luzmila Carpio",50,30 val jenny=new Actor("Jenny Serrano",40,2)

val artistas=Seq(luzmila,jenny) artistas.foreach(artista=>println(artista.nombre)) //> Luzmila Carpio //| Jenny Serrano

Scala: clases class Cancion(val titulo:String) trait Cantante{ def cantar(cancion:Cancion) } trait Compositor{ def componer(titulo:String):Cancion } class Cantautor extends Cantante with Compositor{ def componer(titulo:String)={ new Cancion(titulo) } def cantar(cancion:Cancion)= println(s"♫♫ ${cancion.titulo} ♫♫") }

val matilde=new Cantautor val regreso=matilde.componer("Regreso") matilde.cantar(regreso) //> ♫♫ Regreso ♫♫

Scala: objetos singleton class Departamento(val nombre:String) object Cochabamba extends Departamento("Cochabamba") object Beni extends Departamento("Beni") def iniciales(dpto:Departamento)= dpto.nombre.take(3) iniciales(Beni)

//> res0: String = Ben

object Departamento{ def apply(s:String)=new Departamento(s) } Departamento("Tarija") object Geometria { def area(radio:Int)=math.Pi*radio*radio } Geometria.area(4) //> res2: Double = 50.26548245743669

Scala: clases case case class PlatoTipico(nombre:String,departamento:String) val majao=PlatoTipico("majadito","Santa Cruz") val fricase=PlatoTipico("fricase","La Paz")

println(majao.departamento) //> Santa Cruz val majadito=PlatoTipico("majadito","Santa Cruz") majao == majadito //> res0: Boolean = true

val sonso=majao.copy(nombre="sonso") println(sonso) //> PlatoTipico(sonso,Santa Cruz)

Scala: match case def evaluar(nota:String)={ nota match { case "A" => 70 case "B" => 50 case "F" => 30 case _ => 0 } } //> evaluar: (nota: String)Int evaluar("B") evaluar("h")

//> res0: Int = 50 //> res1: Int = 0

def verificar(a:Any)=a match{ case "A" => "una letra A" case 4 => "un int 45" case 4.5 => "un double 4.5" } //> verificar: (a: Any)String verificar("A") //> res2: String = una letra A // match error verificar("a")

Scala: match case def verificar2(a:Any)=a match { case s:String => "string" case d:Double => "double" case i:Int => "int" case _ => "otro" } //> verificar2: (a: Any)String

Seq("ab",5,3.4,"2",List).map(verificar2) //> res3: Seq[String] = List(string, int, double, string, otro)

Scala: match case trait Region{ val nombre:String } case class Departamento(nombre:String) extends Region case class Provincia(nombre:String,dpto:Departamento) extends Region case class Municipio(nombre:String,prov:Provincia) extends Region val cocha=Departamento("Cochabamba") val cercado=Provincia("Cercado",cocha) val chuqui=Departamento("Chuquisaca") val oropeza=Provincia("Oropeza",chuqui) val sucre=Municipio("Sucre",oropeza) val list:Seq[Region]=Seq(cocha,cercado,oropeza,sucre)

Scala: match case val list:Seq[Region]=Seq(cocha,cercado,oropeza,sucre) list map { case Departamento(nom) => s"Depto $nom" case Provincia(nom,dpto) => s"prov $nom en ${dpto.nombre}" case Municipio(nom,prov) => s"muni $nom en ${prov.nombre}, dpto ${prov.dpto.nombre}" } //> res4: Seq[String] = List(Depto Cochabamba, prov Cercado en Cochabamba, prov //| Oropeza en Chuquisaca, muni Sucre en Oropeza, dpto Chuquisaca)

list map { case d:Departamento => s"Depto ${d.nombre}" case p:Provincia => s"prov ${p.nombre} en ${p.dpto.nombre}" case m:Municipio => s"muni ${m.nombre} en ${m.prov.nombre}, dpto ${m.prov.dpto.nombre}" } //> res5: Seq[String] = List(Depto Cochabamba, prov Cercado en Cochabamba, prov //| Oropeza en Chuquisaca, muni Sucre en Oropeza, dpto Chuquisaca)

Scala: opciones val equipos=Map("lp"->"The Strongest", "scz"->"Oriente", "cocha"->"Wilster", "oru"->"San Jose")

def obtenerEquipo(dpto:String):Option[String]={ equipos.get(dpto) } def hayEquipo(dpto:String)=equipos.get(dpto) match { case Some(eq) => println(s"el equipo es $eq") case None => println("no hay equipo") } hayEquipo("scz") hayEquipo("abc")

//> el equipo es Oriente //> no hay equipo

Scala: opciones case class Persona(nombre:String,email:Option[String])

Persona("felix",Some("[email protected]"))

Persona("lucas",None)

Scala: excepciones def dividir(a:Int,b:Int):Option[Double]= try { Some(a/b) } catch { case ex:Exception=> ex.printStackTrace None } //> dividir: (a: Int, b: Int)Option[Double] val div=dividir(3,0) //> java.lang.ArithmeticException: / by zero

Scala: excepciones def dividir2(a:Int,b:Int):Try[Double]= Try(a/b) val div2=dividir2(3,0) //> div2 : scala.util.Try[Double] = Failure(java.lang.ArithmeticException: div2.isSuccess //> res0: Boolean = false div2 match { case Success(d)=>println(d) case Failure(ex)=>ex.printStackTrace } //> java.lang.ArithmeticException: / by zero div2.toOption //> res1: Option[Double] = None

Scala: implícitos class PlatoTipico{ val ingredientes=new ArrayBuffer[Ingrediente] } case class Ingrediente(i:String) def aumentar(ing:Ingrediente)(implicit plato:PlatoTipico)={ plato.ingredientes+=ing } implicit val silpancho=new PlatoTipico aumentar(Ingrediente("huevo")) aumentar(Ingrediente("arroz")) println(silpancho.ingredientes)

//> ArrayBuffer(Ingrediente(huevo), Ingrediente(arroz))

implicit def strToIngrediente(s:String)=Ingrediente(s) aumentar("apanado")

Scala: implícitos implicit class StringPlus(s:String){ def quitarEspacios=s.replaceAll(" ","") def codificar=Base64.encode(s.getBytes) }

"la unión es la fuerza".quitarEspacios //> res3: String = launióneslafuerza

"catecbol".codificar //> res4: Array[Byte] = Array(89, 50, 70, 48, 90, 87, 78, 105, 98, 50, 119, 61)

Scala: futuros def operacionLarga={ Thread.sleep(5000) println("terminó larga") 4 } def operacionCorta={ Thread.sleep(1) println("terminó corta") } operacionLarga operacionCorta

//> terminó larga //| res0: Int = 4 //> terminó corta

Scala: futuros val fut=Future(operacionLarga) operacionCorta //> terminó corta fut.onComplete { result => println(result) }

Future(operacionLarga) Future(operacionLarga) Future(operacionLarga)

Thread.sleep(10000) //| Success(4) //| terminó larga //| terminó larga //| terminó larga-

Scala: java interop import org.joda.time.DateTime import collection.JavaConversions._ "esta cadena".getClass

//> res0: Class[?0] = class java.lang.String

val fecha=DateTime.now //> fecha:org.joda.time.DateTime=2017-05-26T21:44:14.778+02:00 fecha.toTimeOfDay() //> res1: org.joda.time.TimeOfDay = T21:44:14.778 val javaLista=new java.util.ArrayList[String] javaLista.add("a") javaLista.add("b") javaLista.add("c")

javaLista.foreach(println)

//> a //| b //| c

javaLista.map(_.toUpperCase)

//> res5: ArrayBuffer(A, B, C)

Scala: scalatest class DemoTest extends FlatSpec with Matchers { "Una cadena " should "cumplir" in{ val s="cadena" s should not be (null) s.length shouldBe (6) s should startWith ("c") s should contain ('d') } }

Scala: sbt simple build tool name := "scala-fundamentos" organization := "jpcik" version := "0.0.1" scalaVersion := "2.11.8" libraryDependencies ++= Seq( "com.typesafe" % "config" % "1.3.1", "joda-time" % "joda-time" % "2.9.9", "org.scalatest" %% "scalatest" % "2.2.1" % "test", "junit" % "junit" % "4.12" % "test" ) resolvers ++= Seq( "typesafe" at "http://repo.typesafe.com/typesafe/releases/", Resolver.sonatypeRepo("public") )

http://www.scala-sbt.org/

Scala: IDEs: Eclipse, IntelliJ

http://scala-ide.org/

Scala: akka

http://akka.io/

Scala: play framework

https://playframework.com/

Scala: Apache Spark

https://spark.apache.org

Scala: Docs

http://docs.scala-lang.org/

Material disponible https://github.com/jpcik/tutorials

Catecbol www.catecbol.com

Capacitación Tecnológica Científica para Bolivia facebook.com/catecbol

@catecbol

Gracias [email protected] Jean-Paul Calbimonte

La unión es la fuerza

[email protected]