Passed
Pull Request — develop (#27)
by Glynn
03:24 queued 41s
created

isFactorOf()   A

Complexity

Conditions 4
Paths 2

Size

Total Lines 22
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 4
eloc 8
nc 2
nop 1
dl 0
loc 22
rs 10
c 0
b 0
f 0
1
<?php
2
3
/**
4
 * Number functions.
5
 *
6
 * This file is part of PinkCrab Function Constructors.
7
 *
8
 * PinkCrab Function Constructors is free software: you can redistribute it and/or modify it under the terms of the
9
 * GNU General Public License as published by the Free Software Foundation, either version 2
10
 * of the License, or (at your option) any later version.
11
 *
12
 * PinkCrab Function Constructors is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
13
 * even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
14
 * See the GNU General Public License for more details.
15
 *
16
 * You should have received a copy of the GNU General Public License along with PinkCrab Function Constructors.
17
 * If not, see <https://www.gnu.org/licenses/>.
18
 *
19
 * @author Glynn Quelch <[email protected]>
20
 * @license http://www.gnu.org/licenses/old-licenses/gpl-2.0-standalone.html
21
 * @package PinkCrab\FunctionConstructors
22
 * @since 0.0.1
23
 *
24
 * @template Number of int|float
25
 * @phpstan-template Number of int|float
26
 * @psalm-template Number of int|float
27
 */
28
29
declare(strict_types=1);
30
31
namespace PinkCrab\FunctionConstructors\Numbers;
32
33
use Closure;
34
use InvalidArgumentException;
35
use PinkCrab\FunctionConstructors\Comparisons as C;
1 ignored issue
show
Bug introduced by
The type PinkCrab\FunctionConstructors\Comparisons was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
36
37
/**
38
 * Used to accumulate integers
39
 *
40
 * @param int $initial
41
 * @return Closure(int|null):(Closure|int)
42
 */
43
function accumulatorInt(int $initial = 0): Closure
44
{
45
    /**
46
     * @param int|null $value
47
     * @return Closure(int|null):(Closure|int)|int
48
     */
49
    return function (?int $value = null) use ($initial) {
50
        if ($value) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $value of type integer|null is loosely compared to true; this is ambiguous if the integer can be 0. You might want to explicitly use !== null instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For integer values, zero is a special case, in particular the following results might be unexpected:

0   == false // true
0   == null  // true
123 == false // false
123 == null  // false

// It is often better to use strict comparison
0 === false // false
0 === null  // false
Loading history...
51
            $initial += $value;
52
        }
53
        return $value ? accumulatorInt($initial) : $initial;
54
    };
55
}
56
57
/**
58
 * Used to accumulate floats
59
 *
60
 * @param float $initial
61
 * @return Closure(float|null):(Closure|float)
62
 */
63
function accumulatorFloat(float $initial = 0): Closure
64
{
65
    /**
66
     * @param float|null $value
67
     * @return Closure(float|null):(Closure|float)|float
68
     */
69
    return function (?float $value = null) use ($initial) {
70
        if ($value) {
71
            $initial += $value;
72
        }
73
        return $value ? accumulatorFloat($initial) : $initial;
74
    };
75
}
76
77
/**
78
 * Returns a function for adding a fixed amount.
79
 *
80
 * @param Number $initial Defaults to 0
81
 * @return Closure(Number):Number
82
 * @throws InvalidArgumentException If neither int or float passed.
83
 */
84
function sum($initial = 0): Closure
85
{
86
    if (! C\isNumber($initial)) {
1 ignored issue
show
Bug introduced by
The function isNumber was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

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

86
    if (! /** @scrutinizer ignore-call */ C\isNumber($initial)) {
Loading history...
87
        throw new InvalidArgumentException(__FUNCTION__ . 'only accepts a Number (Float or Int)');
88
    }
89
90
    /**
91
     * @param Number $value
92
     * @return int|float
93
     */
94
    return function ($value) use ($initial) {
95
        return $initial + $value;
96
    };
97
}
98
99
100
/**
101
 * Returns a function for adding a fixed amount.
102
 *
103
 * @param int $initial Defaults to 0
104
 * @return Closure(Number):Number
105
 * @throws InvalidArgumentException If neither int or float passed.
106
 */
107
function subtract($initial = 0): Closure
108
{
109
    if (! C\isNumber($initial)) {
1 ignored issue
show
Bug introduced by
The function isNumber was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

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

109
    if (! /** @scrutinizer ignore-call */ C\isNumber($initial)) {
Loading history...
110
        throw new InvalidArgumentException(__FUNCTION__ . 'only accepts a Number (Float or Int)');
111
    }
112
113
    /**
114
     * @param Number $value
115
     * @return int|float
116
     */
117
    return function ($value) use ($initial) {
118
        return $value - $initial;
119
    };
120
}
121
122
123
/**
124
 * Returns a function for multiplying a fixed amount.
125
 *
126
 * @param Number $initial Defaults to 1
127
 * @return Closure(Number):Number
128
 * @throws InvalidArgumentException
129
 */
130
function multiply($initial = 1): Closure
131
{
132
    if (! C\isNumber($initial)) {
1 ignored issue
show
Bug introduced by
The function isNumber was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

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

132
    if (! /** @scrutinizer ignore-call */ C\isNumber($initial)) {
Loading history...
133
        throw new InvalidArgumentException(__FUNCTION__ . 'only accepts a Number (Float or Int)');
134
    }
135
136
    /**
137
     * @param Number $value
138
     * @return Number
139
     */
140
    return function ($value) use ($initial) {
141
        return $value * $initial;
142
    };
143
}
144
145
146
147
/**
148
 * Returns a function for divideBy a fixed amount.
149
 *
150
 * @param float $divisor The value to divide the passed value by
151
 * @return Closure(Number):float
152
 */
153
function divideBy($divisor = 1): Closure
154
{
155
    if (! C\isNumber($divisor)) {
1 ignored issue
show
Bug introduced by
The function isNumber was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

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

155
    if (! /** @scrutinizer ignore-call */ C\isNumber($divisor)) {
Loading history...
156
        throw new \InvalidArgumentException(__FUNCTION__ . 'only accepts a Number (Float or Int)');
157
    }
158
159
    /**
160
     * @param float $value
161
     * @return float
162
     */
163
    return function ($value) use ($divisor): float {
164
        return $value / $divisor;
165
    };
166
}
167
168
/**
169
 * Returns a function for divideInto a fixed amount.
170
 *
171
 * @param float $dividend The value to divide the passed value by
172
 * @return Closure(Number):float
173
 */
174
function divideInto($dividend = 1): Closure
175
{
176
    if (! C\isNumber($dividend)) {
1 ignored issue
show
Bug introduced by
The function isNumber was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

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

176
    if (! /** @scrutinizer ignore-call */ C\isNumber($dividend)) {
Loading history...
177
        throw new \InvalidArgumentException(__FUNCTION__ . 'only accepts a Number (Float or Int)');
178
    }
179
180
    /**
181
     * @param float $value
182
     * @return float
183
     */
184
    return function ($value) use ($dividend): float {
185
        return $dividend / $value;
186
    };
187
}
188
189
/**
190
 * Returns a function for getting the remainder with a fixed divisor.
191
 *
192
 * @param float $divisor
193
 * @return Closure(Number):float
194
 */
195
function remainderBy($divisor = 1): Closure
196
{
197
    if (! C\isNumber($divisor)) {
1 ignored issue
show
Bug introduced by
The function isNumber was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

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

197
    if (! /** @scrutinizer ignore-call */ C\isNumber($divisor)) {
Loading history...
198
        throw new \InvalidArgumentException(__FUNCTION__ . 'only accepts a Number (Float or Int)');
199
    }
200
201
    /**
202
     * @param float $value
203
     * @return float
204
     */
205
    return function ($value) use ($divisor): float {
206
        return $value % $divisor;
207
    };
208
}
209
210
/**
211
 * Returns a function for getting the remainder with a fixed dividend.
212
 *
213
 * @param float $dividend
214
 * @return Closure(Number):float
215
 */
216
function remainderInto($dividend = 1): Closure
217
{
218
    if (! C\isNumber($dividend)) {
1 ignored issue
show
Bug introduced by
The function isNumber was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

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

218
    if (! /** @scrutinizer ignore-call */ C\isNumber($dividend)) {
Loading history...
219
        throw new \InvalidArgumentException(__FUNCTION__ . 'only accepts a Number (Float or Int)');
220
    }
221
222
    /**
223
     * @param float $value
224
     * @return float
225
     */
226
    return function ($value) use ($dividend): float {
227
        return $dividend % $value;
228
    };
229
}
230
231
/**
232
 * Returns a function for checking if a number has a factor of another number.
233
 *
234
 * @param Number $factor
235
 * @return Closure(Number):bool
236
 * @throws InvalidArgumentException If neither int or float passed.
237
 */
238
function isFactorOf($factor): Closure
239
{
240
    if (! C\isNumber($factor)) {
1 ignored issue
show
Bug introduced by
The function isNumber was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

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

240
    if (! /** @scrutinizer ignore-call */ C\isNumber($factor)) {
Loading history...
241
        throw new \InvalidArgumentException(__FUNCTION__ . 'only accepts a Number (Float or Int)');
242
    }
243
244
    /**
245
     * @param Number $value
246
     * @return bool
247
 * @throws InvalidArgumentException If neither int or float passed.
248
     */
249
    return function ($value) use ($factor): bool {
250
        if (! C\isNumber($value)) {
1 ignored issue
show
Bug introduced by
The function isNumber was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

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

250
        if (! /** @scrutinizer ignore-call */ C\isNumber($value)) {
Loading history...
251
            throw new \InvalidArgumentException(__FUNCTION__ . 'only accepts a Number (Float or Int)');
252
        }
253
254
        // Return false if 0
255
        if ($value === 0) {
256
            return false;
257
        }
258
259
        return $value % $factor === 0;
260
    };
261
}
262
263
264
/**
265
 * Returns a function for getting the remainder with a fixed dividend.
266
 *
267
 * @param int $precision Number of decimal places.
268
 * @return Closure(Number):float
269
 */
270
function round($precision = 1): Closure
271
{
272
    if (! C\isNumber($precision)) {
1 ignored issue
show
Bug introduced by
The function isNumber was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

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

272
    if (! /** @scrutinizer ignore-call */ C\isNumber($precision)) {
Loading history...
273
        throw new \InvalidArgumentException(__FUNCTION__ . 'only accepts a Number (Float or Int)');
274
    }
275
276
    /**
277
     * @param Number $value
278
     * @return float
279
     */
280
    return function ($value) use ($precision): float {
281
        if (! C\isNumber($value)) {
1 ignored issue
show
Bug introduced by
The function isNumber was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

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

281
        if (! /** @scrutinizer ignore-call */ C\isNumber($value)) {
Loading history...
282
            throw new \InvalidArgumentException("Num\\round() only accepts a valid Number ( Int|Float -> Float )");
283
        }
284
        return \round(\floatval($value), $precision);
285
    };
286
}
287