GitHub Access Token became invalid

It seems like the GitHub access token used for retrieving details about this repository from GitHub became invalid. This might prevent certain types of inspections from being run (in particular, everything related to pull requests).
Please ask an admin of your repository to re-new the access token on this website.
Completed
Pull Request — develop (#307)
by
unknown
42s
created

PlayerDivisionInfo   A

Complexity

Total Complexity 4

Size/Duplication

Total Lines 14
Duplicated Lines 0 %

Importance

Changes 1
Bugs 0 Features 1
Metric Value
c 1
b 0
f 1
dl 0
loc 14
rs 10
wmc 4

4 Methods

Rating   Name   Duplication   Size   Complexity  
A __init__() 0 4 1
A __str__() 0 2 1
A is_in_superior_league() 0 2 1
A is_in_inferior_league() 0 2 1
1
# coding=utf-8
2
import logging
3
from typing import List, Dict
0 ignored issues
show
Configuration introduced by
The import typing could not be resolved.

This can be caused by one of the following:

1. Missing Dependencies

This error could indicate a configuration issue of Pylint. Make sure that your libraries are available by adding the necessary commands.

# .scrutinizer.yml
before_commands:
    - sudo pip install abc # Python2
    - sudo pip3 install abc # Python3
Tip: We are currently not using virtualenv to run pylint, when installing your modules make sure to use the command for the correct version.

2. Missing __init__.py files

This error could also result from missing __init__.py files in your module folders. Make sure that you place one file in each sub-folder.

Loading history...
Unused Code introduced by
Unused Dict imported from typing
Loading history...
4
5
logger = logging.getLogger(__name__)
6
7
8
class Division:
9
    def __init__(self, id: int, name: str, league: int, threshold: float):
0 ignored issues
show
Bug Best Practice introduced by
This seems to re-define the built-in id.

It is generally discouraged to redefine built-ins as this makes code very hard to read.

Loading history...
10
        self.id = id
11
        self.name = name
12
        self.league = league
13
        self.threshold = threshold
14
15
16
class PlayerDivisionInfo:
17
    def __init__(self, user_id: int, current_league: int, current_score: float):
18
        self.user_id = user_id
19
        self.league = current_league
20
        self.score = current_score
21
22
    def is_in_inferior_league(self, compared_to: 'PlayerDivisionInfo') -> bool:
23
        return self.league < compared_to.league
24
25
    def is_in_superior_league(self, compared_to: 'PlayerDivisionInfo') -> bool:
26
        return self.league > compared_to.league
27
28
    def __str__(self):
29
        return "PlayerDivisionInfo(user_id=%s, league=%s, score=%s)" % (self.user_id, self.league, self.score)
30
31
32
class DivisionService:
33
    def __init__(self, divisions: List['Division'], player_division_infos: List['PlayerDivisionInfo']):
34
        self.divisions = divisions
35
        self.players = dict()  # type: Dict[int, 'PlayerDivisionInfo']
36
37
        for info in player_division_infos:
38
            self.players[info.user_id] = info
39
40
    def add_player(self, player_id: int) -> None:
41
        logger.debug("Added new player %s to divisions", player_id)
42
        self.players[player_id] = PlayerDivisionInfo(player_id, 1, 0.0)
43
44
    def update_player_score(self, player: PlayerDivisionInfo, new_score: float) -> None:
0 ignored issues
show
Coding Style introduced by
This method could be written as a function/class method.

If a method does not access any attributes of the class, it could also be implemented as a function or static method. This can help improve readability. For example

class Foo:
    def some_method(self, x, y):
        return x + y;

could be written as

class Foo:
    @classmethod
    def some_method(cls, x, y):
        return x + y;
Loading history...
45
        logger.debug("Update score for %s to %s", player)
0 ignored issues
show
Bug introduced by
Not enough arguments for logging format string
Loading history...
46
        player.score = new_score
47
48
    def promote_player(self, player):
0 ignored issues
show
Coding Style introduced by
This method could be written as a function/class method.

If a method does not access any attributes of the class, it could also be implemented as a function or static method. This can help improve readability. For example

class Foo:
    def some_method(self, x, y):
        return x + y;

could be written as

class Foo:
    @classmethod
    def some_method(cls, x, y):
        return x + y;
Loading history...
49
        logger.info("%s got promoted to league %s", player, player.league + 1)
50
        player.score = 0.0
51
        player.league += 1
52
53
    def post_result(self, player_one: int, player_two: int, player_one_has_won: bool) -> None:
54
        if player_one not in self.players:
55
            self.add_player(player_one)
56
57
        if player_two not in self.players:
58
            self.add_player(player_two)
59
60
        winner = self.players[player_one] if player_one_has_won else self.players[player_two]
61
        loser = self.players[player_two] if player_one_has_won else self.players[player_one]
62
63
        if winner.is_in_inferior_league(loser):
64
            gain = 1.5
65
            loss = 1.0
66
        elif winner.is_in_superior_league(loser):
67
            gain = 0.5
68
            loss = 0.5
69
        else:
70
            gain = 1.0
71
            loss = 0.5
72
73
        logger.debug("%s won against %s - gain: %s - loss: %s", winner, loser, gain, loss)
74
75
        if winner.score + gain > self.max_league_threshold(winner.league):
76
            self.promote_player(winner)
77
        else:
78
            self.update_player_score(winner, winner.score + gain)
79
80
        self.update_player_score(loser, max(0.0, loser.score - loss))
81
82
    def get_player_division(self, player_id: int) -> 'Division':
83
        player = self.players[player_id]
84
        return self.get_division(player.league, player.score)
85
86
    def max_league_threshold(self, league: int) -> float:
87
        return max([x.threshold for x in self.divisions if x.league == league])
88
89
    def get_division(self, league: int, score: float) -> Division:
90
        divisions_of_league = [x for x in self.divisions if x.league == league]
91
92
        for division in sorted(divisions_of_league, key=lambda d: d.threshold):
93
            if division.threshold > score:
94
                return division
95
96
        logger.error("league %s has no division for score %s", league, score)
97
        return None
98