Skip to content

Commit

Permalink
Match feature type map hierarchy with regular feature types (#49)
Browse files Browse the repository at this point in the history
  • Loading branch information
tovbinm committed Aug 15, 2018
1 parent 6a308ad commit 68ad5a8
Show file tree
Hide file tree
Showing 6 changed files with 206 additions and 52 deletions.
50 changes: 28 additions & 22 deletions features/src/main/scala/com/salesforce/op/features/types/Maps.scala
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@

package com.salesforce.op.features.types

import org.apache.spark.ml.linalg.{Vector, Vectors}
import org.apache.spark.ml.linalg.Vector

/**
* Map of text values
Expand All @@ -48,7 +48,7 @@ object TextMap {
*
* @param value map of email values
*/
class EmailMap(val value: Map[String, String]) extends OPMap[String]
class EmailMap(value: Map[String, String]) extends TextMap(value)
object EmailMap {
def apply(value: Map[String, String]): EmailMap = new EmailMap(value)
def empty: EmailMap = FeatureTypeDefaults.EmailMap
Expand All @@ -59,7 +59,7 @@ object EmailMap {
*
* @param value map of base64 binary encoded values
*/
class Base64Map(val value: Map[String, String]) extends OPMap[String]
class Base64Map(value: Map[String, String]) extends TextMap(value)
object Base64Map {
def apply(value: Map[String, String]): Base64Map = new Base64Map(value)
def empty: Base64Map = FeatureTypeDefaults.Base64Map
Expand All @@ -70,7 +70,7 @@ object Base64Map {
*
* @param value map of phone values
*/
class PhoneMap(val value: Map[String, String]) extends OPMap[String]
class PhoneMap(value: Map[String, String]) extends TextMap(value)
object PhoneMap {
def apply(value: Map[String, String]): PhoneMap = new PhoneMap(value)
def empty: PhoneMap = FeatureTypeDefaults.PhoneMap
Expand All @@ -81,7 +81,7 @@ object PhoneMap {
*
* @param value map of ID values
*/
class IDMap(val value: Map[String, String]) extends OPMap[String]
class IDMap(value: Map[String, String]) extends TextMap(value)
object IDMap {
def apply(value: Map[String, String]): IDMap = new IDMap(value)
def empty: IDMap = FeatureTypeDefaults.IDMap
Expand All @@ -92,7 +92,7 @@ object IDMap {
*
* @param value map of URL values
*/
class URLMap(val value: Map[String, String]) extends OPMap[String]
class URLMap(value: Map[String, String]) extends TextMap(value)
object URLMap {
def apply(value: Map[String, String]): URLMap = new URLMap(value)
def empty: URLMap = FeatureTypeDefaults.URLMap
Expand All @@ -103,7 +103,7 @@ object URLMap {
*
* @param value map of text area values
*/
class TextAreaMap(val value: Map[String, String]) extends OPMap[String]
class TextAreaMap(value: Map[String, String]) extends TextMap(value)
object TextAreaMap {
def apply(value: Map[String, String]): TextAreaMap = new TextAreaMap(value)
def empty: TextAreaMap = FeatureTypeDefaults.TextAreaMap
Expand All @@ -114,7 +114,7 @@ object TextAreaMap {
*
* @param value map of picklist values
*/
class PickListMap(val value: Map[String, String]) extends OPMap[String]
class PickListMap(value: Map[String, String]) extends TextMap(value) with SingleResponse
object PickListMap {
def apply(value: Map[String, String]): PickListMap = new PickListMap(value)
def empty: PickListMap = FeatureTypeDefaults.PickListMap
Expand All @@ -125,7 +125,7 @@ object PickListMap {
*
* @param value map of combobox values
*/
class ComboBoxMap(val value: Map[String, String]) extends OPMap[String]
class ComboBoxMap(value: Map[String, String]) extends TextMap(value)
object ComboBoxMap {
def apply(value: Map[String, String]): ComboBoxMap = new ComboBoxMap(value)
def empty: ComboBoxMap = FeatureTypeDefaults.ComboBoxMap
Expand All @@ -136,7 +136,9 @@ object ComboBoxMap {
*
* @param value map of binary values
*/
class BinaryMap(val value: Map[String, Boolean]) extends OPMap[Boolean]
class BinaryMap(val value: Map[String, Boolean]) extends OPMap[Boolean] with NumericMap with SingleResponse {
def toDoubleMap: Map[String, Double] = value
}
object BinaryMap {
def apply(value: Map[String, Boolean]): BinaryMap = new BinaryMap(value)
def empty: BinaryMap = FeatureTypeDefaults.BinaryMap
Expand All @@ -147,7 +149,9 @@ object BinaryMap {
*
* @param value map of integral values
*/
class IntegralMap(val value: Map[String, Long]) extends OPMap[Long]
class IntegralMap(val value: Map[String, Long]) extends OPMap[Long] with NumericMap {
def toDoubleMap: Map[String, Double] = value
}
object IntegralMap {
def apply(value: Map[String, Long]): IntegralMap = new IntegralMap(value)
def empty: IntegralMap = FeatureTypeDefaults.IntegralMap
Expand All @@ -158,7 +162,9 @@ object IntegralMap {
*
* @param value map of real values
*/
class RealMap(val value: Map[String, Double]) extends OPMap[Double]
class RealMap(val value: Map[String, Double]) extends OPMap[Double] with NumericMap {
def toDoubleMap: Map[String, Double] = value
}
object RealMap {
def apply(value: Map[String, Double]): RealMap = new RealMap(value)
def empty: RealMap = FeatureTypeDefaults.RealMap
Expand All @@ -169,7 +175,7 @@ object RealMap {
*
* @param value map of percent values
*/
class PercentMap(val value: Map[String, Double]) extends OPMap[Double]
class PercentMap(value: Map[String, Double]) extends RealMap(value)
object PercentMap {
def apply(value: Map[String, Double]): PercentMap = new PercentMap(value)
def empty: PercentMap = FeatureTypeDefaults.PercentMap
Expand All @@ -180,7 +186,7 @@ object PercentMap {
*
* @param value map of currency values
*/
class CurrencyMap(val value: Map[String, Double]) extends OPMap[Double]
class CurrencyMap(value: Map[String, Double]) extends RealMap(value)
object CurrencyMap {
def apply(value: Map[String, Double]): CurrencyMap = new CurrencyMap(value)
def empty: CurrencyMap = FeatureTypeDefaults.CurrencyMap
Expand All @@ -191,7 +197,7 @@ object CurrencyMap {
*
* @param value map of date values
*/
class DateMap(val value: Map[String, Long]) extends OPMap[Long]
class DateMap(value: Map[String, Long]) extends IntegralMap(value)
object DateMap {
def apply(value: Map[String, Long]): DateMap = new DateMap(value)
def empty: DateMap = FeatureTypeDefaults.DateMap
Expand All @@ -202,7 +208,7 @@ object DateMap {
*
* @param value map of date & time values
*/
class DateTimeMap(val value: Map[String, Long]) extends OPMap[Long]
class DateTimeMap(value: Map[String, Long]) extends DateMap(value)
object DateTimeMap {
def apply(value: Map[String, Long]): DateTimeMap = new DateTimeMap(value)
def empty: DateTimeMap = FeatureTypeDefaults.DateTimeMap
Expand All @@ -213,7 +219,7 @@ object DateTimeMap {
*
* @param value map of multi picklist values
*/
class MultiPickListMap(val value: Map[String, Set[String]]) extends OPMap[Set[String]]
class MultiPickListMap(val value: Map[String, Set[String]]) extends OPMap[Set[String]] with MultiResponse
object MultiPickListMap {
def apply(value: Map[String, Set[String]]): MultiPickListMap = new MultiPickListMap(value)
def empty: MultiPickListMap = FeatureTypeDefaults.MultiPickListMap
Expand All @@ -224,7 +230,7 @@ object MultiPickListMap {
*
* @param value map of country values
*/
class CountryMap(val value: Map[String, String]) extends OPMap[String] with Location
class CountryMap(value: Map[String, String]) extends TextMap(value) with Location
object CountryMap {
def apply(value: Map[String, String]): CountryMap = new CountryMap(value)
def empty: CountryMap = FeatureTypeDefaults.CountryMap
Expand All @@ -235,7 +241,7 @@ object CountryMap {
*
* @param value map of state values
*/
class StateMap(val value: Map[String, String]) extends OPMap[String] with Location
class StateMap(value: Map[String, String]) extends TextMap(value) with Location
object StateMap {
def apply(value: Map[String, String]): StateMap = new StateMap(value)
def empty: StateMap = FeatureTypeDefaults.StateMap
Expand All @@ -246,7 +252,7 @@ object StateMap {
*
* @param value map of city values
*/
class CityMap(val value: Map[String, String]) extends OPMap[String] with Location
class CityMap(value: Map[String, String]) extends TextMap(value) with Location
object CityMap {
def apply(value: Map[String, String]): CityMap = new CityMap(value)
def empty: CityMap = FeatureTypeDefaults.CityMap
Expand All @@ -257,7 +263,7 @@ object CityMap {
*
* @param value map of postal code values
*/
class PostalCodeMap(val value: Map[String, String]) extends OPMap[String] with Location
class PostalCodeMap(value: Map[String, String]) extends TextMap(value) with Location
object PostalCodeMap {
def apply(value: Map[String, String]): PostalCodeMap = new PostalCodeMap(value)
def empty: PostalCodeMap = FeatureTypeDefaults.PostalCodeMap
Expand All @@ -268,7 +274,7 @@ object PostalCodeMap {
*
* @param value map of street values
*/
class StreetMap(val value: Map[String, String]) extends OPMap[String] with Location
class StreetMap(value: Map[String, String]) extends TextMap(value) with Location
object StreetMap {
def apply(value: Map[String, String]): StreetMap = new StreetMap(value)
def empty: StreetMap = FeatureTypeDefaults.StreetMap
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,5 +41,18 @@ abstract class OPMap[A] extends OPCollection {
override type Value = Map[String, A]

final def isEmpty: Boolean = value.isEmpty
}

/**
* Numeric Map mixin
*/
trait NumericMap {
self: OPMap[_] =>

/**
* Convert map of numeric values to map of [[Double]] values
*
* @return map of [[Double]] values
*/
def toDoubleMap: Map[String, Double]
}
Original file line number Diff line number Diff line change
Expand Up @@ -235,9 +235,13 @@ package object types extends FeatureTypeSparkConverters {
}
implicit class MapLongConversions(val v: Map[String, Long]) extends AnyVal {
def toIntegralMap: IntegralMap = new IntegralMap(v)
def toDateMap: DateMap = new DateMap(v)
def toDateTimeMap: DateTimeMap = new DateTimeMap(v)
}
implicit class MapDoubleConversions(val v: Map[String, Double]) extends AnyVal {
def toRealMap: RealMap = new RealMap(v)
def toPercentMap: PercentMap = new PercentMap(v)
def toCurrencyMap: CurrencyMap = new CurrencyMap(v)
def toPrediction: Prediction = new Prediction(v)
}
implicit class MapBooleanConversions(val v: Map[String, Boolean]) extends AnyVal {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,10 +48,10 @@ class ListTest extends FlatSpec with TestCommon {
myTextList shouldBe a[OPList[_]]
}
it should "compare values correctly" in {
new TextList(List("Hello", "Bye")).equals(new TextList(List("Hello", "Bye"))) shouldBe true
new TextList(List("Bye", "Hello")).equals(new TextList(List("Hello", "Bye"))) shouldBe false
FeatureTypeDefaults.TextList.equals(new TextList(List("Hello", "Bye"))) shouldBe false
FeatureTypeDefaults.TextList.equals(TextList(List.empty[String])) shouldBe true
new TextList(List("Hello", "Bye")) shouldBe new TextList(List("Hello", "Bye"))
new TextList(List("Bye", "Hello")) should not be new TextList(List("Hello", "Bye"))
FeatureTypeDefaults.TextList should not be new TextList(List("Hello", "Bye"))
FeatureTypeDefaults.TextList shouldBe TextList(List.empty[String])

List("Goodbye", "world").toTextList shouldBe a[TextList]
}
Expand All @@ -64,10 +64,10 @@ class ListTest extends FlatSpec with TestCommon {
myDateList shouldBe a[OPList[_]]
}
it should "compare values correctly" in {
new DateList(List(456L, 13L)).equals(new DateList(List(456L, 13L))) shouldBe true
new DateList(List(13L, 456L)).equals(new DateList(List(456L, 13L))) shouldBe false
FeatureTypeDefaults.DateList.equals(new DateList(List(456L, 13L))) shouldBe false
FeatureTypeDefaults.DateList.equals(DateList(List.empty[Long])) shouldBe true
new DateList(List(456L, 13L)) shouldBe new DateList(List(456L, 13L))
new DateList(List(13L, 456L)) should not be new DateList(List(456L, 13L))
FeatureTypeDefaults.DateList should not be new DateList(List(456L, 13L))
FeatureTypeDefaults.DateList shouldBe new DateList(List.empty[Long])

List(44829L, 389093L).toDateList shouldBe a[DateList]
}
Expand All @@ -78,12 +78,13 @@ class ListTest extends FlatSpec with TestCommon {
myDateTimeList shouldBe a[FeatureType]
myDateTimeList shouldBe a[OPCollection]
myDateTimeList shouldBe a[OPList[_]]
myDateTimeList shouldBe a[DateList]
}
it should "compare values correctly" in {
new DateTimeList(List(456L, 13L)).equals(new DateTimeList(List(456L, 13L))) shouldBe true
new DateTimeList(List(13L, 456L)).equals(new DateTimeList(List(456L, 13L))) shouldBe false
FeatureTypeDefaults.DateTimeList.equals(new DateTimeList(List(456L, 13L))) shouldBe false
FeatureTypeDefaults.DateTimeList.equals(DateTimeList(List.empty[Long])) shouldBe true
new DateTimeList(List(456L, 13L)) shouldBe new DateTimeList(List(456L, 13L))
new DateTimeList(List(13L, 456L)) should not be new DateTimeList(List(456L, 13L))
FeatureTypeDefaults.DateTimeList should not be new DateTimeList(List(456L, 13L))
FeatureTypeDefaults.DateTimeList shouldBe DateTimeList(List.empty[Long])

List(12237834L, 4890489839L).toDateTimeList shouldBe a[DateTimeList]
}
Expand Down
Loading

0 comments on commit 68ad5a8

Please sign in to comment.