0
\$\begingroup\$

I am working on a program that the user can use to track the parameters of his body (such as weight, waist size). I have a code that builds a chart based on these data. I would like to hear criticism on my code. What I don't like :

  1. MeasurementCHartHelperю - It seems to me that this is not a very good name.
  2. Also I do not like that I mixed business logic and code for draw chart. But I do not know how it would be better to separate, what is the best way to name the classes
  3. Measurement.kt. I want to know if it is correct to have my extension functions there

MeasurementChartHelper.kt

class MeasurementChartHelper{
private val now = Date(LocalDateTime.now())

fun getChartData(measurements: List<Measurement>,timeInterval: TimeInterval): LineChartData? {
    val points = getChartPoints(measurements,timeInterval)
    if(points.isNotEmpty()) {
        val seriesData = listOf(LineChartData.SeriesData("", points, Green,gradientFill = true))
        return LineChartData(seriesData,autoYLabels = true,horizontalLines = true)
    }
    return null
}

private fun getChartPoints(measurements: List<Measurement>,timeInterval: TimeInterval): List<LineChartData.SeriesData.Point> {
    return getMeasurementValuesForTimeInterval(measurements.sortByDate(),timeInterval).map { LineChartData.SeriesData.Point(it.key,it.value.toFloat()) }
}

private fun getMeasurementValuesForTimeInterval(measurements: List<Measurement>,timeInterval: TimeInterval): Map<Int, Double> {
    return measurements
        .groupBy { getMeasurementTimeIntervalNumber(it, timeInterval) }
        .filterKeys { it != -1 }
        .mapValues { it.value.map { measurement -> measurement.value }.average() }
}

private fun getMeasurementTimeIntervalNumber(measurement: Measurement, timeInterval: TimeInterval): Int {
    val timeDifference = now - measurement.date
    if(timeDifference.epochMillis >= 0) {
        val daysDifference = (timeDifference.epochMillis / (TimeUnit.DAYS.toSeconds(1) * 1000)).toInt()
        if (daysDifference <= timeInterval.days && daysDifference >= 0)
            return timeInterval.days - (daysDifference / timeInterval.daysInInterval)
    }
    return -1
}

}

Measurement.kt

@Entity
class Measurement(
    @PrimaryKey(autoGenerate = true) var id: Int = 0,
    var measurementType: MeasurementType,
    var value: Float,
    var date: Date
)

fun List<Measurement>.byMeasurementType(): Map<MeasurementType, List<Measurement>> {
    return this.sortByDate().groupBy(Measurement::measurementType)
}

fun List<Measurement>.sortByDate(): List<Measurement> {
    return this.sortedBy { measurement -> measurement.date.epochMillis }
}

MeasurementType,kt

enum class MeasurementType(
    val measurement: String,
    @StringRes val measurementDescription: Int,
    @StringRes val measurementFullDescription: Int
) {
    Weight(
        "Weight",
        R.string.weight_measurement_description,
        R.string.weight_measurement_full_description
    ),
    CaloricIntake(
        "CaloricIntake",
        R.string.weight_caloric_intake_description,
        R.string.weight_caloric_intake_full_description
    ),
    BodyFat(
        "BodyFat",
        R.string.weight_body_fat_description,
        R.string.weight_body_fat_full_description
    ),
    Waist(
        "Waist",
        R.string.waist_description,
        R.string.waist_full_description
    ),
    Chest(
        "Chest",
        R.string.chest_description,
        R.string.chest_full_description
    ),
    Arm(
        "Arm",
        R.string.arm_description,
        R.string.arm_full_description
    );

    companion object {
        fun getMeasurementType(measurementName: String): MeasurementType {
            try {
                return values().find { it.measurement == measurementName }!!
            } catch (ex: Exception) {
                throw EnumConstantNotPresentException(MeasurementType::class.java, measurementName)
            }
        }

        fun getAllMeasurements(): List<MeasurementType> {
            return values().toList()
        }
    }
}

TimeInterval.kt

enum class TimeInterval(val id: Int, val days: Int, val daysInInterval: Int) {
    LastWeek(0, 7, 1),
    LastMonth(1, 30, 3),
    LastTwoMonths(2, 60, 6),
    LastYear(3, 365, 30),
    AllTime(4, 1000000, 1);

    companion object {
        fun findTimeIntervalById(id: Int): TimeInterval {
            return values().firstOrNull { it.id == id }
                ?: error("Cant find TimeInterval with id - $id")
        }
    }
}
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.