Stats performances

feature/top10
Laurent 7 years ago
parent 38da89deb0
commit 5647bed083
  1. 2
      app/src/main/java/net/pokeranalytics/android/PokerAnalyticsApplication.kt
  2. 21
      app/src/main/java/net/pokeranalytics/android/calculus/Calculator.kt
  3. 28
      app/src/main/java/net/pokeranalytics/android/calculus/Computable.kt
  4. 35
      app/src/main/java/net/pokeranalytics/android/model/realm/Result.kt
  5. 102
      app/src/main/java/net/pokeranalytics/android/model/realm/Session.kt
  6. 2
      app/src/main/java/net/pokeranalytics/android/model/realm/SessionSet.kt

@ -90,7 +90,7 @@ class PokerAnalyticsApplication : Application() {
val sessions = realm.where<Session>().findAll() val sessions = realm.where<Session>().findAll()
if (sessions.size < 10) { if (sessions.size < 10) {
val numberOfSessions = 100 val numberOfSessions = 200
Timber.d("*** Start creating ${numberOfSessions} fake sessions...") Timber.d("*** Start creating ${numberOfSessions} fake sessions...")
val s = Date() val s = Date()

@ -1,6 +1,7 @@
package net.pokeranalytics.android.calculus package net.pokeranalytics.android.calculus
import net.pokeranalytics.android.calculus.Stat.* import net.pokeranalytics.android.calculus.Stat.*
import net.pokeranalytics.android.model.realm.Session
import net.pokeranalytics.android.model.realm.SessionSet import net.pokeranalytics.android.model.realm.SessionSet
import timber.log.Timber import timber.log.Timber
@ -113,7 +114,7 @@ class Calculator {
Timber.d(">>>> Start computing group ${sessionGroup.name}, ${sessionGroup.sessions.size} sessions") Timber.d(">>>> Start computing group ${sessionGroup.name}, ${sessionGroup.sessions.size} sessions")
val sessions: List<SessionInterface> = sessionGroup.sessions val sessions: List<Session> = sessionGroup.sessions
val sessionSets = sessionGroup.sessions.mapNotNull { it.sessionSet }.toHashSet() val sessionSets = sessionGroup.sessions.mapNotNull { it.sessionSet }.toHashSet()
val results: ComputedResults = ComputedResults(sessionGroup) val results: ComputedResults = ComputedResults(sessionGroup)
@ -130,12 +131,12 @@ class Calculator {
sessions.forEach { s -> sessions.forEach { s ->
index++; index++;
sum += s.ratedNet val result = s.result!! // ok to crash to see problems
sum += result.ratedNet
bbSum += s.bbNetResult bbSum += s.bbNetResult
bbSessionCount += s.bigBlindSessionCount bbSessionCount += s.hasBigBlind
if (s.value >= 0) { winningSessionCount = result.isPositive
winningSessionCount++
}
totalBuyin += s.buyin totalBuyin += s.buyin
totalHands += s.estimatedHands totalHands += s.estimatedHands
@ -164,9 +165,9 @@ class Calculator {
} }
// Compute for each serie // Compute for each serie
var duration: Double = 0.0 var duration = 0.0
var hourlyRate: Double = 0.0 var hourlyRate = 0.0
var hourlyRateBB: Double = 0.0 var hourlyRateBB = 0.0
var gIndex = 0; var gIndex = 0;
var gSum = 0.0; var gSum = 0.0;
@ -261,7 +262,7 @@ class Calculator {
var stdSum: Double = 0.0 var stdSum: Double = 0.0
var stdBBper100HandsSum: Double = 0.0 var stdBBper100HandsSum: Double = 0.0
sessions.forEach { session -> sessions.forEach { session ->
stdSum += Math.pow(session.ratedNet - average, 2.0) stdSum += Math.pow(session.result!!.ratedNet - average, 2.0)
stdBBper100HandsSum += Math.pow(session.bbPer100Hands - bbPer100Hands, 2.0) stdBBper100HandsSum += Math.pow(session.bbPer100Hands - bbPer100Hands, 2.0)
} }
val standardDeviation: Double = Math.sqrt(stdSum / sessions.size) val standardDeviation: Double = Math.sqrt(stdSum / sessions.size)

@ -1,31 +1,11 @@
package net.pokeranalytics.android.calculus package net.pokeranalytics.android.calculus
import net.pokeranalytics.android.model.realm.SessionSet import net.pokeranalytics.android.model.realm.Session
/**
* An interface to describe objects that can be summed
*/
interface Summable {
var value: Double
}
/**
* An interface describing some class that can be computed
*/
interface SessionInterface : Summable {
var sessionSet: SessionSet?
var estimatedHands: Double
var bbNetResult: Double
var bigBlindSessionCount: Int // 0 or 1
var buyin: Double
var bbPer100Hands: Double
var ratedNet: Double
}
/** /**
* A sessionGroup of computable items identified by a name * A sessionGroup of computable items identified by a name
*/ */
class SessionGroup(name: String, sessions: List<SessionInterface>, stats: List<Stat>? = null) { class SessionGroup(name: String, sessions: List<Session>, stats: List<Stat>? = null) {
/** /**
* The display name of the group * The display name of the group
@ -35,7 +15,7 @@ class SessionGroup(name: String, sessions: List<SessionInterface>, stats: List<S
/** /**
* The list of endedSessions to compute * The list of endedSessions to compute
*/ */
var sessions: List<SessionInterface> = sessions var sessions: List<Session> = sessions
/** /**
* The list of stats to display * The list of stats to display
@ -113,7 +93,7 @@ class ComputedResults(group: SessionGroup) {
if (options.evolutionValues != Calculator.Options.EvolutionValues.NONE) { if (options.evolutionValues != Calculator.Options.EvolutionValues.NONE) {
// Sort points as a distribution // Sort points as a distribution
this._computedStats.keys.filter { it.hasDistributionSorting() }.forEach { stat -> this._computedStats.keys.filter { it.hasDistributionSorting() }.forEach { _ ->
// @todo sort // @todo sort
// var evolutionValues = this._evolutionValues[stat] // var evolutionValues = this._evolutionValues[stat]
// evolutionValues.so // evolutionValues.so

@ -31,10 +31,18 @@ open class Result : RealmObject() {
this.computeNet() this.computeNet()
} }
// The net (readonly) /**
* The pre-computed net (readonly)
*/
var net: Double = 0.0 var net: Double = 0.0
private set private set
/**
* The pre-computed rated net (readonly)
*/
var ratedNet: Double = 0.0
private set
// The transactions associated with the Result, impacting the result // The transactions associated with the Result, impacting the result
var transactions: RealmList<Transaction> = RealmList() var transactions: RealmList<Transaction> = RealmList()
set(value) { set(value) {
@ -45,8 +53,26 @@ open class Result : RealmObject() {
// The tournament final position, if applicable // The tournament final position, if applicable
var tournamentFinalPosition: Int? = null var tournamentFinalPosition: Int? = null
/**
* The automatically Realm-updated sessions list
* Should contain only one element
*/
// @LinkingObjects("result")
// private val sessions: RealmResults<Session>? = null
/**
* The associated Session
*/
// @Ignore
// val session: Session? = this.sessions?.firstOrNull()
/**
* Returns 1 if the session is positive
*/
var isPositive: Int = 0
// Computes the Net // Computes the Net
fun computeNet() { private fun computeNet() {
val transactionsSum = transactions.sumByDouble { it.amount } val transactionsSum = transactions.sumByDouble { it.amount }
this.netResult?.let { this.netResult?.let {
@ -56,8 +82,11 @@ open class Result : RealmObject() {
val cashOut = this.cashout ?: 0.0 val cashOut = this.cashout ?: 0.0
this.net = cashOut - buyin + transactionsSum this.net = cashOut - buyin + transactionsSum
} }
this.ratedNet = this.net * 1.0
this.isPositive = if (this.ratedNet >= 0.0) 1 else 0
} }
// private var rate: Double = (this.session?.bankroll?.currency?.rate ?: 1.0)
// @todo tips? // @todo tips?
} }

@ -10,7 +10,6 @@ import io.realm.annotations.PrimaryKey
import io.realm.kotlin.where import io.realm.kotlin.where
import net.pokeranalytics.android.R import net.pokeranalytics.android.R
import net.pokeranalytics.android.calculus.ComputedStat import net.pokeranalytics.android.calculus.ComputedStat
import net.pokeranalytics.android.calculus.SessionInterface
import net.pokeranalytics.android.calculus.Stat import net.pokeranalytics.android.calculus.Stat
import net.pokeranalytics.android.exceptions.ModelException import net.pokeranalytics.android.exceptions.ModelException
import net.pokeranalytics.android.model.Limit import net.pokeranalytics.android.model.Limit
@ -30,14 +29,13 @@ import net.pokeranalytics.android.ui.view.RowViewType
import net.pokeranalytics.android.ui.view.rowrepresentable.CustomizableRowRepresentable import net.pokeranalytics.android.ui.view.rowrepresentable.CustomizableRowRepresentable
import net.pokeranalytics.android.ui.view.rowrepresentable.SeparatorRowRepresentable import net.pokeranalytics.android.ui.view.rowrepresentable.SeparatorRowRepresentable
import net.pokeranalytics.android.ui.view.rowrepresentable.SessionRow import net.pokeranalytics.android.ui.view.rowrepresentable.SessionRow
import net.pokeranalytics.android.util.* import net.pokeranalytics.android.util.NULL_TEXT
import net.pokeranalytics.android.util.extensions.* import net.pokeranalytics.android.util.extensions.*
import java.util.* import java.util.*
import java.util.Currency import java.util.Currency
import kotlin.collections.ArrayList import kotlin.collections.ArrayList
open class Session : RealmObject(), SessionInterface, Manageable, StaticRowRepresentableDataSource, RowRepresentable, open class Session : RealmObject(), Manageable, StaticRowRepresentableDataSource, RowRepresentable, Timed {
Timed {
enum class Type { enum class Type {
CASH_GAME, CASH_GAME,
@ -78,6 +76,7 @@ open class Session : RealmObject(), SessionInterface, Manageable, StaticRowRepre
set(value) { set(value) {
field = value field = value
this.computeNetDuration() this.computeNetDuration()
this.computeStats()
// nullifies endate when setting the start date after the end date // nullifies endate when setting the start date after the end date
if (value != null && this.endDate != null && value.after(this.endDate)) { if (value != null && this.endDate != null && value.after(this.endDate)) {
this.endDate = null this.endDate = null
@ -92,6 +91,7 @@ open class Session : RealmObject(), SessionInterface, Manageable, StaticRowRepre
set(value) { set(value) {
field = value field = value
this.computeNetDuration() this.computeNetDuration()
this.computeStats()
this.dateChanged() this.dateChanged()
} }
@ -102,6 +102,7 @@ open class Session : RealmObject(), SessionInterface, Manageable, StaticRowRepre
set(value) { set(value) {
field = value field = value
this.computeNetDuration() this.computeNetDuration()
this.computeStats()
} }
/** /**
@ -118,16 +119,8 @@ open class Session : RealmObject(), SessionInterface, Manageable, StaticRowRepre
this.updateRowRepresentation() this.updateRowRepresentation()
} }
// The time frame of the Session, i.e. the start & end date
// var timeFrame: TimeFrame? = null
// set(value) {
// field = value
// value?.let { it.notifySessionDateChange(this) }
// }
// The time frame sessionGroup, which can contain multiple endedSessions // The time frame sessionGroup, which can contain multiple endedSessions
override var sessionSet: SessionSet? = null var sessionSet: SessionSet? = null
// the date of creation of the app // the date of creation of the app
var creationDate: Date = Date() var creationDate: Date = Date()
@ -171,6 +164,9 @@ open class Session : RealmObject(), SessionInterface, Manageable, StaticRowRepre
// The big blind value // The big blind value
var cgBigBlind: Double? = null var cgBigBlind: Double? = null
set(value) {
this.hasBigBlind = if (value != null) 1 else 0
}
// Tournament // Tournament
@ -232,17 +228,38 @@ open class Session : RealmObject(), SessionInterface, Manageable, StaticRowRepre
// Stats // Stats
@Ignore // SessionInterface value
override var value: Double = 0.0
get() {
return this.result?.net ?: 0.0
}
@Ignore @Ignore
val ONLINE_PLAYER_HANDS_PER_HOUR = 400.0 val ONLINE_PLAYER_HANDS_PER_HOUR = 400.0
@Ignore @Ignore
val LIVE_PLAYER_HANDS_PER_HOUR = 250.0 val LIVE_PLAYER_HANDS_PER_HOUR = 250.0
/**
* The estimation of hands played during the session
*/
var estimatedHands: Double = 0.0
private set
/**
* The result in big blinds
*/
var bbNetResult: Double = 0.0
private set
/**
* The number of big blinds won per 100 hands
*/
var bbPer100Hands: Double = 0.0
private set
/**
* Pre-compute various stats
*/
private fun computeStats() {
this.computeEstimatedHands()
this.computeBBNetResult()
this.computeBBPer100Hands()
}
/** /**
* Approximates the number of hands played per hour at the table * Approximates the number of hands played per hour at the table
*/ */
@ -254,31 +271,31 @@ open class Session : RealmObject(), SessionInterface, Manageable, StaticRowRepre
return playerHandsPerHour / tableSize.toDouble() return playerHandsPerHour / tableSize.toDouble()
} }
@Ignore private fun computeEstimatedHands() {
override var estimatedHands: Double = this.numberOfHandsPerHour * this.hourlyDuration this.estimatedHands = this.numberOfHandsPerHour * this.hourlyDuration
@Ignore
override var bbNetResult: Double = 0.0
get() {
this.cgBigBlind?.let { bb ->
this.result?.let { result ->
return result.net / bb
} }
private fun computeBBNetResult() {
val bb = this.cgBigBlind; val result = this.result
if (bb != null && result != null) {
this.bbNetResult = result.net / bb
} else {
this.bbNetResult = 0.0
} }
return 0.0
} }
@Ignore private fun computeBBPer100Hands() {
override var bbPer100Hands: Double = 0.0 this.bbPer100Hands = this.bbNetResult / this.estimatedHands * 100
get() {
return this.bbNetResult / this.estimatedHands * 100.0
} }
@Ignore /**
override var bigBlindSessionCount: Int = if (this.cgBigBlind != null) 1 else 0 * Returns 1 if the session has big blinds, otherwise 0
*/
var hasBigBlind: Int = 0
private set
@Ignore @Ignore
override var buyin: Double = 0.0 var buyin: Double = 0.0
get() { get() {
this.result?.let { result -> this.result?.let { result ->
result.buyin?.let { result.buyin?.let {
@ -296,17 +313,8 @@ open class Session : RealmObject(), SessionInterface, Manageable, StaticRowRepre
throw ModelException("Session should have an existing Result relationship") throw ModelException("Session should have an existing Result relationship")
} }
override var ratedNet: Double = 0.0 // @Ignore
get() { // val ratedNet: Double = this.result?.ratedNet ?: 0.0
this.result?.net?.let { net ->
this.bankroll?.currency?.rate?.let { rate ->
return net * rate
} ?: run {
return net
}
}
return 0.0
}
// States // States

@ -68,7 +68,7 @@ open class SessionSet : RealmObject(), Timed {
val sessions: RealmResults<Session>? = null val sessions: RealmResults<Session>? = null
@Ignore @Ignore
val ratedNet: Double = this.sessions?.sumByDouble { it.ratedNet } ?: 0.0 val ratedNet: Double = this.sessions?.sumByDouble { it.result!!.ratedNet } ?: 0.0
@Ignore @Ignore
val hourlyRate: Double = this.ratedNet / this.hourlyDuration val hourlyRate: Double = this.ratedNet / this.hourlyDuration

Loading…
Cancel
Save