From 5800a71a754c4e1faf9727c2affc5a7d05229d1c Mon Sep 17 00:00:00 2001 From: foralost Date: Sun, 18 Feb 2024 15:14:39 +0100 Subject: [PATCH 1/3] Adding additional columns to header --- .../java/org/isoron/uhabits/core/models/HabitList.kt | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/uhabits-core/src/jvmMain/java/org/isoron/uhabits/core/models/HabitList.kt b/uhabits-core/src/jvmMain/java/org/isoron/uhabits/core/models/HabitList.kt index 74ee0a700..56d9ef168 100644 --- a/uhabits-core/src/jvmMain/java/org/isoron/uhabits/core/models/HabitList.kt +++ b/uhabits-core/src/jvmMain/java/org/isoron/uhabits/core/models/HabitList.kt @@ -186,7 +186,10 @@ abstract class HabitList : Iterable { "Description", "NumRepetitions", "Interval", - "Color" + "Color", + "Unit", + "Target Type", + "Target Value" ) val csv = CSVWriter(out) csv.writeNext(header, false) @@ -199,7 +202,10 @@ abstract class HabitList : Iterable { habit.description, numerator.toString(), denominator.toString(), - habit.color.toCsvColor() + habit.color.toCsvColor(), + habit.unit, + habit.targetType.name, + habit.targetValue.toString() ) csv.writeNext(cols, false) } From 87f51d854ae111d4e5515dfe46dbb7d742bf695b Mon Sep 17 00:00:00 2001 From: foralost Date: Sun, 18 Feb 2024 15:33:31 +0100 Subject: [PATCH 2/3] Names for extra value types and added comma seperator --- .../uhabits/core/io/HabitsCSVExporter.kt | 65 +++++++++++++++++-- 1 file changed, 59 insertions(+), 6 deletions(-) diff --git a/uhabits-core/src/jvmMain/java/org/isoron/uhabits/core/io/HabitsCSVExporter.kt b/uhabits-core/src/jvmMain/java/org/isoron/uhabits/core/io/HabitsCSVExporter.kt index 43dad6954..1748d4bca 100644 --- a/uhabits-core/src/jvmMain/java/org/isoron/uhabits/core/io/HabitsCSVExporter.kt +++ b/uhabits-core/src/jvmMain/java/org/isoron/uhabits/core/io/HabitsCSVExporter.kt @@ -22,6 +22,7 @@ import org.isoron.uhabits.core.models.Entry import org.isoron.uhabits.core.models.EntryList import org.isoron.uhabits.core.models.Habit import org.isoron.uhabits.core.models.HabitList +import org.isoron.uhabits.core.models.HabitType import org.isoron.uhabits.core.models.Score import org.isoron.uhabits.core.models.Timestamp import org.isoron.uhabits.core.utils.DateFormats @@ -95,7 +96,7 @@ class HabitsCSVExporter( File(exportDirName + habitDirName).mkdirs() generatedDirs.add(habitDirName) writeScores(habitDirName, h) - writeEntries(habitDirName, h.computedEntries) + writeEntries(habitDirName, h.computedEntries, h.type) } writeMultipleHabits() } @@ -117,18 +118,65 @@ class HabitsCSVExporter( out.close() } - private fun writeEntries(habitDirName: String, entries: EntryList) { + private fun getEntryTypeNameFromValue(habitType: HabitType, value: Int): String { + // I mean the code below follows pattern + // If there is something in Kotlin that could do: + // if value <= 3: Entry.Companion.get(value).toString(), that would be nice + when (habitType) { + HabitType.NUMERICAL -> { + return when (value) { + Entry.UNKNOWN -> { "UNKNOWN" } + else -> { "" } + } + } + HabitType.YES_NO -> { + return when (value) { + Entry.SKIP -> { "SKIP" } + Entry.YES_AUTO -> { "YES_AUTO" } + Entry.NO -> { "NO" } + Entry.UNKNOWN -> { "UNKNOWN" } + Entry.YES_MANUAL -> { "YES_MANUAL" } + else -> { "" } + } + } + } + } + + private fun writeEntries(habitDirName: String, entries: EntryList, habitType: HabitType) { val filename = habitDirName + "Checkmarks.csv" val out = FileWriter(exportDirName + filename) generatedFilenames.add(filename) val dateFormat = DateFormats.getCSVDateFormat() for ((timestamp, value) in entries.getKnown()) { val date = dateFormat.format(timestamp.toJavaDate()) - out.write(String.format(Locale.US, "%s,%d\n", date, value)) + out.write(String.format(Locale.US, "%s,%s\n", date, getEntryValueString(habitType, value))) } out.close() } + private fun getEntryValueString(habitType: HabitType, value: Int): String { + when (habitType) { + HabitType.NUMERICAL -> { + val outputtedValue = getEntryTypeNameFromValue(habitType, value) + if (outputtedValue.isEmpty()) { + // Not a stringable value + return String.format(Locale.US, "%.3f", value.toDouble() / 1000.0) + } + + return outputtedValue + } + + HabitType.YES_NO -> { + val outputtedValue = getEntryTypeNameFromValue(habitType, value) + if (outputtedValue.isEmpty()) { + throw IllegalStateException() // YES_NO habits should have named entries + } + + return outputtedValue + } + } + } + /** * Writes a scores file and a checkmarks file containing scores and checkmarks of every habit. * The first column corresponds to the date. Subsequent columns correspond to a habit. @@ -150,8 +198,9 @@ class HabitsCSVExporter( val timeframe = getTimeframe() val oldest = timeframe[0] val newest = DateUtils.getTodayWithOffset() - val checkmarks: MutableList> = ArrayList() - val scores: MutableList> = ArrayList() + val checkmarks: ArrayList> = ArrayList() + val scores: ArrayList> = ArrayList() + for (habit in selectedHabits) { checkmarks.add(ArrayList(habit.computedEntries.getByInterval(oldest, newest))) scores.add(ArrayList(habit.scores.getByInterval(oldest, newest))) @@ -167,7 +216,11 @@ class HabitsCSVExporter( checksWriter.write(sb.toString()) scoresWriter.write(sb.toString()) for (j in selectedHabits.indices) { - checksWriter.write(checkmarks[j][i].value.toString()) + val check = String.format( + "%s", + getEntryValueString(selectedHabits[j].type, checkmarks[j][i].value) + ) + checksWriter.write(check) checksWriter.write(delimiter) val score = String.format(Locale.US, "%.4f", scores[j][i].value) scoresWriter.write(score) From 5b291b9a7af3b8a24fd2fea90921405ad80d813b Mon Sep 17 00:00:00 2001 From: foralost Date: Sun, 25 Feb 2024 13:46:37 +0100 Subject: [PATCH 3/3] Fixing CSVExport, CSVWrite tests --- .../002 Wake up early/Checkmarks.csv | 20 +++++++++---------- .../assets/test/csv_export/Checkmarks.csv | 20 +++++++++---------- .../assets/test/csv_export/Habits.csv | 6 +++--- .../uhabits/core/io/HabitsCSVExporterTest.kt | 3 +++ .../uhabits/core/models/HabitListTest.kt | 6 +++--- 5 files changed, 29 insertions(+), 26 deletions(-) diff --git a/uhabits-core/assets/test/csv_export/002 Wake up early/Checkmarks.csv b/uhabits-core/assets/test/csv_export/002 Wake up early/Checkmarks.csv index 89f788f68..b871c4c35 100644 --- a/uhabits-core/assets/test/csv_export/002 Wake up early/Checkmarks.csv +++ b/uhabits-core/assets/test/csv_export/002 Wake up early/Checkmarks.csv @@ -1,10 +1,10 @@ -2015-01-25,2 -2015-01-24,0 -2015-01-23,1 -2015-01-22,2 -2015-01-21,2 -2015-01-20,2 -2015-01-19,1 -2015-01-18,1 -2015-01-17,2 -2015-01-16,2 +2015-01-25,YES_MANUAL +2015-01-24,NO +2015-01-23,YES_AUTO +2015-01-22,YES_MANUAL +2015-01-21,YES_MANUAL +2015-01-20,YES_MANUAL +2015-01-19,YES_AUTO +2015-01-18,YES_AUTO +2015-01-17,YES_MANUAL +2015-01-16,YES_MANUAL diff --git a/uhabits-core/assets/test/csv_export/Checkmarks.csv b/uhabits-core/assets/test/csv_export/Checkmarks.csv index c0788570b..f03bece31 100644 --- a/uhabits-core/assets/test/csv_export/Checkmarks.csv +++ b/uhabits-core/assets/test/csv_export/Checkmarks.csv @@ -1,11 +1,11 @@ Date,Meditate,Wake up early, -2015-01-25,-1,2, -2015-01-24,-1,0, -2015-01-23,-1,1, -2015-01-22,-1,2, -2015-01-21,-1,2, -2015-01-20,-1,2, -2015-01-19,-1,1, -2015-01-18,-1,1, -2015-01-17,-1,2, -2015-01-16,-1,2, +2015-01-25,UNKNOWN,YES_MANUAL, +2015-01-24,UNKNOWN,NO, +2015-01-23,UNKNOWN,YES_AUTO, +2015-01-22,UNKNOWN,YES_MANUAL, +2015-01-21,UNKNOWN,YES_MANUAL, +2015-01-20,UNKNOWN,YES_MANUAL, +2015-01-19,UNKNOWN,YES_AUTO, +2015-01-18,UNKNOWN,YES_AUTO, +2015-01-17,UNKNOWN,YES_MANUAL, +2015-01-16,UNKNOWN,YES_MANUAL, diff --git a/uhabits-core/assets/test/csv_export/Habits.csv b/uhabits-core/assets/test/csv_export/Habits.csv index 672189f33..5770942d6 100644 --- a/uhabits-core/assets/test/csv_export/Habits.csv +++ b/uhabits-core/assets/test/csv_export/Habits.csv @@ -1,3 +1,3 @@ -Position,Name,Question,Description,NumRepetitions,Interval,Color -001,Meditate,Did you meditate this morning?,,1,1,#FF8F00 -002,Wake up early,Did you wake up before 6am?,,2,3,#00897B +Position,Name,Question,Description,NumRepetitions,Interval,Color,Unit,Target Type,Target Value +001,Meditate,Did you meditate this morning?,,1,1,#FF8F00,,AT_LEAST,0.0 +002,Wake up early,Did you wake up before 6am?,,2,3,#00897B,,AT_LEAST,0.0 diff --git a/uhabits-core/src/jvmTest/java/org/isoron/uhabits/core/io/HabitsCSVExporterTest.kt b/uhabits-core/src/jvmTest/java/org/isoron/uhabits/core/io/HabitsCSVExporterTest.kt index bbe069be8..15bc959c7 100644 --- a/uhabits-core/src/jvmTest/java/org/isoron/uhabits/core/io/HabitsCSVExporterTest.kt +++ b/uhabits-core/src/jvmTest/java/org/isoron/uhabits/core/io/HabitsCSVExporterTest.kt @@ -112,6 +112,9 @@ class HabitsCSVExporterTest : BaseUnitTest() { file.deleteOnExit() copyAssetToFile(assetFilename, file) + println(file.path) + println(assetFilename) + assertTrue( FileUtils.contentEquals( file, diff --git a/uhabits-core/src/jvmTest/java/org/isoron/uhabits/core/models/HabitListTest.kt b/uhabits-core/src/jvmTest/java/org/isoron/uhabits/core/models/HabitListTest.kt index f4cecda6f..c62249f37 100644 --- a/uhabits-core/src/jvmTest/java/org/isoron/uhabits/core/models/HabitListTest.kt +++ b/uhabits-core/src/jvmTest/java/org/isoron/uhabits/core/models/HabitListTest.kt @@ -206,9 +206,9 @@ class HabitListTest : BaseUnitTest() { list.add(h2) val expectedCSV = """ - Position,Name,Question,Description,NumRepetitions,Interval,Color - 001,Meditate,Did you meditate this morning?,this is a test description,1,1,#FF8F00 - 002,Wake up early,Did you wake up before 6am?,,2,3,#AFB42B + Position,Name,Question,Description,NumRepetitions,Interval,Color,Unit,Target Type,Target Value + 001,Meditate,Did you meditate this morning?,this is a test description,1,1,#FF8F00,,AT_LEAST,0.0 + 002,Wake up early,Did you wake up before 6am?,,2,3,#AFB42B,,AT_LEAST,0.0 """.trimIndent() val writer = StringWriter()