Skip to content

Commit

Permalink
hid public Iterable.mean() overloads; There's .average() in stdlib,…
Browse files Browse the repository at this point in the history
… plus, aside from columns/dfs, creating public mean functions just clutters the public scope. Simplified internal mean logic and function overloads.
  • Loading branch information
Jolanrensen committed Nov 6, 2024
1 parent 6e028f1 commit dc4687d
Show file tree
Hide file tree
Showing 2 changed files with 41 additions and 20 deletions.
45 changes: 27 additions & 18 deletions core/src/main/kotlin/org/jetbrains/kotlinx/dataframe/math/mean.kt
Original file line number Diff line number Diff line change
@@ -1,24 +1,38 @@
package org.jetbrains.kotlinx.dataframe.math

import org.jetbrains.kotlinx.dataframe.api.mean
import org.jetbrains.kotlinx.dataframe.api.skipNA_default
import org.jetbrains.kotlinx.dataframe.impl.renderType
import org.jetbrains.kotlinx.dataframe.util.INTERNAL_MEAN
import org.jetbrains.kotlinx.dataframe.util.MEAN
import org.jetbrains.kotlinx.dataframe.util.SEQUENCE_FLOAT_MEAN
import java.math.BigDecimal
import java.math.BigInteger
import kotlin.reflect.KType
import kotlin.reflect.full.withNullability
import kotlin.reflect.typeOf

@JvmName("meanIterableReified")
@PublishedApi
internal inline fun <reified T : Number> Iterable<T>.mean(skipNA: Boolean = skipNA_default): Double =
mean(typeOf<T>(), skipNA)

@PublishedApi
internal fun <T : Number> Iterable<T>.mean(type: KType, skipNA: Boolean = skipNA_default): Double =
asSequence().mean(type, skipNA)

@JvmName("meanSequenceReified")
internal inline fun <reified T : Number> Sequence<T>.mean(skipNA: Boolean = skipNA_default): Double =
mean(typeOf<T>(), skipNA)

internal fun <T : Number> Sequence<T>.mean(type: KType, skipNA: Boolean = skipNA_default): Double {
if (type.isMarkedNullable) {
return filterNotNull().mean(type.withNullability(false), skipNA)
}
return when (type.classifier) {
Double::class -> (this as Sequence<Double>).mean(skipNA)

Float::class -> (this as Sequence<Float>).mean(skipNA)
Float::class -> (this as Sequence<Float>).map { it.toDouble() }.mean(skipNA)

Int::class -> (this as Sequence<Int>).map { it.toDouble() }.mean(false)

Expand All @@ -42,7 +56,7 @@ internal fun <T : Number> Sequence<T>.mean(type: KType, skipNA: Boolean = skipNA
}
}

public fun Sequence<Double>.mean(skipNA: Boolean = skipNA_default): Double {
private fun Sequence<Double>.mean(skipNA: Boolean = skipNA_default): Double {
var count = 0
var sum: Double = 0.toDouble()
for (element in this) {
Expand All @@ -59,8 +73,9 @@ public fun Sequence<Double>.mean(skipNA: Boolean = skipNA_default): Double {
return if (count > 0) sum / count else Double.NaN
}

@Deprecated(SEQUENCE_FLOAT_MEAN, level = DeprecationLevel.ERROR)
@JvmName("meanFloat")
public fun Sequence<Float>.mean(skipNA: Boolean = skipNA_default): Double {
internal fun Sequence<Float>.mean(skipNA: Boolean = skipNA_default): Double {
var count = 0
var sum: Double = 0.toDouble()
for (element in this) {
Expand All @@ -77,12 +92,15 @@ public fun Sequence<Float>.mean(skipNA: Boolean = skipNA_default): Double {
return if (count > 0) sum / count else Double.NaN
}

@Deprecated(INTERNAL_MEAN, level = DeprecationLevel.HIDDEN)
@JvmName("doubleMean")
public fun Iterable<Double>.mean(skipNA: Boolean = skipNA_default): Double = asSequence().mean(skipNA)
internal fun Iterable<Double>.mean(skipNA: Boolean = skipNA_default): Double = mean(typeOf<Double>(), skipNA)

@Deprecated(INTERNAL_MEAN, level = DeprecationLevel.HIDDEN)
@JvmName("floatMean")
public fun Iterable<Float>.mean(skipNA: Boolean = skipNA_default): Double = asSequence().mean(skipNA)
internal fun Iterable<Float>.mean(skipNA: Boolean = skipNA_default): Double = mean(typeOf<Float>(), skipNA)

@Deprecated(MEAN, level = DeprecationLevel.HIDDEN)
@JvmName("intMean")
public fun Iterable<Int>.mean(): Double =
if (this is Collection) {
Expand All @@ -96,6 +114,7 @@ public fun Iterable<Int>.mean(): Double =
if (count > 0) sum / count else Double.NaN
}

@Deprecated(MEAN, level = DeprecationLevel.HIDDEN)
@JvmName("shortMean")
public fun Iterable<Short>.mean(): Double =
if (this is Collection) {
Expand All @@ -109,6 +128,7 @@ public fun Iterable<Short>.mean(): Double =
if (count > 0) sum / count else Double.NaN
}

@Deprecated(MEAN, level = DeprecationLevel.HIDDEN)
@JvmName("byteMean")
public fun Iterable<Byte>.mean(): Double =
if (this is Collection) {
Expand All @@ -122,6 +142,7 @@ public fun Iterable<Byte>.mean(): Double =
if (count > 0) sum / count else Double.NaN
}

@Deprecated(MEAN, level = DeprecationLevel.HIDDEN)
@JvmName("longMean")
public fun Iterable<Long>.mean(): Double =
if (this is Collection) {
Expand All @@ -135,19 +156,7 @@ public fun Iterable<Long>.mean(): Double =
if (count > 0) sum / count else Double.NaN
}

@JvmName("bigIntegerMean")
public fun Iterable<BigInteger>.mean(): Double =
if (this is Collection) {
if (size > 0) sumOf { it.toDouble() } / size else Double.NaN
} else {
var count = 0
val sum = sumOf {
count++
it.toDouble()
}
if (count > 0) sum / count else Double.NaN
}

@Deprecated(MEAN, level = DeprecationLevel.HIDDEN)
@JvmName("bigDecimalMean")
public fun Iterable<BigDecimal>.mean(): Double =
if (this is Collection) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,14 @@ package org.jetbrains.kotlinx.dataframe.util
* After each release, all messages should be reviewed and updated.
* Level.WARNING -> Level.ERROR
* Level.ERROR -> Remove
*
* Level.HIDDEN can remain as is but needs to be removed together with other deprecations in
* the same cycle.
*/

// region WARNING in 0.15, ERROR in 0.16

private const val MESSAGE_0_16 = "Will be removed in 0.16."
private const val MESSAGE_0_16 = "Will be ERROR in 0.16."

internal const val DF_READ_NO_CSV = "This function is deprecated and should be replaced with `readCSV`. $MESSAGE_0_16"
internal const val DF_READ_NO_CSV_REPLACE =
Expand Down Expand Up @@ -44,11 +47,20 @@ internal const val PARSER_OPTIONS = "This constructor is only here for binary co

internal const val PARSER_OPTIONS_COPY = "This function is only here for binary compatibility. $MESSAGE_0_16"

internal const val SEQUENCE_FLOAT_MEAN =
"`Sequence<Float>.mean()` is removed since it's already covered by other overloads. $MESSAGE_0_16"

internal const val INTERNAL_MEAN =
"`Iterable.mean(skipNA)` is removed since it's already covered by other overloads. $MESSAGE_0_16"

internal const val MEAN =
"`Iterable.mean()` is removed from the public API because it's outside the scope of DataFrame. You can still call `.mean()` on a column. For most types there's already `.average()` in stdlib. $MESSAGE_0_16"

// endregion

// region WARNING in 0.16, ERROR in 0.17

private const val MESSAGE_0_17 = "Will be removed in 0.17."
private const val MESSAGE_0_17 = "Will be ERROR in 0.17."

// endregion

Expand Down

0 comments on commit dc4687d

Please sign in to comment.