Passed
Push — master ( 6e56fb...e44069 )
by manny
01:57
created

gadgets.coop.Coop.update_coop_text()   F

Complexity

Conditions 16

Size

Total Lines 50
Code Lines 46

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 46
dl 0
loc 50
rs 2.4
c 0
b 0
f 0
cc 16
nop 3

How to fix   Complexity   

Complexity

Complex classes like gadgets.coop.Coop.update_coop_text() often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

1
from datetime import datetime, timedelta, timezone
2
from models.race import Entrant, Race
3
import logging
4
from .timer import Timer
5
6
class Coop:
7
    logger = logging.Logger("racetime-obs")
8
    enabled = False
9
    partner = None
10
    opponent2 = None
11
    opponent1 = None
12
    source_name = None
13
    label_source_name = None
14
    text = " "
15
    label_text = "Race still in progress"
16
    
17
    def update_coop_text(self, race: Race, full_name):
18
        entrant = race.get_entrant_by_name(full_name)
19
        partner = race.get_entrant_by_name(self.partner)
20
        opponent1 = race.get_entrant_by_name(self.opponent1)
21
        opponent2 = race.get_entrant_by_name(self.opponent2)
22
23
        if not self.enabled or entrant is None or partner is None or opponent1 is None or opponent2 is None:
24
            return
25
26
        self.logger.debug(f"use_coop: {self.enabled}")
27
        self.logger.debug(f"entrant name: {full_name}, entrant: {entrant}")
28
        self.logger.debug(f"entrant name: {self.partner}, entrant: {partner}")
29
        self.logger.debug(f"entrant name: {self.opponent1}, entrant: {opponent1}")
30
        self.logger.debug(f"entrant name: {self.opponent2}, entrant: {opponent2}")
31
32
        our_total, opponent_total = self.get_coop_times(
33
            entrant, partner, opponent1, opponent2)
34
        if race.entrants_count_finished == 2:
35
            if our_total is not None:
36
                label_text = "We won!"
37
                text = self.timer_to_str(our_total / 2)
38
            elif opponent_total is not None:
39
                label_text = "They won. :("
40
                text = self.timer_to_str(opponent_total / 2)
41
        if race.entrants_count_finished == 3:
42
            current_timer = datetime.now(timezone.utc) - race.started_at
43
            if not entrant.finish_time:
44
                coop_label_text, coop_text = self.get_coop_text(
45
                    "I need ", partner, opponent_total, current_timer)
46
            elif not partner.finish_time:
47
                prefix = partner.user.name + " needs to finish before"
48
                coop_label_text, coop_text = self.get_coop_text(
49
                    prefix, entrant, opponent1, opponent2, current_timer)
50
            elif not opponent1.finish_time:
51
                prefix = opponent1.user.name + " needs "
52
                coop_label_text, coop_text = self.get_coop_text(
53
                    prefix, opponent2, entrant, partner, current_timer)
54
            elif not opponent2.finish_time:
55
                prefix = opponent2.user.name + " needs "
56
                coop_label_text, coop_text = self.get_coop_text(
57
                    prefix, opponent1, entrant, partner, current_timer)
58
        if race.entrants_count_finished == 4:
59
            our_total = entrant.finish_time + partner.finish_time
60
            opponent_total = opponent1.finish_time + opponent2.finish_time
61
            if our_total < opponent_total:
62
                coop_label_text = "We won!!! Average time:"
63
                coop_text = Timer.timer_to_str(our_total / 2)
64
            else:
65
                coop_label_text = "Opponents won, average time:"
66
                coop_text = Timer.timer_to_str(opponent_total / 2)
67
68
69
    def get_coop_text(label_text_start: str, finished_partner: Entrant, finished1: Entrant, finished2: Entrant, current_timer: timedelta):
70
        finished_team_total = finished1.finish_time + finished2.finish_time
71
        time_to_beat = finished_team_total - finished_partner.finish_time
72
        if time_to_beat < current_timer:
73
            coop_text = Timer.timer_to_str(time_to_beat)
74
            coop_label_text = label_text_start + "to finish before"
75
        else:
76
            coop_label_text = finished1.user.name + finished2.user.name + " won"
77
            coop_text = Timer.timer_to_str(finished_team_total / 2)
78
        return coop_label_text, coop_text
79
80
81
    def get_coop_times(self, entrant, partner, opponent1, opponent2):
82
        our_total = None
83
        opponent_total = None
84
        if entrant.finish_time and partner.finish_time:
85
            our_total = entrant.finish_time + partner.finish_time
86
            self.logger.debug(f"calculated our average is {our_total / 2}")
87
        else:
88
            self.logger.debug(f"we haven't finished yet")
89
        if opponent1.finish_time and opponent2.finish_time:
90
            opponent_total = opponent1.finish_time + opponent2.finish_time
91
            self.logger.debug(
92
                f"calculated our opponent's average is {opponent_total / 2}")
93
        else:
94
            self.logger.debug(f"our opponents haven't finished")
95
        return our_total, opponent_total