These are chat archives for hackbio/learnbio

21st
Aug 2015
Anton Kulaga
@antonkulaga
Aug 21 2015 15:19
@OlenaMaiakovska , пинг
Olena
@OlenaMaiakovska
Aug 21 2015 15:21
@antonkulaga
как ты это сделал?
))
или у меня получилось
Anton Kulaga
@antonkulaga
Aug 21 2015 15:22
вроде получилось
ну, в общем спрашивай-рассказывай
Olena
@OlenaMaiakovska
Aug 21 2015 15:24
начала с курса на прометеусе..
но там нет системы, а сразу прогруз в отдельных темах
в продвинутого программиста наверно про азы спрашивать бессмысленно,
Anton Kulaga
@antonkulaga
Aug 21 2015 15:25
Насколько различные if-else деревья, циклы и т.п. тебе привычны?
Olena
@OlenaMaiakovska
Aug 21 2015 15:26
а приходить с конкретными вопросами..
Anton Kulaga
@antonkulaga
Aug 21 2015 15:26
То есть, можешь ли ты думаешь о задаче без привязки к языку на уровне алгоритма?
Olena
@OlenaMaiakovska
Aug 21 2015 15:26
да, это более-менее привычно
но вот рекурсия..
Anton Kulaga
@antonkulaga
Aug 21 2015 15:27
Я почему спрашивал, потому, что многие начинают сразу учить с синтаксиса конкретного языка, но даже представить блок-схему алгоритма не могут
Olena
@OlenaMaiakovska
Aug 21 2015 15:27
это да..
но пока что задачки для решаемы
ну по крайней мере на степике
Anton Kulaga
@antonkulaga
Aug 21 2015 15:28
К примеру, не могут расписать алгоритм приготовления яичницы =)
Olena
@OlenaMaiakovska
Aug 21 2015 15:28
))))
мне нравится)))гениально
Anton Kulaga
@antonkulaga
Aug 21 2015 15:30
Я недавно свою маму обучал, причем на blocky (визуальный блоковый язык). Она говорит "та, эти иф-элсы" элементарны, потом загрузил её решить задачку на вывод человека из лабиринта и она надолго подвисла, хотя там while if/else только
Anton Kulaga
@antonkulaga
Aug 21 2015 15:40
Так с чем сложности, с рекурсией, ООП, алгоритмами? Можно сейчас кое-что разобрать
С рекурсией проще всего на List-ах
Olena
@OlenaMaiakovska
Aug 21 2015 15:41
на list-ax?
я подсела с твоей задачкой
лабиринтом)
Anton Kulaga
@antonkulaga
Aug 21 2015 15:41
рекомендую перед десяткой попробовать одну из тех, что пораньше была, чтобы привыкнуть к блоковой разметке
хорошо, маякнёшь с собачкой, когда разберёшься с лабиринтом.
думаю, минут 15-20 точно на это уйдёт
там по решению задачки джаваскриптный код показывает
Olena
@OlenaMaiakovska
Aug 21 2015 15:44
классно)))
хорошо
Anton Kulaga
@antonkulaga
Aug 21 2015 15:46
я с мамой где-то час с копейками возился пока мы все 10 задаче прошли из которых 25 минут ушло на 10тку, но у неё опыта практически не было (только перфокарты в студенческие времени и hello world не помню на чём уже)
Olena
@OlenaMaiakovska
Aug 21 2015 16:41
у меня не получается последний шаг сделать
сейчас переделаю всю схему
Anton Kulaga
@antonkulaga
Aug 21 2015 16:44
=)
Olena
@OlenaMaiakovska
Aug 21 2015 16:47
он ведь может ходить сначала не туда?))
а то я выбираю строго правильну. траекторию с наименьшим числом шагов
Anton Kulaga
@antonkulaga
Aug 21 2015 16:48
Я могу подсказать о том, как можно мыслить
Эта задачка учит одной полезной и одновременно очень вредной вещи - ставить костыли
У тебя он то одного из перекрёстков доходит нормально, а вот на следующем после нормального перекрёстка начинает тупить. Подумай, чем перекрёсток, где он тупит, отличается от перекрёстков, где он идёт правильно (какого-то направления не хватает?) и как это можно в ифе красиво выразить
Вторая вещь, которой учит задачка - экономить операции. У меня на всю задачку только один repeat и один moveforward, всё остальное - это if и if-else
Olena
@OlenaMaiakovska
Aug 21 2015 16:52
не знаю на каких перекрестках он тупит ( у всех по-разному))))
но я ставлю поворот на право
Anton Kulaga
@antonkulaga
Aug 21 2015 16:53
до какого перекрёстка он у тебя доходит?
Olena
@OlenaMaiakovska
Aug 21 2015 16:53
до поворота на цель
Anton Kulaga
@antonkulaga
Aug 21 2015 16:53
кстати, можешь скинуть скриншот блоков твоего лучшего результата
Olena
@OlenaMaiakovska
Aug 21 2015 16:53
точнее остался поворот и ход
Anton Kulaga
@antonkulaga
Aug 21 2015 16:53
alt+prinscreen
Olena
@OlenaMaiakovska
Aug 21 2015 16:57
blob
Anton Kulaga
@antonkulaga
Aug 21 2015 16:57
зачем два мувфорварда?
Olena
@OlenaMaiakovska
Aug 21 2015 16:57
все-все я над этим работаю))
Anton Kulaga
@antonkulaga
Aug 21 2015 16:57
точнее даже четыре
у меня он на весь код всего лишь один
и ктстаи, подумай, что логичнее: сначала прыгать вперёд или в начале повернуть в правильную сторону, а потом делать шаг?
Хотелось бы понять твою логику когда ты ставил два мувфорварда, на что ты опиралась? Просто разбор мышления над задачей не мене важен, чем решение самой задачи
Olena
@OlenaMaiakovska
Aug 21 2015 17:00
)))
на то, что ему надо идти два шага до перекрестка
аааааааааа
до меня дошло
я поняла что ты имел ввиду
Anton Kulaga
@antonkulaga
Aug 21 2015 17:02
А если у тебя лабиринт будет с тысячью шагами между перекрёстками, будешь тысячу мув форвардов ставить?
Olena
@OlenaMaiakovska
Aug 21 2015 17:02
))))))
я же биолог!
постараюсь!
)))))
Anton Kulaga
@antonkulaga
Aug 21 2015 17:03
возьмёшь дробовик, постреляешь по тысяче лабиринтов и посмотришь через какие образовался проход?
Все повторяющиеся операции можно всегда делать или через цикл+действие или через рекурсию. У тебя, как минимум, один цикл уже есть
Anton Kulaga
@antonkulaga
Aug 21 2015 17:08
В твоем случае у системы "чело в лабиринте" есть некоторый набор состояний.
Состояние 1: есть проход вперёд, слева и справа стены
Состояние 2: перекрёсток трёх дорог
Состояние 3: развилка, вперди тупик
Состояние 4: впереди тупик, есть один из поворот
Olena
@OlenaMaiakovska
Aug 21 2015 17:09
Спасибо, Антон!
Anton Kulaga
@antonkulaga
Aug 21 2015 17:09
Если у тебя есть цикл, в котором он правильно действует в этих состояниях (с помощью ифов и поворотов) и постоянно идёт вперёд, то он дойдёт до цели
Olena
@OlenaMaiakovska
Aug 21 2015 17:09
только все, все ...я сама хочу
просто отвлекаюсь каждые пять минут...
нужно потом сесть
Anton Kulaga
@antonkulaga
Aug 21 2015 17:10
ну, я тебе не дал готовое решение, я просто показал как можно мыслить
Olena
@OlenaMaiakovska
Aug 21 2015 19:01
@antonkulaga
while (notDone()) {
  moveForward();
  if (isPathForward()) {
    if (isPathLeft()) {
      if (isPathRight()) {
        turnRight();
      } else {
        turnLeft();
      }
    }
  } else {
    if (isPathLeft()) {
      turnLeft();
    } else {
      turnRight();
    }
  }
}
blob
может по-тупому я решила, но работает
Olena
@OlenaMaiakovska
Aug 21 2015 19:11
обидели улитку, не знаю про какого они калеку, но я вижу нормальную улитку одногоную, гастроподу одноногую...
blob
Anton Kulaga
@antonkulaga
Aug 21 2015 19:17
@OlenaMaiakovska решение аналогичное моему, у меня тоже один форвард только, сейчас свой вариант кину
Screenshot from 2015-08-21 22:17:50.png
while (notDone()) {
  if (isPathForward()) {
    if (isPathRight()) {
      turnRight();
    } else {
      if (isPathLeft()) {
        turnLeft();
      }
    }
  } else {
    if (isPathLeft()) {
      turnLeft();
    } else {
      turnRight();
    }
  }
  moveForward();
}
Olena
@OlenaMaiakovska
Aug 21 2015 19:22
ясно)
ну начит мой вариант не дурацкий)
Anton Kulaga
@antonkulaga
Aug 21 2015 19:23
отчего же, вполне нормальный вариант
у нас с тобой кстати симетрия даже: где у меня направо, у тебя налево и наоборот
Честно говоря, не думал, что тебя так зацепит, что аж до улитки дойдёшь=) Просто хотел дать как пример, что даже if-else не всегда тривиален
Olena
@OlenaMaiakovska
Aug 21 2015 19:28
просто интересные игры)))
даже не столько интересны, сколько прикольные
Anton Kulaga
@antonkulaga
Aug 21 2015 19:29
так что, объяснить рекурсию?
Olena
@OlenaMaiakovska
Aug 21 2015 19:29

кстати твое объяснение
В твоем случае у системы "чело в лабиринте" есть некоторый набор состояний.
Состояние 1: есть проход вперёд, слева и справа стены
Состояние 2: перекрёсток трёх дорог
Состояние 3: развилка, вперди тупик
Состояние 4: впереди тупик, есть один из поворот

совсем не понятно)))

реально, это можно применить ко всем перекресткам)))
я так смеялась, когда пыталась это понять и увидеть на карте)))))
да, давай за рекурсию
кстати, эту задачку я решила без отвлечений за 30 мин
Anton Kulaga
@antonkulaga
Aug 21 2015 19:34
ну, ты не просила пояснить мне моё объяснение, думал, что понятно. На самом деле, через состояния и переходы между ними задачи описываются в концепции конечных автоматов
по поводу рекурсии, наверное проще всего попробовать с List-а
Anton Kulaga
@antonkulaga
Aug 21 2015 19:39
functional-list.png
Что такое List, это структура данных, которая выглядит примерно так
Давай с тобой попробуем парочку упражнений в консоли сделать на рекурсию
Я для консоли использую http://lihaoyi.github.io/Ammonite/
в линухом терминале можно набрать
curl -L -o amm http://git.io/v3Xln; chmod +x amm; ./amm
он скачает аммонит. Затем можно будет запустить скаченніе файл
./amm
после запуска ammonit-а ты увидешь Scala консоль
вышеуказанный список можно создать конструктором
val mylist = List(1,3,42,28)
Anton Kulaga
@antonkulaga
Aug 21 2015 19:44
что прикольно в консоли, что если ты что-то пишель и дальше жмёшь Tab , то тебе будут автоподсказки даваться
Olena
@OlenaMaiakovska
Aug 21 2015 19:44
а это вместо скачки? curl
?
Anton Kulaga
@antonkulaga
Aug 21 2015 19:45
это стандартная утилита линуха для работы с сетью
если не нравится curl, то есть еще wget ,которая аналогичное делает
Olena
@OlenaMaiakovska
Aug 21 2015 19:46
инсталирую curl
качаю
Anton Kulaga
@antonkulaga
Aug 21 2015 19:49

у списков есть два важных метода head и tail если ты в списке myLIst скажешь head, то получишь 1 , если tail, то List(3,42,28) а если

mylist.tail.tail

то List(42,28)
То есть, у нас тут матрёшка получается

Olena
@OlenaMaiakovska
Aug 21 2015 19:52
val mylist = List(1,3,42,28)
у меня получилось,
Anton Kulaga
@antonkulaga
Aug 21 2015 19:54
@OlenaMaiakovska ссори, у меня инет барахилил, перезапускал модем
Olena
@OlenaMaiakovska
Aug 21 2015 19:55
blob
blob
на предыдущей терминал хотела показать)))
Anton Kulaga
@antonkulaga
Aug 21 2015 19:56
теперь вернёмся к рекурсии. По факту рекурсия это вызов функции внутри самой себя. Чтобы она не подвесила программу, у любой рекурсии должен быть выход, то есть, условие при котором она не будет себя вызывать
давай с помощью рекурсии сделаем сумму элементов List-а
def sum(list:List):Int = //какой-то код
тебе задача - с помощью методов head и tail сделать это вещь=)
Полезная штука: когда у тебя рекурсия, нужно думать " с конца". То есть, при каком условии ты перестанешь себя вызывать, так как получишь результат, который тебе понравится. К тебе вопрос, в нашем случае, какое это будет условие?
Olena
@OlenaMaiakovska
Aug 21 2015 19:59
когда ничего оставаться не будет
когда хвоста не будет
Anton Kulaga
@antonkulaga
Aug 21 2015 20:00
верно. А значит, что нам надо начать нашу функци с if(list.isEmpty) /твой код / else /твой код/
Olena
@OlenaMaiakovska
Aug 21 2015 20:01
я все равно не очень понимаю..
как это испольковать
использовать
может мне почяитать что-то
Anton Kulaga
@antonkulaga
Aug 21 2015 20:01
давай попробуем пошагов
Olena
@OlenaMaiakovska
Aug 21 2015 20:02
в "мой код" пишем те фрагменты кот должны считаться в сумме
или код "sum//"
"sum.."
Anton Kulaga
@antonkulaga
Aug 21 2015 20:03
допустим у тебя есть твой функция sum ,которая возвращает сумму того списка, что ей передается.
если у тебя есть sum(mylist.tail), что она должна вернуть?
Olena
@OlenaMaiakovska
Aug 21 2015 20:04
голову...
Anton Kulaga
@antonkulaga
Aug 21 2015 20:04
нет
Olena
@OlenaMaiakovska
Aug 21 2015 20:04
остаток, хвост?
я не очень понимаю все равно
сложно так
Anton Kulaga
@antonkulaga
Aug 21 2015 20:05
у тебя есть фукнция, которая берет список, неважно какой и его сумирует. Представь, что єто ч’рній ящки
ты уже делала mylist.tail и понимаешь (см картинку вверху), что єто подсписок (без первого элемента mylist)-а
mylist.tail - это ведь список, но без первого элемента (в случае если mylist это List(1,3,42,28) , то без единицы), верно?
Olena
@OlenaMaiakovska
Aug 21 2015 20:06
да, это понятно)
Anton Kulaga
@antonkulaga
Aug 21 2015 20:06
то есть, функция sum вернет тебе сумму его элементов, верно?
(элементов хвоста, в смысле)
Olena
@OlenaMaiakovska
Aug 21 2015 20:07
да)
значит я пишу точно также, каждый раз пописывая tail.
Anton Kulaga
@antonkulaga
Aug 21 2015 20:07
а теперь представь:
mylist.head+sum(mylist.tail)
Olena
@OlenaMaiakovska
Aug 21 2015 20:07
дописывая*
Anton Kulaga
@antonkulaga
Aug 21 2015 20:07
чему будет равнятся эта строка?
Olena
@OlenaMaiakovska
Aug 21 2015 20:07
1
))))
я шучу
Anton Kulaga
@antonkulaga
Aug 21 2015 20:08
мы чётко знает, что mylist.head - это первый элемент , а sum(mylist.tail) вернула нам сумму хвоста, верно?
Olena
@OlenaMaiakovska
Aug 21 2015 20:08
будет равна всем предыдущим цифрам
да,
значит тут будет общая сумма того списка цифр
?
1 - это голова и к ней прибавляется сумма обща хвоста
Anton Kulaga
@antonkulaga
Aug 21 2015 20:09
а теперь подумай, что вернёт нам
mylist.tail.head+sum(mylist.tail.tail) ?
Olena
@OlenaMaiakovska
Aug 21 2015 20:10
sum(mylist.tail.tai.tail
Anton Kulaga
@antonkulaga
Aug 21 2015 20:10
подумай внимательно
Olena
@OlenaMaiakovska
Aug 21 2015 20:10
не могу((((
Anton Kulaga
@antonkulaga
Aug 21 2015 20:11
sum(mylist) == mylist.head+sum(mylist.tail) //true
sum(mylist.tail) == mylist.tail.head+sum(mylist.tail.tail)
если не очень понятно попробуй просто представить:
val mylist2 = mylist.tail
sum(mylist2) == mylist2.head+sum(mylist.tail2)
Olena
@OlenaMaiakovska
Aug 21 2015 20:13
не, это плохая идея так заниматься
все равно не понимаю(((
Anton Kulaga
@antonkulaga
Aug 21 2015 20:14
то есть, для нас
mylist.tail - это не более чем какой-нибудь лист, к которому мы можем аналогичную схему применить:
val sumOfElements =  mylist2.head+sum(mylist.tail2)
Olena
@OlenaMaiakovska
Aug 21 2015 20:14
не буду тебя мучить, попробую сама разобраться
Anton Kulaga
@antonkulaga
Aug 21 2015 20:14
ты ведь поняла, что
mylist.head+sum(mylist.tail) - это сумма всеъ элементов mylist-а?
мы добавляем первый элемент к сумме элементов хвоста и получаем сумму элементов всего списка, верно?
Olena
@OlenaMaiakovska
Aug 21 2015 20:15
да)))
но это меня не спасает
Anton Kulaga
@antonkulaga
Aug 21 2015 20:16
а теперь представь как в математике, что sum(mylist.tail) мы можем переписать как mylist.tail.head+sum(mylist.tail.tail) и получить mylist.head+ mylist.tail.head+sum(mylist.tail.tail) что тоже сумма всего листа?
Olena
@OlenaMaiakovska
Aug 21 2015 20:16
mylist.head+sum(mylist.tail) - я так понимаю тут общая голова
не, мои попытки безнадежны
Anton Kulaga
@antonkulaga
Aug 21 2015 20:17
если val mylist = List(1,3,42,28)
то, mylist.head ==1
mylist.tail.head ==3
mylist.tail.tail.head ==42
Olena
@OlenaMaiakovska
Aug 21 2015 20:18
ага
Anton Kulaga
@antonkulaga
Aug 21 2015 20:18
mylist.head+sum(mylist.tail)
тоже самое что:
1+сумма(3,42,28)
тоже самое что
1+3+сумма(42,28)
тоже самое что
1+3+42+сумма(28+0)
тоже самое что
1+3+42+28+0
functional-list.png
Olena
@OlenaMaiakovska
Aug 21 2015 20:20
ага, тогда в код мы ставляем форулировку такую:mylist.head+sum(mylist.tail)
Anton Kulaga
@antonkulaga
Aug 21 2015 20:20
поняла таки?
Olena
@OlenaMaiakovska
Aug 21 2015 20:21
+sum(mylist.tai.tail)//и т.д.
?
Anton Kulaga
@antonkulaga
Aug 21 2015 20:22

смотри, допустим у нас функция говорит list.head+sum(list.tail)
когда мы передаём в функцию вроде

def sum(list:List[Int]) = ///чё-та там

когда мы передаём list.tail
то уже внутри sum это ведь будет обычный список, ей ведь не надо знать что он чей-то хвост, верно?

Olena
@OlenaMaiakovska
Aug 21 2015 20:22
а зачем еще else нужен?
Anton Kulaga
@antonkulaga
Aug 21 2015 20:23
а теперь подумай, а что случится, если мы дойдём до конца списка и захотим пойти дальше?
def sum(list:List[Int]):Int = if(list.isEmpty) 0 else list.head+sum(list.tail)
Olena
@OlenaMaiakovska
Aug 21 2015 20:24
так мы же написали if(list.isEmpty)
аааа
он еще раз посчитает то же самое
Anton Kulaga
@antonkulaga
Aug 21 2015 20:25
сейчас запущу у себя
вроде считает правильно
теперь самое сложное - понять почему так происходит.
У нас получается какая штука:
list.head+sum(list.tail), что разворачивается в list.head+list.tail.head+sum(list.tail.tail) и так продолжается (если помнишь прогрессии в математике, то это оно) пока мы не уткнёмся, кггда следующего элемента не будет, и там мы уже вместо суммы хвоста добавим ноль, так как в хвосте нет никаких элементов
Olena
@OlenaMaiakovska
Aug 21 2015 20:29
может поняла а может и нет...
но логику поймала
мне так сложно разобраться
Anton Kulaga
@antonkulaga
Aug 21 2015 20:29
что тебе нужно сделать, чтобы понять?
как ты узнаешь, что ты поняла? =)
попробуй, например, рекурсивно поссчитать факториал
в факториале, даже списков не нужно, просто
n(n-1)( (n-1) -1 )...* 1
Olena
@OlenaMaiakovska
Aug 21 2015 20:31
когда пойму, когда не будет вопросов
мне и математику повторить надо...
)))
Anton Kulaga
@antonkulaga
Aug 21 2015 20:32
если не поняла, то должні біть вопросі, задавай
Olena
@OlenaMaiakovska
Aug 21 2015 20:32
еще не сформулировала
давай отложим это,
я пока пройду на более простых темах,
может потом дойдет...
Anton Kulaga
@antonkulaga
Aug 21 2015 20:36
FishEatFish.jpg
Olena
@OlenaMaiakovska
Aug 21 2015 20:36
))))))))))))
это гениально))))
чтобы биологу было понятно?))))))))
Anton Kulaga
@antonkulaga
Aug 21 2015 20:36
@OlenaMaiakovska В моем случае мне помогало разбирать рекурсию с хвоста. Самый последняя рыбка получает пустой список (то есть, list.empty==true)
в смысле правая рыбка получает пустой список
Olena
@OlenaMaiakovska
Aug 21 2015 20:38
у тебя телефон не работает?
насмешил ужасно)))))
Anton Kulaga
@antonkulaga
Aug 21 2015 20:39
рыбка чуть левее от самой правой кушает ноль, который вернула самая правая рыбка с пустым списком и добавляет
28 (так как у неё только List(28)
рыбка ещё левее кушает рыбку, что возвращает 28 и складывает её с 42 и так пока не дойдём до первой рыбки, которые съес всех, добавит 1-чку и выдаст общую сумму
телефон сейчас включу
рекурсия - это то, что создаёт рыбок
если не прописать условия для самой правой рыбки, то рыбк подвиснут, так как будут создаваться до бесконечности
включил телефо
н
Olena
@OlenaMaiakovska
Aug 21 2015 20:56
не, я сдаюсь
Anton Kulaga
@antonkulaga
Aug 21 2015 20:58
def rybka(n:Int):Int =if(n==1) 1 else n*rybka(n-1)
Olena
@OlenaMaiakovska
Aug 21 2015 21:00
у меня не шло оттого что неправильно n:Int):Int указала(((
говорю же, мне надо синтаксиса набраться
Anton Kulaga
@antonkulaga
Aug 21 2015 21:00
сначала ты думаешь о самой маленькой рыбке, которая только и может появится, что она должна что-то вернуть (так как не может создавать рыбок до бесконечности), затем ты задаешь общую логику - умножить число на более маленькую рыбку
да, есть такое. Но принцип стал понятнее?
Olena
@OlenaMaiakovska
Aug 21 2015 21:01
принцип да, факториал лучший пример
Anton Kulaga
@antonkulaga
Aug 21 2015 21:02
ну, списки тоже откусывают
на вещах вроде рекурций концепция функционального программирования строится. Если взять тот же https://www.coursera.org/course/progfun то там первая домашка сугубо по рекурсиям
Olena
@OlenaMaiakovska
Aug 21 2015 21:08
я лучше с уточками поиграюсь
рано мне еще рекурсии мучить
Anton Kulaga
@antonkulaga
Aug 21 2015 21:08
замучал бедную злыми пираньями? =)
Olena
@OlenaMaiakovska
Aug 21 2015 21:09
пираньи веселее показались)
просто сосредоточиться не могу
Anton Kulaga
@antonkulaga
Aug 21 2015 21:10
вся природа не рекурсиях строятся, не замечала, что ветки у деревьев рекурсивные, также как и снежинки?
Olena
@OlenaMaiakovska
Aug 21 2015 21:10
)))))))))))
чего только природа не задумала...
ну иначе бы я не стала заниматься биоинформатикой
Anton Kulaga
@antonkulaga
Aug 21 2015 21:11
факториалы в одну строчку, это разве не красиво?