Трета задача

  1. Та четох четох и още четох, гледах spec-а прочетох от тук от там (stackoverflow) какво прави let и съответно не получих сам отговор на въпроса който ще последва :)

    Въпросния въпрос:

    inventory = Invenotory.new
    inventory.register 'Green Tea',    '0.79'
    inventory.register 'Earl Grey',    '0.99'
    
    cart = inventоry.new_cart
    inventory.register 'Black Coffee', '1.99'
    cart.add 'Green Tea'
    cart.add 'Earl Grey', 3
    cart.add 'Black Coffee', 2 # грешка или трябва да сработи ? 
    

    П.П.: Въпроса е на последния ред от кода

    Разликата между двете е голяма от гледна точка на имплементация и никой от дадените тестове нито документацията хвърля някаква светлина върху въпроса.

  2. @Михаил

    Редактирах ти поста и го форматирах адекватно. Моля те, научи Markdown и следващия път го направи сам. Може да бъркам, но мисля, че това не е първия път, в който ти го казвам. Можеш да си редактираш поста и да видиш какво точно съм оправил.

    Колкото до let:

    Значи, в RSpec следното нещо е един test case:

    it "does something" do
      answer = 42
      answer.should eq 42
    end
    

    Тази част с should eq е като assertEqual. Това ясно. Сега с let:

    let(:answer) { 42 }
    
    it "does something" do
      answer.should eq 42
    end
    

    Първо, let добавя метод с името на символа в контекста на теста. Съответно, в answer.should eq 42, answer е метод. Това е удобен начин да изваждаш общите неща за всички тестове. Далеч по-удобно от променлива в setUp блок.

    Второ, let прави мемоизация. Демек, изпълнява блока само веднъж. При повторни извиквания на answer се връща резултата, без да се изчислява блока отново.

    В примерния тест, има само един инвентар (достъпен като inventory) и само една количка (достъпна като cart).

  3. Не бъркаш.

    Ще ги кача малко по-късно. За нетърпеливите, въртят се около 2 нива на влагане, 8 реда в метод и 10 метода в клас.

    За протокола, аз съм с 1 ниво на влагане, 5 реда на метод и 8 метода в клас. Не правя нищо сложно. Искам просто да преценя колко отстъпка да ви дам.

  4. Простичко.

    Това дава малко абстракция. По този начин количката може да е всякакъв клас. Може да го кръстите както искате. Конструктора му може да взема каквито критерии искате.

  5. Oтносно принтването на бележката: та или аз нещо съм недоразбрала или примерчетата са малко сбъркани.

    Ако имаме за продукт промоция тип get_one_free n, не трябва ли в бележката да пише (buy n, get 1 free), а не (buy n-1, get free) (както е в примерите). Нали идеята е да купиш определения брой, за да получиш безплатен.

  6. Да, трябва да си купиш n-те продукта, и от тях един ти е безплатен. Т.е. когато купиш n продукта, плащаш n - 1, а 1 е free. Mоже би е малко по-удачно, да е paid, не buy или даже
    вместо
    (buy 2, get 1 free)
    да е
    (buy 3, pay 2, get 1 free)

    PS това е примерът за зеления чай

  7. Искам да попитам дали за един продукт могат да се регистрират повече от една промоция и ако да - в какъв ред трябва да се прилагат и дали да имат отношение една към друга (как да се отразява в касовата бележка и в total например).

  8. @Тони:

    Искам да попитам дали за един продукт могат да се регистрират повече от една промоция и ако да - в какъв ред трябва да се прилагат и дали да имат отношение една към друга (как да се отразява в касовата бележка и в total например).

    В условието пише така:

    Един продукт може да се пусне само под една промоция.

    Edit: Също така, понеже си зададох същите въпроси преди да си препрочета условието, нещата с купоните стоят така:

    Във всяка количка може да ползвате най-много един купон.

    Отстъпката от купона се прилага след отстъпката от промоции по продуктите. (б.м. важи и за двата купона)

    Ако отстъпката от купона е по-голяма от общата цена на продуктите, цената на цялата поръчка става 0.00. (б.м. важи само за втория купон)

  9. А ако се опитаме да регистрираме в Inventory един и същи купон два пъти? Т.е. inventory.register_coupon 'FREE BEER', amount: '2.00' inventory.register_coupon 'FREE BEER', amount: '1.00'

    трябва ли да гърми? Също, ако в количка опитаме да използваме купон, който не съществува, трябва да вдигнем изключение, нали така? Звучи логично да е така, просто го няма в условието (а като гледам, и в теста).

  10. Предполагам глупав въпрос, но какво точно се подава на inventory_register при промоция. Примерно inventory.register 'Gum', '1.00', get_one_free: 3 това get_one_free: 3 като String ли да го очакваме, т.е "get_one_free: 3" или е някаква по-шано форма за конструиране на hash (но не сработва в интерпретатора ми)?

  11. Предполагам глупав въпрос, но какво точно се подава на inventory_register при промоция. Примерно inventory.register 'Gum', '1.00', get_one_free: 3 това get_one_free: 3 като String ли да го очакваме, т.е "get_one_free: 3" или е някаква по-шано форма за конструиране на hash (но не сработва в интерпретатора ми)?

    Тук, тук и тук :)

    P.S. В Markdown inline код се загражда с `

  12. И аз имах такъв спомен, 10х :) Впрочем предполагам, че "Green tea" и "green tea" се считат за едни и същи продукти?(и изобщо всякакви вариации на case-a). Или не обръщаме внимание на такива неща?

    P.P също - може ли от количката да се махат някакви неща? Например cart.add 'Теа' -1

  13. @Мартин

    Всички такива въпроси са напълно отговорени от теста. Ако теста очаква "Green tea" и "green tea" да са един продукт, значи са един. Ако очаква да са различни, значи са различни. Ако не очаква нищо, значи няма значение и може да подходите както искате.

    Далеч по-интересно е ако не разбирате нещо в теста.

    П.П.: Поста на Пламен е жълт, защото печели точка. Печели точка, защото помага на другарчета. Ще се радвам всички да си помагате един на друг в този курс.

  14. Един малко тъп въпрос, но... Има ли нормален начин за форматиране на BigDecimal? Нещо като to_s, но с по-полезни параметри, в които да може да се задават брой цифри след десетичната запетая. Удачно ли е на monkey_patch-нем BigDecimal, ако няма?

  15. @Ивайло

    И аз се питах т'ва и стигнах до извода, че за тая цел може да се ползва това, ако целта ти е просто да определиш колко цифри искаш да има след запетаята в стринга. В случая просто добавянето на едно извикване на round като че ли е по-добра идея от monkey-patch. А и май от философска гледна точка, почти всичко е по-добре от monkey-patch.

  16. @Евгени

    Гледах го това преди да пиша, но на мен не ми върши никаква работа. Проблема не ми е, че имам повече цифри след десетичната запетая, а точно обратното. Имам 0.0 например и искам да стане 0.00. Ползвам sprintf, но се надявах да има нещо по-красиво :)

  17. Ако искаме да върнем многоредов стринг по-уместно ли е да си го сглобяваме на части или следното е приемливо: def multi_line_string <<LOTSOFLINES Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nam auctor enim id arcu vehicula tempus. Curabitur elit sapien, tincidunt eget sodales eu, vulputate vel leo. Aliquam id dui LOTSOFLINES end

  18. @Ивана, предполага се, че родителят не знае за съществуването на евентуални негови наследници. Следователно, не би трябвало да може да върне обкет от тип "някой мой наследник". Че може да стане в Ruby — може — но не е добра идея. Опитай да промениш дизайна (радикално) в тази част от кода, за да избегнеш тази ситуация.

    @Евгени, ако низът е статичен и ти се налага да го вкараш в кода, може да ползваш HEREDOCs, да, не е проблем. Виж spec-а на трета задача за пример.

  19. Забелязах грешка в spec.rb или в условието на задачката. Става въпрос по-конкретно за купон 'Фиксирана сума'. В условието се подава inventory.register_coupon 'FRIENDS', amount: '7.00' , т.е. цената е от тип String, а в spec.rb се подава BigDecimal : inventory.register_coupon 'TEA-TIME', amount: '10.00'.to_d

    Искам да попитам кой е валидният синтаксис?

    П.С. Интересно защо никой досега не е попитал това...Сигурно бъркам нещо?!

  20. @Мартин, в спецификацията (условието) на задачата, всички цени, които се подават на описаните методи, са текстови низове. Спецификацията в твоя случай е правилна и стойността на купона също трябва да се подава като текстови низ на register_coupon.

    Относно spec-а, в случая той не е правилен. Коригирал съм го, благодаря за бележката.

  21. Здравейте,

    само на мен ли ми се струва странно, че купона се регистрира в инвентара. Доколкото видях по примерите и тестовете навсякъде се използва една количка, но според мен е съвсем реален use-case от един инвентар да се вземат повече колички. Та, в такъв случай въпросът ми е - ако се вземат две колички и после се викне register_coupon към коя количка да се регистрира купона или въобще да предположим че количката е Singleton?

    П.П. Извинявам се, сега май разбрах какво се е имало впредвид...игнорирайте горното моля :).

  22. @Димитър Димитров Не беше ли по-разумният вариант да се промени в спецификацията на задачата това, а не в тестовете? Започнах да си пиша домашното във вторник и съответно тогава си свалих тестовете от github. Не прочетох поста на адаша и съответно сега имам 3 fail-a на новите тестове, при положение че преди нямах?

Трябва да сте влезли в системата, за да може да отговаряте на теми.