README.md (3404B)
1 # oboeru - 覚える 2 A collection of simple tools for reviewing flashcards. 3 4 Inspired by [oboeta](https://github.com/jtvaughan/oboeta). 5 6 ## Just use Anki 7 [Anki](https://github.com/ankitects/anki) was always a little bit 8 excessive but it has only gotten worse as time goes on. Here are some 9 key problems with it: 10 11 * Cards are stored in a binary database. 12 13 * Relies on tons of terrible software such as qtwebengine. 14 15 * Build system relies on java despite there not being a single line of 16 java in Anki's code base. 17 18 * Newer versions are not portable because of the terrible build system. 19 20 * Anki's buttons for rating cards can have unintended 21 [consequences](https://web.archive.org/web/20201101024335if_/https://massimmersionapproach.com/table-of-contents/anki/low-key-anki/the-ease-factor-problem). 22 23 There is really no reason for flashcards to be this complicated. 24 25 ## Solution 26 oboeru solves this problem by not caring about how you store your 27 cards. In fact all it does is maintain a ledger of card ids, their 28 creation date, their due date, and the number of times the card has 29 acted as a leech. Everything else is completely up to you. 30 31 ### What _does_ oboeru do then? 32 oboeru reads supplied ledgers, finds cards up for review, shuffles 33 them, and finally prints out the originating ledgers name and card id 34 separated by a tab to stdout. Then it waits for commands provided via 35 a named pipe. Depending on the response it will update the current card 36 and print the next card to stdout or rewrite the ledgers and exit. 37 38 ## Algorithm 39 oboeru uses an algorithm inspired by the simplicity of the 40 [Leitner](https://en.wikipedia.org/wiki/Leitner_system) 41 system but still drawing on some of the lessons of the SuperMemo 42 [SM-2](https://www.supermemo.com/en/archives1990-2015/english/ol/sm2) 43 algorithm. Specifically a card can only be passed or failed and it's 44 interval will always be changed by a fixed growth or shrink rate. Like 45 in Anki, cards can become leeches from too many failures. The relevant 46 code is as follows (some parts omitted): 47 48 static void 49 bump_card(Card *card, int status) 50 { 51 diff = card->due - card->reviewed; 52 switch (status) { 53 case CARD_PASS: 54 if (diff < MINIMUM_INCREASE) 55 card->due += MINIMUM_INCREASE; 56 else 57 card->due += diff * GROWTH_RATE; 58 break; 59 case CARD_FAIL: 60 if (diff > LEECH_AGE) 61 card->leeches++; 62 card->due += diff * SHRINK_RATE; 63 } 64 card->reviewed = time(NULL); 65 } 66 67 Take for example a card with an interval of 6 days, `GROWTH_RATE = 1.8`, 68 and `SHRINK_RATE = 0.66` (simplified for readability): 69 70 bump_card(card, CARD_PASS) 71 card->due = +10.8 days 72 bump_card(card, CARD_FAIL) 73 card->due = +4 days 74 75 ## Ledger Format 76 The format for storing the ledgers is 1 card per line with fields tab 77 separated. An example follows: 78 79 # id reviewed due leeches extra 80 23 2021年07月09日16時18分 2021年08月09日05時01分 3 全て 81 0099 2021年07月09日14時18分 2021年08月11日14時19分 0 飲み込む 82 83 The time formatting is configurable via `config.h`. The extra field 84 can be used for whatever, for example to check for duplicates. It can 85 contain any character besides `\0` and `\n`. 86 87 ## Installation 88 Modify `config.h` and `config.mk` to your liking and use the following 89 to install (using root as needed): 90 91 make clean install 92 93 ## Example Usage 94 See [omoidasu](https://github.com/0x766F6964/omoidasu) for one example 95 of how to use these programs.