Втора задача

  1. С малко закъснение втора задача е вече качена. Тук може да задавате въпроси.

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

    Извиняваме се за закъснението!

    Постът беше редактиран. Ето и оригинала:

    Втора задача

    • Ще ви я пуснем до края на деня
    • Проверете на обичайното място"

    ...из "Материали", лекция 7, 30.10.2013

    Задача няма все още

  2. @Георги Кръстев, добър въпрос!

    Вярно е първото от изброените. Ако имаме задача с етикет foo (но без bar) и задача с етикет bar (но без foo), то филтриране с Criteria.tags(%w[foo bar]) няма да върне нищо.

    Условието е обновено, както и примерните тестове.

  3. @Кристиян, не се работи с файлове, а с текстови низове. На метода TodoList.parse му подаваме направо текстов низ със "съдържанието на файла", ако предположим, че нещата са били във файл.

    Забележете, че това е добра абстракция, понеже позволява информацията за todo списъка да не се намира само в локален текстов файл. Може да е в базата данни, може да дойде някъде по мрежата, може потребител да я въведе... Всичко ще работи.

  4. Има ли някакъв шанс това:

    • TodoList#tasks_todo - връща броя на задачите, които трябва да се направят (със статус :todo).

    • TodoList#tasks_in_progress - връща броя на задачите, които са в прогрес (със статус :current).

    • TodoList#tasks_completed - връща броя на завършените задачи (със статус :done).

    да го уеднаквим малко? :) т.е. методите да се казват например TodoList#tasks_todo, TodoList#tasks_current и TodoList#tasks_done?

  5. @Георги, интересна бележка. Ще оставя Христо да си каже мнението, като автор на задачата, имащ повече контекст от мен и ще добавя само това:

    Аз бих кръстил тези методи completed_tasks, pending_tasks и tasks_in_progress, например, а не с тази "обратна" граматика. Да ги кръстим както ти предлагаш, ми харесва от гледна точка на консистентност, но бих разместил tasks_current -> current_tasks и tasks_done -> done_tasks (макар че това не звучи много добре).

    И последно, вече сме дали задачата и е минало немалко време от срока и за съжаление, не е много добра идея да сменяме интерфейса сега, дори сегашният да не е добре дефиниран.

  6. @Митьо, на мен done_tasks и current_tasks ми звучат ок, но todo_tasks не чак толкова :)

    Иначе, поне на мен като цяло не ми харесва особено това, че tasks_X връща броя на задачите с този статус, а не списък от задачи - по-интуитивно би ми било второто :) Ако говорим за реална употреба, всеки може да направи list.done_tasks.size - така ще има и лесен достъп до всички задачи с даден статус и ще ползва Criteria само за по-сложни търсения :)

    • Знам, че се прецака консистентността, но така имената на методите звучаха по-добре.

    • Предложените от Митьо имена определено са по-добре.

    • @Георги Гърдев, прав си за последното. Исках да има нещо, което да води статистика за задачите, но определено не го измислих като хората. Като се замисля сега метод като stats, който да връща хеш с ключ - статус и стойност - броя на задачите с тоя статус би било добра алтернатива.

    Но както каза Митьо, за съжаление вече е късно да се променя условието.

  7. @Димитър Ок, щом предполагаме, че нещата са били във файл, тогава така ли ще се подава стринга в параметрите на метода: "TODO | Eat spaghetti. | High | food, happiness\nTODO | Get 8 hours of sleep. | Low | health...\n\eof", защото както забелязах няма как да стане с copy/paste директно.

  8. @Кристиян, не те разбрах. Какво общо има copy/paste? Освен това, не мислете за файлове. Файловете нямат нищо общо в случая. Ще получавате просто текст с по едно todo на ред. Редовете ще са разделени с \n, ако държите да знаете това, макар че не би трябвало да ви интересува.

    P.S. Форматирането на поста ти не ми помага да разбера какво искаш да кажеш. Даже по-скоро ми пречи.

  9. @Димитър Отивам в условието на задачата тук в сайта, селектирам входния низ, давам му Copy, след това в Interactive Ruby му давам Paste на мястото на параметъра на метода.Сега разбра ли ?

    Защото иначе ще трябва за тестовете си да пиша "единият ред\nдругият ред\nтретиятн ред", което при 100 реда не е яко, но явно така ще става.

    "Освен това, не мислете за файлове" ? Нямаше да мисля за файлове ако в условието не пишеше : "Имплементирайте класове за работа с To-do списъци. Те трябва да могат да прочитат текстов файл с определен формат и да предлагат определена функционалност."

  10. @Кристиян, добре, сега те разбрах.

    За условието си прав, виждам къде е подвеждащо. Коригирано е.

    За да тестваш по-лесно, може да си запазиш този низ във файл и да го ползваш така (дори и от irb):

    File.read('todos.txt')
    

    Горното ще ти върне точно текстовия низ, който ти трябва. На мястото на името на файл, може да сложиш и релативен или абсолютен път.

  11. @Кристиян, в условието също така пишеше:

    Където text е текстов низ със съдържание във формата, описан по-горе (с цел опростена проверка).

    Отделно, не знам дали си погледнал примерния тест, но виж как е там. Ако не ти става ясно, прочети за heredoc и съответно как се ползва в Ruby. В последствие, ако имаш въпроси, питай смело (:

  12. Нещо не ви се разбира условието, цитирам: "TodoList с "класов" метод parse и методи filter и adjoin, които връщат нещо, което има същите методи."

    т.е filter и adjoin връщат нов TodoList, което е ОК, така и го направих, уви в тестовете е съвсем различно:

    todo_list.filter(Criteria.tags %w[wtf]).map(&:description).should =~ ['Hunt saber-toothed cats.']

    според горното, filter връща просто масив от задачи с поле/метод description. Т.е имам клас TodoList с аксесор 'tasks' - масив от този клас: class TodoTask attr_reader :status, :description, :priority, :tags #... end

    filter трябва да върне tasks или новa инстанция на TodoList?

  13. @Иван TodoList имплементира Enumerable => може да се вика map върху него. А самия map връща масив.

    Нещо като (1..10).map { |num| num + 1 } . 1..10 не е масив, но имплементира Enumerable, а резултата от цялата операция е масив.

  14. @Иван Проданов, parse е, както беше цитирал сам в предишния си пост, "класов" метод.

    @Иван Капукаранов, според мен не е добра практика, освен в някакви изключително крайни (странни) ситуации, за които не се сещам. Може би, ако не искаш да замърсяваш по някакъв начин namespace-a, ама и това е... Не знам. Нека Митьо се изкаже защо би се ползвал require в метод.

    За всеки случай това не ти трябва да го правиш, за да решиш задачата.

  15. Аха, ясно. Значи ако иска тези с :todo Или :done ще трябва да правя Criteria.status(:todo) | Criteria.status(:done).

    A, тестовете ще включват ли по-сложни логически изрази от сорта:

    (Criteria.status(:todo) | Criteria.priority(:high)) & Criteria.tags(['studies'])

    1. require в метод не се ползва; нареждате require-клаузите в началото на файла, по конвенция.
    2. Използвайте синтаксиса на Markdown, за да вкарвате код в публикациите си, четимостта се повишава значително. Достатъчно технически грамотни хора сме всички тук, за да се справим с този малък и прост синтаксис :)
    3. @Александър Попов, да, прав си, че трябва да се използва expect()-синтаксиса :) Също така, приемаме PR-и :)
  16. TodoList#tasks_completed по дефиниця е class method.

    TodoList#tasks_todo - връща броя на задачите, които трябва да се направят (със статус :todo).
    
    TodoList#tasks_in_progress - връща броя на задачите, които са в прогрес (със статус :current).
    
    TodoList#tasks_completed - връща броя на завършените задачи (със статус :done).
    

    В теста обаче се използва като instance method на обекта върнат от TodoList#parse

    it "returns the number of the completed tasks" do
      todo_list.tasks_completed.should eq 2
    end
    
  17. @Митко - да, с удоволствие ще го направя, дори започнах, само че се натъкнах на следното в GitHub repo-то на rspec expectations:

    Note: The new expect syntax no longer supports the =~ matcher.

    Търсейки по темата се натъкнах на този gist, който казва:

    However, there's still a work around! Although "stand alone" operator matchers are out, the be matcher has operator matches on it

    От тук въпросът ми - това правилна преработка ли е:

    todo_list.filter(Criteria.tags %w[wtf]).map(&:description).should =~ ['Hunt saber-toothed cats.']
    

    в

    expect(todo_list.filter(Criteria.tags %w[wtf]).map(&:description)).to be =~ ['Hunt saber-toothed cats.']
    

    ?

  18. Статусите (TODO, CURRENT, DONE) и приоритетите (High, Low, Normal) само тези ли могат да бъдат или трябва да може да работи с произволни (примерно някой подава списък, който съдържа ред:

    PLANNED | 'Create a feature branch' | Conditional | debugging
    

    ?

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