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