Решение на Първа задача от Иван Кавалджиев

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

Към профила на Иван Кавалджиев

Резултати

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

Код

def series(type, number)
case type
when 'fibonacci' then series_element_generator(1, 1, number)
when 'lucas' then series_element_generator(2, 1, number)
when 'summed' then series('fibonacci', number) + series('lucas', number)
end
end
def series_element_generator(first, second, number)
(number - 1).times { first, second = second, first + second }
first
end

Лог от изпълнението

............

Finished in 0.01318 seconds
12 examples, 0 failures

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

Иван обнови решението на 10.10.2014 03:00 (преди около 10 години)

+def series(type,number)
+ return fibonacci(number) if(type == 'fibonacci')
+ return lucas(number) if(type == 'lucas')
+ return summed(number) if(type == 'summed')
+end
+
+def fibonacci(number)
+ first, second = 0, 1
+ number.times { first,second = second, first + second }
+ return first
+end
+
+def lucas(number)
+ first, second = -1, 2
+ (number).times { first ,second = second, first + second }
+ return first
+end
+
+def summed(number)
+ fibonacci(number) + lucas(number)
+end

Добро решение. Лесно се чете и е с линейна сложност. Въпреки това имам няколко забележки:

  • Функциите fibonacci и lucas са почти идентични, опитай се да изведеш общия код в отделна функция.

  • При функциите fibonacci и lucas ще бъде по-ясно какво се случва, ако началните ти стойности са началните стойности от математическите редици.

  • Разгледай case конструкцията.

  • Whitespace-a при запетаите на двойното присвояване не е добре.

  • Няма нужда да пишеш return в края на функциите. Функциите винаги връщат последния остойностен израз.

  • Скобите около number на 15-ти ред са излишни. Бъди консистентен :).

Съгласен съм с всичко :). Само не знам дали има итерактивен подход, при който да се започне с началните стойности от математическите редици? Грешка ли е, ако оставя началните стойности да са тези, с които съм работил сега?

Има :).

Не е грешка, ако са такива началните стойности, просто е хубаво кодът да е максимално изразителен и ясен. При теб е така, но и задачата е лека. Ще ти дам hint :

Помисли над number.times. Например 0.times { ... } няма да изпълни блока.

Иван обнови решението на 10.10.2014 22:14 (преди около 10 години)

def series(type,number)
- return fibonacci(number) if(type == 'fibonacci')
- return lucas(number) if(type == 'lucas')
- return summed(number) if(type == 'summed')
+ case type
+ when 'fibonacci' then fibonacci(number)
+ when 'lucas' then lucas(number)
+ else summed(number)
+ end
end
def fibonacci(number)
- first, second = 0, 1
- number.times { first,second = second, first + second }
- return first
+ auxiliary(1,1,number)
end
def lucas(number)
- first, second = -1, 2
- (number).times { first ,second = second, first + second }
- return first
+ auxiliary(2,1,number)
end
+
+def summed(number)
+ fibonacci(number) + lucas(number)
+end
+
+def auxiliary(first,second,number)
+ (number-1).times { first,second = second,first + second }
+ first
+end
+
def summed(number)
fibonacci(number) + lucas(number)
end

Иван обнови решението на 11.10.2014 00:55 (преди около 10 години)

def series(type,number)
case type
when 'fibonacci' then fibonacci(number)
when 'lucas' then lucas(number)
else summed(number)
end
end
def fibonacci(number)
auxiliary(1,1,number)
end
def lucas(number)
auxiliary(2,1,number)
end
def summed(number)
fibonacci(number) + lucas(number)
end
def auxiliary(first,second,number)
(number-1).times { first,second = second,first + second }
first
end
-
-def summed(number)
- fibonacci(number) + lucas(number)
-end

Иван обнови решението на 11.10.2014 01:20 (преди около 10 години)

def series(type,number)
case type
- when 'fibonacci' then fibonacci(number)
- when 'lucas' then lucas(number)
+ when 'fibonacci' then series_element_generator(1,1,number)
+ when 'lucas' then series_element_generator(2,1,number)
else summed(number)
end
end
def fibonacci(number)
- auxiliary(1,1,number)
+ series_element_generator(1,1,number)
end
def lucas(number)
- auxiliary(2,1,number)
+ series_element_generator(2,1,number)
end
def summed(number)
fibonacci(number) + lucas(number)
end
-def auxiliary(first,second,number)
+def series_element_generator(first,second,number)
(number-1).times { first,second = second,first + second }
first
end
+

Добре се получава. :)

Хубаво е, че си се сетил да преименуваш auxiliary, защото това име не носи никаква информация. Помощна функция, но какво точно прави, не става ясно от името. series_element_generator е по-добре. Аз лично бих предпочел глагола compute вместо generate, но и така е ок.

Функциите fibonacci и lucas не са ти нужни вече, защото в series case-a е достатъчно описателен. Там е написано when 'fibonacci' then ... това ти наименова логиката след then и тъй като въпросната логика е достатъчно кратка, няма нужда да я именоваш още веднъж (като отделна функция), освен ако не искаш да я преизползваш някъде. Това можеш да го направиш и за summed. Може да махнеш функцията summed, а самото название summed да го вкараш в when при case-a. Така ще получиш и допълнителна функционалност - ако някой реши да подаде тип редица, който не се поддържа от series ще получи nil (case връща nil, ако никое условие не съвпадне и нямаш else), вместо summed. Получавайки nil веднага става ясно, че функцията не поддържа тази редица, докато връщайки summed, може да подведе ползвателя, че си имплементирал и тази хипотетична редица.

Предполагам че и сам си се досетил за това, но си запазил нещата по този начин, защото ако махнеш summed и използваш series_element_generator 5-ти ред ще ти стане много дълъг :). Помисли коя друга функция можеш да извикаш на 5-ти ред, която ти смята елемент от редицата на Фибоначи и елемент от редицата на Лукас.

P.S.

Виж в style guide-a как се индентира case и къде се оставя whitespace при оператори (на 22 ред има такъв проблем). Винаги оставяй място след запетая.

Иван обнови решението на 12.10.2014 00:47 (преди около 10 години)

def series(type,number)
case type
- when 'fibonacci' then series_element_generator(1,1,number)
- when 'lucas' then series_element_generator(2,1,number)
- else summed(number)
+ when 'fibonacci' then series_element_generator(1,1,number)
+ when 'lucas' then series_element_generator(2,1,number)
+ when 'summed' then series('fibonacci',number) + series('lucas',number)
end
end
-def fibonacci(number)
- series_element_generator(1,1,number)
-end
-def lucas(number)
- series_element_generator(2,1,number)
-end
-
-def summed(number)
- fibonacci(number) + lucas(number)
-end
-
def series_element_generator(first,second,number)
- (number-1).times { first,second = second,first + second }
+ (number-1).times { first, second = second, first + second }
first
end
+

Иван обнови решението на 13.10.2014 22:19 (преди около 10 години)

-def series(type,number)
+def series(type, number)
case type
- when 'fibonacci' then series_element_generator(1,1,number)
- when 'lucas' then series_element_generator(2,1,number)
- when 'summed' then series('fibonacci',number) + series('lucas',number)
+ when 'fibonacci' then series_element_generator(1, 1, number)
+ when 'lucas' then series_element_generator(2, 1, number)
+ when 'summed' then series('fibonacci', number) + series('lucas', number)
end
end
-def series_element_generator(first,second,number)
- (number-1).times { first, second = second, first + second }
+def series_element_generator(first, second, number)
+ (number - 1).times { first, second = second, first + second }
first
end

Готино :) Последни много дребни забележки.

  • Оставяй по 1 ред между дефинициите на функциите.
  • Махни празните редове накрая.
  • Може да подравниш then-овете в case един под друг. Ето така:

    when 'happy'   then ..
    when 'hungry'  then ..
    when 'thirsty' then ..
    

    Това ти дава някакъв по-структуриран, табличен вид.

Иван обнови решението на 14.10.2014 16:18 (преди около 10 години)

def series(type, number)
case type
when 'fibonacci' then series_element_generator(1, 1, number)
- when 'lucas' then series_element_generator(2, 1, number)
- when 'summed' then series('fibonacci', number) + series('lucas', number)
+ when 'lucas' then series_element_generator(2, 1, number)
+ when 'summed' then series('fibonacci', number) + series('lucas', number)
end
end
-
def series_element_generator(first, second, number)
(number - 1).times { first, second = second, first + second }
first
-end
-
+end
-
-