Witaj Gościu! ( Zaloguj | Rejestruj )

Forum PHP.pl

> [PHP]"problem plecakowy" - usprawnienie kodu
mike287
post 30.03.2018, 15:09:43
Post #1





Grupa: Zarejestrowani
Postów: 22
Pomógł: 0
Dołączył: 5.03.2017

Ostrzeżenie: (0%)
-----


Cześć,
dostałem zadanie ostatnio do rozwiązania tzw. "problem plecakowy", poniżej zamieszczam kod. Usłyszałem że jest zbyt mało obiektowy... czy macie jakieś wskazówki co można poprawić, albo jak do tego podejść ?
Chodzi mi o jakieś wskazówki, bo patrze na to i nie wiem co mam rozumieć przez za mało obiektowy kod...

informacje o przedmiotach jakie mam "wsadzic do plecaka zaciagam z pliku csv, gdzie w pierwszym wierszu sa nazwy kolumn, ktorych nie potrzebuje wiec dlatego napisane jest w kodzie tak by to pominąć.

  1.  
  2. <?php
  3.  
  4. class BagTask
  5. {
  6. private $arr;
  7. private $count;
  8. private $finalArr = [];
  9. private $weight;
  10. private $bagArr;
  11.  
  12. public function __construct($arr, $weight)
  13. {
  14. $this->arr = file($arr);
  15. $this->weight = $weight;
  16.  
  17. $this->countOfItemsInArray();
  18. $this->prepareArray();
  19. $this->changeKeyNames();
  20. $this->sort();
  21. $this->toBag();
  22. $this->summary();
  23. $this->showBag();
  24.  
  25. // var_dump($this->bagArr);
  26. }
  27.  
  28. /**
  29.  * Metoda countOfItemsInArray zwraca ilosc wierszy w tablyc arr (tam są przedtrzymywane dane z pliku csv)
  30.  */
  31.  
  32. public function countOfItemsInArray()
  33. {
  34. $this->count = count($this->arr);
  35. return $this->count;
  36. }
  37.  
  38. /**
  39.  * Metoda prepareArray tworzy tablice finalArr, wyrzuca "," między elementami i tworzy nowy wspólczynnik waga/wartość na 3 pozycji.
  40.  */
  41. public function prepareArray()
  42. {
  43.  
  44. $partArr = [];
  45. $finalArr = [];
  46.  
  47. for($i = 1; $i < $this->countOfItemsInArray(); $i++)
  48. {
  49. array_push($partArr, explode(",", $this->arr[$i]));
  50. array_push($finalArr, $partArr[$i-1]);
  51.  
  52. array_push($finalArr[$i-1], $partArr[$i-1][2] / $partArr[$i-1][1]);
  53.  
  54. }
  55. return $this->finalArr = $finalArr;
  56. }
  57.  
  58. /**
  59.  * Metoda changeKeyNames nadaje kluczom nazwy, zamiast liczb.
  60.  */
  61. public function changeKeyNames(){
  62.  
  63. $this->finalArr = array_map(function($arr) {
  64.  
  65. return array(
  66. 'id' => $arr[0],
  67. 'weight' => $arr[1],
  68. 'value' => $arr[2],
  69. 'W/V' => $arr[3]
  70. );
  71. }, $this->finalArr);
  72.  
  73. }
  74.  
  75. /**
  76.  * Metoda sort sortuje tablice tablic po współczynniku W/V od największego.
  77.  */
  78. public function sort(){
  79.  
  80. usort($this->finalArr, function ($item1, $item2) {
  81. if ($item1['W/V'] == $item2['W/V']) return 0;
  82. return $item1['W/V'] > $item2['W/V'] ? -1 : 1;
  83. });
  84.  
  85. }
  86.  
  87. /**
  88.  * Metoda toBag uzupełnia tablice plecaka pobierając z posegregowanej tablicy finalArr elementy
  89.  * na wejściu sprawdzając wagę elementu i zestawia ją z limitem jaki pozostał.
  90.  */
  91. public function toBag()
  92. {
  93. $bagLimit = 0;
  94. $bagArr = [];
  95. for ($i = 0; $i < $this->countOfItemsInArray()-1; $i++)
  96. {
  97. if($this->finalArr[$i]['weight'] <= $this->weight)
  98. {
  99. $bagLimit += $this->finalArr[$i]['weight'];
  100.  
  101. if ($bagLimit <= $this->weight)
  102. {
  103. array_push($bagArr, $this->finalArr[$i]);
  104. }
  105. }
  106. }
  107.  
  108. return $this->bagArr = $bagArr;
  109. }
  110.  
  111. /**
  112.  * Metoda countOfItemsInTheBag, podaje ilość elementów wsadzonych do plecaka
  113.  */
  114.  
  115. public function countOfItemsInTheBag()
  116. {
  117. $countOfItemsInTheBag = count($this->bagArr);
  118.  
  119. return $countOfItemsInTheBag;
  120. }
  121.  
  122. /**
  123.  * Metoda weightOfBag, zwraca wagę plecaka
  124.  */
  125.  
  126. public function weightOfBag()
  127. {
  128. $weight = 0;
  129. foreach ($this->bagArr as $key)
  130. {
  131. $weight += $key['weight'];
  132. }
  133. return $weight;
  134. }
  135.  
  136. /**
  137.  * Metoda valueOfBag, zwraca wartość plecaka
  138.  */
  139. public function valueOfBag()
  140. {
  141. $value = 0;
  142. foreach ($this->bagArr as $key)
  143. {
  144. $value += $key['value'];
  145. }
  146. return $value;
  147. }
  148.  
  149. /**
  150.  * Metoda showBag, zwraca informacje wyjściowe na temat plecaka
  151.  */
  152. public function showBag()
  153. {
  154. $i = 0;
  155. foreach ($this->bagArr as $value)
  156. { $i++;
  157.  
  158. echo "przedmiot ".$i." o id ".$value['id']." jego waga - ".$value['weight']." wartość to ".$value['value']."<br>";
  159.  
  160. }
  161. }
  162.  
  163. /**
  164.  * Metoda summary, wyświetla informacje na temat przedmiotów w plecaku
  165.  */
  166. public function summary()
  167. {
  168. echo "liczba elementów znajdujących się w plecaku to ".$this->countOfItemsInTheBag()."<br>";
  169. echo "limit plecaka = ".$this->weight."<br>";
  170. echo "wykorzystana waga plecaka = ".$this->weightOfBag()."<br>";
  171. echo "całkowita wartość plecaka = ".$this->valueOfBag()."<br>";
  172.  
  173. }
  174.  
  175. }
  176.  
  177. $bag = new BagTask('csvArray.csv', 1);
  178.  
Go to the top of the page
+Quote Post
 
Start new topic
Odpowiedzi (1 - 5)
Tomplus
post 30.03.2018, 15:58:40
Post #2





Grupa: Zarejestrowani
Postów: 1 874
Pomógł: 230
Dołączył: 20.03.2005
Skąd: Będzin

Ostrzeżenie: (0%)
-----


Swoją drogą, problem plecakowy dotyczy bardziej pojemności kontenerów, a nie ilości przedmiotów w kontenerze.

Ja w takich przypadkach posługuję się gotową klasą:
https://github.com/dvdoug/BoxPacker
Go to the top of the page
+Quote Post
mike287
post 30.03.2018, 16:22:29
Post #3





Grupa: Zarejestrowani
Postów: 22
Pomógł: 0
Dołączył: 5.03.2017

Ostrzeżenie: (0%)
-----


zastanawia mnie co w tym kodzie jest takiego ze jest "zbyt mało obiektowy", widzialem tez roznego rodzaju rozwiazania problemu plecakowego, ale napisalem swoj i chcialem sie poradzic co tu mozna zmienic zeby byl lepszy
Go to the top of the page
+Quote Post
rad11
post 30.03.2018, 16:25:30
Post #4





Grupa: Zarejestrowani
Postów: 1 270
Pomógł: 184
Dołączył: 7.10.2012
Skąd: Warszawa

Ostrzeżenie: (0%)
-----


Poczytaj o https://pl.m.wikipedia.org/wiki/SOLID_(prog...anie_obiektowe) te wiadomosci napewno pozwola Ci zrobic z Twojego kodu bardziej obiektowy
Go to the top of the page
+Quote Post
emillo91
post 2.04.2018, 15:02:08
Post #5





Grupa: Zarejestrowani
Postów: 129
Pomógł: 13
Dołączył: 29.03.2012

Ostrzeżenie: (0%)
-----


Możliwe, że chodzi tutaj o dużą ilość pętli. Na przykład metoda toBag mogłaby być od razu implementowana w metodzie countOfItemsInTheBag(). Wszystko wyświetlasz w konstruktorze i może o to chodzi.
Go to the top of the page
+Quote Post
markuz
post 2.04.2018, 19:26:35
Post #6





Grupa: Zarejestrowani
Postów: 1 240
Pomógł: 278
Dołączył: 11.03.2008

Ostrzeżenie: (0%)
-----


Masz 1 klasę a na szybko narzucają się przynajmniej 2 - Bag, Element (chociaż nazwa element jest trochę za ogólna i przydało by się ją skrócić do konkretnego problemu np. Apple jeżeli w Bag możemy trzymać tylko jabłka, ew. przedmiot).

W konstruktorze jako arr podajesz nazwę pliku CSV - czyli przy zmianie sposobu wczytywaniu danych trzeba zmieniać twoją klasę - tam mógłby być jakiś interfejs np. Source + implementacja Source z CSV np. CSVSource dzięki czemu masz już 4 klasy.

Co tam robi zakomentowany var_dump?
Dlaczego nie używasz PHP 7.1?

Nie ma żadnego wyjątku a jak np. bag się przepełni to powinien zostać rzucony wyjątek.

Patrząc na wnętrze konstruktora już wiadomo, że ten kod coś nie halo wink.gif


--------------------
Go to the top of the page
+Quote Post

Reply to this topicStart new topic
1 Użytkowników czyta ten temat (1 Gości i 0 Anonimowych użytkowników)
0 Zarejestrowanych:

 



RSS Wersja Lo-Fi Aktualny czas: 2.07.2025 - 03:20