PolicyDistributionPair::getPersonDistributions()   A
last analyzed

Complexity

Conditions 5
Paths 8

Size

Total Lines 29
Code Lines 17

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 5
eloc 17
nc 8
nop 4
dl 0
loc 29
rs 9.3888
c 1
b 0
f 0
1
<?php
2
3
/**
4
 * Party Cohort Class
5
 *
6
 * @package TheyWorkForYou
7
 */
8
9
namespace MySociety\TheyWorkForYou;
10
11
/**
12
 * Policy DistributionPair
13
 * Brings together the member_distribution (their own policy score)
14
 * And the comporable members total and score.
15
 */
16
17
class PolicyDistributionPair {
18
    public ?PolicyDistribution $member_distribution;
19
    public ?PolicyDistribution $comparison_distribution;
20
    public int $policy_id;
21
    public string $policy_desc;
22
    public bool $covid_affected;
23
    public int $annotation_count;
24
25
26
    public function __construct(
27
        ?PolicyDistribution $member_distribution,
28
        ?PolicyDistribution $comparison_distribution,
29
        array $annotation_counts = []
30
    ) {
31
        $this->member_distribution = $member_distribution;
32
        $this->comparison_distribution = $comparison_distribution;
33
        $this->policy_id = $this->getPolicyId();
34
35
        $policies_obj = new Policies();
36
        $policies_obj->getCovidAffected();
37
        $this->covid_affected = in_array($this->policy_id, $policies_obj->getCovidAffected());
38
39
        $this->policy_desc = $policies_obj->getPolicies()[$this->policy_id];
40
41
        // Check if this policy has any annotations for the member
42
        $this->annotation_count = $annotation_counts[$this->policy_id] ?? 0;
43
    }
44
45
    public function getMoreDetailsLink(): string {
46
        $person_id = $this->getPersonId();
47
        ;
48
        $policy_id = $this->getPolicyId();
49
        $period = strtolower($this->getVotingPeriod());
50
        $party_slug = $this->member_distribution->party_slug;
51
        return TWFY_VOTES_URL . "/person/$person_id/policies/commons/$party_slug/$period/$policy_id";
0 ignored issues
show
Bug introduced by
The constant MySociety\TheyWorkForYou\TWFY_VOTES_URL was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
52
    }
53
54
    public function getPersonId(): int {
55
        return $this->member_distribution->person_id;
56
    }
57
58
59
    public function getPartySlug(): string {
60
        return $this->member_distribution->party_slug;
61
    }
62
63
    public function getVotingPeriod(): string {
64
        return $this->member_distribution->period_slug;
65
    }
66
67
    public function getPolicyId(): int {
68
        if ($this->member_distribution) {
69
            return $this->member_distribution->policy_id;
70
        }
71
        if ($this->comparison_distribution) {
72
            return $this->comparison_distribution->policy_id;
73
        }
74
        throw new \Exception('No policy ID found for this pair');
75
    }
76
77
    public function scoreDifference(): float {
78
79
        if (!$this->comparison_distribution) {
80
            return 0;
81
        }
82
83
        return $this->member_distribution->distance_score - $this->comparison_distribution->distance_score;
84
    }
85
86
87
    /**
88
     * Calculates the significance score difference.
89
     *
90
     * This function determines whether there is a significant difference
91
     * in scores between two policy distributions.
92
     * This is used to see if it should be highlighted separately as a difference with the party.
93
     * A different is significant is a members and the comparison score are
94
     * strongly directional in different directions.
95
     * e.g. as distance is between 0 and 1
96
     * if the member score is less than 0.4 and the comparison score is greater than 0.6
97
     * or
98
     * if the member score is greater than 0.6 and the comparison score is less than 0.4
99
     * Significant differences
100
     * @return bool Returns true if a significant difference exists, otherwise false.
101
     */
102
    public function sigScoreDifference(): bool {
103
104
        if (!$this->comparison_distribution) {
105
            return false;
106
        }
107
108
        $member_score = $this->member_distribution->distance_score;
109
        $comparison_score = $this->comparison_distribution->distance_score;
110
111
        if ($this->member_distribution->noDataAvailable()) {
0 ignored issues
show
Bug introduced by
The method noDataAvailable() does not exist on null. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

111
        if ($this->member_distribution->/** @scrutinizer ignore-call */ noDataAvailable()) {

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
112
            return false;
113
        }
114
115
        if ($member_score < 0.4 && $comparison_score > 0.6) {
116
            return true;
117
        }
118
        if ($member_score > 0.6 && $comparison_score < 0.4) {
119
            return true;
120
        }
121
        return false;
122
123
    }
124
125
126
    /**
127
     * Retrieves the policy distribution pairs for a specific person, party, period, and chamber.
128
     *
129
     * @param int $person_id The ID of the person.
130
     * @param string $party_slug The slug of the party.
131
     * @param string $period_slug The slug of the period.
132
     * @param int $house The ID of the house (default is HOUSE_TYPE_COMMONS).
133
     * @return PolicyDistributionPair[] An array of PolicyDistributionPair objects.
134
     */
135
    public static function getPersonDistributions(int $person_id, string $party_slug, string $period_slug, int $house = HOUSE_TYPE_COMMONS): array {
136
137
        $distributions = PolicyDistribution::getPersonDistributions($person_id, $party_slug, $period_slug, $house);
138
139
        // Get annotation counts for all policies for this person
140
        $policies = new Policies();
141
        $annotation_counts = $policies->getAnnotationCountsForAllPolicies($person_id);
142
143
        // group the distributions by policy_id
144
        $grouped_distributions = [];
145
        foreach ($distributions as $distribution) {
146
            $grouped_distributions[$distribution->policy_id][] = $distribution;
147
        }
148
149
        $pairs = [];
150
        foreach ($grouped_distributions as $policy_id => $policy
151
        ) {
152
            $member_distribution = null;
153
            $comparison_distribution = null;
154
            foreach ($policy as $distribution) {
155
                if ($distribution->is_target) {
156
                    $member_distribution = $distribution;
157
                } else {
158
                    $comparison_distribution = $distribution;
159
                }
160
            }
161
            $pairs[] = new PolicyDistributionPair($member_distribution, $comparison_distribution, $annotation_counts);
162
        }
163
        return $pairs;
164
    }
165
166
}
167