Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

utility class to display a numeric value #262

Merged
merged 7 commits into from
Jul 25, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ dependencies {
val arrowVersion = "1.1.5"
val olcaSimaproVersion = "3.0.5"
val kotlinxSerializationJSONVersion = "1.5.1"

implementation(platform("io.arrow-kt:arrow-stack:$arrowVersion"))
implementation("io.arrow-kt:arrow-core")
implementation("io.arrow-kt:arrow-optics")
Expand Down Expand Up @@ -91,7 +92,6 @@ qodana {
showReport.set(System.getenv("QODANA_SHOW_REPORT")?.toBoolean() ?: false)
}


tasks {
// Set the JVM compatibility versions
properties("javaVersion").let {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
package ch.kleis.lcaplugin.ui.toolwindow

import arrow.core.flatten
import arrow.core.replicate
import com.intellij.util.containers.tail
import kotlin.math.*

data class FloatingPointRepresentation(
val isPositive: Boolean,
val digits: List<Int>,
val positionalExponent: Int,
val nbSignificantDigits: Int,
) {
companion object {
fun of(value: Double, nbSignificantDigits: Int = 3): FloatingPointRepresentation {
if (value == 0.0) {
return FloatingPointRepresentation(
true,
IntRange(1, nbSignificantDigits).map { 0 },
0,
nbSignificantDigits
)
}
val isPositive = value > 0.0
val w = abs(value)
val e = ceil(log10(w)).toInt()
val positionalExponent =
if (w == 10.0.pow(e)) e
else e - 1
val shift = nbSignificantDigits - positionalExponent
val reversedDigits = ArrayList<Int>()
var u = floor(w * (10.0.pow(shift))).toInt()
while (u > 0) {
reversedDigits.add(u.mod(10))
u /= 10
}
val digits = reversedDigits.reversed().take(nbSignificantDigits)

if (digits.tail().take(nbSignificantDigits - 1).all { it == 9 }) {
val hd = digits[0]
if (hd == 9) {
val zeros = listOf(0).replicate(nbSignificantDigits - 2).flatten()
return FloatingPointRepresentation(
isPositive,
listOf(1, 0) + zeros,
positionalExponent + 1,
nbSignificantDigits
)
}
val zeros = listOf(0).replicate(nbSignificantDigits - 1).flatten()
return FloatingPointRepresentation(
isPositive,
listOf(hd + 1) + zeros,
positionalExponent,
nbSignificantDigits
)
}
return FloatingPointRepresentation(isPositive, digits, positionalExponent, nbSignificantDigits)
}
}

override fun toString(): String {
return when (positionalExponent) {
in -2..-1 -> {
val hd = listOf(0).replicate(-positionalExponent - 1).flatten()
.joinToString("")
.let { "0.$it" }
val tl = digits.take(nbSignificantDigits - positionalExponent + 1)
.dropLastWhile { it == 0 }
.joinToString("")
val sign = if (isPositive) "" else "-"
"$sign$hd$tl"
}

in 0..2 -> {
val midpoint = min(positionalExponent + 1, nbSignificantDigits)
val hd = digits.subList(0, midpoint)
.joinToString("")
val tl = digits.subList(midpoint, nbSignificantDigits)
.dropLastWhile { it == 0 }
.joinToString("")
.let { if (it.isEmpty()) "" else ".$it" }
val sign = if (isPositive) "" else "-"
"$sign$hd$tl"
}

else -> {
val hd = digits.subList(0, 1)
.joinToString("")
val tl = digits.subList(1, nbSignificantDigits)
.dropLastWhile { it == 0 }
.joinToString("")
.let { if (it.isEmpty()) "" else ".$it" }
val sign = if (isPositive) "" else "-"
val e = "E$positionalExponent"
"$sign$hd$tl$e"
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ package ch.kleis.lcaplugin.ui.toolwindow

import ch.kleis.lcaplugin.core.assessment.Inventory
import ch.kleis.lcaplugin.core.lang.value.MatrixColumnIndex
import ch.kleis.lcaplugin.core.matrix.ImpactFactorMatrix
import javax.swing.event.TableModelListener
import javax.swing.table.TableModel

Expand Down Expand Up @@ -59,15 +58,15 @@ class InventoryTableModel(

val quantity = inventory.supply.quantityOf(outputProduct)
if (columnIndex == 1) {
return "${quantity.amount}"
return FloatingPointRepresentation.of(quantity.amount).toString()
}
if (columnIndex == 2) {
return "${quantity.unit.symbol}"
}

val inputProduct = sortedControllablePorts[columnIndex - 3]
val ratio = inventory.impactFactors.valueRatio(outputProduct, inputProduct).amount
return quantity.amount * ratio
return FloatingPointRepresentation.of(quantity.amount * ratio).toString()
}

override fun setValueAt(aValue: Any?, rowIndex: Int, columnIndex: Int) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
package ch.kleis.lcaplugin.ui.toolwindow

import org.junit.Assert.assertEquals
import org.junit.Test
import org.junit.runner.RunWith
import org.junit.runners.Parameterized
import org.junit.runners.Parameterized.Parameters


@RunWith(Parameterized::class)
class DisplayedNumberTest(
private val value: Double,
private val expected: String,
) {
companion object {
@Parameters
@JvmStatic
fun getDisplayedStrings(): Collection<Array<Any>> {
return listOf(
arrayOf(0.0, "0"),
arrayOf(0.0001, "1E-4"),
arrayOf(0.001, "1E-3"),
arrayOf(0.01, "0.01"),
arrayOf(0.1, "0.1"),
arrayOf(1.0, "1"),
arrayOf(10.0, "10"),
arrayOf(100.0, "100"),
arrayOf(1000.0, "1E3"),

arrayOf(0.000999, "1E-3"),
arrayOf(0.00999, "0.01"),
arrayOf(0.0999, "0.1"),
arrayOf(0.999, "1"),
arrayOf(9.99, "10"),
arrayOf(99.9, "100"),
arrayOf(999.0, "1E3"),

arrayOf(0.00123, "1.23E-3"),
arrayOf(0.0123, "0.0123"),
arrayOf(0.123, "0.123"),
arrayOf(1.2345, "1.23"),
arrayOf(12.345, "12.3"),
arrayOf(123.45, "123"),
arrayOf(1234.5, "1.23E3"),
arrayOf(12345.123, "1.23E4"),

arrayOf(-0.0, "0"),
arrayOf(-0.00123, "-1.23E-3"),
arrayOf(-0.0123, "-0.0123"),
arrayOf(-0.123, "-0.123"),
arrayOf(-1.2345, "-1.23"),
arrayOf(-12.345, "-12.3"),
arrayOf(-123.45, "-123"),
arrayOf(-1234.5, "-1.23E3"),
arrayOf(-12345.123, "-1.23E4"),
)
}
}

@Test
fun run() {
// when
val actual = FloatingPointRepresentation.of(value).toString()

// then
assertEquals(expected, actual)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
package ch.kleis.lcaplugin.ui.toolwindow

import org.junit.runner.RunWith
import org.junit.runners.Parameterized
import org.junit.runners.Parameterized.Parameters
import org.junit.Test
import kotlin.test.assertEquals

private fun digits(s: String): List<Int> {
return s.map { Integer.parseInt(it.toString()) }
}

@RunWith(Parameterized::class)
class FloatingPointRepresentationTest(
private val value: Double,
private val expected: FloatingPointRepresentation,
) {
companion object {

@Parameters
@JvmStatic
fun getFloatingPointRepresentationSamples(): Collection<Array<Any>> {
return listOf(
arrayOf(0.0012345, FloatingPointRepresentation(true, digits("123"), -3, 3)),
arrayOf(0.012345, FloatingPointRepresentation(true, digits("123"), -2, 3)),
arrayOf(0.12345, FloatingPointRepresentation(true, digits("123"), -1, 3)),
arrayOf(1.2345, FloatingPointRepresentation(true, digits("123"), 0, 3)),
arrayOf(12.345, FloatingPointRepresentation(true, digits("123"), 1, 3)),
arrayOf(123.45, FloatingPointRepresentation(true, digits("123"), 2, 3)),
arrayOf(1234.5, FloatingPointRepresentation(true, digits("123"), 3, 3)),
arrayOf(12345.0, FloatingPointRepresentation(true, digits("123"), 4, 3)),

arrayOf(0.0, FloatingPointRepresentation(true, digits("000"), 0, 3)),
arrayOf(0.0001, FloatingPointRepresentation(true, digits("100"), -4, 3)),
arrayOf(0.001, FloatingPointRepresentation(true, digits("100"), -3, 3)),
arrayOf(0.01, FloatingPointRepresentation(true, digits("100"), -2, 3)),
arrayOf(0.1, FloatingPointRepresentation(true, digits("100"), -1, 3)),
arrayOf(1.0, FloatingPointRepresentation(true, digits("100"), 0, 3)),
arrayOf(10.0, FloatingPointRepresentation(true, digits("100"), 1, 3)),
arrayOf(100.0, FloatingPointRepresentation(true, digits("100"), 2, 3)),
arrayOf(1000.0, FloatingPointRepresentation(true, digits("100"), 3, 3)),

arrayOf(0.000999, FloatingPointRepresentation(true, digits("100"), -3, 3)),
arrayOf(0.00999, FloatingPointRepresentation(true, digits("100"), -2, 3)),
arrayOf(0.0999, FloatingPointRepresentation(true, digits("100"), -1, 3)),
arrayOf(0.999, FloatingPointRepresentation(true, digits("100"), 0, 3)),
arrayOf(9.99, FloatingPointRepresentation(true, digits("100"), 1, 3)),
arrayOf(99.9, FloatingPointRepresentation(true, digits("100"), 2, 3)),
arrayOf(999.0, FloatingPointRepresentation(true, digits("100"), 3, 3)),

arrayOf(0.001001, FloatingPointRepresentation(true, digits("100"), -3, 3)),
arrayOf(0.01001, FloatingPointRepresentation(true, digits("100"), -2, 3)),
arrayOf(0.1001, FloatingPointRepresentation(true, digits("100"), -1, 3)),
arrayOf(1.001, FloatingPointRepresentation(true, digits("100"), 0, 3)),
arrayOf(10.01, FloatingPointRepresentation(true, digits("100"), 1, 3)),
arrayOf(100.1, FloatingPointRepresentation(true, digits("100"), 2, 3)),
arrayOf(1001.0, FloatingPointRepresentation(true, digits("100"), 3, 3)),

arrayOf(0.0002999, FloatingPointRepresentation(true, digits("300"), -4, 3)),
arrayOf(0.003999, FloatingPointRepresentation(true, digits("400"), -3, 3)),
arrayOf(0.04999, FloatingPointRepresentation(true, digits("500"), -2, 3)),
arrayOf(0.5999, FloatingPointRepresentation(true, digits("600"), -1, 3)),
arrayOf(6.999, FloatingPointRepresentation(true, digits("700"), 0, 3)),
arrayOf(79.99, FloatingPointRepresentation(true, digits("800"), 1, 3)),
arrayOf(899.9, FloatingPointRepresentation(true, digits("900"), 2, 3)),

arrayOf(-0.0012345, FloatingPointRepresentation(false, digits("123"), -3, 3)),
arrayOf(-0.012345, FloatingPointRepresentation(false, digits("123"), -2, 3)),
arrayOf(-0.12345, FloatingPointRepresentation(false, digits("123"), -1, 3)),
arrayOf(-1.2345, FloatingPointRepresentation(false, digits("123"), 0, 3)),
arrayOf(-12.345, FloatingPointRepresentation(false, digits("123"), 1, 3)),
arrayOf(-123.45, FloatingPointRepresentation(false, digits("123"), 2, 3)),
arrayOf(-1234.5, FloatingPointRepresentation(false, digits("123"), 3, 3)),
arrayOf(-12345.0, FloatingPointRepresentation(false, digits("123"), 4, 3)),

arrayOf(-0.0, FloatingPointRepresentation(true, digits("000"), 0, 3)),
arrayOf(-0.0001, FloatingPointRepresentation(false, digits("100"), -4, 3)),
arrayOf(-0.001, FloatingPointRepresentation(false, digits("100"), -3, 3)),
arrayOf(-0.01, FloatingPointRepresentation(false, digits("100"), -2, 3)),
arrayOf(-0.1, FloatingPointRepresentation(false, digits("100"), -1, 3)),
arrayOf(-1.0, FloatingPointRepresentation(false, digits("100"), 0, 3)),
arrayOf(-10.0, FloatingPointRepresentation(false, digits("100"), 1, 3)),
arrayOf(-100.0, FloatingPointRepresentation(false, digits("100"), 2, 3)),
arrayOf(-1000.0, FloatingPointRepresentation(false, digits("100"), 3, 3)),

arrayOf(-0.000999, FloatingPointRepresentation(false, digits("100"), -3, 3)),
arrayOf(-0.00999, FloatingPointRepresentation(false, digits("100"), -2, 3)),
arrayOf(-0.0999, FloatingPointRepresentation(false, digits("100"), -1, 3)),
arrayOf(-0.999, FloatingPointRepresentation(false, digits("100"), 0, 3)),
arrayOf(-9.99, FloatingPointRepresentation(false, digits("100"), 1, 3)),
arrayOf(-99.9, FloatingPointRepresentation(false, digits("100"), 2, 3)),
arrayOf(-999.0, FloatingPointRepresentation(false, digits("100"), 3, 3)),

arrayOf(-0.001001, FloatingPointRepresentation(false, digits("100"), -3, 3)),
arrayOf(-0.01001, FloatingPointRepresentation(false, digits("100"), -2, 3)),
arrayOf(-0.1001, FloatingPointRepresentation(false, digits("100"), -1, 3)),
arrayOf(-1.001, FloatingPointRepresentation(false, digits("100"), 0, 3)),
arrayOf(-10.01, FloatingPointRepresentation(false, digits("100"), 1, 3)),
arrayOf(-100.1, FloatingPointRepresentation(false, digits("100"), 2, 3)),
arrayOf(-1001.0, FloatingPointRepresentation(false, digits("100"), 3, 3)),

arrayOf(-0.0002999, FloatingPointRepresentation(false, digits("300"), -4, 3)),
arrayOf(-0.003999, FloatingPointRepresentation(false, digits("400"), -3, 3)),
arrayOf(-0.04999, FloatingPointRepresentation(false, digits("500"), -2, 3)),
arrayOf(-0.5999, FloatingPointRepresentation(false, digits("600"), -1, 3)),
arrayOf(-6.999, FloatingPointRepresentation(false, digits("700"), 0, 3)),
arrayOf(-79.99, FloatingPointRepresentation(false, digits("800"), 1, 3)),
arrayOf(-899.9, FloatingPointRepresentation(false, digits("900"), 2, 3)),
)
}

}

@Test
fun run() {
// when
val actual = FloatingPointRepresentation.of(value, 3)

// then
assertEquals(expected, actual, "value = $value")
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ class LcaProcessAssessResultTest {
assertThat(html, containsString("<td>carrot</td>"))
val text = result.getTransferData(DataFlavor("text/plain;class=java.lang.String")) as String
assertThat(text, containsString("item\tquantity\tunit\t[Resource] propanol(air) [kg]"))
assertThat(text, containsString("\ncarrot\t1.0\tg\t0.001\t"))
assertThat(text, containsString("\ncarrot\t1\tg\t1E-3\t"))
}

}