Я всегда считал, что ленивый программист это хороший программист. Почему? Потому что попроси трудолюбивого сделать что-то, он пойдет и сделает. А ленивый программист потратит в 2-3 раза больше времени, но напишет скрипт, который будет — это делать за него. Может быть, в первый раз на это будет потрачено неоправданно много времени, но при условии повторяющихся задач этот подход очень быстро окупается. Я считаю себя ленивым программистом. Это была преамбула, а теперь перейдем к делу.


История первая


Несколько лет назад я задумался, как бы мне улучшить свой английский. Ничего лучшего, чем чтение литературы, на ум не пришло. Была приобретена электронная читалка, закачаны книги и я начал читать. В процессе чтения постоянно попадались незнакомые слова. Я их сразу переводил посредством встроенных в читалку словарей, но я заметил одну особенность: слова не хотели запоминаться. Когда я через несколько страниц снова встречал это слово, то с 90% вероятностью я снова нуждался в переводе, и так каждый раз. Напрашивался вывод, что мало просто переводить незнакомые слова в процессе чтения, нужно делать что-то еще. Идеальным бы вариантом было ввести его в обиход и начать пользоваться, но я живу не в англоязычной стране и это маловозможно. Тут мне вспомнилось, что я когда-то читал про Интервальные повторения.


Что это такое и с чем его едят? Если коротко, то есть такая кривая забывания, далее цитата из Википедии:


Уже в течение первого часа забывается до 60 % всей полученной информации, через 10 часов после заучивания в памяти остаётся 35 % от изученного. Далее процесс забывания идёт медленно, и через 6 дней в памяти остаётся около 20 % от общего числа первоначально выученных слогов, столько же остаётся в памяти и через месяц.

И вывод остюда


Выводы, которые можно сделать на основании данной кривой в том, что для эффективного запоминания необходимо повторение заученного материала.

Вот мы и пришли к идее интервального повторения.


АNKI это абсолютная бесплатная с открытым исходным кодом программа, которая реализует идею интервального повторения. Проще говоря, компьютеризированные флэш карточки, на одной стороне вопрос, на другой ответ. Так как вы можете делать вопросы/ответы с помощью обычного html/css/javascript, то можно сказать, что она обладает поистине безграничными возможностями. Кроме того, она расширяема специальными плагинами, и один из них нам в дальнейшем очень пригодится.


Вручную создавать карточки это долго, нудно, и с большой вероятностью через некоторое время вы на — это дело забьете и поэтому я в какой то момент задал себе вопрос, а можно ли это дело автоматизировать. Ответ — да, можно. И я это сделал. Скажу сразу, это больше POC (Proof of concept), но которым можно пользоваться. Если будет интерес со стороны пользователей и подтянутся другие разработчики, то его можно довести до готового продукта, которым сможет пользоваться даже технически неграмотные пользователи. Сейчас же использование моей утилиты подразумевает некоторые знания в программировании.


Я читаю книги с помощью программы AIReader. У нее есть возможность подключения внешних словарей, а также при переводе слова она сохраняет слово, на которое вы вызвали перевод, в текстовый файл. Осталось дело за малым, перевести эти слова и создать ANKI карточки.


Сначала я пытался использовать для перевода Google Translate, Lingvo API и т.д. Но с бесплатными сервисами дело не пошло. Бесплатный лимит я исчерпывал еще в процессе разработки, кроме того, по условиям лицензии я не имел права кэшировать слова. В какой то момент я понял, что нужно переводить слова самому. В итоге был написан модуль dsl2html к которому можно подключать DSL словари и который умеет конвертировать их в HTML формат.


Вот так выглядит словарная статья в *.html, мой вариант в сравнении с вариантом GoldenDict


dsl2html vs GoldenDict


Перед тем как искать слово в подключенных словарях я привожу его к словарной форме (лемме) с помощью библиотеки Stanford CoreNLP. На самом деле из-за этой библиотеки я и начал писать на Java и первоначальный план был написать все на Java, но в процессе я нашел библиотеку node-java с помощью которой можно относительно просто исполнять Java код из nodejs и часть кода написана на JavaScript. Если бы я нашел эту библиотеку раньше, то на Java не было бы написано ни строчки. Еще один побочный проект который родился в процессе это создание репозитория с DSL документацией которая была найдена в сети в формате *.chm, сконвертирована и приведена в божеский вид. Если автор оригинального файла пользователь по ником yozhic видит эту статью то большое ему спасибо за проделанную работу, без его документации у меня бы скорее всего ничего не получилось.


Итак, у меня есть слово на английском, его словарная статья в формате *.html, осталось свести все воедино, создать ANKI статьи из списка слов и внести их в базу данных ANKI. Для этой цели был создан следующий проект data2anki. Он умеет на вход брать список слов, переводить, создавать ANKI *.html статьи и записывать их в базу данных ANKI. В конце статьи статьи есть инструкция как им пользоваться. Пока же история вторая где интервальные повторения могут быть полезны.


История вторая.


Все люди в поиске более/менее квалифицированной специальности в том числе и программисты сталкиваются с необходимостью подготовки к интервью. Многие концепты которые спрашивают на интервью вы не используете в каждодневной практике и они забываются. При очередной подготовке к интервью, пролистывая конспект, книгу, справочник я столкнулся с тем, что очень много времени и внимания берет на то, чтобы отсеять информацию которую вы уже знаете потому, что она не всегда очевидна и приходится вчитываться, чтобы понять, что это нерелевантно. Когда же вы подходите к теме, которую действительно нужно повторить, очень часто бывает, что вы уже устали и качество подготовки страдает. В какой то момент я подумал, а почему бы не использоваться ANKI карточки и для этого? Например при конспектировании какой то темы, сразу создавать конспект в виде вопроса — ответа, а затем при повторении вы сразу будете знать, знаете вы или нет ответ на этот вопрос.


Проблема возникла только в том, что набивать вопросы очень долго и нудно. Чтобы облегчить процесс, в data2anki проект я добавил функциональность конвертировать markdown текст в ANKI карточки. Все, что вам надо, это написать один большой файл, в котором вопросы и ответы будут помечены заранее оговоренной последовательностью символов, по которым парсер будет понимать, где вопрос, а где ответ.


После того, как этот файл будет создан, вы запускаете data2anki и он создает ANKI карточки. Оригинальный файл легко править и делится, нужно лишь стереть соответствующую карточку(и) и снова запустить программу, и новый вариант будет создан.


Установка и пользованию


  1. Установка ANKI + AnkiConnect


    1. Скачиваете ANKI отсюда: https://apps.ankiweb.net/
    2. Устанавливаете AnkiConnect plugin: https://ankiweb.net/shared/info/2055492159

  2. Установка data2anki


    1. Скачиваете data2anki c github репозитория
      git clone https://github.com/anatoly314/data2anki
    2. Устанавливаете зависимости
      cd data2anki && npm install
    3. Скачиваете java зависимости https://github.com/anatoly314/data2anki/releases/download/0.1.0/jar-dependencies.zip
    4. Распаковываете jar-dependencies.zip и помещаете его содержимое в data2anki/java/jars

  3. Использование для перевода слов:


    1. В файле data2anki/config.json:


      • в ключе mode прописываете значение dsl2anki


      • в ключе modules.dsl.anki.deckName и modules.dsl.anki.modelName прописываете, соответственно, Deck Name и Model Name (уже должны быть созданы перед созданием карточек). Сейчас поддерживается только модель типа Basic:


        Has Front and Back fields, and will create one card. Text you enter in Front will appear on the front of the card, and text you enter in Back will appear on the back of the card.

        где исходное слово это Front field, а перевод будет в Back field.


        Нет никакой проблемы добавить поддержку Basic (and reversed card), где на слово и перевод будет создаваться и обратная карточка, где по переводу нужно будет вспомнить оригинальное слово. Нужно только наличие времени и желания.


      • в ключе modules.dsl.dictionariesPath прописываете массив с подключенными *.dsl словарями. Каждый подключенный словарь это директория в которой находятся файлы словаря в соответствии с форматом: Строение словаря DSL


      • в ключе modules.dsl.wordToTranslatePath прописываете путь к списку слов которые вы хотите перевести.



    2. Запускаете при рабочем ANKI приложении
      node data2anki\index.js
    3. PROFIT!!!

  4. Использования для создания карточек из markdown


    1. В файле data2anki/config.json:


      • в ключе mode прописываете значение markdown2anki
      • в ключе modules.markdown.anki.deckName и modules.dsl.anki.modelName прописываете, соответственно, Deck Name и Model Name (уже должны быть созданы перед созданием карточек). Для markdown2anki mode поддерживается только модель типа Basic.
      • в ключе modules.markdown.selectors.startQuestionSelectors и modules.markdown.selectors.startAnswerSelectors прописываете селекторы которыми вы отмечаете начало вопроса и ответа соответственно. Сама строка с селектором не будет отпарсена и в карточку не попадет, парсер начнет работу со следующей строки.


        Например вот эта карточка вопрос/ответ:

        Anki card example


        Будет выглядеть в markdown следующим образом:



        #QUESTION#
        ## Question 5. Write a mul function which will work properly when invoked with following syntax.
        
        ```javascript
        console.log(mul(2)(3)(4)); // output : 24
        console.log(mul(4)(3)(4)); // output : 48
        ```
        #ANSWER#
        Below is the code followed by the explanation of how it works:
        
        ```javascript
        function mul (x) {
          return function (y) { // anonymous function
            return function (z) { // anonymous function
              return x * y * z;
            };
          };
        }
        ```
        
        Here the `mul` function accepts the first argument and returns the anonymous function which takes the second parameter and returns the anonymous function which takes the third parameter and returns the multiplication of arguments which is being passed in successive
        
        In Javascript function defined inside has access to outer function variable and function is the first class object so it can be returned by the function as well and passed as an argument in another function.
        - A function is an instance of the Object type
        - A function can have properties and has a link back to its constructor method
        - A function can be stored as variable
        - A function can be pass as a parameter to another function
        - A function can be returned from another function
        



        Пример взят отсюда: 123-JavaScript-Interview-Questions

        Еще есть файл с примерами в папке проекта examples/markdown2anki-example.md


      • в ключе modules.markdown.pathToFile
        прописывате, путь к файлу где лежит *.md файл с вопросами/ответами

    2. Запускаете при рабочем ANKI приложении
      node data2anki\index.js
    3. PROFIT!!!


Вот так это выглядит на мобильном телефоне:



Результат


Полученные на desktop версии ANKI карточки без проблем синхронизируются с ANKI облаком (бесплатно до 100mb), а дальше вы можете пользоваться ими уже везде. Есть клиенты под Android и iPhone, также можно пользоваться и в браузере. В результате, если у вас есть время, которое не на что потратить, то вместо того, чтобы бесцельно пролистывать фейсбук или котиков в инстаграм, можно учить что-то новое.


Эпилог


Как я уже упоминал, это скорее рабочий POC, которым можно пользоваться, чем законченный продукт. Где-то процентов 30% стандарта DSL парсера не имплементировано, и поэтому, например не все словарные статьи которые есть в словарях могут быть найдены, также есть идея переписать его на JavaScript, так как хочется "consistency", а кроме того, сейчас он написан не очень оптимально. Сейчас парсер строит дерево, а это помоему лишнее и не нужно усложняет код. В markdown2anki режиме картинки не парсятся. Я буду стараться потихоньку пилить, но, так как пока пишу для себя, то в первую очередь буду решать те грабли, на которые буду сам наступать, но если кто-то захочет помочь, то милости просим. Если есть вопросы, по программе, то буду рад помочь через отрытые issues в соответствующих проектах. Остальную критику и предложения пишите здесь. Надеюсь, кому-то этот проект будет полезен.


P.S. Если заметили ошибки (а они, к сожалению, есть), пишите в личку, все поправлю.

Комментарии (7)


  1. oldbie
    31.05.2019 20:09
    +2

    По своему опыту использования Anki считаю автоматизации и почти все что вы тут описали вредным. 50% качественного запоминания это то самое собственноручное нудное составление карточек. И главное делать это не однообразным потоком, а наоборот стараться создать каждую максимально уникальной и бороться с тем чтобы процесс становился поточным и однообразным. С таким подходом при должном старании составление карточки уже приводит к достаточному запоминанию и дальше они нужны только для того чтобы не «выветрилось».

    И вообще процесс закачки информации в мозг сам по себе утомителен по определению. Да это может раздражать и желание упростить и автоматизировать естественно, однако функции мозгов не заавтоматизировать. А попытки это небольшой самообман — хоп-хоп и в продашн в памяти не получится =). Поэтому считаю порочной практику shared decks и использование для этого чужих материалов.


    1. anatoly314 Автор
      31.05.2019 20:57

      Ну во первых все индивидуально, я не буду утверждать, что всем это подходит. У меня лично, не хватит терпения вручную вводить карточки. Но с другой стороны, если во время прочтения книги/изучения какого-то материала, вести паралельно конспект в подходящем формате — задавать вопрос и своими словами на него отвечать. Потом с этого конспекта сделать карточки, то я думаю это может очень посодействовать в укреплении или освежении материала. Кроме того, если уже будут готовые карточки по какому-то курсу/книге. То после прочтения книги/изучения курса, а может и во время процесса пользоваться карточками, которые составил другой человек тоже будет полезно.
      Со словами тоже самое. Вы не с воздуха их берете. Вы читаете книгу, и этими словами вы будете пользоваться, так автора, довольно часто используют одни и теже слова. Просто использовать набор слов который составил другой человек, без связи с действительностью, я тоже считаю глупым.


  1. hexploy
    01.06.2019 09:20

    Глядя на jar-dependencies.zip у меня возник вопрос — а почему вы верите в npm, но не верите в gradle/maven?


    1. anatoly314 Автор
      01.06.2019 09:53

      Я очень верю в maven, но не хотел усложнять установку настройкой и конфигурацией maven для того, у кого его нет. nodejs + npm в разы проще поставить.


      1. hexploy
        01.06.2019 10:17
        +1

        Взгляните в сторону github.com/takari/maven-wrapper
        Если подойдет — не обязательно заставлять пользователей ставить что-то руками в систему.


  1. petropavel
    02.06.2019 16:56

    Пользуюсь ANKI уже много лет.

    Только всегда считал, что в Андроиде и так удобно слова добавлять: видишь незнакомое слово — share>ColorDict, прочитал перевод, share>AnkiDroid>Save. Три касания, чтоб прочитать перевод (два, если из FBReader-а), еще три — чтоб добавить в Anki, пара секунд на слово, куда уж быстрее.


    1. anatoly314 Автор
      02.06.2019 20:53

      Ужас, вашему терпению только позавидовать :)