Skip to content

Commit da440c1

Browse files
committed
Improve error message for row.getColumnGroup and fix warnings
1 parent e9bac15 commit da440c1

File tree

5 files changed

+37
-7
lines changed

5 files changed

+37
-7
lines changed

core/src/main/kotlin/org/jetbrains/kotlinx/dataframe/DataRow.kt

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package org.jetbrains.kotlinx.dataframe
22

33
import org.jetbrains.kotlinx.dataframe.api.next
44
import org.jetbrains.kotlinx.dataframe.api.prev
5+
import org.jetbrains.kotlinx.dataframe.columns.ColumnKind
56
import org.jetbrains.kotlinx.dataframe.columns.ColumnPath
67
import org.jetbrains.kotlinx.dataframe.columns.ColumnReference
78
import org.jetbrains.kotlinx.dataframe.impl.columnName
@@ -31,7 +32,17 @@ public interface DataRow<out T> {
3132
public operator fun get(first: String, vararg other: String): DataRow<T> = owner.get(first, *other)[index]
3233
public operator fun get(path: ColumnPath): Any? = owner.get(path)[index]
3334
public operator fun get(name: String): Any?
34-
public fun getColumnGroup(columnName: String): AnyRow = get(columnName) as AnyRow
35+
public fun getColumnGroup(columnName: String): AnyRow {
36+
val value = get(columnName)
37+
if (value == null) {
38+
val kind = df()[columnName].kind()
39+
if (kind != ColumnKind.Group) {
40+
error("Cannot cast null value of a $kind to a ${DataRow::class}")
41+
}
42+
}
43+
return value as AnyRow
44+
}
45+
3546
public fun getOrNull(name: String): Any?
3647
public fun <R> getValueOrNull(column: ColumnReference<R>): R?
3748

core/src/main/kotlin/org/jetbrains/kotlinx/dataframe/api/DataRowApi.kt

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ public fun AnyRow.isNotEmpty(): Boolean = !isEmpty()
2424

2525
public inline fun <reified R> AnyRow.valuesOf(): List<R> = values().filterIsInstance<R>()
2626

27+
// region DataSchema
2728
@DataSchema
2829
public data class NameValuePair<V>(val name: String, val value: V)
2930

@@ -39,6 +40,8 @@ public val DataRow<NameValuePair<*>>.name: String @JvmName("NameValuePairAny_nam
3940
public val ColumnsContainer<NameValuePair<*>>.value: DataColumn<*> @JvmName("NameValuePairAny_value") get() = this["value"]
4041
public val DataRow<NameValuePair<*>>.value: Any? @JvmName("NameValuePairAny_value") get() = this["value"]
4142

43+
// endregion
44+
4245
public inline fun <reified R> AnyRow.namedValuesOf(): List<NameValuePair<R>> =
4346
values().zip(columnNames()).filter { it.first is R }.map { NameValuePair(it.second, it.first as R) }
4447

@@ -106,11 +109,11 @@ public fun <T> DataRow<T>.relative(relativeIndices: Iterable<Int>): DataFrame<T>
106109
getRows(relativeIndices.mapNotNull { (index + it).let { if (it >= 0 && it < df().rowsCount()) it else null } })
107110

108111
public fun <T> DataRow<T>.relative(relativeIndices: IntRange): DataFrame<T> =
109-
getRows((relativeIndices.start + index).coerceIn(df().indices)..(relativeIndices.endInclusive + index).coerceIn(df().indices))
112+
getRows((relativeIndices.first + index).coerceIn(df().indices)..(relativeIndices.last + index).coerceIn(df().indices))
110113

111114
public fun <T> DataRow<T>.movingAverage(k: Int, expression: RowExpression<T, Number>): Double {
112115
var count = 0
113-
return backwardIterable().take(k).sumByDouble {
116+
return backwardIterable().take(k).sumOf {
114117
count++
115118
expression(it).toDouble()
116119
} / count
Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,13 @@
11
package org.jetbrains.kotlinx.dataframe.columns
22

33
public enum class ColumnKind {
4-
Value,
5-
Group,
6-
Frame
4+
Value {
5+
override fun toString(): String = "ValueColumn"
6+
},
7+
Group {
8+
override fun toString(): String = "ColumnGroup"
9+
},
10+
Frame {
11+
override fun toString(): String = "FrameColumn"
12+
}
713
}

core/src/main/kotlin/org/jetbrains/kotlinx/dataframe/io/json.kt

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,6 @@ public fun DataRow.Companion.readJson(file: File, header: List<String> = emptyLi
6262
public fun DataFrame.Companion.readJson(path: String, header: List<String> = emptyList()): AnyFrame = readJson(asURL(path), header)
6363
public fun DataRow.Companion.readJson(path: String, header: List<String> = emptyList()): AnyRow = DataFrame.readJson(path, header).single()
6464

65-
@Suppress("UNCHECKED_CAST")
6665
public fun DataFrame.Companion.readJson(url: URL, header: List<String> = emptyList()): AnyFrame = catchHttpResponse(url) { readJson(it, header) }
6766
public fun DataRow.Companion.readJson(url: URL, header: List<String> = emptyList()): AnyRow = DataFrame.readJson(url, header).single()
6867

tests/src/test/kotlin/org/jetbrains/kotlinx/dataframe/api/get.kt

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
package org.jetbrains.kotlinx.dataframe.api
22

33
import io.kotest.assertions.throwables.shouldThrow
4+
import io.kotest.assertions.throwables.shouldThrowAny
45
import io.kotest.matchers.shouldBe
6+
import io.kotest.matchers.string.shouldContain
57
import org.jetbrains.kotlinx.dataframe.DataFrame
68
import org.jetbrains.kotlinx.dataframe.annotations.DataSchema
79
import org.junit.Test
@@ -78,4 +80,13 @@ class GetTests {
7880
df[x][0].a shouldBe 1
7981
df[1][x].a shouldBe 3
8082
}
83+
84+
@Test
85+
fun `throw meaningful exception when traverse columns in DataRow`() {
86+
val df = dataFrameOf("a")(null)
87+
val throwable = shouldThrowAny {
88+
df[0].getColumnGroup("a")
89+
}
90+
throwable.message shouldContain "Cannot cast null value of a ValueColumn to"
91+
}
8192
}

0 commit comments

Comments
 (0)