Skip to content

Commit 0a5265f

Browse files
committedMar 18, 2025
pre-calculate standardised scores
1 parent 2c6c844 commit 0a5265f

File tree

3 files changed

+34
-8
lines changed

3 files changed

+34
-8
lines changed
 

Diff for: ‎app/Models/Contest.php

+15-1
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
use Illuminate\Database\Eloquent\Relations\HasMany;
1818

1919
/**
20+
* @property-read Collection<ContestJudge> $contestJudges
2021
* @property \Carbon\Carbon|null $created_at
2122
* @property string $description_enter
2223
* @property string|null $description_voting
@@ -28,7 +29,7 @@
2829
* @property string $header_url
2930
* @property int $id
3031
* @property mixed $link_icon
31-
* @property-read Collection<ContestJudge> $judges
32+
* @property-read Collection<User> $judges
3233
* @property int $max_entries
3334
* @property int $max_votes
3435
* @property string $name
@@ -57,6 +58,11 @@ class Contest extends Model
5758
'voting_starts_at' => 'datetime',
5859
];
5960

61+
public function contestJudges(): HasMany
62+
{
63+
return $this->HasMany(ContestJudge::class);
64+
}
65+
6066
public function entries()
6167
{
6268
return $this->hasMany(ContestEntry::class);
@@ -115,6 +121,14 @@ public function assertVoteRequirement(?User $user): void
115121
}
116122
}
117123

124+
public function calculateScores(): void
125+
{
126+
$this->contestJudges->each->calculateStdDev();
127+
128+
$judgeVotes = ContestJudgeVote::whereHas('entry', fn ($q) => $q->whereHas('contest', fn ($qq) => $qq->where('contest_id', $this->getKey())))->get();
129+
$judgeVotes->each->calculateScore();
130+
}
131+
118132
public function isBestOf(): bool
119133
{
120134
return isset($this->getExtraOptions()['best_of']);

Diff for: ‎app/Models/ContestJudge.php

+10-1
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@
1313
/**
1414
* @property-read Contest $contest
1515
* @property int $contest_id
16+
* @property ?float $mean
17+
* @property ?float $std_dev
1618
* @property-read User $user
1719
* @property int $user_id
1820
*/
@@ -29,7 +31,14 @@ public function user(): BelongsTo
2931
return $this->belongsTo(User::class, 'user_id');
3032
}
3133

32-
public function stdDev()
34+
public function calculateStdDev(): void
35+
{
36+
[$stdDev, $mean] = $this->stdDev();
37+
38+
$this->update(['mean' => $mean, 'std_dev' => $stdDev]);
39+
}
40+
41+
public function stdDev(): array
3342
{
3443
// TODO: treat missing scores as 0?
3544
$entryScores = ContestJudgeScore::scoresByEntry()

Diff for: ‎app/Models/ContestJudgeVote.php

+9-6
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
* @property \Carbon\Carbon|null $created_at
1919
* @property-read ContestEntry $entry
2020
* @property int $id
21+
* @property float $total_score_std
2122
* @property \Carbon\Carbon|null $updated_at
2223
* @property-read User $user
2324
* @property int $user_id
@@ -39,15 +40,17 @@ public function totalScore(): int
3940
return intval($this->scores()->sum('value'));
4041
}
4142

42-
public function totalScoreStd(): float
43+
public function user(): BelongsTo
4344
{
44-
[$stdDev, $mean] = ContestJudge::where(['contest_id' => $this->entry->contest_id, 'user_id' => $this->user_id])->first()->stdDev();
45-
46-
return ($this->totalScore() - $mean) / $stdDev;
45+
return $this->belongsTo(User::class, 'user_id');
4746
}
4847

49-
public function user(): BelongsTo
48+
public function calculateScore(): void
5049
{
51-
return $this->belongsTo(User::class, 'user_id');
50+
$judge = ContestJudge::where(['contest_id' => $this->entry->contest_id, 'user_id' => $this->user_id])->first();
51+
52+
if ($judge->std_dev !== null) {
53+
$this->update(['total_score_std' => ($this->totalScore() - $judge->mean) / $judge->std_dev]);
54+
}
5255
}
5356
}

0 commit comments

Comments
 (0)
Failed to load comments.