From 824407b136915ffafa220e9cf673f75d3b361183 Mon Sep 17 00:00:00 2001 From: Shlomi Fish Date: Tue, 30 Apr 2019 17:14:57 +0300 Subject: [PATCH] Extract a common module/library/header. This is Refactoring / code cleanup. See: * https://refactoring.com/catalog/extractMethod.html * https://en.wikipedia.org/wiki/Code_refactoring * https://www.refactoring.com/ * https://www.joelonsoftware.com/2002/01/23/rub-a-dub-dub/ Some small optimisations may have slipped in as well. --- pysollib/app.py | 127 +------------------------------- pysollib/app_statistics.py | 143 +++++++++++++++++++++++++++++++++++++ 2 files changed, 144 insertions(+), 126 deletions(-) create mode 100644 pysollib/app_statistics.py diff --git a/pysollib/app.py b/pysollib/app.py index fa480c62..4e363af9 100644 --- a/pysollib/app.py +++ b/pysollib/app.py @@ -29,8 +29,8 @@ import sys import traceback from pickle import UnpicklingError -from pysollib.app_stat import GameStat from pysollib.app_stat_result import GameStatResult +from pysollib.app_statistics import Statistics from pysollib.gamedb import GAME_DB, GI, loadGame from pysollib.images import Images, SubsampledImages from pysollib.mfxutil import Struct, destruct @@ -70,134 +70,9 @@ if True: # This prevents from travis 'error' E402. from pysollib.actions import PysolToolbar from pysollib.help import help_about, destroy_help_html -# ************************************************************************ -# * Statistics -# ************************************************************************ _GameStatResult = GameStatResult -class Statistics: - def __init__(self): - self.version_tuple = VERSION_TUPLE - self.saved = 0 - # a dictionary of dictionaries of GameStat (keys: player and gameid) - self.games_stats = {} - # a dictionary of lists of tuples (key: player) - self.prev_games = {} - self.all_prev_games = {} - self.session_games = {} - # some simple balance scores (key: gameid) - self.total_balance = {} # a dictionary of integers - self.session_balance = {} # reset per session - self.gameid_balance = 0 # reset when changing the gameid - - def new(self): - return Statistics() - - # - # player & demo statistics - # - - def resetStats(self, player, gameid): - self.__resetPrevGames(player, self.prev_games, gameid) - self.__resetPrevGames(player, self.session_games, gameid) - if player not in self.games_stats: - return - if gameid == 0: - # remove all games - try: - del self.games_stats[player] - except KeyError: - pass - else: - try: - del self.games_stats[player][gameid] - except KeyError: - pass - - def __resetPrevGames(self, player, games, gameid): - if player not in games: - return - if gameid == 0: - del games[player] - else: - games[player] = [g for g in games[player] if g[0] != gameid] - - def getStats(self, player, gameid): - # returned (won, lost) - return self.getFullStats(player, gameid)[:2] - - def getFullStats(self, player, gameid): - # returned (won, lost, playing time, moves) - stats = self.games_stats - if player in stats and gameid in stats[player]: - s = self.games_stats[player][gameid] - return (s.num_won+s.num_perfect, - s.num_lost, - s.time_result.average, - s.moves_result.average,) - return (0, 0, 0, 0) - - def getSessionStats(self, player, gameid): - games = self.session_games.get(player, []) - games = [g for g in games if g[0] == gameid] - won = len([g for g in games if g[2] > 0]) - lost = len([g for g in games if g[2] == 0]) - return won, lost - - def updateStats(self, player, game, status): - ret = None - log = (game.id, game.getGameNumber(format=0), status, - game.gstats.start_time, game.gstats.total_elapsed_time, - VERSION_TUPLE, game.getGameScore(), game.getGameScoreCasino(), - game.GAME_VERSION) - # full log - if status >= 0: - if player is None: - # demo - ret = self.updateGameStat(player, game, status) - else: - # player - if player not in self.prev_games: - self.prev_games[player] = [] - self.prev_games[player].append(log) - if player not in self.all_prev_games: - self.all_prev_games[player] = [] - self.all_prev_games[player].append(log) - ret = self.updateGameStat(player, game, status) - # session log - if player not in self.session_games: - self.session_games[player] = [] - self.session_games[player].append(log) - return ret - - def updateGameStat(self, player, game, status): - # - if player not in self.games_stats: - self.games_stats[player] = {} - if game.id not in self.games_stats[player]: - game_stat = GameStat(game.id) - self.games_stats[player][game.id] = game_stat - else: - game_stat = self.games_stats[player][game.id] - if 'all' not in self.games_stats[player]: - all_games_stat = GameStat('all') - self.games_stats[player]['all'] = all_games_stat - else: - all_games_stat = self.games_stats[player]['all'] - all_games_stat.update(game, status) - return game_stat.update(game, status) - -# def __setstate__(self, state): # for backward compatible -# if 'gameid' not in state: -# self.gameid = None -# self.__dict__.update(state) - - -# ************************************************************************ -# * Comments -# ************************************************************************ - class Comments: def __init__(self): self.version_tuple = VERSION_TUPLE diff --git a/pysollib/app_statistics.py b/pysollib/app_statistics.py new file mode 100644 index 00000000..c2117ffc --- /dev/null +++ b/pysollib/app_statistics.py @@ -0,0 +1,143 @@ +#!/usr/bin/env python +# -*- mode: python; coding: utf-8; -*- +# ---------------------------------------------------------------------------## +# +# Copyright (C) 1998-2003 Markus Franz Xaver Johannes Oberhumer +# Copyright (C) 2003 Mt. Hood Playing Card Co. +# Copyright (C) 2005-2009 Skomoroh +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . +# +# ---------------------------------------------------------------------------## + +from pysollib.app_stat import GameStat +from pysollib.settings import VERSION_TUPLE + + +class Statistics: + def __init__(self): + self.version_tuple = VERSION_TUPLE + self.saved = 0 + # a dictionary of dictionaries of GameStat (keys: player and gameid) + self.games_stats = {} + # a dictionary of lists of tuples (key: player) + self.prev_games = {} + self.all_prev_games = {} + self.session_games = {} + # some simple balance scores (key: gameid) + self.total_balance = {} # a dictionary of integers + self.session_balance = {} # reset per session + self.gameid_balance = 0 # reset when changing the gameid + + def new(self): + return Statistics() + + # + # player & demo statistics + # + + def resetStats(self, player, gameid): + self.__resetPrevGames(player, self.prev_games, gameid) + self.__resetPrevGames(player, self.session_games, gameid) + if player not in self.games_stats: + return + if gameid == 0: + # remove all games + try: + del self.games_stats[player] + except KeyError: + pass + else: + try: + del self.games_stats[player][gameid] + except KeyError: + pass + + def __resetPrevGames(self, player, games, gameid): + if player not in games: + return + if gameid == 0: + del games[player] + else: + games[player] = [g for g in games[player] if g[0] != gameid] + + def getStats(self, player, gameid): + # returned (won, lost) + return self.getFullStats(player, gameid)[:2] + + def getFullStats(self, player, gameid): + # returned (won, lost, playing time, moves) + stats = self.games_stats + if player in stats and gameid in stats[player]: + s = self.games_stats[player][gameid] + return (s.num_won+s.num_perfect, + s.num_lost, + s.time_result.average, + s.moves_result.average,) + return (0, 0, 0, 0) + + def getSessionStats(self, player, gameid): + games = self.session_games.get(player, []) + games = [g for g in games if g[0] == gameid] + won = len([g for g in games if g[2] > 0]) + lost = len([g for g in games if g[2] == 0]) + return won, lost + + def updateStats(self, player, game, status): + ret = None + log = (game.id, game.getGameNumber(format=0), status, + game.gstats.start_time, game.gstats.total_elapsed_time, + VERSION_TUPLE, game.getGameScore(), game.getGameScoreCasino(), + game.GAME_VERSION) + # full log + if status >= 0: + if player is None: + # demo + ret = self.updateGameStat(player, game, status) + else: + # player + if player not in self.prev_games: + self.prev_games[player] = [] + self.prev_games[player].append(log) + if player not in self.all_prev_games: + self.all_prev_games[player] = [] + self.all_prev_games[player].append(log) + ret = self.updateGameStat(player, game, status) + # session log + if player not in self.session_games: + self.session_games[player] = [] + self.session_games[player].append(log) + return ret + + def updateGameStat(self, player, game, status): + # + if player not in self.games_stats: + self.games_stats[player] = {} + if game.id not in self.games_stats[player]: + game_stat = GameStat(game.id) + self.games_stats[player][game.id] = game_stat + else: + game_stat = self.games_stats[player][game.id] + if 'all' not in self.games_stats[player]: + all_games_stat = GameStat('all') + self.games_stats[player]['all'] = all_games_stat + else: + all_games_stat = self.games_stats[player]['all'] + all_games_stat.update(game, status) + return game_stat.update(game, status) + +# def __setstate__(self, state): # for backward compatible +# if 'gameid' not in state: +# self.gameid = None +# self.__dict__.update(state)