Completed
Pull Request — master (#122)
by Matthias
01:39
created

Result::getScore()   B

Complexity

Conditions 1
Paths 1

Size

Total Lines 35
Code Lines 11

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 35
rs 8.8571
c 0
b 0
f 0
cc 1
eloc 11
nc 1
nop 2
1
<?php declare(strict_types = 1);
2
3
namespace Churn\Results;
4
5
use Illuminate\Contracts\Support\Arrayable;
6
use Webmozart\Assert\Assert;
7
8
class Result implements Arrayable
9
{
10
    /**
11
     * The file property.
12
     * @var string
13
     */
14
    private $file;
15
16
    /**
17
     * The commits property.
18
     * @var integer
19
     */
20
    private $commits;
21
22
    /**
23
     * The complexity property.
24
     * @var integer
25
     */
26
    private $complexity;
27
28
    /**
29
     * Class constructor.
30
     * @param array $data Data to store in the object.
31
     */
32
    public function __construct(array $data)
33
    {
34
        $this->file       = $data['file'];
35
        $this->commits    = $data['commits'];
36
        $this->complexity = $data['complexity'];
37
    }
38
39
    /**
40
     * Get the file property.
41
     * @return string
42
     */
43
    public function getFile(): string
44
    {
45
        return $this->file;
46
    }
47
48
    /**
49
     * Get the file property.
50
     * @return integer
51
     */
52
    public function getCommits(): int
53
    {
54
        return $this->commits;
55
    }
56
57
    /**
58
     * Get the file property.
59
     * @return integer
60
     */
61
    public function getComplexity(): int
62
    {
63
        return $this->complexity;
64
    }
65
66
    /**
67
     * Calculate the score.
68
     * @return float
69
     */
70
    public function getScore(int $maxCommits, int $maxComplexity): float
71
    {
72
        Assert::greaterThan($maxComplexity, 0);
73
        Assert::greaterThan($maxCommits, 0);
74
75
        /*
76
         * Calculate the horizontal and vertical distance from the "top right"
77
         * corner.
78
         */
79
        $horizontalDistance = $maxCommits - $this->getCommits();
80
        $verticalDistance = $maxComplexity - $this->getComplexity();
81
82
        /*
83
         * Normalize these values over time, we first divide by the maximum
84
         * values, to always end up with distances between 0 and 1.
85
         */
86
        $normalizedHorizontalDistance = $horizontalDistance / $maxCommits;
87
        $normalizedVerticalDistance = $verticalDistance / $maxComplexity;
88
89
        /*
90
         * Calculate the distance of this class from the "top right" corner,
91
         * using the simple formula A^2 + B^2 = C^2; or: C = sqrt(A^2 + B^2)).
92
         */
93
        $distanceFromTopRightCorner = sqrt(
94
            $normalizedHorizontalDistance ** 2
95
            + $normalizedVerticalDistance ** 2
96
        );
97
98
        /*
99
         * The resulting value will be between 0 and sqrt(2). A short distance is bad,
100
         * so in order to end up with a high score, we invert the value by
101
         * subtracting it from 1.
102
         */
103
        return 1 - $distanceFromTopRightCorner;
104
    }
105
106
    /**
107
     * Output results to an array.
108
     * @return array
109
     */
110
    public function toArray(): array
111
    {
112
        return [
113
            $this->getFile(),
114
            $this->getCommits(),
115
            $this->getComplexity()
116
        ];
117
    }
118
}
119