Skip to content

Commit dc16b4f

Browse files
NathekipDanySK
authored andcommitted
feat: allow to round values in CSVExporter
1 parent 4d95c29 commit dc16b4f

2 files changed

Lines changed: 22 additions & 14 deletions

File tree

alchemist-loading/src/main/kotlin/it/unibo/alchemist/boundary/exporters/CSVExporter.kt

Lines changed: 21 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ class CSVExporter<T, P : Position<P>>
4444
constructor(
4545
private val fileNameRoot: String = "",
4646
val interval: Double = DEFAULT_INTERVAL,
47-
val decimalPlacesCount: String = "2",
47+
val decimalPlacesCount: Int = 2,
4848
val exportPath: String =
4949
createTempDirectory("alchemist-export")
5050
.absolutePathString()
@@ -103,17 +103,20 @@ constructor(
103103
val names = extractor.columnNames
104104
when {
105105
data.size <= 1 ->
106-
roundValues(data.values, decimalPlacesCount.toInt()).joinToString(" ")
106+
roundValues(data.values, decimalPlacesCount).joinToString(" ")
107107
// Labels and keys match
108108
data.size == names.size && data.keys.containsAll(names) ->
109-
names.joinToString(" ") {
110-
requireNotNull(data[it]) {
111-
BugReporting.reportBug(
112-
"Bug in ${this::class.simpleName}",
113-
mapOf("key" to it, "data" to data),
114-
)
115-
}
116-
}
109+
roundValues(
110+
names.map { name ->
111+
requireNotNull(data[name]) {
112+
BugReporting.reportBug(
113+
"Bug in ${this::class.simpleName}",
114+
mapOf("key" to name, "data" to data),
115+
)
116+
}
117+
},
118+
decimalPlacesCount,
119+
).joinToString(" ")
117120
// If the labels do not match keys, require predictable iteration order
118121
else -> {
119122
require(data.hasPredictableIteration) {
@@ -125,7 +128,7 @@ constructor(
125128
""".trimIndent(),
126129
)
127130
}
128-
data.values.joinToString(" ")
131+
roundValues(data.values, decimalPlacesCount).joinToString(" ")
129132
}
130133
}
131134
}
@@ -143,8 +146,13 @@ constructor(
143146
}
144147
}
145148

146-
private fun roundValues(values: Collection<String>, decimalsNumber: Int): Collection<String> = values.map {
147-
if (it.toDouble() % 0 == 0.0) it else String.format(Locale.US, "%.${decimalsNumber}f", it.toDouble())
149+
private fun roundValues(values: Collection<String>, decimalsNumber: Int): Collection<String> = values.map { raw ->
150+
val number = raw.toDoubleOrNull()
151+
if (number == null || !number.isFinite() || number % 1.0 == 0.0) {
152+
raw
153+
} else {
154+
String.format(Locale.US, "%.${decimalsNumber}f", number)
155+
}
148156
}
149157

150158
private companion object {

alchemist-loading/src/test/kotlin/it/unibo/alchemist/test/TestCSVExporter.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ class TestCSVExporter<T, P : Position<P>> :
5757
}
5858
"should have limited-length decimals" {
5959
val limitedDecimalsFile = simulation.csvExporters()[1].dataFile("fixed-decimals_")
60-
val precision2 = """(\d\d.\d\d|0\.0*\d\d|\d\.0*\d|\d\.\d|\d\d)(e(-|\+)\d+)?"""
60+
val precision2 = """(\d\d\.\d\d|0\.0*\d\d|\d\.0*\d|\d\.\d|\d\d)(e(-|\+)\d+)?"""
6161
val lineRegex = Regex("""^$precision2(\s($precision2))+$""")
6262
limitedDecimalsFile.useLines { lines ->
6363
lines

0 commit comments

Comments
 (0)