Spaces:
Sleeping
Sleeping
File size: 7,802 Bytes
641009d |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 |
from collections import defaultdict
from datetime import datetime
from statistics import median
import pandas as pd
def calculate_probability(numerator, denominator):
"""Calculate percentage probability."""
return (numerator / denominator * 100) if denominator else 0
def analyze_streaks(games_sorted, username):
"""Analyze win/loss streaks within the same hour."""
win_after_win_same_hour = 0
loss_after_loss_same_hour = 0
total_win_streaks_same_hour = 0
total_loss_streaks_same_hour = 0
previous_result = None
previous_hour = None
for game in games_sorted:
end_time = game.get('end_time')
if not end_time:
continue
hour_of_day = datetime.fromtimestamp(end_time).hour
current_result = get_game_result(game, username)
if not current_result:
continue
if previous_result and previous_hour == hour_of_day:
if previous_result == 'win':
total_win_streaks_same_hour += 1
if current_result == 'win':
win_after_win_same_hour += 1
elif previous_result == 'loss':
total_loss_streaks_same_hour += 1
if current_result == 'loss':
loss_after_loss_same_hour += 1
previous_result = current_result
previous_hour = hour_of_day
print(f"Total win streaks: {total_win_streaks_same_hour}, Wins after win: {win_after_win_same_hour}")
print(f"Total loss streaks: {total_loss_streaks_same_hour}, Losses after loss: {loss_after_loss_same_hour}")
win_probability = calculate_probability(win_after_win_same_hour, total_win_streaks_same_hour)
loss_probability = calculate_probability(loss_after_loss_same_hour, total_loss_streaks_same_hour)
return win_probability, loss_probability
def analyze_sequences(games_sorted, username):
"""Analyze 'win-loss' and 'loss-win' sequences within the same hour."""
win_after_win_loss_same_hour = 0
win_after_loss_win_same_hour = 0
total_win_loss_sequences_same_hour = 0
total_loss_win_sequences_same_hour = 0
previous_result = None
previous_hour = None
for i, game in enumerate(games_sorted):
end_time = game.get('end_time')
if not end_time:
continue
hour_of_day = datetime.fromtimestamp(end_time).hour
current_result = get_game_result(game, username)
if not current_result:
continue
if previous_result and previous_hour == hour_of_day:
if previous_result == 'win' and current_result == 'loss':
total_win_loss_sequences_same_hour += 1
next_game_result = get_game_result(games_sorted[i + 1], username) if i + 1 < len(games_sorted) else None
if next_game_result == 'win':
win_after_win_loss_same_hour += 1
elif previous_result == 'loss' and current_result == 'win':
total_loss_win_sequences_same_hour += 1
next_game_result = get_game_result(games_sorted[i + 1], username) if i + 1 < len(games_sorted) else None
if next_game_result == 'win':
win_after_loss_win_same_hour += 1
previous_result = current_result
previous_hour = hour_of_day
print(f"Total 'win-loss' sequences: {total_win_loss_sequences_same_hour}, Wins after 'win-loss': {win_after_win_loss_same_hour}")
print(f"Total 'loss-win' sequences: {total_loss_win_sequences_same_hour}, Wins after 'loss-win': {win_after_loss_win_same_hour}")
win_after_win_loss_probability = calculate_probability(win_after_win_loss_same_hour, total_win_loss_sequences_same_hour)
win_after_loss_win_probability = calculate_probability(win_after_loss_win_same_hour, total_loss_win_sequences_same_hour)
return win_after_win_loss_probability, win_after_loss_win_probability
def analyze_games(games, username):
"""Analyze games by month and return statistics."""
games_per_month = defaultdict(int)
stats_per_month = defaultdict(lambda: defaultdict(int))
total_games = 0
total_wins = 0
total_losses = 0
total_timeouts = 0
for game in games:
end_time = game.get('end_time')
if not end_time:
continue
end_datetime = datetime.fromtimestamp(end_time)
month = end_datetime.strftime('%Y-%m')
result = get_game_result(game, username)
if result == 'win':
stats_per_month[month]['wins'] += 1
total_wins += 1
elif result == 'timeout':
stats_per_month[month]['timeouts'] += 1
total_timeouts += 1
stats_per_month[month]['losses'] += 1 # Count timeout as a loss
total_losses += 1
elif result == 'loss':
stats_per_month[month]['losses'] += 1
total_losses += 1
games_per_month[month] += 1
total_games += 1
total_months_played = len(games_per_month)
return games_per_month, stats_per_month, total_games, total_wins, total_losses, total_timeouts, total_months_played
def generate_monthly_report(games_per_month, stats_per_month):
"""Generate a Pandas DataFrame report for monthly analysis including Timeout Rate."""
data = []
for month, total_games in games_per_month.items():
wins = stats_per_month[month]['wins']
losses = stats_per_month[month]['losses']
timeouts = stats_per_month[month]['timeouts']
win_rate = (wins / total_games * 100) if total_games else 0
loss_rate = (losses / total_games * 100) if total_games else 0
timeout_rate = (timeouts / total_games * 100) if total_games else 0
data.append({
'Month': month,
'Games Played': total_games,
'Wins': wins,
'Losses': losses,
'Win Rate (%)': round(win_rate, 1),
'Loss Rate (%)': round(loss_rate, 1),
'Timeout Rate (%)': round(timeout_rate, 1)
})
return pd.DataFrame(data)
def get_game_result(game, username):
"""Determine if the user won or lost the game."""
result = None
if game.get('white', {}).get('username') == username:
result = game.get('white', {}).get('result')
elif game.get('black', {}).get('username') == username:
result = game.get('black', {}).get('result')
if result == 'win':
return 'win'
elif result == 'timeout':
return 'timeout' # Explicitly return "timeout"
elif result in ['checkmated', 'resigned', 'lose', 'abandoned']:
return 'loss'
return None
def calculate_average_and_median_games(games):
"""Calculate the average and median number of games played per day."""
games_per_day = defaultdict(int)
for game in games:
end_time = game.get('end_time')
if not end_time:
continue
end_date = datetime.fromtimestamp(end_time).date()
games_per_day[end_date] += 1
total_days = len(games_per_day)
total_games = sum(games_per_day.values())
average_games = total_games / total_days if total_days else 0
median_games = median(games_per_day.values()) if total_days else 0
return average_games, median_games
def format_duration(total_months):
"""Format the duration as 'X years, Y months'."""
years = total_months // 12
months = total_months % 12
if years > 0 and months > 0:
return f"{years} year(s), {months} month(s)"
elif years > 0:
return f"{years} year(s)"
else:
return f"{months} month(s)" |