Wednesday, September 25, 2019

Scala: creating nested maps of maps from nested Seq's of tuples

A messy solution to a problem when the map had to be created in a recursive function with branches.



scala> val x = List("s"->List("a"->1).groupBy(_._1).map { case (k,v) =>;(k,v.map(_._2))}).groupBy(_._1).map { case (k,v) =>; (k,v.map(_._2))}

x: scala.collection.immutable.Map[String,List[scala.collection.immutable.Map[String,List[Int]]]] = Map(s->List(Map(a->List(1))))

scala>; val x = List("s"->List("a"->1))
x: List[(String, List[(String, Int)])] = List((s,List((a,1))))

scala>; x.groupBy(_._1).map({case (k,v) =>; (k,v.flatMap(_._2).toMap)})

res13: scala.collection.immutable.Map[String,scala.collection.immutable.Map[String,Int]] = Map(s->Map(a->1))

scala>; val x = Seq(("s"->Seq("a"->1)),("t"->Seq("b"->2)))
x: Seq[(String, Seq[(String, Int)])] = List((s,List((a,1))), (t,List((b,2))))

scala>; x.groupBy(_._1).map{case (k,v) =>; (k, v.flatMap{_._2}.toMap)}
res44: scala.collection.immutable.Map[String,scala.collection.immutable.Map[String,Int]] = Map(t->Map(b->2), s->Map(a->1))

scala>; val x = List("s" ->; List("a" ->; 1))
x
scala> val x = Seq(("i" -> Seq("a" -> Seq("p" -> "x"))), ("j"-> Seq("b" -> Seq("q" -> "y"))))
x: Seq[(String, Seq[(String, Seq[(String, String)])])] = List((i,List((a,List((p,x))))), (j,List((b,List((q,y))))))

scala> x.groupBy(_._1).mapValues{ x => x.flatMap{ x => (x._2.map{x => (x._1, x._2.map{ case (k,v) => (k,v)}.toMap)})}.toMap}
res97: scala.collection.immutable.Map[String,scala.collection.immutable.Map[String,scala.collection.immutable.Map[String,String]]] = Map(j -> Map(b -> Map(q -> y)), i -> Map(a -> Map(p -> x)))

Monday, September 16, 2019

install GraphViz with app on Mac OSX

https://github.com/parrt/dtreeviz/issues/33#issuecomment-460478876

brew uninstall graphviz
brew upgrade pango librsvg

cd /tmp
wget https://graphviz.gitlab.io/pub/graphviz/stable/SOURCES/graphviz.tar.gz
tar xvfz graphviz.tar.gz
cd graphviz-2.40.1/

rm -rf /usr/local/lib/graphviz # in case old stuff is there
./configure --includedir=/usr/local/include/graphviz
make -j 8 # 8 threads
make install

More Scala fold examples

https://coderwall.com/p/4l73-a/scala-fold-foldleft-and-foldright



class Foo(val name: String, val age: Int, val sex: Symbol)

object Foo {
  def apply(name: String, age: Int, sex: Symbol) = new Foo(name, age, sex)
}

val fooList = Foo("Joe Smith", 25, 'male) :: Foo("Susan Jones", 43, 'female) :: Foo("Fred Flintstone", 37, 'male) :: Nil

val stringList = fooList.foldLeft(List[String]()) { (z, f) =>
  val title = f.sex match {
    case 'male => "Mr."
    case 'female => "Ms."
  }
  z :+ s"$title ${f.name}, ${f.age}"
}

scala> class Foo(val name: String, val age: Int, val sex: Symbol)
defined class Foo
warning: previously defined object Foo is not a companion to class Foo.
Companions must be defined together; you may wish to use :paste mode for this.

scala> 

scala> object Foo {
     |   def apply(name: String, age: Int, sex: Symbol) = new Foo(name, age, sex)
     | }
defined object Foo
warning: previously defined class Foo is not a companion to object Foo.
Companions must be defined together; you may wish to use :paste mode for this.

scala> 

scala> val fooList = Foo("Joe Smith", 25, 'male) :: Foo("Susan Jones", 43, 'female) :: Foo("Fred Flintstone", 37, 'male) :: Nil
fooList: List[Foo] = List(Foo@52d3542b, Foo@282afe91, Foo@7b1e1c25)

scala> 

scala> val stringList = fooList.foldLeft(List[String]()) { (z, f) =>
     |   val title = f.sex match {
     |     case 'male => "Mr."
     |     case 'female => "Ms."
     |   }
     |   z :+ s"$title ${f.name}, ${f.age}"
     | }
stringList: List[String] = List(Mr. Joe Smith, 25, Ms. Susan Jones, 43, Mr. Fred Flintstone, 37)


Unify two maps in Scala using a function arg


def unify[K, V](a: Map[K, V], b: Map[K, V])(f: (V, V) => V): Map[K, V] =
    b.foldLeft(a) { case (acc, (k, v)) =>
      acc + (k -> acc.get(k).map(f(_, v)).getOrElse(v))
    }

val m = Map[String, Int](("a", 1),("b", 2),("c", 3),("d", 4),("e", 5),("f", 6))

val n = Map[String, Int](("a", 11),("b", 12),("c", 13),("d", 14),("e", 15),("f", 16))


def f(i: Int, j: Int): Int = Math.max(i,j)

unify(m,n)(f)

Scala fold left-augmented examples

https://commitlogs.com/2016/09/10/scala-fold-foldleft-and-foldright/

Code copied from the above link.
Print statements added to show the intermediate results.

val inputList: List[Int] = List(1, 3, 5)
inputList.foldLeft(0) { (acc, i) => acc + i }

def op(acc: Int, i: Int): Int = acc + i

op(acc = 0, i = 1) // 1
op(acc = 1, i = 3) // 4
op(acc = 4, i = 5) // 9

op(op(op(0, 1), 3), 5)
op(op(0 + 1, 3), 5)
op(op(1, 3), 5)
op(1 + 3, 5)
op(4, 5)
(4 + 5)
9
_________________________________________________________________________________

def len(list: List[Any]): Int = list.foldLeft(0) { (count, _) => count + 1 }

op(0, 1) // 1
op(1, 3) // 2
op(2, 5) // 3

op(op(op(0, 1), 3), 5)
op(op(1, 3), 5)
op(2, 5)
3

_________________________________________________________________________________

def len(list: List[Any]): Int = list.foldLeft(0) { (count, i) => println(s"""c: $count i: $i"""); count + 1 }

op(0, 1) // 1
op(1, 3) // 2
op(2, 5) // 3

op(op(op(0, 1), 3), 5)
op(op(1, 3), 5)
op(2, 5)
3

_________________________________________________________________________________

scala> def len(list: List[Any]): Int = list.foldLeft(0) { (count, i) => println(s"""c: $count i: $i"""); count + 1 }
len: (list: List[Any])Int

scala> val inputList: List[Int] = List(1, 3, 5)
inputList: List[Int] = List(1, 3, 5)

scala> len(inputList)
c: 0 i: 1
c: 1 i: 3
c: 2 i: 5
res0: Int = 3

_________________________________________________________________________________


scala> def last[A](list: List[A]): A = list.foldLeft[A](list.head) { (x, cur) =>  println(s"""x: $x cur: $cur"""); cur }
last: [A](list: List[A])A

scala> last(inputList)
x: 1 cur: 1
x: 1 cur: 3
x: 3 cur: 5

res1: Int = 5

_________________________________________________________________________________


scala>  def average(list: List[Double]): Double = list match {
     |   case head :: tail => tail.foldLeft((head, 1.0)) { (avg, cur) =>
     |     ((avg._1 * avg._2 + cur)/(avg._2 + 1.0), avg._2 + 1.0)
     |   }._1
     |   case Nil => Double.NaN
     | }
average: (list: List[Double])Double

scala> average(inputList.map(_.toDouble))
res4: Double = 3.0




_________________________________________________________________________________


scala>  def average(list: List[Double]): Double = list match {
     |   case head :: tail => tail.foldLeft((head, 1.0)) { (avg, cur) =>
     |     println(s"""sum: ${avg._1 * avg._2 + cur} count: ${avg._2 + 1.0}""");
     |     ((avg._1 * avg._2 + cur)/(avg._2 + 1.0), avg._2 + 1.0)
     |   }._1
     |   case Nil => Double.NaN
     | }
average: (list: List[Double])Double

scala> 

scala> average(inputList.map(_.toDouble))
sum: 4.0 count: 2.0
sum: 9.0 count: 3.0
res7: Double = 3.0

_________________________________________________________________________________

scala> def reverse[A](list: List[A]): List[A] =
     |   list.foldLeft(List[A]()) { (r,c) =>  println(s"""r: ${r} c: ${c} """); c :: r }
reverse: [A](list: List[A])List[A]

scala> val l = List(1,3,5,7,9,11,13,15,17)
l: List[Int] = List(1, 3, 5, 7, 9, 11, 13, 15, 17)

scala> reverse(l)
r: List() c: 1 
r: List(1) c: 3 
r: List(3, 1) c: 5 
r: List(5, 3, 1) c: 7 
r: List(7, 5, 3, 1) c: 9 
r: List(9, 7, 5, 3, 1) c: 11 
r: List(11, 9, 7, 5, 3, 1) c: 13 
r: List(13, 11, 9, 7, 5, 3, 1) c: 15 
r: List(15, 13, 11, 9, 7, 5, 3, 1) c: 17 
res10: List[Int] = List(17, 15, 13, 11, 9, 7, 5, 3, 1)

_________________________________________________________________________________

scala> def reverse[A](list: List[A]): List[A] =
     |   list.foldLeft(List[A]()) { (r,c) =>  println(s"""r: ${r} c: ${c} """); c :: r }
reverse: [A](list: List[A])List[A]

scala> val l = List(1,3,5,7,9,11,13,15,17)
l: List[Int] = List(1, 3, 5, 7, 9, 11, 13, 15, 17)

scala> reverse(l)
r: List() c: 1 
r: List(1) c: 3 
r: List(3, 1) c: 5 
r: List(5, 3, 1) c: 7 
r: List(7, 5, 3, 1) c: 9 
r: List(9, 7, 5, 3, 1) c: 11 
r: List(11, 9, 7, 5, 3, 1) c: 13 
r: List(13, 11, 9, 7, 5, 3, 1) c: 15 
r: List(15, 13, 11, 9, 7, 5, 3, 1) c: 17 
res10: List[Int] = List(17, 15, 13, 11, 9, 7, 5, 3, 1)
















Thursday, September 5, 2019

Debugging SBT build files

1. How to see dependency tree in sbt?
-Inspect the SBT dependency tree as described in the documentation:
sbt:foo> inspect tree clean

2. Sonatype repos
https://oss.sonatype.org/content/repositories/public/

3. Resolvers
resolvers ++= Seq(
Resolver.sonatypeRepo("releases"),
Resolver.sonatypeRepo("snapshots")
)

3. Why is SBT unable to resolve my dependency?

4.

5. sbt: Dependency Management

6. When the libdeps are not being imported by a resolver check that the resolver is looking for the correct version at the remote repo. Check the Scala compiler and package version number.

val circeVersion = "0.8.0"
resolvers ++= Seq(
  Resolver.sonatypeRepo("releases"),  Resolver.sonatypeRepo("snapshots")
)

libraryDependencies ++= Seq(
  "io.circe" %% "circe-core",  "io.circe" %% "circe-generic",  "io.circe" %% "circe-parser").map(_ % circeVersion)

7. Check the package Scala compiler and package version numbers in the Ivy cache.

 → ls ~/.ivy2/cache/io.circe/circe-core_2.12/jars/
circe-core_2.12-0.8.0.jar

8. Search at the remote repo for the package to see the version numbers that are available.
https://oss.sonatype.org/#nexus-search;quick~circe

Tuesday, August 27, 2019

Scala ArrowAssoc

https://stackoverflow.com/questions/4980515/scala-maps-operator/4980734

implicit def any2ArrowAssoc[A](x: A): ArrowAssoc[A] = new ArrowAssoc(x)
This will convert any type into an instance of "ArrowAssoc"
class ArrowAssoc[A](x: A) {
    def -> [B](y: B): Tuple2[A, B] = Tuple2(x, y)
}
So when Scala sees 
"a"->1
It says "There is no method named '->' on String. Are there any implicit conversions in scope that can give me a type that has a method named '->'?" Predef.scala is automatically in scope, and offers a conversion to ArrowAssoc, which obviously has the '->' method. Scala then essentially converts the above to
any2ArrowAssoc("a").->(1)
This method returns a Tuple2("a", 1) (often called a Pair). Map has a constructor that thats an array (varargs) of Tuple2s, so we're off to races! No magic in the compiler (besides implicit conversion, which is used extensively and for many different purposes), and no magic in Maps constructor.