feature/top10
Laurent 7 years ago
parent 353a69824d
commit 153e561705
  1. 2
      app/build.gradle
  2. 4
      app/src/main/java/net/pokeranalytics/android/PokerAnalyticsApplication.kt
  3. 36
      app/src/main/java/net/pokeranalytics/android/calculus/Calculator.kt
  4. 25
      app/src/main/java/net/pokeranalytics/android/calculus/Report.kt
  5. 2
      app/src/main/java/net/pokeranalytics/android/calculus/Stat.kt
  6. 10
      app/src/main/java/net/pokeranalytics/android/calculus/bankroll/BankrollCalculator.kt
  7. 15
      app/src/main/java/net/pokeranalytics/android/calculus/bankroll/BankrollReport.kt
  8. 194
      app/src/main/java/net/pokeranalytics/android/model/Criteria.kt
  9. 10
      app/src/main/java/net/pokeranalytics/android/model/filter/Filterable.kt
  10. 63
      app/src/main/java/net/pokeranalytics/android/model/filter/Query.kt
  11. 18
      app/src/main/java/net/pokeranalytics/android/model/filter/QueryCondition.kt
  12. 3
      app/src/main/java/net/pokeranalytics/android/model/migrations/Patcher.kt
  13. 5
      app/src/main/java/net/pokeranalytics/android/model/realm/Filter.kt
  14. 33
      app/src/main/java/net/pokeranalytics/android/ui/fragment/CalendarDetailsFragment.kt
  15. 21
      app/src/main/java/net/pokeranalytics/android/ui/fragment/CalendarFragment.kt
  16. 3
      app/src/main/java/net/pokeranalytics/android/ui/fragment/ReportsFragment.kt
  17. 4
      app/src/main/java/net/pokeranalytics/android/ui/fragment/StatisticDetailsFragment.kt
  18. 8
      app/src/main/java/net/pokeranalytics/android/ui/fragment/StatisticsFragment.kt
  19. 34
      app/src/main/java/net/pokeranalytics/android/ui/view/rowrepresentable/FilterSectionRow.kt

@ -28,7 +28,7 @@ android {
applicationId "net.pokeranalytics.android"
minSdkVersion 23
targetSdkVersion 28
versionCode 18
versionCode 19
versionName "1.0"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
}

@ -52,7 +52,7 @@ class PokerAnalyticsApplication : Application() {
if (BuildConfig.DEBUG) {
Timber.d("UserPreferences.defaultCurrency: ${UserDefaults.currency.symbol}")
// this.createFakeSessions()
this.createFakeSessions()
}
Patcher.patchBreaks()
@ -69,7 +69,7 @@ class PokerAnalyticsApplication : Application() {
if (sessionsCount < 1) {
GlobalScope.launch {
FakeDataManager.createFakeSessions(2000)
FakeDataManager.createFakeSessions(200)
}
}

@ -5,12 +5,10 @@ import net.pokeranalytics.android.calculus.Stat.*
import net.pokeranalytics.android.model.Criteria
import net.pokeranalytics.android.model.combined
import net.pokeranalytics.android.model.extensions.hourlyDuration
import net.pokeranalytics.android.model.filter.QueryCondition
import net.pokeranalytics.android.model.filter.Query
import net.pokeranalytics.android.model.filter.filter
import net.pokeranalytics.android.model.filter.name
import net.pokeranalytics.android.model.realm.ComputableResult
import net.pokeranalytics.android.model.realm.SessionSet
import net.pokeranalytics.android.model.upToNow
import net.pokeranalytics.android.util.extensions.startOfDay
import timber.log.Timber
import java.util.*
@ -121,34 +119,32 @@ class Calculator {
return when (aggregationType) {
AggregationType.SESSION, AggregationType.DURATION -> this.computeGroups(realm, listOf(group), options)
AggregationType.MONTH, AggregationType.YEAR -> {
val criteria: List<Criteria> = aggregationType.criterias
this.computeStatsWithComparators(realm, criteria, group.conditions, options)
this.computeStatsWithCriterias(realm, aggregationType.criterias, group.query, options)
}
}
}
fun computeStatsWithComparators(
realm: Realm,
criteria: List<Criteria> = listOf(),
conditions: List<QueryCondition> = listOf(),
options: Options = Options()
fun computeStatsWithCriterias(
realm: Realm,
criterias: List<Criteria> = listOf(),
query: Query = Query(),
options: Options = Options()
): Report {
val computableGroups: MutableList<ComputableGroup> = mutableListOf()
criteria.combined().upToNow().forEach { comparatorConditions ->
criterias.combined().forEach { comparatorQuery ->
val allConditions = mutableListOf<QueryCondition>()
allConditions.addAll(conditions)
allConditions.addAll(comparatorConditions)
comparatorQuery.merge(query)
val group = ComputableGroup(allConditions.name(), allConditions)
val group = ComputableGroup(comparatorQuery)
computableGroups.add(group)
}
if (computableGroups.size == 0) {
val group = ComputableGroup(conditions.name(), conditions)
val group = ComputableGroup(query)
computableGroups.add(group)
}
@ -373,7 +369,7 @@ class Calculator {
sessionSets.forEach { sessionSet ->
tIndex++
val setStats = SSStats(sessionSet, computableGroup.conditions)
val setStats = SSStats(sessionSet, computableGroup.query)
tRatedNetSum += setStats.ratedNet
tBBSum += setStats.bbSum
@ -499,7 +495,7 @@ class Calculator {
if (gHourlyDuration != null) {
var hourlyStdSum = 0.0
sessionSets.forEach { set ->
val ssStats = SSStats(set, computableGroup.conditions)
val ssStats = SSStats(set, computableGroup.query)
val sHourlyRate = ssStats.hourlyRate
hourlyStdSum += Math.pow(sHourlyRate - hourlyRate, 2.0)
}
@ -517,7 +513,7 @@ class Calculator {
}
class SSStats(sessionSet: SessionSet, conditions: List<QueryCondition>) { // Session Set Stats
class SSStats(sessionSet: SessionSet, query: Query) { // Session Set Stats
var hourlyDuration: Double = 0.0
var estimatedHands: Double = 0.0
@ -535,7 +531,7 @@ class SSStats(sessionSet: SessionSet, conditions: List<QueryCondition>) { // Ses
this.initStatsWithSet(sessionSet)
} else { // dynamically filter and compute subset
val setSessions = sessionSet.sessions!!
val filteredSessions = setSessions.filter(conditions)
val filteredSessions = setSessions.filter(query)
if (setSessions.size == filteredSessions.size) {
this.initStatsWithSet(sessionSet)
} else {

@ -5,6 +5,7 @@ import com.github.mikephil.charting.data.*
import io.realm.Realm
import io.realm.RealmResults
import net.pokeranalytics.android.R
import net.pokeranalytics.android.model.filter.Query
import net.pokeranalytics.android.model.filter.QueryCondition
import net.pokeranalytics.android.model.interfaces.Timed
import net.pokeranalytics.android.model.realm.ComputableResult
@ -94,17 +95,29 @@ class Report(var options: Calculator.Options) {
/**
* A sessionGroup of computable items identified by a name
*/
class ComputableGroup(name: String = "", conditions: List<QueryCondition> = listOf(), stats: List<Stat>? = null) {
class ComputableGroup(query: Query, stats: List<Stat>? = null) {
// constructor(query: Query, stats: List<Stat>? = null) : this(query.name, query.conditions)
//
// private constructor(name: String = "", conditions: List<QueryCondition> = listOf(), stats: List<Stat>? = null)
var query: Query = query
/**
* The display name of the group
*/
var name: String = name
var name: String = ""
get() {
return this.query.name
}
/**
* A list of conditions to get
* A list of _conditions to get
*/
var conditions: List<QueryCondition> = conditions
var conditions: List<QueryCondition> = listOf()
get() {
return this.query.conditions
}
/**
* The list of endedSessions to compute
@ -124,7 +137,7 @@ class ComputableGroup(name: String = "", conditions: List<QueryCondition> = list
}
val sortedField = if (sorted) "session.startDate" else null
val computables = Filter.queryOn<ComputableResult>(realm, this.conditions, sortedField)
val computables = Filter.queryOn<ComputableResult>(realm, this.query, sortedField)
this._computables = computables
return computables
}
@ -146,7 +159,7 @@ class ComputableGroup(name: String = "", conditions: List<QueryCondition> = list
}
val sortedField = if (sorted) SessionSet.Field.START_DATE.identifier else null
val sets = Filter.queryOn<SessionSet>(realm, this.conditions, sortedField)
val sets = Filter.queryOn<SessionSet>(realm, this.query, sortedField)
this._sessionSets = sets
return sets
}

@ -50,7 +50,7 @@ enum class AggregationType {
val criterias: List<Criteria>
get() {
return when (this) {
MONTH -> listOf(Criteria.Years, Criteria.MonthsOfYear)
MONTH -> listOf(Criteria.AllMonthsUpToNow)
YEAR -> listOf(Criteria.Years)
else -> listOf()
}

@ -32,21 +32,21 @@ class BankrollCalculator {
report.transactionsNet = transactionNet
report.initial = initialValue
val queryConditions = setup.queryConditions
val transactions = Filter.queryOn<Transaction>(realm, queryConditions)
val query = setup.query
val transactions = Filter.queryOn<Transaction>(realm, query)
report.addDatedItems(transactions)
transactions.forEach {
report.addTransaction(it)
}
val sessions = Filter.queryOn<Session>(realm, queryConditions)
val sessions = Filter.queryOn<Session>(realm, query)
report.addDatedItems(sessions)
if (setup.virtualBankroll) {
val options = Calculator.Options(stats = listOf(Stat.NET_RESULT, Stat.HOURLY_RATE, Stat.STANDARD_DEVIATION_HOURLY))
val group = ComputableGroup(conditions = queryConditions)
val group = ComputableGroup(query)
val result = Calculator.compute(realm, group, options)
result.computedStat(Stat.NET_RESULT)?.let {
report.netResult = it.value
@ -55,7 +55,7 @@ class BankrollCalculator {
} else {
val results = Filter.queryOn<Result>(realm, queryConditions)
val results = Filter.queryOn<Result>(realm, query)
report.netResult = results.sum("net").toDouble()
}

@ -3,6 +3,7 @@ package net.pokeranalytics.android.calculus.bankroll
import android.content.Context
import com.github.mikephil.charting.data.Entry
import com.github.mikephil.charting.data.LineDataSet
import net.pokeranalytics.android.model.filter.Query
import net.pokeranalytics.android.model.filter.QueryCondition
import net.pokeranalytics.android.model.interfaces.DatedValue
import net.pokeranalytics.android.model.realm.Bankroll
@ -153,25 +154,25 @@ class BankrollReportSetup(val bankroll: Bankroll? = null, val from: Date? = null
return this.bankroll == null
}
val queryConditions: List<QueryCondition>
val query: Query
get() {
val conditions = mutableListOf<QueryCondition>()
val query = Query()
this.bankroll?.let {
val bankrollCondition = QueryCondition.AnyBankroll(bankroll)
conditions.add(bankrollCondition)
query.add(bankrollCondition)
}
this.from?.let {
val fromCondition = QueryCondition.StartedFromDate()
fromCondition.singleValue = it
conditions.add(fromCondition)
query.add(fromCondition)
}
this.to?.let {
val toCondition = QueryCondition.StartedToDate()
toCondition.singleValue = it
conditions.add(toCondition)
query.add(toCondition)
}
return conditions
return query
}
}

@ -4,118 +4,102 @@ import io.realm.Realm
import io.realm.Sort
import io.realm.kotlin.where
import net.pokeranalytics.android.exceptions.PokerAnalyticsException
import net.pokeranalytics.android.model.Criteria.Bankrolls.comparison
import net.pokeranalytics.android.model.Criteria.Blinds.comparison
import net.pokeranalytics.android.model.Criteria.Games.comparison
import net.pokeranalytics.android.model.Criteria.Limits.comparison
import net.pokeranalytics.android.model.Criteria.Locations.comparison
import net.pokeranalytics.android.model.Criteria.TableSizes.comparison
import net.pokeranalytics.android.model.Criteria.TournamentFeatures.comparison
import net.pokeranalytics.android.model.Criteria.TournamentFees.comparison
import net.pokeranalytics.android.model.Criteria.TournamentNames.comparison
import net.pokeranalytics.android.model.Criteria.TournamentTypes.comparison
import net.pokeranalytics.android.model.filter.Query
import net.pokeranalytics.android.model.filter.QueryCondition
import net.pokeranalytics.android.model.interfaces.NameManageable
import net.pokeranalytics.android.model.realm.*
import java.util.*
import kotlin.collections.ArrayList
fun List<Criteria>.combined(): List<List<QueryCondition>> {
val comparatorList = ArrayList<List<QueryCondition>>()
this.forEach {
comparatorList.add(it.queryConditions)
fun List<Criteria>.combined(): List<Query> {
val comparatorList = ArrayList<List<Query>>()
this.forEach { criteria ->
comparatorList.add(criteria.queries)
}
return getCombinations(comparatorList)
}
fun List<List<QueryCondition>>.upToNow(): List<List<QueryCondition>> {
val calendar = Calendar.getInstance()
calendar.time = Date()
val currentYear = calendar.get(Calendar.YEAR)
val currentMonth = calendar.get(Calendar.MONTH)
fun getCombinations(queries: List<List<Query>>): List<Query> {
val realm = Realm.getDefaultInstance()
val firstSession = realm.where<Session>().sort("year", Sort.ASCENDING).findFirst()
realm.close()
if (queries.size == 0) { return listOf() }
val firstYear = firstSession?.year ?: currentYear
val firstMonth = firstSession?.month ?: currentMonth
val mutableQueries = queries.toMutableList()
var combinations = mutableQueries.removeAt(0)
val toRemove = this.filter { list ->
list.any { it is QueryCondition.AnyYear && it.listOfValues.first() == currentYear }
}.filter { list ->
list.any {
it is QueryCondition.AnyMonthOfYear && it.listOfValues.first() > currentMonth
}
}
val toRemoveBefore = this.filter { list ->
list.any { it is QueryCondition.AnyYear && it.listOfValues.first() == firstYear }
}.filter { list ->
list.any {
it is QueryCondition.AnyMonthOfYear && it.listOfValues.first() < firstMonth
}
}
for (queryList in mutableQueries) {
return this.filter{ list ->
var keep = true
toRemove.forEach {
if (list.containsAll(it)) {
keep = false
}
}
firstSession?.let {
toRemoveBefore.forEach {
if (list.containsAll(it)) {
keep = false
}
}
}
keep
}
}
fun <T> getCombinations(lists: List<List<T>>): List<List<T>> {
var combinations: LinkedHashSet<List<T>> = LinkedHashSet()
var newCombinations: LinkedHashSet<List<T>>
var index = 0
// extract each of the integers in the first list
// and add each to ints as a new list
if (lists.isNotEmpty()) {
for (i in lists[0]) {
val newList = ArrayList<T>()
newList.add(i)
combinations.add(newList)
}
index++
}
while (index < lists.size) {
val nextList = lists[index]
newCombinations = LinkedHashSet()
for (first in combinations) {
for (second in nextList) {
val newList = ArrayList<T>()
newList.addAll(first)
newList.add(second)
newCombinations.add(newList)
val newCombinations = mutableListOf<Query>()
combinations.forEach { combinedQuery ->
queryList.forEach { queryToAdd ->
val nq = Query().merge(combinedQuery).merge(queryToAdd)
newCombinations.add(nq)
}
}
combinations = newCombinations
index++
}
return combinations.toList()
return combinations
}
//fun getCombinations(lists: List<Query>): List<Query> {
// var combinations: LinkedHashSet<Query> = LinkedHashSet()
// var newCombinations: LinkedHashSet<Query>
//
// var index = 0
//
// // extract each of the integers in the first list
// // and add each to ints as a new list
// if (lists.isNotEmpty()) {
// for (i in lists[0]) {
// val newList = ArrayList<T>()
// newList.add(i)
// combinations.add(newList)
// }
// index++
// }
// while (index < lists.size) {
// val nextList = lists[index]
// newCombinations = LinkedHashSet()
// for (first in combinations) {
// for (second in nextList) {
// val newList = ArrayList<T>()
// newList.addAll(first)
// newList.add(second)
// newCombinations.add(newList)
// }
// }
// combinations = newCombinations
//
// index++
// }
//
// return combinations.toList()
//}
sealed class Criteria {
abstract class RealmCriteria : Criteria() {
inline fun <reified T: NameManageable> comparison(): List<QueryCondition> {
inline fun <reified T: NameManageable> comparison(): List<Query> {
return compare<QueryCondition.QueryDataCondition<NameManageable>, T>()
.sorted()
// .sorted()
}
}
abstract class SimpleCriteria(private val conditions:List<QueryCondition>): Criteria() {
fun comparison(): List<QueryCondition> {
return conditions
fun comparison(): List<Query> {
return conditions.map { Query(it) }
}
}
abstract class ListCriteria : Criteria() {
inline fun <reified T:QueryCondition.ListOfValues<S>, reified S:Comparable<S>> comparison(): List<QueryCondition> {
inline fun <reified T : QueryCondition.ListOfValues<S>, reified S : Comparable<S>> comparison(): List<Query> {
QueryCondition.distinct<Session, T, S>()?.let {
val values = it.mapNotNull { session ->
when (this) {
@ -127,9 +111,9 @@ sealed class Criteria {
else -> null
}
}.distinct()
return compareList<T, S>(values = values).sorted()
return compareList<T, S>(values = values)//.sorted()
}
return listOf<T>()
return listOf()
}
}
@ -154,7 +138,7 @@ sealed class Criteria {
object Cash: SimpleCriteria(listOf(QueryCondition.IsCash))
object Tournament: SimpleCriteria(listOf(QueryCondition.IsTournament))
val predicates: List<List<QueryCondition>>
val queries: List<Query>
get() {
return when (this) {
is AllMonthsUpToNow -> {
@ -163,7 +147,7 @@ sealed class Criteria {
val lastSession = realm.where<Session>().sort("startDate", Sort.DESCENDING).findFirst()
realm.close()
val years: ArrayList<List<QueryCondition>> = arrayListOf()
val years: ArrayList<Query> = arrayListOf()
val firstYear = firstSession?.year ?: return years
val firstMonth = firstSession.month ?: return years
@ -182,17 +166,19 @@ sealed class Criteria {
}
val currentMonth = QueryCondition.AnyMonthOfYear(month)
val currentList = listOf<QueryCondition>(currentYear, currentMonth)
years.add(currentList)
val query = Query(currentYear, currentMonth)
years.add(query)
}
}
years
}
else -> listOf(listOf())
else -> {
return this.queryConditions
}
}
}
val queryConditions: List<QueryCondition>
val queryConditions: List<Query>
get() {
return when (this) {
is Bankrolls -> comparison<Bankroll>()
@ -206,20 +192,21 @@ sealed class Criteria {
is TableSizes -> comparison<QueryCondition.AnyTableSize, Int>()
is TournamentFees -> comparison<QueryCondition.TournamentFee, Double >()
is Years -> {
val years = arrayListOf<QueryCondition.AnyYear>()
val years = arrayListOf<Query>()
val realm = Realm.getDefaultInstance()
val lastSession = realm.where<Session>().sort("startDate", Sort.DESCENDING).findFirst()
val yearNow = lastSession?.year ?: return years
realm.where<Session>().sort("year", Sort.ASCENDING).findFirst()?.year?.let {
for (index in 0..(yearNow - it)) {
years.add(QueryCondition.AnyYear().apply {
val yearCondition = QueryCondition.AnyYear().apply {
listOfValues = arrayListOf(yearNow - index)
})
}
years.add(Query(yearCondition))
}
}
realm.close()
years.sorted()
years//.sorted()
}
is Blinds -> comparison<QueryCondition.AnyBlind, String >()
else -> throw PokerAnalyticsException.QueryTypeUnhandled
@ -227,24 +214,27 @@ sealed class Criteria {
}
companion object {
inline fun < reified S : QueryCondition.QueryDataCondition<NameManageable >, reified T : NameManageable > compare(): List<S> {
val objects = arrayListOf<S>()
inline fun <reified S : QueryCondition.QueryDataCondition<NameManageable >, reified T : NameManageable> compare(): List<Query> {
val objects = mutableListOf<Query>()
val realm = Realm.getDefaultInstance()
realm.where<T>().findAll().forEach {
objects.add((QueryCondition.getInstance<T>() as S).apply {
val condition = (QueryCondition.getInstance<T>() as S).apply {
setObject(it)
})
}
val query = Query(condition)
objects.add(query)
}
realm.close()
return objects
}
inline fun < reified S : QueryCondition.ListOfValues<T>, T:Any > compareList(values:List<T>): List<S> {
val objects = arrayListOf<S>()
inline fun < reified S : QueryCondition.ListOfValues<T>, T:Any > compareList(values:List<T>): List<Query> {
val objects = mutableListOf<Query>()
values.forEach {
objects.add((S::class.java.newInstance()).apply {
val condition =(S::class.java.newInstance()).apply {
listOfValues = arrayListOf(it)
})
}
objects.add(Query(condition))
}
return objects
}

@ -3,11 +3,7 @@ package net.pokeranalytics.android.model.filter
import io.realm.RealmModel
import io.realm.RealmResults
import net.pokeranalytics.android.exceptions.PokerAnalyticsException
import net.pokeranalytics.android.model.realm.ComputableResult
import net.pokeranalytics.android.model.realm.Session
import net.pokeranalytics.android.model.realm.SessionSet
import net.pokeranalytics.android.model.realm.Transaction
import net.pokeranalytics.android.model.realm.Result
import net.pokeranalytics.android.model.realm.*
/**
* We want to be able to store filters in the database:
@ -51,8 +47,8 @@ interface Filterable : RealmModel {
}
inline fun <reified T : Filterable> RealmResults<T>.filter(conditions: List<QueryCondition>) : RealmResults<T> {
return conditions.queryWith(this.where()).findAll()
inline fun <reified T : Filterable> RealmResults<T>.filter(query: Query) : RealmResults<T> {
return query.queryWith(this.where()).findAll()
}
class FilterHelper {

@ -0,0 +1,63 @@
package net.pokeranalytics.android.model.filter
import io.realm.RealmQuery
fun List<Query>.mapFirstCondition() : List<QueryCondition> {
return this.map { it.conditions.first() }
}
class Query : Comparable<QueryCondition> {
override fun compareTo(other: QueryCondition): Int {
TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
}
constructor(vararg elements: QueryCondition) {
if (elements.size > 0) {
this.add(elements.asList())
}
}
private val _conditions: MutableList<QueryCondition> = mutableListOf()
val conditions: List<QueryCondition>
get() {
return this._conditions
}
fun add(vararg elements: QueryCondition) {
if (elements.size > 0) {
this.add(elements.asList())
}
}
fun add(queryCondition: QueryCondition) {
this._conditions.add(queryCondition)
}
fun remove(queryCondition: QueryCondition) {
this._conditions.remove(queryCondition)
}
fun add(queryConditions: List<QueryCondition>) {
this._conditions.addAll(queryConditions)
}
val name: String
get() {
return this._conditions.joinToString(" : ") { it.getDisplayName() }
}
inline fun <reified T : Filterable> queryWith(query: RealmQuery<T>): RealmQuery<T> {
var realmQuery = query
this.conditions.forEach {
realmQuery = it.queryWith(realmQuery)
}
return realmQuery
}
fun merge(query: Query) : Query {
this.add(query.conditions)
return this
}
}

@ -26,28 +26,13 @@ import java.text.DateFormatSymbols
import java.util.*
import kotlin.collections.ArrayList
fun List<QueryCondition>.name() : String {
return this.map { it.getDisplayName() }.joinToString(" : ")
}
//inline fun <reified T : Filterable> List<QueryCondition>.query(realm: Realm): RealmQuery<T> {
// return this.queryWith(realm.where())
//}
inline fun <reified T : Filterable> List<QueryCondition>.queryWith(query: RealmQuery<T>): RealmQuery<T> {
var realmQuery = query
this.forEach {
realmQuery = it.queryWith(realmQuery)
}
return realmQuery
}
/**
* Enum describing the way a query should be handled
* Some queries requires a value to be checked upon through equals, in, more, less, between
*/
sealed class QueryCondition : FilterElementRow {
companion object {
inline fun < reified T:QueryCondition> more():T { return T::class.java.newInstance().apply { this.operator = Operator.MORE } }
inline fun < reified T:QueryCondition> less():T { return T::class.java.newInstance().apply { this.operator = Operator.LESS } }
@ -118,6 +103,7 @@ sealed class QueryCondition : FilterElementRow {
open var operator: Operator = Operator.ANY
abstract class ListOfValues<T>: QueryCondition(), Comparable<ListOfValues<T>> where T:Comparable<T> {
abstract var listOfValues: ArrayList<T>
abstract fun labelForValue(value:T): String

@ -1,6 +1,7 @@
package net.pokeranalytics.android.model.migrations
import io.realm.Realm
import net.pokeranalytics.android.model.filter.Query
import net.pokeranalytics.android.model.filter.QueryCondition
import net.pokeranalytics.android.model.realm.Filter
import net.pokeranalytics.android.model.realm.Result
@ -15,7 +16,7 @@ class Patcher {
val realm = Realm.getDefaultInstance()
val sets = realm.where(SessionSet::class.java).findAll()
val sessions = Filter.queryOn<Session>(realm, arrayListOf(QueryCondition.IsCash))
val sessions = Filter.queryOn<Session>(realm, Query(QueryCondition.IsCash))
val results = realm.where(Result::class.java).findAll()
realm.executeTransaction {

@ -4,6 +4,7 @@ import io.realm.*
import io.realm.annotations.PrimaryKey
import io.realm.kotlin.where
import net.pokeranalytics.android.model.filter.Filterable
import net.pokeranalytics.android.model.filter.Query
import net.pokeranalytics.android.model.filter.QueryCondition
import net.pokeranalytics.android.ui.view.rowrepresentable.FilterCategoryRow
import timber.log.Timber
@ -29,9 +30,9 @@ open class Filter : RealmObject() {
return realm.where<Filter>().equalTo("id", filterId).findFirst()
}
inline fun <reified T : Filterable> queryOn(realm: Realm, queries: List<QueryCondition>, sortField: String? = null): RealmResults<T> {
inline fun <reified T : Filterable> queryOn(realm: Realm, query: Query, sortField: String? = null): RealmResults<T> {
var realmQuery = realm.where<T>()
queries.forEach {
query.conditions.forEach {
realmQuery = it.queryWith(realmQuery)
}
sortField?.let {

@ -18,7 +18,7 @@ import net.pokeranalytics.android.R
import net.pokeranalytics.android.calculus.Calculator
import net.pokeranalytics.android.calculus.ComputedResults
import net.pokeranalytics.android.calculus.Stat
import net.pokeranalytics.android.model.Criteria
import net.pokeranalytics.android.model.filter.Query
import net.pokeranalytics.android.model.filter.QueryCondition
import net.pokeranalytics.android.ui.activity.StatisticDetailsActivity
import net.pokeranalytics.android.ui.activity.components.PokerAnalyticsActivity
@ -173,22 +173,31 @@ class CalendarDetailsFragment : PokerAnalyticsFragment(), StaticRowRepresentable
val startDate = Date()
val realm = Realm.getDefaultInstance()
val conditions = ArrayList<QueryCondition>().apply {
addAll(computedResults.group.conditions)
// Remove session type conditions
removeAll(Criteria.Cash.queryConditions)
removeAll(Criteria.Tournament.queryConditions)
when (sessionTypeCondition) {
QueryCondition.IsCash -> addAll(Criteria.Cash.queryConditions)
QueryCondition.IsTournament -> addAll(Criteria.Tournament.queryConditions)
}
val query = Query().merge(computedResults.group.query)
query.remove(QueryCondition.IsCash)
query.remove(QueryCondition.IsTournament)
when (sessionTypeCondition) {
QueryCondition.IsCash -> query.add(QueryCondition.IsCash)
QueryCondition.IsTournament -> query.add(QueryCondition.IsTournament)
}
// val conditions = ArrayList<QueryCondition>().apply {
// addAll(computedResults.group.conditions)
//
// // Remove session type _conditions
// removeAll(Criteria.Cash.queryConditions)
// removeAll(Criteria.Tournament.queryConditions)
//
// when (sessionTypeCondition) {
// QueryCondition.IsCash -> addAll(Criteria.Cash.queryConditions)
// QueryCondition.IsTournament -> addAll(Criteria.Tournament.queryConditions)
// }
// }
val requiredStats: List<Stat> = listOf(Stat.LOCATIONS_PLAYED, Stat.LONGEST_STREAKS, Stat.DAYS_PLAYED, Stat.STANDARD_DEVIATION_HOURLY)
val options = Calculator.Options(evolutionValues = Calculator.Options.EvolutionValues.STANDARD, stats = requiredStats)
val report = Calculator.computeStatsWithComparators(realm, conditions = conditions, options = options)
val report = Calculator.computeStatsWithCriterias(realm, listOf(), query, options)
Timber.d("Report take: ${System.currentTimeMillis() - startDate.time}ms")

@ -240,21 +240,20 @@ class CalendarFragment : SessionObserverFragment(), CoroutineScope, StaticRowRep
// Compute data per AnyYear and AnyMonthOfYear
println(">>>> ${Criteria.MonthsOfYear.queryConditions.map { it.id }}")
// println(">>>> ${Criteria.MonthsOfYear.queryConditions.map { it.id }}")
val monthConditions = when (sessionTypeCondition) {
QueryCondition.IsCash -> listOf(Criteria.Years, Criteria.MonthsOfYear, Criteria.Cash).combined()
QueryCondition.IsTournament -> listOf(Criteria.Years, Criteria.MonthsOfYear, Criteria.Tournament).combined()
val monthlyQueries = when (sessionTypeCondition) {
QueryCondition.IsCash -> listOf(Criteria.AllMonthsUpToNow, Criteria.Cash).combined()
QueryCondition.IsTournament -> listOf(Criteria.AllMonthsUpToNow, Criteria.Tournament).combined()
else -> listOf(Criteria.Years, Criteria.MonthsOfYear).combined()
}
monthConditions.forEach { conditions ->
val report = Calculator.computeStatsWithComparators(realm, conditions = conditions, options = options)
monthlyQueries.forEach { query ->
val report = Calculator.computeStatsWithCriterias(realm, query = query, options = options)
report.results.forEach { computedResults ->
if (!computedResults.isEmpty) {
// Set date data
conditions.forEach { condition ->
query.conditions.forEach { condition ->
when (condition) {
is QueryCondition.AnyYear -> calendar.set(Calendar.YEAR, condition.listOfValues.first())
is QueryCondition.AnyMonthOfYear -> calendar.set(Calendar.MONTH, condition.listOfValues.first())
@ -275,12 +274,12 @@ class CalendarFragment : SessionObserverFragment(), CoroutineScope, StaticRowRep
else -> listOf(Criteria.Years).combined()
}
yearConditions.forEach { conditions ->
val report = Calculator.computeStatsWithComparators(realm, conditions = conditions, options = options)
yearConditions.forEach { query ->
val report = Calculator.computeStatsWithCriterias(realm, query = query, options = options)
report.results.forEach { computedResults ->
if (!computedResults.isEmpty) {
// Set date data
conditions.forEach { condition ->
query.conditions.forEach { condition ->
when (condition) {
is QueryCondition.AnyYear -> calendar.set(Calendar.YEAR, condition.listOfValues.first())
}

@ -122,7 +122,8 @@ class ReportsFragment : PokerAnalyticsFragment(), StaticRowRepresentableDataSour
val requiredStats: List<Stat> = listOf(Stat.NET_RESULT)
val options = Calculator.Options(evolutionValues = Calculator.Options.EvolutionValues.STANDARD, stats = requiredStats)
val report = Calculator.computeStatsWithComparators(realm, criteria = criteria, options = options)
val report = Calculator.computeStatsWithCriterias(realm, criteria, options = options)
// val report = Calculator.computeStatsWithComparators(realm, criteria = criteria, options = options)
Timber.d("launchComputation: ${System.currentTimeMillis() - startDate.time}ms")

@ -127,8 +127,8 @@ class StatisticDetailsFragment : PokerAnalyticsFragment() {
when (aggregationType) {
AggregationType.MONTH, AggregationType.YEAR -> {
val queryConditions = aggregationType.criterias.combined()
if (queryConditions.size < 2) {
if (aggregationType.criterias.combined().size < 2) {
Toast.makeText(context, R.string.less_then_2_values_for_display, Toast.LENGTH_LONG).show()
return
}

@ -12,6 +12,7 @@ import net.pokeranalytics.android.calculus.Calculator
import net.pokeranalytics.android.calculus.ComputableGroup
import net.pokeranalytics.android.calculus.Report
import net.pokeranalytics.android.calculus.Stat
import net.pokeranalytics.android.model.filter.Query
import net.pokeranalytics.android.model.filter.QueryCondition
import net.pokeranalytics.android.ui.view.RowRepresentable
import net.pokeranalytics.android.ui.view.rowrepresentable.CustomizableRowRepresentable
@ -120,7 +121,8 @@ class StatisticsFragment : TableReportFragment() {
Stat.AVERAGE_HOURLY_DURATION,
Stat.HOURLY_DURATION
)
val allSessionGroup = ComputableGroup(stringAll, listOf(), allStats)
val allSessionGroup = ComputableGroup(Query(), allStats)
val cgStats: List<Stat> = listOf(
Stat.NET_RESULT,
Stat.HOURLY_RATE,
@ -132,10 +134,10 @@ class StatisticsFragment : TableReportFragment() {
Stat.NUMBER_OF_GAMES,
Stat.AVERAGE_BUYIN
)
val cgSessionGroup = ComputableGroup(stringCashGame, listOf(QueryCondition.IsCash), cgStats)
val cgSessionGroup = ComputableGroup(Query(QueryCondition.IsCash), cgStats)
val tStats: List<Stat> =
listOf(Stat.NET_RESULT, Stat.HOURLY_RATE, Stat.ROI, Stat.WIN_RATIO, Stat.NUMBER_OF_GAMES, Stat.AVERAGE_BUYIN)
val tSessionGroup = ComputableGroup(stringTournament, listOf(QueryCondition.IsTournament), tStats)
val tSessionGroup = ComputableGroup(Query(QueryCondition.IsTournament), tStats)
Timber.d(">>>>> Start computations...")

@ -3,7 +3,7 @@ package net.pokeranalytics.android.ui.view.rowrepresentable
import net.pokeranalytics.android.R
import net.pokeranalytics.android.model.Criteria
import net.pokeranalytics.android.model.filter.QueryCondition
import net.pokeranalytics.android.model.filter.QueryCondition.NumberOfTable.*
import net.pokeranalytics.android.model.filter.mapFirstCondition
import net.pokeranalytics.android.ui.view.RowRepresentable
import net.pokeranalytics.android.ui.view.RowViewType
@ -60,11 +60,11 @@ enum class FilterSectionRow(override val resId: Int?) : RowRepresentable {
when (this@FilterSectionRow) {
// General
CASH_TOURNAMENT -> Criteria.SessionTypes.queryConditions
LIVE_ONLINE -> Criteria.BankrollTypes.queryConditions
GAME -> Criteria.Games.queryConditions
LIMIT_TYPE -> Criteria.Limits.queryConditions
TABLE_SIZE -> Criteria.TableSizes.queryConditions
CASH_TOURNAMENT -> Criteria.SessionTypes.queryConditions.mapFirstCondition()
LIVE_ONLINE -> Criteria.BankrollTypes.queryConditions.mapFirstCondition()
GAME -> Criteria.Games.queryConditions.mapFirstCondition()
LIMIT_TYPE -> Criteria.Limits.queryConditions.mapFirstCondition()
TABLE_SIZE -> Criteria.TableSizes.queryConditions.mapFirstCondition()
// Date
DYNAMIC_DATE -> arrayListOf(
QueryCondition.IsToday,
@ -77,9 +77,9 @@ enum class FilterSectionRow(override val resId: Int?) : RowRepresentable {
FIXED_DATE -> arrayListOf(QueryCondition.StartedFromDate(), QueryCondition.EndedToDate())
DURATION -> arrayListOf(QueryCondition.PastDay())
WEEKDAYS_OR_WEEKEND -> arrayListOf(QueryCondition.IsWeekDay, QueryCondition.IsWeekEnd)
YEAR -> Criteria.Years.queryConditions
DAY_OF_WEEK -> Criteria.DaysOfWeek.queryConditions
MONTH_OF_YEAR -> Criteria.MonthsOfYear.queryConditions
YEAR -> Criteria.Years.queryConditions.mapFirstCondition()
DAY_OF_WEEK -> Criteria.DaysOfWeek.queryConditions.mapFirstCondition()
MONTH_OF_YEAR -> Criteria.MonthsOfYear.queryConditions.mapFirstCondition()
// Duration
SESSION_DURATION -> QueryCondition.moreOrLess<QueryCondition.Duration>()
@ -89,19 +89,21 @@ enum class FilterSectionRow(override val resId: Int?) : RowRepresentable {
SESSIONS -> arrayListOf(QueryCondition.LastGame(), QueryCondition.LastSession())
// Cash
BLIND -> Criteria.Blinds.queryConditions
BLIND -> Criteria.Blinds.queryConditions.mapFirstCondition()
// CASH_RE_BUY_COUNT -> QueryCondition.moreOrLess<QueryCondition.Rebuy>()
// Tournament
TOURNAMENT_TYPE -> Criteria.TournamentTypes.queryConditions
TOURNAMENT_TYPE -> Criteria.TournamentTypes.queryConditions.mapFirstCondition()
// COMPLETION_PERCENTAGE -> arrayListOf()
//PLACE -> QueryCondition.moreOrLess<QueryCondition.TournamentFinalPosition>()
PLAYERS_COUNT -> QueryCondition.moreOrLess<QueryCondition.NumberOfPlayer>()
ENTRY_FEE -> Criteria.TournamentFees.queryConditions
// TOURNAMENT_RE_BUY_COUNT -> QueryCondition.moreOrLess<QueryCondition.BuyIn>()
ENTRY_FEE -> Criteria.TournamentFees.queryConditions.mapFirstCondition()
TOURNAMENT_NAME -> Criteria.TournamentNames.queryConditions
TOURNAMENT_FEATURE -> Criteria.TournamentFeatures.queryConditions
LOCATION -> Criteria.Locations.queryConditions
BANKROLL -> Criteria.Bankrolls.queryConditions
TOURNAMENT_NAME -> Criteria.TournamentNames.queryConditions.mapFirstCondition()
TOURNAMENT_FEATURE -> Criteria.TournamentFeatures.queryConditions.mapFirstCondition()
LOCATION -> Criteria.Locations.queryConditions.mapFirstCondition()
BANKROLL -> Criteria.Bankrolls.queryConditions.mapFirstCondition()
MULTI_TABLING -> QueryCondition.moreOrLess<QueryCondition.NumberOfTable>()
NUMBER_OF_PLAYERS -> QueryCondition.moreOrLess<QueryCondition.NumberOfPlayer>()
NUMBER_OF_REBUY -> QueryCondition.moreOrLess<QueryCondition.NumberOfRebuy>()

Loading…
Cancel
Save