Решение на Пета задача от Давид Петров

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

Към профила на Давид Петров

Резултати

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

Код

REPOSITORY = 'https://github.com/davidpetrov/Homework5'
# Двадесет неща, които научих.
# 1. Когато, искаме да викнем метод на текущия клас може да изпускаме self, тъй като
# той се подразбира. Например в задача 1 метода Integer prime? вместо self.abs можем
# да ползваме само abs.
# 2. Вместо inject {|a,b| a+b} можем да ползваме reduce(:+) съкратена форма, която
# е по-ясна и по-кратка. Същото важи и за map.
# 3. Monkey patching - добавянето или променянането на вградените класове, като например Integer
# не е добра идея, освен в много редки случаи.
# 4. Правилното подравняване, оставяна на space-ове между операторите и празни редове където е
# необходимо прави кода значително по четим и ясен.
# 5. Когато искаме да дефинираме в даден клас повече от един класови метода, вместо за всеки да
# използваме синтаксиса self.method_name ili Class_name.method_name, по-удачно е да ползваме
# синтаксиса class << self <body> end , където в body дефинираме методите по традиционния начин.
# 6. proc i lambda могат да бъдат взаимозаменяеми, но имат разлики в поведението в някои случаи, за
# които трябва да се внимава. Например подаване на по-малко или повече от дефинирания брой аргументи
# или подаване на масив от аргументи.
# 7. Единичните и двойните кавички имат различно поведение при екраниране, като двойните са по-добрия вариант
# защото екранират по-голям набор от символи. Интересен частен случай, който ми отне доста време да осъзная
# е когато имаме стринг от вида "ааа 'ааа' " , вътрешните кавички трябва да са единични, или да са двойни
# но да бъдат екранирани "ааа \"aaa\"". В задача 3 има тест в който regex израз изрично match-ва вторият
# случай и съответно не минава иначе.
# 8. Когато имаме 2 метода които правят едно и също нещо(синоними) можем да ползваме синтаксиса
# alias new_method old_method
# 9. Когато искаме да дефинираме методи сетъри и гетъри на property-та можем да използваме синтаксиса
# attr_accessor, attr_reader и attr_writer последван от списък с имена на методи като символи, което
# е значително по-кратък и ясен начин от реалното писане на тези методи.
# 10. Добър принцип е да не даваме излишен достъп към обектите ни, било то под формата на ненужни attr_accessor
# и най-вече при употребата на вътрешни методи, използвани за реализацията на публичните методи.
# 11. Добра практика всички методи, които не са public или са помощни да бъдат private, което отново спомага
# за капсулацията.
# 12. Добре е на места където можем да използваме вградени методи да го правим, вместо по-неясни операции с индекси.
# Например в моето първо решение на 3 та задача ползвам неясни индекси в метода render_as_html final[0..-31] + final[-26..-1],
# с цел да премахна последното срещане на даден substring, когато има вграден метод chomp, който прави това.
# 13. По-доброто именоване прави кода значително по-четим и разбираем. Което е съществен проблем в моите решения
# например в задача 4.
# 14. method_missing е интересен и полезен метод, който можем да ползваме когато искаме да handle-ваме случаи
# в които се викат несъществуващи методи. Удобен е и за направата на proxy обекти.
# 15. define_method е друг похват от метапрограмирането, който позволява например да се дефинират динамично методи или
# да се дефинират наведнъж много методи с подобна функционалност.(Пример задача 4 различните jump методи).
# 16. Премахването на излишните повторения не само намалява обема на кода но го и прави по-четим и разбираем.
# Това може да се постигна чрез присвояване на локални променливи, чрез хешове вместо обемната конструкция
# if elsif else.
# 17. Добра практика е стойности присвоени на константи да бъдат freeze-нати с цел защита от външна намеса.
# 18. Ако искаме на нащите класове да викаме вградените методи като map, reduce и т.н е необходимо да инклуднем модула Enumerable
# и миимум да имлементираме each.
# P.S. Тъй-като имах неопределими проблеми с инсталирането на aspell и skeptic за версия 2.1 съм тествал със версия 0.0.3
# на skeptic, съответно нямаж никакъв начин да правя проверки за правилни английски думи. Въпреки, че съм се старал
# максимално в тази насока е възможно да има някое изключение. Надявам се в такъв случай проблемите свързани с тестването
# на 5 та задача под Windows(което се оказа невъзможно...).

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

Давид обнови решението на 22.01.2014 17:13 (преди около 10 години)

+REPOSITORY = 'https://github.com/davidpetrov/Homework5'
+
+# Двадесет неща, които научих.
+
+# 1. Когато, искаме да викнем метод на текущия клас може да изпускаме self, тъй като
+# той се подразбира. Например в задача 1 метода Integer prime? вместо self.abs можем
+# да ползваме само abs.
+# 2. Вместо inject {|a,b| a+b} можем да ползваме reduce(:+) съкратена форма, която
+# е по-ясна и по-кратка. Същото важи и за map.
+# 3. Monkey patching - добавянето или променянането на вградените класове, като например Integer
+# не е добра идея, освен в много редки случаи.
+# 4. Правилното подравняване, оставяна на space-ове между операторите и празни редове където е
+# необходимо прави кода значително по четим и ясен.
+# 5. Когато искаме да дефинираме в даден клас повече от един класови метода, вместо за всеки да
+# използваме синтаксиса self.method_name ili Class_name.method_name, по-удачно е да ползваме
+# синтаксиса class << self <body> end , където в body дефинираме методите по традиционния начин.
+# 6. proc i lambda могат да бъдат взаимозаменяеми, но имат разлики в поведението в някои случаи, за
+# които трябва да се внимава. Например подаване на по-малко или повече от дефинирания брой аргументи
+# или подаване на масив от аргументи.
+# 7. Единичните и двойните кавички имат различно поведение при екраниране, като двойните са по-добрия вариант
+# защото екранират по-голям набор от символи. Интересен частен случай, който ми отне доста време да осъзная
+# е когато имаме стринг от вида "ааа 'ааа' " , вътрешните кавички трябва да са единични, или да са двойни
+# но да бъдат екранирани "ааа \"aaa\"". В задача 3 има тест в който regex израз изрично match-ва вторият
+# случай и съответно не минава иначе.
+# 8. Когато имаме 2 метода които правят едно и също нещо(синоними) можем да ползваме синтаксиса
+# alias new_method old_method
+# 9. Когато искаме да дефинираме методи сетъри и гетъри на property-та можем да използваме синтаксиса
+# attr_accessor, attr_reader и attr_writer последван от списък с имена на методи като символи, което
+# е значително по-кратък и ясен начин от реалното писане на тези методи.
+# 10. Добър принцип е да не даваме излишен достъп към обектите ни, било то под формата на ненужни attr_accessor
+# и най-вече при употребата на вътрешни методи, използвани за реализацията на публичните методи.
+# 11. Добра практика всички методи, които не са public или са помощни да бъдат private, което отново спомага
+# за капсулацията.
+# 12. Добре е на места където можем да използваме вградени методи да го правим, вместо по-неясни операции с индекси.
+# Например в моето първо решение на 3 та задача ползвам неясни индекси в метода render_as_html final[0..-31] + final[-26..-1],
+# с цел да премахна последното срещане на даден substring, когато има вграден метод chomp, който прави това.
+# 13. По-доброто именоване прави кода значително по-четим и разбираем. Което е съществен проблем в моите решения
+# например в задача 4.
+# 14. method_missing е интересен и полезен метод, който можем да ползваме когато искаме да handle-ваме случаи
+# в които се викат несъществуващи методи. Удобен е и за направата на proxy обекти.
+# 15. define_method е друг похват от метапрограмирането, който позволява например да се дефинират динамично методи или
+# да се дефинират наведнъж много методи с подобна функционалност.(Пример задача 4 различните jump методи).
+# 16. Премахването на излишните повторения не само намалява обема на кода но го и прави по-четим и разбираем.
+# Това може да се постигна чрез присвояване на локални променливи, чрез хешове вместо обемната конструкция
+# if elsif else.

Давид обнови решението на 22.01.2014 17:29 (преди около 10 години)

REPOSITORY = 'https://github.com/davidpetrov/Homework5'
# Двадесет неща, които научих.
# 1. Когато, искаме да викнем метод на текущия клас може да изпускаме self, тъй като
# той се подразбира. Например в задача 1 метода Integer prime? вместо self.abs можем
# да ползваме само abs.
# 2. Вместо inject {|a,b| a+b} можем да ползваме reduce(:+) съкратена форма, която
# е по-ясна и по-кратка. Същото важи и за map.
# 3. Monkey patching - добавянето или променянането на вградените класове, като например Integer
# не е добра идея, освен в много редки случаи.
# 4. Правилното подравняване, оставяна на space-ове между операторите и празни редове където е
# необходимо прави кода значително по четим и ясен.
# 5. Когато искаме да дефинираме в даден клас повече от един класови метода, вместо за всеки да
# използваме синтаксиса self.method_name ili Class_name.method_name, по-удачно е да ползваме
# синтаксиса class << self <body> end , където в body дефинираме методите по традиционния начин.
# 6. proc i lambda могат да бъдат взаимозаменяеми, но имат разлики в поведението в някои случаи, за
# които трябва да се внимава. Например подаване на по-малко или повече от дефинирания брой аргументи
# или подаване на масив от аргументи.
# 7. Единичните и двойните кавички имат различно поведение при екраниране, като двойните са по-добрия вариант
# защото екранират по-голям набор от символи. Интересен частен случай, който ми отне доста време да осъзная
# е когато имаме стринг от вида "ааа 'ааа' " , вътрешните кавички трябва да са единични, или да са двойни
# но да бъдат екранирани "ааа \"aaa\"". В задача 3 има тест в който regex израз изрично match-ва вторият
# случай и съответно не минава иначе.
# 8. Когато имаме 2 метода които правят едно и също нещо(синоними) можем да ползваме синтаксиса
# alias new_method old_method
# 9. Когато искаме да дефинираме методи сетъри и гетъри на property-та можем да използваме синтаксиса
# attr_accessor, attr_reader и attr_writer последван от списък с имена на методи като символи, което
# е значително по-кратък и ясен начин от реалното писане на тези методи.
# 10. Добър принцип е да не даваме излишен достъп към обектите ни, било то под формата на ненужни attr_accessor
# и най-вече при употребата на вътрешни методи, използвани за реализацията на публичните методи.
# 11. Добра практика всички методи, които не са public или са помощни да бъдат private, което отново спомага
# за капсулацията.
# 12. Добре е на места където можем да използваме вградени методи да го правим, вместо по-неясни операции с индекси.
# Например в моето първо решение на 3 та задача ползвам неясни индекси в метода render_as_html final[0..-31] + final[-26..-1],
# с цел да премахна последното срещане на даден substring, когато има вграден метод chomp, който прави това.
# 13. По-доброто именоване прави кода значително по-четим и разбираем. Което е съществен проблем в моите решения
# например в задача 4.
# 14. method_missing е интересен и полезен метод, който можем да ползваме когато искаме да handle-ваме случаи
# в които се викат несъществуващи методи. Удобен е и за направата на proxy обекти.
# 15. define_method е друг похват от метапрограмирането, който позволява например да се дефинират динамично методи или
# да се дефинират наведнъж много методи с подобна функционалност.(Пример задача 4 различните jump методи).
# 16. Премахването на излишните повторения не само намалява обема на кода но го и прави по-четим и разбираем.
# Това може да се постигна чрез присвояване на локални променливи, чрез хешове вместо обемната конструкция
-# if elsif else.
+# if elsif else.
+# 17. Добра практика е стойности присвоени на константи да бъдат freeze-нати с цел защита от външна намеса.
+# 18. Ако искаме на нащите класове да викаме вградените методи като map, reduce и т.н е необходимо да инклуднем модула Enumerable
+# и миимум да имлементираме each.
+
+# P.S. Тъй-като имах неопределими проблеми с инсталирането на aspell и skeptic за версия 2.1 съм тествал със версия 0.0.3
+# на skeptic, съответно нямаж никакъв начин да правя проверки за правилни английски думи. Въпреки, че съм се старал
+# максимално в тази насока е възможно да има някое изключение. Надявам се в такъв случай проблемите свързани с тестването
+# на 5 та задача под Windows(което се оказа невъзможно...).

Нямаш проблеми с английските думи, проверих.

Имам някои забележки около именуването на неща в кода ти, както и някои особено поставени празни редове (или липсата на такива). Например, името array е лошо в TodoList.parse. В същия метод има и други проблеми (предпочитай Array#<< пред Array#push). Самият метод ползва anti-pattern "each + accumulator", вместо да ползва map и да се напише така:

TodoList.new text.lines.map { |line| Task.new line.split('|') }

По трета задача - констатите START_HTML и END_HTML не им е мястото в Graphics - по-добре да стоят в Renderers::Html и да се казват HEADER и FOOTER. Представяне на canvas като хеш ми се струва по-добра идея. Имаш дребни проблеми с идентацията (ред 60, например, както и draw_rectangle).

В четвърта задача, не виждам проблем да беше ползвал новия (Ruby 1.9) синтаксис за хешове за дефиниция на JUMPS. Не ми харесва много името Helper. С какво помага? Виж решенията на колегите си, как те са именували подобни класове. Примерно, EvaluationContext или нещо от сорта ми се струва малко по-добро, макар че мисля, че може и още по-добро име да се измисли.

По коментарите ти имам следните бележки:

  • В точка 7 не бих казал, че двойните кавички са по-добрият вариант. Просто са различни. Даже аз предпочитам единични, защото в тях има по-малко специални символи и "ъпгрейдвам" низ към двойни кавички само ако ми се наложи.

Нещата, които си описал като научени, ми харесват. Надявам се и ти да си доволен от процеса :)