Passed
Push — master ( a96f03...4562f1 )
by
unknown
02:32
created

SvmDataset::parseLine()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 10
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 10
rs 9.4285
c 0
b 0
f 0
cc 1
eloc 6
nc 1
nop 1
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Phpml\Dataset;
6
7
use Phpml\Exception\DatasetException;
8
use Phpml\Exception\FileException;
9
10
class SvmDataset extends ArrayDataset
11
{
12
    public function __construct(string $filePath)
13
    {
14
        [$samples, $targets] = self::readProblem($filePath);
0 ignored issues
show
Bug introduced by
The variable $samples does not exist. Did you forget to declare it?

This check marks access to variables or properties that have not been declared yet. While PHP has no explicit notion of declaring a variable, accessing it before a value is assigned to it is most likely a bug.

Loading history...
Bug introduced by
The variable $targets does not exist. Did you forget to declare it?

This check marks access to variables or properties that have not been declared yet. While PHP has no explicit notion of declaring a variable, accessing it before a value is assigned to it is most likely a bug.

Loading history...
15
16
        parent::__construct($samples, $targets);
17
    }
18
19
    private static function readProblem(string $filePath): array
20
    {
21
        $handle = self::openFile($filePath);
22
23
        $samples = [];
24
        $targets = [];
25
        $maxIndex = 0;
26
        while (($line = fgets($handle)) !== false) {
27
            [$sample, $target, $maxIndex] = self::processLine($line, $maxIndex);
0 ignored issues
show
Bug introduced by
The variable $sample seems only to be defined at a later point. Did you maybe move this code here without moving the variable definition?

This error can happen if you refactor code and forget to move the variable initialization.

Let’s take a look at a simple example:

function someFunction() {
    $x = 5;
    echo $x;
}

The above code is perfectly fine. Now imagine that we re-order the statements:

function someFunction() {
    echo $x;
    $x = 5;
}

In that case, $x would be read before it is initialized. This was a very basic example, however the principle is the same for the found issue.

Loading history...
Bug introduced by
The variable $target does not exist. Did you mean $targets?

This check looks for variables that are accessed but have not been defined. It raises an issue if it finds another variable that has a similar name.

The variable may have been renamed without also renaming all references.

Loading history...
28
            $samples[] = $sample;
0 ignored issues
show
Bug introduced by
The variable $sample seems only to be defined at a later point. Did you maybe move this code here without moving the variable definition?

This error can happen if you refactor code and forget to move the variable initialization.

Let’s take a look at a simple example:

function someFunction() {
    $x = 5;
    echo $x;
}

The above code is perfectly fine. Now imagine that we re-order the statements:

function someFunction() {
    echo $x;
    $x = 5;
}

In that case, $x would be read before it is initialized. This was a very basic example, however the principle is the same for the found issue.

Loading history...
29
            $targets[] = $target;
0 ignored issues
show
Bug introduced by
The variable $target does not exist. Did you mean $targets?

This check looks for variables that are accessed but have not been defined. It raises an issue if it finds another variable that has a similar name.

The variable may have been renamed without also renaming all references.

Loading history...
30
        }
31
32
        fclose($handle);
33
34
        foreach ($samples as &$sample) {
35
            $sample = array_pad($sample, $maxIndex + 1, 0);
36
        }
37
38
        return [$samples, $targets];
39
    }
40
41
    private static function openFile(string $filePath)
42
    {
43
        if (!file_exists($filePath)) {
44
            throw FileException::missingFile(basename($filePath));
45
        }
46
47
        $handle = fopen($filePath, 'rb');
48
        if ($handle === false) {
49
            throw FileException::cantOpenFile(basename($filePath));
50
        }
51
52
        return $handle;
53
    }
54
55
    private static function processLine(string $line, int $maxIndex): array
56
    {
57
        $columns = self::parseLine($line);
58
59
        $target = self::parseTargetColumn($columns[0]);
60
        $sample = array_fill(0, $maxIndex + 1, 0);
61
62
        $n = count($columns);
63
        for ($i = 1; $i < $n; ++$i) {
64
            [$index, $value] = self::parseFeatureColumn($columns[$i]);
0 ignored issues
show
Bug introduced by
The variable $index does not exist. Did you forget to declare it?

This check marks access to variables or properties that have not been declared yet. While PHP has no explicit notion of declaring a variable, accessing it before a value is assigned to it is most likely a bug.

Loading history...
Bug introduced by
The variable $value does not exist. Did you forget to declare it?

This check marks access to variables or properties that have not been declared yet. While PHP has no explicit notion of declaring a variable, accessing it before a value is assigned to it is most likely a bug.

Loading history...
65
            if ($index > $maxIndex) {
66
                $maxIndex = $index;
67
                $sample = array_pad($sample, $maxIndex + 1, 0);
68
            }
69
70
            $sample[$index] = $value;
71
        }
72
73
        return [$sample, $target, $maxIndex];
74
    }
75
76
    private static function parseLine(string $line): array
77
    {
78
        $line = explode('#', $line, 2)[0];
79
        $line = rtrim($line);
80
        $line = str_replace("\t", ' ', $line);
81
82
        $columns = explode(' ', $line);
83
84
        return $columns;
85
    }
86
87
    private static function parseTargetColumn(string $column): float
88
    {
89
        if (!is_numeric($column)) {
90
            throw DatasetException::invalidTarget($column);
91
        }
92
93
        return (float) $column;
94
    }
95
96
    private static function parseFeatureColumn(string $column): array
97
    {
98
        $feature = explode(':', $column, 2);
99
        if (count($feature) != 2) {
100
            throw DatasetException::invalidValue($column);
101
        }
102
103
        $index = self::parseFeatureIndex($feature[0]);
104
        $value = self::parseFeatureValue($feature[1]);
105
106
        return [$index, $value];
107
    }
108
109
    private static function parseFeatureIndex(string $index): int
110
    {
111
        if (!is_numeric($index) || !ctype_digit($index)) {
112
            throw DatasetException::invalidIndex($index);
113
        }
114
115
        if ((int) $index < 1) {
116
            throw DatasetException::invalidIndex($index);
117
        }
118
119
        return (int) $index - 1;
120
    }
121
122
    private static function parseFeatureValue(string $value): float
123
    {
124
        if (!is_numeric($value)) {
125
            throw DatasetException::invalidValue($value);
126
        }
127
128
        return (float) $value;
129
    }
130
}
131