Completed
Push — master ( a49478...ff8a6e )
by Pol
01:00 queued 10s
created

Combinatorics::count()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

Changes 0
Metric Value
dl 0
loc 4
ccs 2
cts 2
cp 1
rs 10
c 0
b 0
f 0
cc 1
eloc 2
nc 1
nop 0
crap 1
1
<?php
2
3
namespace drupol\phpermutations;
4
5
/**
6
 * Class Combinatorics.
7
 */
8
abstract class Combinatorics implements \Countable
9
{
10
    /**
11
     * The dataset.
12
     *
13
     * @var array
14
     */
15
    protected $dataset;
16
17
    /**
18
     * The number of values in the dataset.
19
     *
20
     * @var int
21
     */
22
    protected $datasetCount;
23
24
    /**
25
     * The length.
26
     *
27
     * @var int
28
     */
29
    protected $length;
30
31
    /**
32
     * Combinatorics constructor.
33
     *
34
     * @param array    $dataset
35
     *                          The dataset
36
     * @param int|null $length
37
     *                          The length
38
     */
39 52
    public function __construct(array $dataset = [], $length = null)
40
    {
41 52
        $this->setDataset($dataset);
42 52
        $this->datasetCount = count($this->dataset);
43 52
        $this->setLength($length);
44 52
    }
45
46
    /**
47
     * Set the length.
48
     *
49
     * @param int $length
50
     *                    The length
51
     *
52
     * @return $this
53
     */
54 40 View Code Duplication
    public function setLength($length = null)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
55
    {
56 40
        $length = (null === $length) ? $this->datasetCount : $length;
57 40
        $this->length = ($length > $this->datasetCount) ? $this->datasetCount : $length;
58
59 40
        return $this;
60
    }
61
62
    /**
63
     * Get the length.
64
     *
65
     * @return int
66
     *             The length
67
     */
68 14
    public function getLength()
69
    {
70 14
        return (int) $this->length;
71
    }
72
73
    /**
74
     * Set the dataset.
75
     *
76
     * @param array $dataset
77
     *                       The dataset
78
     *
79
     * @return $this
80
     */
81 52
    public function setDataset(array $dataset = [])
82
    {
83 52
        $this->dataset = $dataset;
84
85 52
        return $this;
86
    }
87
88
    /**
89
     * Get the dataset.
90
     *
91
     * @return mixed[]
92
     *                 The dataset
93
     */
94 34
    public function getDataset()
95
    {
96 34
        return $this->dataset;
97
    }
98
99
    /**
100
     * Count elements of an object.
101
     *
102
     * @return int
103
     *             The number of element
104
     */
105 10
    public function count()
106
    {
107 10
        return count($this->toArray());
108
    }
109
110
    /**
111
     * Convert the iterator into an array.
112
     *
113
     * @return array
114
     *               The elements
115
     */
116 22 View Code Duplication
    public function toArray()
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
117
    {
118 22
        $data = [];
119
120 22
        for ($this->rewind(); $this->valid(); $this->next()) {
0 ignored issues
show
Bug introduced by
It seems like you code against a specific sub-type and not the parent class drupol\phpermutations\Combinatorics as the method rewind() does only exist in the following sub-classes of drupol\phpermutations\Combinatorics: drupol\phpermutations\Generators\Combinations, drupol\phpermutations\Generators\Fibonacci, drupol\phpermutations\Generators\FiniteGroup, drupol\phpermutations\Generators\NGrams, drupol\phpermutations\Generators\Perfect, drupol\phpermutations\Generators\Prime, drupol\phpermutations\Generators\PrimeFactors, drupol\phpermutations\Generators\Product, drupol\phpermutations\Generators\Shift, drupol\phpermutations\Iterators\Combinations, drupol\phpermutations\Iterators\Cycle, drupol\phpermutations\Iterators\Fibonacci, drupol\phpermutations\Iterators\FiniteGroup, drupol\phpermutations\Iterators\NGrams, drupol\phpermutations\Iterators\Perfect, drupol\phpermutations\Iterators\Prime, drupol\phpermutations\Iterators\PrimeFactors, drupol\phpermutations\Iterators\Product, drupol\phpermutations\Iterators\Rotation, drupol\phpermutations\Iterators\Shift. Maybe you want to instanceof check for one of these explicitly?

Let’s take a look at an example:

abstract class User
{
    /** @return string */
    abstract public function getPassword();
}

class MyUser extends User
{
    public function getPassword()
    {
        // return something
    }

    public function getDisplayName()
    {
        // return some name.
    }
}

class AuthSystem
{
    public function authenticate(User $user)
    {
        $this->logger->info(sprintf('Authenticating %s.', $user->getDisplayName()));
        // do something.
    }
}

In the above example, the authenticate() method works fine as long as you just pass instances of MyUser. However, if you now also want to pass a different sub-classes of User which does not have a getDisplayName() method, the code will break.

Available Fixes

  1. Change the type-hint for the parameter:

    class AuthSystem
    {
        public function authenticate(MyUser $user) { /* ... */ }
    }
    
  2. Add an additional type-check:

    class AuthSystem
    {
        public function authenticate(User $user)
        {
            if ($user instanceof MyUser) {
                $this->logger->info(/** ... */);
            }
    
            // or alternatively
            if ( ! $user instanceof MyUser) {
                throw new \LogicException(
                    '$user must be an instance of MyUser, '
                   .'other instances are not supported.'
                );
            }
    
        }
    }
    
Note: PHP Analyzer uses reverse abstract interpretation to narrow down the types inside the if block in such a case.
  1. Add the method to the parent class:

    abstract class User
    {
        /** @return string */
        abstract public function getPassword();
    
        /** @return string */
        abstract public function getDisplayName();
    }
    
Loading history...
Bug introduced by
It seems like you code against a specific sub-type and not the parent class drupol\phpermutations\Combinatorics as the method valid() does only exist in the following sub-classes of drupol\phpermutations\Combinatorics: drupol\phpermutations\Generators\Combinations, drupol\phpermutations\Generators\Fibonacci, drupol\phpermutations\Generators\FiniteGroup, drupol\phpermutations\Generators\NGrams, drupol\phpermutations\Generators\Perfect, drupol\phpermutations\Generators\Prime, drupol\phpermutations\Generators\PrimeFactors, drupol\phpermutations\Generators\Product, drupol\phpermutations\Generators\Shift, drupol\phpermutations\Iterators\Combinations, drupol\phpermutations\Iterators\Cycle, drupol\phpermutations\Iterators\Fibonacci, drupol\phpermutations\Iterators\FiniteGroup, drupol\phpermutations\Iterators\NGrams, drupol\phpermutations\Iterators\Perfect, drupol\phpermutations\Iterators\Prime, drupol\phpermutations\Iterators\PrimeFactors, drupol\phpermutations\Iterators\Product, drupol\phpermutations\Iterators\Rotation, drupol\phpermutations\Iterators\Shift. Maybe you want to instanceof check for one of these explicitly?

Let’s take a look at an example:

abstract class User
{
    /** @return string */
    abstract public function getPassword();
}

class MyUser extends User
{
    public function getPassword()
    {
        // return something
    }

    public function getDisplayName()
    {
        // return some name.
    }
}

class AuthSystem
{
    public function authenticate(User $user)
    {
        $this->logger->info(sprintf('Authenticating %s.', $user->getDisplayName()));
        // do something.
    }
}

In the above example, the authenticate() method works fine as long as you just pass instances of MyUser. However, if you now also want to pass a different sub-classes of User which does not have a getDisplayName() method, the code will break.

Available Fixes

  1. Change the type-hint for the parameter:

    class AuthSystem
    {
        public function authenticate(MyUser $user) { /* ... */ }
    }
    
  2. Add an additional type-check:

    class AuthSystem
    {
        public function authenticate(User $user)
        {
            if ($user instanceof MyUser) {
                $this->logger->info(/** ... */);
            }
    
            // or alternatively
            if ( ! $user instanceof MyUser) {
                throw new \LogicException(
                    '$user must be an instance of MyUser, '
                   .'other instances are not supported.'
                );
            }
    
        }
    }
    
Note: PHP Analyzer uses reverse abstract interpretation to narrow down the types inside the if block in such a case.
  1. Add the method to the parent class:

    abstract class User
    {
        /** @return string */
        abstract public function getPassword();
    
        /** @return string */
        abstract public function getDisplayName();
    }
    
Loading history...
Bug introduced by
It seems like you code against a specific sub-type and not the parent class drupol\phpermutations\Combinatorics as the method next() does only exist in the following sub-classes of drupol\phpermutations\Combinatorics: drupol\phpermutations\Generators\Combinations, drupol\phpermutations\Generators\Fibonacci, drupol\phpermutations\Generators\FiniteGroup, drupol\phpermutations\Generators\NGrams, drupol\phpermutations\Generators\Perfect, drupol\phpermutations\Generators\Prime, drupol\phpermutations\Generators\PrimeFactors, drupol\phpermutations\Generators\Product, drupol\phpermutations\Generators\Shift, drupol\phpermutations\Iterators\Combinations, drupol\phpermutations\Iterators\Cycle, drupol\phpermutations\Iterators\Fibonacci, drupol\phpermutations\Iterators\FiniteGroup, drupol\phpermutations\Iterators\NGrams, drupol\phpermutations\Iterators\Perfect, drupol\phpermutations\Iterators\Prime, drupol\phpermutations\Iterators\PrimeFactors, drupol\phpermutations\Iterators\Product, drupol\phpermutations\Iterators\Rotation, drupol\phpermutations\Iterators\Shift. Maybe you want to instanceof check for one of these explicitly?

Let’s take a look at an example:

abstract class User
{
    /** @return string */
    abstract public function getPassword();
}

class MyUser extends User
{
    public function getPassword()
    {
        // return something
    }

    public function getDisplayName()
    {
        // return some name.
    }
}

class AuthSystem
{
    public function authenticate(User $user)
    {
        $this->logger->info(sprintf('Authenticating %s.', $user->getDisplayName()));
        // do something.
    }
}

In the above example, the authenticate() method works fine as long as you just pass instances of MyUser. However, if you now also want to pass a different sub-classes of User which does not have a getDisplayName() method, the code will break.

Available Fixes

  1. Change the type-hint for the parameter:

    class AuthSystem
    {
        public function authenticate(MyUser $user) { /* ... */ }
    }
    
  2. Add an additional type-check:

    class AuthSystem
    {
        public function authenticate(User $user)
        {
            if ($user instanceof MyUser) {
                $this->logger->info(/** ... */);
            }
    
            // or alternatively
            if ( ! $user instanceof MyUser) {
                throw new \LogicException(
                    '$user must be an instance of MyUser, '
                   .'other instances are not supported.'
                );
            }
    
        }
    }
    
Note: PHP Analyzer uses reverse abstract interpretation to narrow down the types inside the if block in such a case.
  1. Add the method to the parent class:

    abstract class User
    {
        /** @return string */
        abstract public function getPassword();
    
        /** @return string */
        abstract public function getDisplayName();
    }
    
Loading history...
121 22
            $data[] = $this->current();
0 ignored issues
show
Bug introduced by
It seems like you code against a specific sub-type and not the parent class drupol\phpermutations\Combinatorics as the method current() does only exist in the following sub-classes of drupol\phpermutations\Combinatorics: drupol\phpermutations\Generators\Combinations, drupol\phpermutations\Generators\Fibonacci, drupol\phpermutations\Generators\FiniteGroup, drupol\phpermutations\Generators\NGrams, drupol\phpermutations\Generators\Perfect, drupol\phpermutations\Generators\Prime, drupol\phpermutations\Generators\PrimeFactors, drupol\phpermutations\Generators\Product, drupol\phpermutations\Generators\Shift, drupol\phpermutations\Iterators\Combinations, drupol\phpermutations\Iterators\Cycle, drupol\phpermutations\Iterators\Fibonacci, drupol\phpermutations\Iterators\FiniteGroup, drupol\phpermutations\Iterators\NGrams, drupol\phpermutations\Iterators\Perfect, drupol\phpermutations\Iterators\Prime, drupol\phpermutations\Iterators\PrimeFactors, drupol\phpermutations\Iterators\Product, drupol\phpermutations\Iterators\Rotation, drupol\phpermutations\Iterators\Shift. Maybe you want to instanceof check for one of these explicitly?

Let’s take a look at an example:

abstract class User
{
    /** @return string */
    abstract public function getPassword();
}

class MyUser extends User
{
    public function getPassword()
    {
        // return something
    }

    public function getDisplayName()
    {
        // return some name.
    }
}

class AuthSystem
{
    public function authenticate(User $user)
    {
        $this->logger->info(sprintf('Authenticating %s.', $user->getDisplayName()));
        // do something.
    }
}

In the above example, the authenticate() method works fine as long as you just pass instances of MyUser. However, if you now also want to pass a different sub-classes of User which does not have a getDisplayName() method, the code will break.

Available Fixes

  1. Change the type-hint for the parameter:

    class AuthSystem
    {
        public function authenticate(MyUser $user) { /* ... */ }
    }
    
  2. Add an additional type-check:

    class AuthSystem
    {
        public function authenticate(User $user)
        {
            if ($user instanceof MyUser) {
                $this->logger->info(/** ... */);
            }
    
            // or alternatively
            if ( ! $user instanceof MyUser) {
                throw new \LogicException(
                    '$user must be an instance of MyUser, '
                   .'other instances are not supported.'
                );
            }
    
        }
    }
    
Note: PHP Analyzer uses reverse abstract interpretation to narrow down the types inside the if block in such a case.
  1. Add the method to the parent class:

    abstract class User
    {
        /** @return string */
        abstract public function getPassword();
    
        /** @return string */
        abstract public function getDisplayName();
    }
    
Loading history...
122
        }
123
124 22
        return $data;
125
    }
126
127
    /**
128
     * {@inheritdoc}
129
     */
130 16
    public function key()
0 ignored issues
show
Documentation introduced by
The return type could not be reliably inferred; please add a @return annotation.

Our type inference engine in quite powerful, but sometimes the code does not provide enough clues to go by. In these cases we request you to add a @return annotation as described here.

Loading history...
131
    {
132 16
        return $this->key;
133
    }
134
135
    /**
136
     * Compute the factorial of an integer.
137
     *
138
     * @param int $n
139
     *                   The number to get its factorial
140
     * @param int $total
141
     *                   The total
142
     *
143
     * @return int
144
     *             The factorial of $n
145
     */
146 10
    protected function fact($n, $total = 1)
0 ignored issues
show
Comprehensibility introduced by
Avoid variables with short names like $n. Configured minimum length is 3.

Short variable names may make your code harder to understand. Variable names should be self-descriptive. This check looks for variable names who are shorter than a configured minimum.

Loading history...
147
    {
148 10
        return ($n < 2) ? $total : $this->fact($n - 1, $total * $n);
149
    }
150
}
151