Решение на Четвърта задача от Тони Ризов

Обратно към всички решения

Към профила на Тони Ризов

Резултати

  • 0 точки от тестове
  • 0 бонус точки
  • 0 точки общо
  • 0 успешни тест(а)
  • 0 неуспешни тест(а)

Код

REPOSITORY = 'https://github.com/HaNdyMaN89/ruby-retrospective-1'
#зад 1:
#1) В occurences_count трябваше индексирането на върнатия речник да връща 0,
# ако елемент не се среща в масива, затова инициализирах речника с Hash.new(0).
#2) Enumerable#inject се оказа неподходящо за някои от функциите, например при моето старо
# решение на функцията subarray_count давах начална стойност [0, 0] (първият елемент на
# двойката следи началото на потенциалния подмасив, а във втория се трупа броят намерени
# досега срещания) и при празен масив, вместо функцията да върне 0, тя връща [0, 0].
#3) Enumerable#each_cons е много подходящо за subarray_count, т.к. връща всички подмасиви от
# поредни елементи на масива с определена дължина.
#4) В index_by използвам функцията to_hash и map, генериращ стойността на дадения блок за
# всяка стойност на масива, zip-вам масива и map-а и от получения масив от двойки връщам речник.
#5) Т.к. в index_by се изисква стойностите на блоковете да са ключовете, а самите елементи на
# масива да са стойностите на речника, използвах Hash.invert
# (можеше и map(...).zip(self) наистина).
#6) При фигурни скоби {thing} да се форматира { thing }.
#7) На методите to_hash и occurences_count може да се използва Object#tap.
#зад 2:
#8) Имам функция is_desired? на класа Song, в която акумулирах (desired = desired and ...) на
# boolean променлива резултата от проверката за всеки възможен критерий. Mоже директно
# да се връща false с return, ако някоя проверка не мине.
#9) Вместо да намирам стойността на tag без последния символ така : tag[0..tag.length - 2],
# използвам tag.chomp('!').
#10) collect { |attr| attr.strip } може да се запише така : collect(&:strip).
#11) От тази : if genre_sub.length > 1 then genre_sub[1] else nil end проверка няма нужда,
# т.к. genre_sub[1] ще върне nil, ако дължината на масива е <= 1.
#12) След горната поправка може двата реда genre = genre_sub[0] и subgenre = genre_sub[1]
# направо да се заместят с genre, subgenre = genre_sub.
#13) self. е излишно, т.к. така и така методът е на самата инстанция на класа,
# за която се вика последвалия метод/поле.
#14) Вместо да се прави проверка за типа на tags в метода includes_tags? на Song, на tags
# може да се зададе нова стойност, която ще върне масив от tags, ако tags е String, и
# самия tags в противен случай :
# - tags = Array(tags)
# - tags = [*tags]
# - tags = [tags].flatten
#15) has_tag? на класа Song може да се напише с изключващо или :
# tag.end_with?("!") ^ @tags.include?(tag.chomp "!")
# (ако tag завършва на '!', то очакваме tags.include?(tag.chomp "!") да е false и, ако tag
# не завършва на '!', то искаме tags.include? tag да е true, a tag.chomp "!" ще върне
# самия tag)
#зад.3
#16) Вместо @name + " " * (32 - @name.length) може да се използва sptrinf("%-32s", @name).
#17) По-добре е да има различни класове за различните промоции и купони, т.к. ако в
# спецификацията се добави възможността за други купони или промоции, на много места ще трябва
# да се правят промени в противен случай.
#18) attr_reader е било излишно в много от класовете, т.к. достъпвам само методите в тях.
#19) Би трябвало вместо купоните и продуктите да се пазят в inventory-то в речници, да се пазят
# в списъци, т.к. досега бях направил ключа да е името на продукта/купона, което
# може да създаде проблеми при промяна на спецификацията (например ако може да има два
# продукта с едно и също име).
#20) За регистрирация на купони и продукти в inventory-то е удобно да има метод
# find_product/find_coupon, който да хвърля грешка при невалидни параметри.

История (1 версия и 0 коментара)

Тони обнови решението на 12.11.2011 21:27 (преди над 12 години)

+REPOSITORY = 'https://github.com/HaNdyMaN89/ruby-retrospective-1'
+
+#зад 1:
+#1) В occurences_count трябваше индексирането на върнатия речник да връща 0,
+# ако елемент не се среща в масива, затова инициализирах речника с Hash.new(0).
+#2) Enumerable#inject се оказа неподходящо за някои от функциите, например при моето старо
+# решение на функцията subarray_count давах начална стойност [0, 0] (първият елемент на
+# двойката следи началото на потенциалния подмасив, а във втория се трупа броят намерени
+# досега срещания) и при празен масив, вместо функцията да върне 0, тя връща [0, 0].
+#3) Enumerable#each_cons е много подходящо за subarray_count, т.к. връща всички подмасиви от
+# поредни елементи на масива с определена дължина.
+#4) В index_by използвам функцията to_hash и map, генериращ стойността на дадения блок за
+# всяка стойност на масива, zip-вам масива и map-а и от получения масив от двойки връщам речник.
+#5) Т.к. в index_by се изисква стойностите на блоковете да са ключовете, а самите елементи на
+# масива да са стойностите на речника, използвах Hash.invert
+# (можеше и map(...).zip(self) наистина).
+#6) При фигурни скоби {thing} да се форматира { thing }.
+#7) На методите to_hash и occurences_count може да се използва Object#tap.
+#зад 2:
+#8) Имам функция is_desired? на класа Song, в която акумулирах (desired = desired and ...) на
+# boolean променлива резултата от проверката за всеки възможен критерий. Mоже директно
+# да се връща false с return, ако някоя проверка не мине.
+#9) Вместо да намирам стойността на tag без последния символ така : tag[0..tag.length - 2],
+# използвам tag.chomp('!').
+#10) collect { |attr| attr.strip } може да се запише така : collect(&:strip).
+#11) От тази : if genre_sub.length > 1 then genre_sub[1] else nil end проверка няма нужда,
+# т.к. genre_sub[1] ще върне nil, ако дължината на масива е <= 1.
+#12) След горната поправка може двата реда genre = genre_sub[0] и subgenre = genre_sub[1]
+# направо да се заместят с genre, subgenre = genre_sub.
+#13) self. е излишно, т.к. така и така методът е на самата инстанция на класа,
+# за която се вика последвалия метод/поле.
+#14) Вместо да се прави проверка за типа на tags в метода includes_tags? на Song, на tags
+# може да се зададе нова стойност, която ще върне масив от tags, ако tags е String, и
+# самия tags в противен случай :
+# - tags = Array(tags)
+# - tags = [*tags]
+# - tags = [tags].flatten
+#15) has_tag? на класа Song може да се напише с изключващо или :
+# tag.end_with?("!") ^ @tags.include?(tag.chomp "!")
+# (ако tag завършва на '!', то очакваме tags.include?(tag.chomp "!") да е false и, ако tag
+# не завършва на '!', то искаме tags.include? tag да е true, a tag.chomp "!" ще върне
+# самия tag)
+#зад.3
+#16) Вместо @name + " " * (32 - @name.length) може да се използва sptrinf("%-32s", @name).
+#17) По-добре е да има различни класове за различните промоции и купони, т.к. ако в
+# спецификацията се добави възможността за други купони или промоции, на много места ще трябва
+# да се правят промени в противен случай.
+#18) attr_reader е било излишно в много от класовете, т.к. достъпвам само методите в тях.
+#19) Би трябвало вместо купоните и продуктите да се пазят в inventory-то в речници, да се пазят
+# в списъци, т.к. досега бях направил ключа да е името на продукта/купона, което
+# може да създаде проблеми при промяна на спецификацията (например ако може да има два
+# продукта с едно и също име).
+#20) За регистрирация на купони и продукти в inventory-то е удобно да има метод
+# find_product/find_coupon, който да хвърля грешка при невалидни параметри.