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. 37
      app/src/main/java/net/pokeranalytics/android/model/realm/Result.kt
  5. 106
      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()
if (sessions.size < 10) {
val numberOfSessions = 100
val numberOfSessions = 200
Timber.d("*** Start creating ${numberOfSessions} fake sessions...")
val s = Date()

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

@ -1,31 +1,11 @@
package net.pokeranalytics.android.calculus
import net.pokeranalytics.android.model.realm.SessionSet
/**
* 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
}
import net.pokeranalytics.android.model.realm.Session
/**
* 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
@ -35,7 +15,7 @@ class SessionGroup(name: String, sessions: List<SessionInterface>, stats: List<S
/**
* The list of endedSessions to compute
*/
var sessions: List<SessionInterface> = sessions
var sessions: List<Session> = sessions
/**
* The list of stats to display
@ -113,7 +93,7 @@ class ComputedResults(group: SessionGroup) {
if (options.evolutionValues != Calculator.Options.EvolutionValues.NONE) {
// Sort points as a distribution
this._computedStats.keys.filter { it.hasDistributionSorting() }.forEach { stat ->
this._computedStats.keys.filter { it.hasDistributionSorting() }.forEach { _ ->
// @todo sort
// var evolutionValues = this._evolutionValues[stat]
// evolutionValues.so

@ -31,11 +31,19 @@ open class Result : RealmObject() {
this.computeNet()
}
// The net (readonly)
/**
* The pre-computed net (readonly)
*/
var net: Double = 0.0
private set
// The transactions associated with the Result, impacting the result
/**
* The pre-computed rated net (readonly)
*/
var ratedNet: Double = 0.0
private set
// The transactions associated with the Result, impacting the result
var transactions: RealmList<Transaction> = RealmList()
set(value) {
field = value
@ -45,8 +53,26 @@ open class Result : RealmObject() {
// The tournament final position, if applicable
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
fun computeNet() {
private fun computeNet() {
val transactionsSum = transactions.sumByDouble { it.amount }
this.netResult?.let {
@ -56,8 +82,11 @@ open class Result : RealmObject() {
val cashOut = this.cashout ?: 0.0
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?
}

@ -10,7 +10,6 @@ import io.realm.annotations.PrimaryKey
import io.realm.kotlin.where
import net.pokeranalytics.android.R
import net.pokeranalytics.android.calculus.ComputedStat
import net.pokeranalytics.android.calculus.SessionInterface
import net.pokeranalytics.android.calculus.Stat
import net.pokeranalytics.android.exceptions.ModelException
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.SeparatorRowRepresentable
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 java.util.*
import java.util.Currency
import kotlin.collections.ArrayList
open class Session : RealmObject(), SessionInterface, Manageable, StaticRowRepresentableDataSource, RowRepresentable,
Timed {
open class Session : RealmObject(), Manageable, StaticRowRepresentableDataSource, RowRepresentable, Timed {
enum class Type {
CASH_GAME,
@ -78,6 +76,7 @@ open class Session : RealmObject(), SessionInterface, Manageable, StaticRowRepre
set(value) {
field = value
this.computeNetDuration()
this.computeStats()
// nullifies endate when setting the start date after the end date
if (value != null && this.endDate != null && value.after(this.endDate)) {
this.endDate = null
@ -92,6 +91,7 @@ open class Session : RealmObject(), SessionInterface, Manageable, StaticRowRepre
set(value) {
field = value
this.computeNetDuration()
this.computeStats()
this.dateChanged()
}
@ -102,6 +102,7 @@ open class Session : RealmObject(), SessionInterface, Manageable, StaticRowRepre
set(value) {
field = value
this.computeNetDuration()
this.computeStats()
}
/**
@ -118,16 +119,8 @@ open class Session : RealmObject(), SessionInterface, Manageable, StaticRowRepre
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
override var sessionSet: SessionSet? = null
var sessionSet: SessionSet? = null
// the date of creation of the app
var creationDate: Date = Date()
@ -171,6 +164,9 @@ open class Session : RealmObject(), SessionInterface, Manageable, StaticRowRepre
// The big blind value
var cgBigBlind: Double? = null
set(value) {
this.hasBigBlind = if (value != null) 1 else 0
}
// Tournament
@ -232,17 +228,38 @@ open class Session : RealmObject(), SessionInterface, Manageable, StaticRowRepre
// Stats
@Ignore // SessionInterface value
override var value: Double = 0.0
get() {
return this.result?.net ?: 0.0
}
@Ignore
val ONLINE_PLAYER_HANDS_PER_HOUR = 400.0
@Ignore
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
*/
@ -254,31 +271,31 @@ open class Session : RealmObject(), SessionInterface, Manageable, StaticRowRepre
return playerHandsPerHour / tableSize.toDouble()
}
@Ignore
override var estimatedHands: Double = this.numberOfHandsPerHour * this.hourlyDuration
private fun computeEstimatedHands() {
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
}
}
return 0.0
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
}
}
@Ignore
override var bbPer100Hands: Double = 0.0
get() {
return this.bbNetResult / this.estimatedHands * 100.0
}
private fun computeBBPer100Hands() {
this.bbPer100Hands = this.bbNetResult / this.estimatedHands * 100
}
@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
override var buyin: Double = 0.0
var buyin: Double = 0.0
get() {
this.result?.let { result ->
result.buyin?.let {
@ -296,17 +313,8 @@ open class Session : RealmObject(), SessionInterface, Manageable, StaticRowRepre
throw ModelException("Session should have an existing Result relationship")
}
override var ratedNet: Double = 0.0
get() {
this.result?.net?.let { net ->
this.bankroll?.currency?.rate?.let { rate ->
return net * rate
} ?: run {
return net
}
}
return 0.0
}
// @Ignore
// val ratedNet: Double = this.result?.ratedNet ?: 0.0
// States

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

Loading…
Cancel
Save