# Calculate click-through rate (CTR) with Stream Processing

For calculating CTR (Click Through Rate) we can create two activity stream:

1. Search Events
2. Click Events

create table of two corresponding search events and click events with Stream-stream join using one of Stream Processing engine, so we can count number of clicks and number of total search and calculate CTR.

# Knapsack

This video is a good start to learn how to solve 0/1 Knapsack problem with Dynamic Programming. If you want to solve dynamic programmings in functional paradigm, see these series of articles.

# Conversion Between DTO and Entity Classes in Scala

When you practicing DDD (Domain-Driven-Design), you need to create different bounded countexts, for example when you receive DTO object `PersonDTO`, It should be mapped to `PersonEntity`. This conversion, have lots of repetitive works to copy fields of one object to another.

In scala there is type-safa data transoformer chimney which can do it for you with macros and providing simple dsl for it.

Scala-Automapper is another library which is similar to `chimney` but when you have some difference in fields type, you can’t do it, easily like `chimney`

# Scala Intramap

Intramap have following definition:

``````def imap[A, B](fa: F[A])(f: A => B)(g: B => A): F[B]
``````

So when you have Funtor[A] and you want to create new Functor[B] which is invariant with Functor[A] you can use `imap` method.

In following example, You I’ve wrote Codec for `Person` type, by using `String` Codec.

``````trait Codec[A] {
self =>
def encode(value: A): String

def decode(value: String): A

def imap[B](dec: A => B, enc: B => A): Codec[B] = new Codec[B] {
override def encode(value: B): String =
self.encode(enc(value))

override def decode(value: String): B =
dec(self.decode(value))
}
}

def encode[A](value: A)(implicit c: Codec[A]): String = c.encode(value)

def decode[A](value: String)(implicit c: Codec[A]): A = c.decode(value)

object CodecImplicits {

implicit val stringCodec: Codec[String] = new Codec[String] {
override def encode(value: String): String = value

override def decode(value: String): String = value
}

implicit val intCodec: Codec[Int] = stringCodec.imap(
_.toInt, _.toString
)
}

import CodecImplicits._

case class Person(name: String, age: Int)

implicit val personCodec: Codec[Person] = stringCodec.imap[Person](
str => {
val lines = str.split(',')
Person(decode[String](lines(0)), decode[Int](lines(1)))
},
person => s"\${person.name},\${person.age}"
)

val ali: String = encode[Person](Person("Ali", 25))

println(ali)
``````

Result:

``````Ali,25
``````

# Scala Contramap

Contramap function have the following definition:

``````def contramap[A, B](fa: F[A])(f: B => A): F[B]
``````

For example `scala.math.Ordering` have `by` function that is contramap, we can create Complicated orderings by use of Simple Orderings.

``````def by[T, S](f: T => S)(implicit ord: Ordering[S]): Ordering[T]
``````

Create Ordering for type Money with `by` contramap

``````case class Money(amount: Int)

import scala.math.Ordered._

implicit val moneyOrdering: Ordering[Money] = Ordering.by(_.amount)

Money(300) < Money(200)
``````