ruby-first-task ================================================================================ Задача 1: Карта сайта Трактуем сайт как ориентированный граф (digraph). Вершины (vertex) - уникальные страницы. Уникальность определяется по относительному адресу страницы (например /about /home). Если страница A ссылается на страницу Б, то имеем ребро (edge) l:A → B. Полустепень захода вершины (indegree) - число страниц указывающих на нее. Со стандартного входа подается URL стартовой страницы. Будем исследовать подсайт, определенный как множество страниц которые включают переданный URL (стартовая страница очевидно входит в это множество) и к которым мы можем прийти со стартовой странице, не выходя за пределы подсайта. Вычислите граф, соответствующий подсайту и выведите все его вершины, отсортированные по степени захода, на стандартный вывод. Ограничения: 1. работаем только с оперативной памятью, использовать файловую систему запрещено. 2. разрешено использование только stdlib. 3. разрешено использование только функциональной части языка. Решение должно быть оформлено в виде открытого репозитория на github. Код должен быть оформлен согласно правилам оформления. Название и содержание коммитов должны быть согласованы. ================================================================================ 2.10.2014 АК: Разобрался с тем, как использовать open-uri. Сначала нужно подключать библиотеку: require 'open-uri' Договорились с Ильёй, что есть необходимость в функции поиска ссылок указывающих на подстраницы. Возможно, эта функция будет использоваться рекурсивно, чтобы найти на подстраницах ссылки на другие подстраницы. Результатом этой функции будет хеш. Обсуждали с Ильёй, как он будет выглядеть. По предварительной договоренности, что-то вроде: {'a/home' => {'a/home/blog'=>2, 'a/home/users'=>1, 'a/home/contacts'=>4}} {"URL страницы" => {"URL подстраницы" => "сколько раз на подстранице встречается ссылка на a\home ", a\home\users => 1, a\home\contacts => 4}} Нужно разбить задачу на более мелкие подзадачи-функции. Думаем над этим. ================================================================================ 3.10.2014 * IlyaKhlyzov Первые мысли: - Принять со стандартного входа URL. Распарить его регулярным выражением. Вывод ошибки в случае неудачи. - Создать функцию, принимающую на вход URL: в которой ищем все подсайты, и вызываем для них эту же функцию. Логично, что возвращает эта функция какой-то хэш. - Модифицировать функцию так, чтобы она ещё считала кол-во ссылок на самый первый URL. - Вывести отсортированный хеш. ================================================================================ 3.10.2014 * IlyaKhlyzov Последующие мысли: Неправильно интерпретировал задачи. Обновление: - Принять со стандартного входа URL. - Создать функцию, принимающую на вход url, которая возвращает хеш с подсайтами. Функция вызывается рекурсивно. Поиск подсайтов выполняется регулярным выражением. - (не уверен, что правильно следующее) Полученный хеш используем для выбора всех уникальных элементов и кол-ва повторений этих элементов: результатом тоже может быть хеш. - Результат сортируем и выводим. ================================================================================ 3.10.2013 * EugeneHlyzov Решил, что это не очень справедливо, что вы ведете лог, а я даю вам обратную связь по почте. Исправляюсь. Буду писать сюда все то, что может помочь вам обоим. Увидел функцию - сразу назови ее и ссылайся только по имени. Правильно выбирать имена функций - критично. Поэтому можно сначала использовать имена на русском языке, а при кодировании уже переводить на английский. Например, т.к. функция ищет ссылки, то ее можно назвать ПоискСсылок (search_for_links). В Ruby принято использовать выразительные имена функций. Далее, вы слишком углубляетесь для этого этапа. Сложно заранее угадать вид функции ПоискСсылок если не понятен общий контекст ее использования. Рекомендация: не думай о типах данных до того, как понимаешь как программа будет работать целиком. И какие функции, кроме ПоискСсылок ей нужны. Представь, что все нужные функции уже реализованы и отлажены - как будет в этом случае выглядеть программа? -- дополнение Ставьте цели. Формулировка "нужно сделать А" не конструктивная. Конструктивно - "следующим шагом сделаем А таким-то образом. Оценка времени: два дня, если все будет хорошо, 4 дня - в противном случае." Это дает мне возможность легитимно спросить о ходе работ через конкретное время. А вам дает какие-то ориентиры. Не создавайте неопределенность там, где ее можно избежать. ================================================================================ 6.10 * IlyaKhlyzov Нету темпа в построении решении задач. Нужно как минимум раз в два дня сообщать о своих результатах. Основное в комментарии Евгения Хлызова за 3 октября: понять, какие функции будут использованы (как будто программа уже есть, типы данных - не главное; выразительные имена) + цели с конкретным результатом за определённое время. Соответственно: Пускай в программе будет две функции: первая основная - ИскатьПодсайт - сначала будет искать все ссылки на главной страницы, содержащий оригинальный URL, потом - на найденных ссылках и так далее. Функция принимает в качестве входного параметра URL адрес. А в качестве результата возвращает список найденных ссылок в переданной URL страницы; вторая вспомогательная - ПроверитьУникальностьПодсайта - решает такую проблему, как если мы уже проводили поиск подсайта на переданной странице, то вторично проводить поиск - не имеет смысла. Стоит просто увеличить счётчик Indegree для переданной страницы. Насчёт счётчика: т.к. необходимо учитывать Indegree, то стоит для этого сделать список: URL страница - кол-во ссылок на эту URL-страницу По целям: Самое главное построить функцию ИскатьПодсайт, хотя бы для первого уровня сайта. Должно занять немного времени (несколько часов), до завтра сделаю. Если не буду успевать, то напишу сюда. Дальнейшие задачи: реализовать функцию ПроверитьУникальностьПодсайта, модифицировать ИскатьПодсайт (добавить рекурсивный вызов для URL подсайта). ================================================================================ 7.10.2014 * AK Согласен с предложением Ильи. - Принять со стандартного входа URL. Если это будет ввиде отдельной функции, предлагаю название "ПолучитьУРЛ". Итого имеем следующее: 1. "ПолучитьУРЛ" - получаем URL со стандартного ввода. 2-3 часа. 2. "ИскатьПодсайт" - описано выше Ильёй. 5-6 часов. 3. "ПроверитьУникальностьПодсайта" - возможно это будет часть функции "ИскатьПодсайт". 1 час. 4. "СортироватьРезультаты" - сортировка результатов. 3-4 часа. 5. "ВыводРезультатов" - возможно часть "СортироватьРезультаты". 0.5 -1 час. Есть пара замечаний. Во-первых, давать оценки времени выполнения каждой функции (лично для меня) еще тяжело. Возможно, будут потери времени из-за синтаксических ошибок и тому подобного. Во-вторых, я согласен с утверждением Ильи, что самое главное построить функцию ИскатьПодсайт, хотя бы для первого уровня сайта (даже пробовал начать), но Женя просил не начинать писать код, без понимания того, как программа будет работать в целом. Кроме того, нужно определиться кто какую функцию прорабатывает. Или каждый пишет все функции отдельно сам по себе? ================================================================================ 7.10.2014 * Eugene 1. Оценивать в часах не нужно 2. Не надо заморачиваться сейчас чтением из stdin, используйте вот этот сниппет: url = ARGV[0] || STDIN.gets.chomp 3. Название "ИскатьПодсайт" подразумевает что вы будете где-то искать подсайт. Но это не совсем так, вы будете его строить. Смотрите, из комментария выше "ИскатьПодсайт - сначала будет искать все ссылки на главной страницы". Судя по этому определению функция должна называться ИскатьСсылкиНаГлавнойСтранице :-) Название функции должно максимально точно отражать то, что она делает.