Трета задача

  1. След дълго чакане, с удоволствие искам да ви съобщя, че сме публикували трета задача. Имате малко повече от седмица, до следващата неделя вечер.

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

    Има няколко нови неща около тази задача:

    • Използва нововъведения в skeptic, появили се от версия 0.0.7 нататък. Тоест, ако искате да си тествате задачата локално, си инсталирайте най-новата версия на skeptic локално. Няма проблем и да не го инсталирате – като опитате да качите решението си на сайта, ще видите как се вписвате в ограниченията.
    • Има ново ограничение, което проверява дали сте спазили конвенциите за именуване на променливи, методи, класове, модули и константи.
    • Има ново ограничение, проверяващо дали сте използвали само валидни английски думи или комбинация от такива за именуване на неща. Това е най-забавното ограничение. Възможно е речникът, който използваме, да има някои пропуски. Ако смятате, че името, което искате да използвате, е валидно, пратете ни един имейл (за да реагираме по-бързо) и ще го добавим в изключенията.
    • Ограниченията за брой методи, брой редове и брой символи на ред са доста сурови предвид задачата. Съвсем малко над нашето решение са. Както се досещате, това е напълно умишлено и очаквам, че ще събуди голяма креативност у вас.

    Можете да намерите малко примерни тестове на обичайното място.

    Насреща сме за вашите въпроси. И успех :)

    НОВО: В тази задача ще ви взимаме наказателно точки, ако не сте спазвали конвенциите в езика за идентиране или сте погазили грубо други стилови препоръки, които сме давали нееднократно.

  2. @Георги, добър въпрос. Логиката ми е била, че Point, Line, Rectangle и Canvas са top-level обекти в библиотеката и в домейна на проблемната област. От друга страна, името на рендерериращите "неща" не е top-level концепция и исках да го скрия/капсулирам някъде. Затова те са напъхани в Renderers, докато другите обекти са оставени в "top-level" Graphics scope-a.

  3. Ок нещо не ти разбирам условието за правоъгълника. Какво ще получа, ако изпълнявам следния код?

    a = Rectangle.new(Point.new(0,0), Point(0,5))
    p a.left #=> Point(0,0)
    p a.right #=> Point(0,5) или Point(5,5) ?
    

    Аналогично ако двете точки са с еднаква ордината, какво ще изведе a.right? Point(5,0) или Point(5,5)?

  4. @Иван, благодаря за въпроса. В конкретния пример, a.left трябва да е 0, 0, а a.right да е 0, 5.

    Методите left и right трябва да отговарят на двете точки, подадени от потребителя при конструкцията на правоъгълника. Просто left трябва да е лявата (или горната, ако са на една x координата) от двете, а right да е другата.

    За останалите ъгли са специалните методи top_left, top_right, bottom_left и bottom_right.

  5. Растеризирането на линия на пано не е съвсем тривиална задача. Свободни сте да използвате какъвто алгоритъм желаете за целта.
    

    Това означава ли, че няма да има тестове за конкретен изход от рисуване на наклонени линии?

    Задачата е много интересна :)

  6. @Иван, може да имате каквито си искате допълнителни методи, private или public, допълнителни класове или модули, константи и прочее. Това е идеята – да построите дизайн, който ви се струва най-подходящ за тази задача. Добавяйте по ваша преценка, съобразено с изискванията в условието.

    @Кристиян, технически погледнато, Ascii си е константа. Но си прав, че конвенцията за именуване на класове и модули е такава, а за "обикновени" константи е само с главни букви. Тоест, в случая се налага (и заради skeptic ограничения), зад тази константа да има модул или клас.

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

  7. И искам да добавя следното:

    В тази задача ще ви взимаме наказателно точки, ако не сте спазвали конвенциите в езика за идентиране или сте погазили грубо други стилови препоръки, които сме давали нееднократно.

  8. В условието пише:
    Ще искаме методите == и eql? да работят по смислен начин за всеки от трите вида геометрични обекти.
    В нашия контекст е допустимо двата метода да са синоними.
    Въпроса ми е следния: Има ли случай в който двата метода не са синоними?

  9. @Ангел, в контекста на тази задача няма нужда да са различни == и eql?. Принципно, в Ruby, двата метода са почти еквивалентни, с малки изключения – примерно, == в Numeric прави type coercieon, а eql? не прави. Тоест, 1.0 == 1 # true, но 1.0.eql?(1) # false.

    Ето документация по въпроса:

    1. BasicObject#==
    2. Numeric#==

    Бонус точки за човека, който добави слайдове за това в съответната презентация :)

    @Сашо, не е забранено да ползваш Set, но не мисля, че е много необходимо. Ще ти погледна решението и ще ти оставя коментар там.

  10. За имплементацията на hash е допустимо и да стъпите на hash методите на класове от Ruby.

    Може ли малко уточнение по този въпрос. Попаднах на една дискусия, където се спори дали има или няма, трябва или не трябва да има "стандартен начин на имплементиране на #hash функцията за стойностни обекти". В крайна сметка по-скоро няма. Бихте ли дали някакъв коментар по въпросa.

  11. @Сашо, за целите на тази задача не ни интересува дали има "стандартен" начин за имплементация на hash или не. А и това дали има такъв начин е все едно да питаш дали има "стандартен" алгоритъм за сортиране, или "стандартен" език за програмиране. Има различни такива, като всеки има силни и слаби страни и всеки си има своята най-подходяща област на приложение.

    Обратно в контекста на задачата, някои от примерите в тази дискусия загатват за една възможна имплементация на hash, която ще покрие изискванията в условието. В крайна сметка, това е, което трябва да направите – нещо, което отговаря на критериите на условието. И аз ви казвам, че може да стъпите на вече съществуващи "аксиоми" и да надградите някак :)

  12. От условието на задачата разбирам, че Line.new(Point.new(4, 4), Point.new(2, 2)) е валидно задаване на линия, както и Rectangle.new(Point.new(3, 1), Point.new(1, 3)) е валидно зададен правоъгълник или не?

    В такъв случай from за линията трябва да върне 2, 2, а left за правоъгълника 1, 1, нали?

    Освен това каква е разликата между left и top_left и right и bottom_right?

  13. @Мария, да, и двата ти примера са валидни дефиниции на линия и правоъгълник, съответно.

    За Line#from в твоя пример си права, че трябва да върне Point.new(2, 2), но Rectangle#left трябва да върне 1, 3, а не 1, 1. Това не е top_left, както и right не е bottom_right. Виж този мой отговор по-нагоре в тази тема.

  14. Мисля, че в Renderers трябва да има метод render_as който да взима като аргумент обект от тип Canvas, за да го рендерира. Така Renderers и ще е плъгин, защото Canvas няма да знае за него. Спомена го един колега (не му знам името), и аз съм напълно съгласен с него. Какво е мнението на екипа по този дизайн въпрос?

    И още един въпрос - споделянето на тестовете е ОК, за задачи, а не само за предизвикателства, нали?

  15. C:\Users\Ivan>skeptic --lines-per-method 6 --line-length 90 --max-nesting-depth 2 --methods-per-class 12 --no-semicolons --no-trailing-whitespace --check-syntax --no-global-variables --english-words-for-names='rasterize rasterization render er renderers html ascii eql bresenham' --naming-conventions solution.rb C:/Ruby210/lib/ruby/site_ruby/2.1.0/rubygems/core_ext/kernel_require.rb:55:in r equire': cannot load such file -- ffi_c (LoadError) from C:/Ruby210/lib/ruby/site_ruby/2.1.0/rubygems/core_ext/kernel_requir e.rb:55:inrequire' from C:/Ruby210/lib/ruby/gems/2.1.0/gems/ffi-1.9.3-x86-mingw32/lib/ffi.r b:14:in rescue in <top (required)>' from C:/Ruby210/lib/ruby/gems/2.1.0/gems/ffi-1.9.3-x86-mingw32/lib/ffi.r b:3:in' from C:/Ruby210/lib/ruby/site_ruby/2.1.0/rubygems/core_ext/kernel_requir e.rb:55:in require' from C:/Ruby210/lib/ruby/site_ruby/2.1.0/rubygems/core_ext/kernel_requir e.rb:55:inrequire' from C:/Ruby210/lib/ruby/gems/2.1.0/gems/ffi-aspell-0.0.3/lib/ffi/aspell .rb:1:in <top (required)>' from C:/Ruby210/lib/ruby/site_ruby/2.1.0/rubygems/core_ext/kernel_requir e.rb:55:inrequire' from C:/Ruby210/lib/ruby/site_ruby/2.1.0/rubygems/core_ext/kernel_requir e.rb:55:in require' from C:/Ruby210/lib/ruby/gems/2.1.0/gems/skeptic-0.0.7/lib/skeptic/rules /english_words_for_names.rb:1:in' from C:/Ruby210/lib/ruby/site_ruby/2.1.0/rubygems/core_ext/kernel_requir e.rb:55:in require' from C:/Ruby210/lib/ruby/site_ruby/2.1.0/rubygems/core_ext/kernel_requir e.rb:55:inrequire' from C:/Ruby210/lib/ruby/gems/2.1.0/gems/skeptic-0.0.7/lib/skeptic.rb:14 :in <top (required)>' from C:/Ruby210/lib/ruby/site_ruby/2.1.0/rubygems/core_ext/kernel_requir e.rb:55:inrequire' from C:/Ruby210/lib/ruby/site_ruby/2.1.0/rubygems/core_ext/kernel_requir e.rb:55:in require' from C:/Ruby210/lib/ruby/gems/2.1.0/gems/skeptic-0.0.7/bin/skeptic:3:in' from C:/Ruby210/bin/skeptic:23:in load' from C:/Ruby210/bin/skeptic:23:in'

    как да го подкарам skeptic?

  16. Kоя версия точно на алгоритъма на Брезенхайм ползвате , тъй като каквото и да съм намерил по нета , и да съм го имплементирал води до R от примера изглеждащо така:

    --------------
    ----@@@@@-----
    ----@----@----
    ----@@@@@-----
    ----@---@-----
    ----@---@-----
    ----@----@----
    

    вместо

    --------------
    ----@@@@@-----
    ----@----@----
    ----@@@@@-----
    ----@---@-----
    ----@----@---- <разлика тук
    ----@----@----
    
  17. @Михаил, това е въпрос на някакво закръгляне, или, общо-взето, кое квадратче да избереш при еднаква тежест и на двете. Опитай да осмислиш алгоритъма и да намериш къде е това място, за да го промениш така, както ние сме го направили.

    Относно - и @, може да ползваш блокове с код, за да вкараш тези рисунки в публикациите си. Редактирал съм ти публикацята, влез в редакция и ти, за да видиш как съм я форматирал.

  18. Когато си тествам задачата локално със skeptic получавам [BUG] Segmentation fault. Като махна --english-words-for-names='rasterize rasterization renderer renderers html ascii eql bresenham vertices' и тествам за другите ограничения, skeptic ми изписва ok, а сайтът не ми даде грешка, когато се опитах да си кача задачата и ми прие решението. Това означава ли, че всичко с именуването в задачата ми е оk?

  19. Ще има ли тестове с фигури, които имат координати извън паното? Тоест, нужно ли е в кода си да правим валидация на данните?

    Също искам да попитам, резултатът от рендърите трябва просто да се визуализира в конзолата или трябва да се върне като стринг?

  20. При правоъгълника top_left не е ли по-точно да отговаря на точката с min х координата и max y координата, а не както е сега(поне както аз рабирам от текущите постове във форума) - min x и min y? Подобно горна точка при линия е точката с по-малка y координата, нали?

    Мисля, че за подобни property-та е добре да има по-детайлни описания в условието на задачата.

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