Add more filters and heatmaps

This commit is contained in:
kageru 2019-11-26 13:01:29 +01:00
parent cd6bd4b488
commit f2a1a74bb8
6 changed files with 89 additions and 28 deletions

View File

@ -0,0 +1,26 @@
package moe.kageru.spektacles
open class Counter<T>(source: Iterable<T>) : Iterable<Map.Entry<T, Int>> {
val counts: Map<T, Int> = mutableMapOf<T, Int>().apply {
for (element in source) {
this[element] = this.getOrDefault(element, 0) + 1
}
}
override fun iterator(): Iterator<Map.Entry<T, Int>> {
return counts.entries.iterator()
}
override fun toString(): String {
return counts.entries.joinToString("\n") { "${it.key}: ${it.value}" }
}
}
class SortedCounter<T: Comparable<T>>(source: Iterable<T>): Counter<T>(source) {
override fun toString(): String {
return counts.entries.sortedBy { it.key }.joinToString("\n") { "${it.key}: ${it.value}" }
}
}
fun <T> Iterable<T>.toCounter(): Counter<T> = Counter(this)
fun <T: Comparable<T>> Iterable<T>.toSortedCounter(): SortedCounter<T> = SortedCounter(this)

View File

@ -0,0 +1,23 @@
package moe.kageru.spektacles
import java.time.Month
fun ParsedLines.filterUsers(vararg users: String): ParsedLines {
return this.filter { line -> line.user.exists { it in users } }
}
fun ParsedLines.filterModes(vararg modes: UserMode): ParsedLines {
return this.filter { line -> line.userMode in modes }
}
fun ParsedLines.filterYears(vararg years: Int): ParsedLines {
return this.filter { line -> line.time.year in years }
}
fun ParsedLines.filterMonths(vararg months: Month): ParsedLines {
return this.filter { line -> line.time.month in months }
}
fun ParsedLines.filterDays(vararg days: Int): ParsedLines {
return this.filter { line -> line.time.dayOfMonth in days }
}

View File

@ -8,4 +8,4 @@ object IoHandler {
.filter { !it.startsWith("****") }
}
typealias Lines = Sequence<String>
typealias Lines = Sequence<String>

View File

@ -6,7 +6,7 @@ import java.time.LocalDateTime
class ParsedLine(val time: LocalDateTime,
val user: Option<String>,
val userMode: Option<UserMode>,
val userMode: UserMode,
val message: String,
val isSystemMessage: Boolean,
private val originalMessage: String
@ -30,7 +30,7 @@ class ParsedLine(val time: LocalDateTime,
it.groups["second"]!!.value.toInt()
),
it.groups["author"]?.value.toOption(),
it.groups["mode"]?.value?.let { UserMode.values().first { mode -> mode.icon == it } }.toOption(),
it.groups["mode"]?.value?.let { UserMode.values().first { mode -> mode.icon == it } } ?: UserMode.NONE,
it.groups["message"]!!.value,
it.groups["author"] == null,
it.value
@ -44,5 +44,13 @@ enum class UserMode(val icon: String) {
BOT("&"),
OP("@"),
HOP("%"),
VOICE("+");
}
VOICE("+"),
NONE("")
}
typealias ParsedLines = Sequence<ParsedLine>
fun Lines.parse(): ParsedLines {
return map { ParsedLine.parse(it) }
.filterNotNull()
}

View File

@ -0,0 +1,15 @@
package moe.kageru.spektacles
import java.time.Month
fun ParsedLines.heatMapByHour(): SortedCounter<Int> = heatMapBy { it.time.hour }
fun ParsedLines.heatMapByMinute(): SortedCounter<Int> = heatMapBy { it.time.hour * 100 + it.time.minute }
fun ParsedLines.heatMapByMonth(): SortedCounter<Month> = heatMapBy { it.time.month }
private fun <T: Comparable<T>>ParsedLines.heatMapBy(op: (ParsedLine) -> T): SortedCounter<T> {
return this.map(op)
.asIterable()
.toSortedCounter()
}

View File

@ -1,32 +1,21 @@
package moe.kageru.spektacles
import java.time.Month
import kotlin.system.measureTimeMillis
fun main() {
val res = measureTimeMillis {
IoHandler.readFile("test.log")
.map { ParsedLine.parse(it) }
.filterNotNull()
.filter { line -> line.user.exists { it == "kageru_" } }
.flatMap { it.message.split(' ').asSequence() }
//.flatMap { it.message.split(' ').k() }
//.toCounter()
//.counts["selphyDango"]
val time = measureTimeMillis {
spektacle()
}
println(res)
println("Time spent: $time ms")
}
class Counter<T>(source: Iterable<T>) : Iterable<T> {
val counts = mutableMapOf<T, Int>().apply {
for (element in source) {
this[element] = this.getOrDefault(element, 0) + 1
}
}
override fun iterator(): Iterator<T> {
return counts.keys.iterator()
}
fun spektacle() {
IoHandler.readFile("test.log")
.parse()
.filterUsers("kageru_")
.filterModes(UserMode.OP)
.filterMonths(Month.APRIL)
.heatMapByHour()
.let(::println)
}
fun <T> Iterable<T>.toCounter(): Counter<T> = Counter(this)