Skip to content

Lazy value returns different result on second call #7748

Closed
@scabug

Description

@scabug

The following code returns a different result on the second call. It seems that the second call returns only the calculated percents without passing it to the prettifyPercents method.

import scala.util.Try

object Bug {
  def main(args: Array[String]) {
    val results = Map(1 -> 1, 2 -> 1 , 3 -> 1, 4 -> 4)
    val survey = Survey(results)

    println(survey.percents)
    println(survey.percents)
  }
}

case class Survey(results: Map[Int, Int]) {

  lazy val percents: Map[Int, Int] = prettifyPercents {
    val total = results.foldLeft(0)(_+_._2)
    for ((key, value) <- results) yield key -> Try(math.round(value * 100.0 / total).toInt).getOrElse(0)
  }

  private def prettifyPercents(percents: Map[Int, Int]) = {
    percents.foldLeft(0)(_+_._2) match {
      case 100 => percents
      case total: Int => {
        var remainder = 100 - total
        percents.mapValues { percent =>
          if (percent != 0 && remainder > 0) {
            remainder = remainder - 1
            percent + 1
          } else if (percent != 0 && remainder < 0) {
            remainder = remainder + 1
            percent - 1
          } else {
            percent
          }
        }
      }
    }
  }
}

Expected output:

Map(1 -> 15, 2 -> 14, 3 -> 14, 4 -> 57)
Map(1 -> 15, 2 -> 14, 3 -> 14, 4 -> 57)

Actual output:

Map(1 -> 15, 2 -> 14, 3 -> 14, 4 -> 57)
Map(1 -> 14, 2 -> 14, 3 -> 14, 4 -> 57)

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions