/** * A collection of helper functions for common utility tasks. */ object HelperFunctions { /** * Computes the total number of steps needed to process the given total volume. * * @param totalVolume the total amount that needs to be processed * @param volumePerStep the amount to process per step * @return the number of steps required to process the total volume */ fun calculateTotalSteps(totalVolume: Int, volumePerStep: Int) = totalVolume / volumePerStep + if (totalVolume % volumePerStep > 0) { 1 } else { 0 } /** * Prints a progress report to console showing current step, total steps, elapsed time, and estimated remaining time. * * @param step The current step number * @param of The total number of steps * @param dur The elapsed duration so far in milliseconds */ fun report(step: Int, of: Int, dur: Long) { val remaining = (dur / step) * (of - step) print("\rStep $step of $of (${prettyTimeString(dur)} complete\t|\t~${prettyTimeString(remaining)} remaining) ") } /** * Converts a duration in milliseconds to a human-readable string. * * @param durationMillis The duration to convert, in milliseconds * @return A string representation of the duration, in the format XhYmZs */ fun prettyTimeString(durationMillis: Long): String { if (durationMillis == 0L) { return "No time data yet" } val millisPerSecond = 1000L val millisPerMinute = 60L * millisPerSecond val millisPerHour = 60L * millisPerMinute return if (durationMillis > millisPerHour) { return "${durationMillis / millisPerHour}h${(durationMillis % millisPerHour) / millisPerMinute}m${(durationMillis % millisPerMinute) / millisPerSecond}s" } else if (durationMillis > millisPerMinute) { return "${(durationMillis % millisPerHour) / millisPerMinute}m${(durationMillis % millisPerMinute) / millisPerSecond}s" } else { "${(durationMillis % millisPerMinute) / millisPerSecond}s" } } }