mysociety /
theyworkforyou
| 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
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
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
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 |