Passed
Push — 3.x ( f78397...42dd24 )
by Doug
09:29
created

PackedBoxList::count()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

Changes 0
Metric Value
cc 1
eloc 1
nc 1
nop 0
dl 0
loc 3
ccs 2
cts 2
cp 1
crap 1
rs 10
c 0
b 0
f 0
1
<?php
2
/**
3
 * Box packing (3D bin packing, knapsack problem).
4
 *
5
 * @author Doug Wright
6
 */
7
declare(strict_types=1);
8
9
namespace DVDoug\BoxPacker;
10
11
use ArrayIterator;
12
use function count;
13
use Countable;
14
use IteratorAggregate;
15
use JsonSerializable;
16
use function reset;
17
use ReturnTypeWillChange;
18
use function round;
19
use Traversable;
20
21
/**
22
 * List of packed boxes.
23
 *
24
 * @author Doug Wright
25
 */
26
class PackedBoxList implements IteratorAggregate, Countable, JsonSerializable
27
{
28
    /**
29
     * List containing boxes.
30
     *
31
     * @var PackedBox[]
32
     */
33
    private $list = [];
34
35
    /**
36
     * @return Traversable|PackedBox[]
37
     */
38 28
    public function getIterator(): Traversable
39
    {
40 28
        return new ArrayIterator($this->list);
41
    }
42
43
    /**
44
     * Number of items in list.
45
     */
46 39
    public function count(): int
47
    {
48 39
        return count($this->list);
49
    }
50
51 44
    public function insert(PackedBox $item): void
52
    {
53 44
        $this->list[] = $item;
54
    }
55
56
    /**
57
     * Do a bulk insert.
58
     *
59
     * @internal
60
     *
61
     * @param PackedBox[] $boxes
62
     */
63 13
    public function insertFromArray(array $boxes): void
64
    {
65 13
        foreach ($boxes as $box) {
66 13
            $this->insert($box);
67
        }
68
    }
69
70
    /**
71
     * @internal
72
     */
73 6
    public function top(): PackedBox
74
    {
75 6
        return reset($this->list);
76
    }
77
78
    /**
79
     * Calculate the average (mean) weight of the boxes.
80
     */
81 14
    public function getMeanWeight(): float
82
    {
83 14
        $meanWeight = 0;
84
85
        /** @var PackedBox $box */
86 14
        foreach ($this->list as $box) {
87 14
            $meanWeight += $box->getWeight();
88
        }
89
90 14
        return $meanWeight / count($this->list);
91
    }
92
93
    /**
94
     * Calculate the average (mean) weight of the boxes.
95
     */
96 12
    public function getMeanItemWeight(): float
97
    {
98 12
        $meanWeight = 0;
99
100
        /** @var PackedBox $box */
101 12
        foreach ($this->list as $box) {
102 12
            $meanWeight += $box->getItemWeight();
103
        }
104
105 12
        return $meanWeight / count($this->list);
106
    }
107
108
    /**
109
     * Calculate the variance in weight between these boxes.
110
     */
111 13
    public function getWeightVariance(): float
112
    {
113 13
        $mean = $this->getMeanWeight();
114
115 13
        $weightVariance = 0;
116
        /** @var PackedBox $box */
117 13
        foreach ($this->list as $box) {
118 13
            $weightVariance += ($box->getWeight() - $mean) ** 2;
119
        }
120
121 13
        return round($weightVariance / count($this->list), 1);
122
    }
123
124
    /**
125
     * Get volume utilisation of the set of packed boxes.
126
     */
127 1
    public function getVolumeUtilisation(): float
128
    {
129 1
        $itemVolume = 0;
130 1
        $boxVolume = 0;
131
132
        /** @var PackedBox $box */
133 1
        foreach ($this as $box) {
134 1
            $boxVolume += $box->getInnerVolume();
135
136
            /** @var PackedItem $item */
137 1
            foreach ($box->getItems() as $item) {
138 1
                $itemVolume += ($item->getItem()->getWidth() * $item->getItem()->getLength() * $item->getItem()->getDepth());
139
            }
140
        }
141
142 1
        return round($itemVolume / $boxVolume * 100, 1);
143
    }
144
145 1
    #[ReturnTypeWillChange]
146
    public function jsonSerialize()/* : mixed */
147
    {
148 1
        return $this->list;
149
    }
150
}
151