indentation
indentation

Reputation: 77

Exception in thread "main" java.lang.IllegalArgumentException: For input string: " false"

enter code here
package anotherExample

object StringSplitter {
  def computePercentTrue(line: String): Double = {
    val splits: Array[String] = line.split(";")
    var totalCount: Double = 0
    //println("Hi!")
    var trueCount: Double = 0
    for (value <- splits) {
      //println("Hello!")
      val valueAsBoolean: Boolean = value.toBoolean
      //println(3)
      if (valueAsBoolean) {
        trueCount += 1
      }
      totalCount += 1
    }
    trueCount / totalCount
  }

  def main(args: Array[String]): Unit = {
    val testInput = "true; false; true; true; true"
    val percentTrue = computePercentTrue(testInput) // expecting 0.8
    println("Percentage true == " + percentTrue)
  }


}

Hi, so the point of this code is given a string of boolean values(true/false) and splitting by semicolons, I'm trying to return the percentage of values that are true. I don't understand the error message and I'm new to Scala, so can someone explain what's going on? I'm getting this error message:

Exception in thread "main" java.lang.IllegalArgumentException: For input string: " false"
    at scala.collection.immutable.StringLike.parseBoolean(StringLike.scala:327)
    at scala.collection.immutable.StringLike.toBoolean(StringLike.scala:289)
    at scala.collection.immutable.StringLike.toBoolean$(StringLike.scala:289)
    at scala.collection.immutable.StringOps.toBoolean(StringOps.scala:33)
    at anotherExample.StringSplitter$.$anonfun$computePercentTrue$1(StringSplitter.scala:11)
    at anotherExample.StringSplitter$.$anonfun$computePercentTrue$1$adapted(StringSplitter.scala:9)
    at scala.collection.IndexedSeqOptimized.foreach(IndexedSeqOptimized.scala:36)
    at scala.collection.IndexedSeqOptimized.foreach$(IndexedSeqOptimized.scala:33)
    at scala.collection.mutable.ArrayOps$ofRef.foreach(ArrayOps.scala:198)
    at anotherExample.StringSplitter$.computePercentTrue(StringSplitter.scala:9)
    at anotherExample.StringSplitter$.main(StringSplitter.scala:23)
    at anotherExample.StringSplitter.main(StringSplitter.scala)

Upvotes: 0

Views: 1652

Answers (2)

jwvh
jwvh

Reputation: 51271

With a regex solution you can be a bit more forgiving of poorly formatted input.

def computePercentTrue(line: String): Double = {
  val vctr = "(true|false)".r.findAllMatchIn(line)
                           .map(_.group(1)=="true")
                           .toVector
  vctr.count(identity) / vctr.length.toDouble
}

computePercentTrue("true;; false;x; true=true -- true")
//res0: Double = 0.8

Upvotes: 0

pme
pme

Reputation: 14803

As @asanand mentioned in his comment, you should use trim.

In Scala 2.13 you can do it entirely safe (no Exception), use this:

stringValue.trim.toBooleanOption.getOrElse(false)

Or with previous Versions:

Try(stringValue.trim.toBoolean).getOrElse(false)

See here: https://stackoverflow.com/a/54991592/2750966

By the way in Scala always try to avoid mutable state vars.

Here an example using foldLeft:

def computePercentTrue(line: String): Double = {
   val (trueCount, totalCount) = 
      line.split(";")
        .foldLeft((0.0, 0)){case ((count, total), value) => 
           (if(value.trim.toBooleanOption.getOrElse(false))
               count + 1
            else 
               count
            , total + 1)
        } 
   trueCount / totalCount
}

Upvotes: 2

Related Questions