Решение на Първа задача от Мая Терзиева

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

Към профила на Мая Терзиева

Резултати

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

Код

def calculate_member(first_member, second_member, number)
current_member, next_member = first_member, second_member
1.upto(number - 1) do
current_member, next_member = next_member, current_member + next_member
end
current_member
end
def series(series, number)
return calculate_member(1, 1, number) if series == "fibonacci"
return calculate_member(2, 1, number) if series == "lucas"
calculate_member(1, 1, number) + calculate_member(2, 1, number)
end

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

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

Finished in 0.01285 seconds
12 examples, 0 failures

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

Мая обнови решението на 10.10.2014 16:28 (преди около 10 години)

+def calculate_member(first, second, number)
+ (1...number).each { first, second = second, first + second }
+ first
+end
+
+def series(series, number)
+ return calculate_member(1, 1, number) if series == "fibonacci"
+ return calculate_member(2, 1, number) if series == "lucas"
+ calculate_member(1, 1, number) + calculate_member(2, 1, number)
+end
  • Какво са first и second? Може би първият и вторият ред на редицата. Но после стават на нещо друго.
  • Много се радвам, че си видяла за множественото присвояване на един ред. Но като цяло избягвай да го използваш в цикли - не винаги е най-четимото нещо, а и създава масиви зад завесите. По принцип не гоним оптималност на кода, но spawn-ването на количество short lived обекти не е добра практика.
  • В подобна ситуация се предпочита x.upto(y) за конструиране на Range. .. и ... обикновено се ползват в комбинация с === или when.

Ще е супер ако успееш да адресираш горните точки и останеш с ясен код. Ако не - обмисли дали можеш да пренапишеш имплементацията си на calculate_member.

  • Опционално може да експериментираш дали if - elsif - else или case без return-и биха повишили естетичността на кода :)

Благодаря за бързия коментар!

Абсолютно съгласна съм с първа точка. Много ми се искаше да измисля някакво кратко и хитро решение, но изглежда само на кратко го докарах... Осъзнавам, че съм нарушила поне два основни принципа.

По втора точка, наистина не знаех какво се случва "зад завесите", благодаря.

По трета точка, признавам, че въобще не зная Ruby и едва ли не останах с впечатлението, че съдържа множество взаимозаменяеми конструкции/методи/... И че някак просто трябва да си харесам тази, която ми допада (: . Имам много да чета, дааа. Ще го махна това.

По опционалната точка - след лекцията с коментарите по решенията на първото предизвикателство, си помислих, че такъв обратен запис + ранен return са по-привлекателни от if - elsif - else. Още повече, че ми спестиха редове, с case skeptic ми пищеше. Наистина ли не е естетично? Признавам си, че на мен ми харесва така и, ако не е подсъдимо, бих го оставила.

За всичко друго, благодаря още веднъж! Ще поровя документация, ще помисля и ще опитам да подобря!

Никога не се притеснявай от незнанието си, още повече за неща, които все още не сме преподали. (: Точно обратното - радвай се, че си се сблъскала с тях.

Ясно и кратко е за предпочитане пред кратко и хитро. Само ясно - също.

Да, в Ruby има много синоними/алтернативни форми. Може да се каже, че спадат в една от три категории:

  1. Едното от двете е за предпочитане в 99-100% от случаите и не трябва да използваш другото изобщо или освен ако не знаеш защо.
  2. И двете се използват, но за различни ситуации.
  3. И двете се използват в еднаква ситуация и е въпрос на автора да реши кое е по-благозвучно в конкретния случай.

Начините за получаване на Range спадат повече към втората категория.

За case - можеш да се вместиш в ограниченията с when - then. Не, return x if y не е лошо, но аз не бих го ползвал ако ще го сложа на всеки ред, освен последния.

Мая обнови решението на 15.10.2014 16:13 (преди около 10 години)

-def calculate_member(first, second, number)
- (1...number).each { first, second = second, first + second }
- first
+def calculate_member(first_member, second_member, number)
+ current_member, next_member = first_member, second_member
+ 1.upto(number - 1) do
+ current_member, next_member = next_member, current_member + next_member
+ end
+ current_member
end
def series(series, number)
return calculate_member(1, 1, number) if series == "fibonacci"
return calculate_member(2, 1, number) if series == "lucas"
calculate_member(1, 1, number) + calculate_member(2, 1, number)
end

Надявам се, че опитът да поправя именуването на променливи не е направило по-голяма каша. (:

Забележката за множественото присвояване не я адресирам с ясното съзнание, че, щом ми е направена, могат да ми бъдат отнети точки по нея.

Да видим...

Не сме толкова зли, че да ви вземем точки още от първата задача. (:

И все пак, наистина ли това:

current_member, next_member = next_member, current_member + next_member

ти изглежда по-четимо от това:

current_member = next_member
next_member    = current_member + next_member

Не, въобще не ми изглежда по-четимо.

Признавам си, че минах през това на двата реда, пуснах тестовете и... :D Смешно, при положение, че първото нещо, което се учи след "Hello world!" е размяна на стойностите на променливи. Отне ми известно време да гледам тъпо, докато разбера какъв ми е проблемът. Но допълнителен ред не можех да си позволя. Не че нямаше какво друго да се направи, но не исках да променям твърде много първоначалното решение, както си го бях надробила.

Мерси, че си отдели време да погледнеш, въпреки, че срокът изтече!