Escaping "Anki hell" by direct manipulation of the Anki sqlite3 database

There’s a phenomenon that verteran Anki users are familiar with - the so-called “Anki hell” or “ease hell.”

Origins of ease hell

The descent into ease hell has to do with the way Anki handles correct and incorrect answers when it presents cards for review. Ease is a numerical score associated with every card in the database and represents a valuation of the difficulty of the card. By default, when cards graduate from the learning phase, an ease of 250% is applied to the card. If you continue to get the card correct, then the ease remains at 250% in perpetuity. As you see the card at its increasing intervals, the ease will remain the same. All good. Sort of.

But what happens if you fail the card at some point in the review process, then the ease becomes 250% minus 15% or 235%. Then, say, you relearn the card and the ease has stablized at 235% percent again. Then later you miss the card. Now you get another 15% hit to the ease. For older cards, you can see where this is going. Eventually the ease bottoms out at 130% and you will see the card frequently forever…

Unless you intervene in one of a handful of ways. The simplest approach is to keep track of the ease values and use the “Easy” button on the card to recover the 15% that was deducted when you missed the card previously. The logical problem behind all of this is that getting a card wrong leaves you with 15% less ease, but getting a card correct has no effect.

A blunt force approach to fixing ease hell

I was skeptical of the concept of ease hell until I ran a search on all my 22,000 Russian cards. Sure enough thousands were stuck at an ease of 130%. My solution was to identify these cards in ease hell and put them back to the starting point of 250%. Here’s the process I used:

  1. Quit Anki so that you can manipulate the database behind its back.
  2. Find the location of the database. On macOS, it’s ~/Application Support/Anki2/name_of_collection/collection.anki2
  3. Open the database using Base sqlite3 database editor, or you can just use sqlite3 straight from the Terminal or iTerm. The advantage of using the GUI application Base is that it’s easier to see the results of your actions; but either way works. If you’re using Base, skip to step 5, otherwise go to step 4
  4. In Terminal or iTerm (I use the latter.) open the Anki collection database: sqlite3 path_to_your_db. To illustrate how SQL queries work, you can execute a quick query against the cards table: SELECT * FROM cards LIMIT 2; The query should return some data with fields delimited by ‘|’ characters.
  5. In Base find the SQL tab. In the text box, you can input a SQL query and press “Execute”.
  6. To target all cards in ease hell, those having an ease factor of 130 (or 1300) as it’s encoded in the database, you would issue the SQL query:
UPDATE cards SET factor = 2500 WHERE factor = 1300 AND factor > 0

Save the database and exit. Now Anki should reflect that ease factor changes.

Alternative approach

You can also accomplish this same feat using an add-on. For example, ResetEZ.py discussed on Mass Immersion Approach will reset all of the ease factors. The same page also features other components of the low-key Anki approach that will maintain the ease factors at 250%.

Maintenance after climbing out of Anki hell

One approach is to simply abuse the Easy button which will repeatedly boost the ease and, in time, build up a buffer against potential future incorrect responses. Another approach to maintenance is to adopt the “straight reward” approach while adds ease bonuses for several correct responses in a row.

Conclusion

Anki hell, also known as ease hell is a real phenomenon, one that defeats the effciencies that could otherwise be gained through spaced repetition.

References

  • Staight Reward add-on - I haven’t used this one because I’m stuck on an earlier version of Anki due to incompatibilities with other add-ons. But it is widely used.
  • Low-key Anki - this site has a suite of add-ons available in a zip file. Together, they correct and prevent ease hell by resetting and keeping all of the ease factors at 2500.
  • Explanation of ease hell - AnKing explains the phenomenon.

Typing Russian stress marks on macOS

While Russian text intended for native speakers doesn’t show accented vowel characters to point out the syllabic stress (ударение) , many texts intended for learners often do have these marks. But how to apply these marks when typing?

Typically, for Latin keyboards on macOS, you can hold down the key (like long-press on iOS) and a popup dialog will show you options for that character. But in the standard Russian phonetic keyboard it doesn’t work. Hold down the e key and you’ll get the option for the letter ë (yes, it’s regarded as a separate letter in Russian - the essential but misbegotten ë .)

So there’s the problem. Stress marks1 are occasionally needed but are nearly impossible to type.

Solution

The solution is a little complicated and it requires some modifications to the instructions noted here on Ask Metafilter.

Here are the steps to follow:

  1. Download the .keylayout file Russian - Phonetic Accents.keylayout from this guy’s public Dropbox. If the idea of that creeps you out and you trust me slightly more, or if that link goes down, you can download it from my site.
  2. Move this .keylayout file to ~/Library/Keyboard Layouts. You will need to authenticate as an Administrator for this computer. Alternatively, you can download the key layout modification application Ukulele, install it and use it to open the “Russian - Phonetic Accents.keylayout” file that you downloaded in step one and then use Ukulele to install the keyboard. If you don’t completely know your way around macOS then that might be a safer approach. Either way, you may have to restart or log out and log in for this to take effect.
  3. Go to System Preferences > Keyboard > Input Sources
  4. Click the (+) button to add a keyboard layout. Scroll down to the bottom of the list of languages to find “Others”
  5. Click on “Others” and you’ll see the new keyboard. Install it be clicking “Add”.
  6. If you type in both Russian and English, then you probably already have the input menu displayed in the menu bar, but if not, it’s activated at System Preferences > Keyboard > Input Sources and select “Show Input menu in menu bar.” Now you should be see all of your input sources in the keyboard and character menu bar item:

  1. To type a character with stress marks, just type ⌥ + ‘, that’s option-apostrophe followed by the Russian vowel that you when to mark.

Alternative

There is a slightly more cumbersome alternative approach to going(nearly) straight to the Unicode character your intend to type. But if you only rarely need to input these stress-marked vowels, it might be worth exploring. Here are the steps:

  1. If you don’t have the input menu displayed in the menu bar, you’ll need to activate it now by going to System Preferences > Keyboard > Input Sources and selecting “Show Input menu in menu bar.”
  2. Now from the Input menu, select “Show Emoji & Symbols.”
  3. Select the ⚙ button at the top left. > “Customize List…”
  4. Select Code Tables > Unicode
  5. Now when you want to add a stress mark on a vowel, return to the character menu (Input menu, select “Show Emoji & Symbols”), select Unicode > 00000300 Combining Diacritical Marks and find row “0300”. Drag glyph 0301 (the second one in on that row) to a location just after the vowel you want to mark.

If you encounter any problems, feel free to use my contact page and I can talk you through the process.

References


  1. I somewhat loosely interchange the terms “accented characters” and “stress marks”. Although they change the pronounciation of vowels like accents in languages such as French, it’s only because they indicate the syllabic stress location ударение in the word and that in turn changes the pronunciation. It’s not an entirely pedantic point so I’ve used the terms interchangeably. ↩︎

Stripping surveillance parameters from Facebook and Google links

While largely opaque to most users, Facebook and Google massage any links that you acquire on their sites to include data used to track you around the web. This script attempts to strip these surveillance parameters from the URL’s. It is by no means all-inclusive. Imaginably, there are links that I haven’t yet encountered and that need to be considered in a future version. So consider this a proof-of-concept.

The problem

For example, I performed a Google search1 for “Smarties”. Inspecting the first link - to Wikipedia, I see:

Predictions 2021

Predictions for 2021

Humans are notoriously poor at assigning probabilities to events, even those that are highly relevant to their daily lives. This year I’m making a deliberate attempt to calibrate my prediction abilities by correlating predictions with reality. The judgments of truth of these outcomes will be made on December 31, 2021, although some of the outcomes will have been decided substantially in advance of that.

Coronavirus

  1. An effective vaccine will be widely available in Canada: 70%.
  2. I will have received a coronavirus vaccine: 65%
  3. I will have personally contracted coronavirus infection: 20%
  4. Someone in my household will have contracted coronavirus: 20%
  5. Schools in London-Middlesex will close due to coronavirus outbreak: 30%
  6. U.S. deaths from COVID-19 > 300,000: 60%
  7. YAPCA will resume in-person activities before end of term because of lifting coronavirus restrictions: 15%
  8. Violin lessons will resume in-person before the end of term because of lifting coronavirus restrictions: 20%
  9. Daily case counts exceed 30 on any day in 2021 for London-Middlesex: 50%.

Politics

  1. Joe Biden will be elected to the U.S. Presidency: 80%
  2. Donald Trump will officially concede the election if he is defeated: 10%
  3. The U.S. Senate will change to Democratic control: 60%
  4. The U.S. House of Representatives will remain in Democratic control: 99%
  5. Joe Biden will die or become impaired in office: 10%
  6. Florida’s electoral votes go to Biden: 45%
  7. Michigan’s electoral votes go to Biden: 50%
  8. Pennsylvania’s electoral votes go to Biden: 60%
  9. Ohio’s electoral votes go to Biden: 20%
  10. Wisonsin’s electoral votes go to Biden: 40%
  11. Arizona’s electoral votes go to Biden: 55%
  12. Lindsey Graham is defeated: 30%
  13. Mitch McConnell is defeated: 10%
  14. Susan Collins is defeated: 45%
  15. Results of election are known by November 5, 2020: 60%
  16. Donald Trump attends the Inauguration ceremonies: 20%
  17. Boris Johnson is still UK PM: 60%
  18. Justin Trudeau is still Canadian PM: 70%
  19. Queen Elizabeth dies: 20%
  20. Prince Philip dies: 30%
  21. Roe v. Wade is overturned: 10%
  22. Coney-Barrett is confirmed: 100%

Family

  1. [redacted]: 70%
  2. [redacted]: 50%
  3. [redacted]: 60%
  4. [redacted]: 80%
  5. [redacted]: 30%
  6. [redacted]: 50%
  7. We own a third dog: 25%
  8. [redacted]: 20%
  9. [redacted]: 20%
  10. Any member of our immediate family household travels on an airliner: 40%
  11. Audra has a new car: 25%
  12. [redacted]: 20%
  13. Interlochen holds in-person summer camp: 40%

Russian

  1. I complete Anki reviews on 100% of days: 70%
  2. I complete Anki reviews on at least 80% of days: 80%
  3. My tutor-rated speaking ability is improved by at least 25% on a 0-10 scale: 70%
  4. I’ve read at least 6 short stories in Russian: 25%
  5. I do prosody practice on at least 50% of days: 10%

Writing

  1. I write more than 5 articles on Suzuki Experience: 40%
  2. I write more than 12 articles on Ojisanseiuichi.com: 60%

Technology/Economy

  1. I purchase a new laptop: 15%
  2. I purchase a new cell phone: 10%
  3. I set up a VPN for privacy purposes: 65%
  4. I cancel my Facebook account: 20%
  5. I check Facebook less than twice a day on 80% of days: 90%
  6. I resume using Instagram: 20%
  7. I’m using a text editor other than Sublime or Atom: 50%
  8. I unblock Twitter: 10%
  9. DJIA closes above 30,000: 60% 10 I update to new major macOS version: 60%

Personal

  1. I workout on at least 80% of days: 20%
  2. I workout on at least 50% of days: 40%
  3. I workout on at least 25% of days: 50%
  4. I take an SSRI or related medication: 30%
  5. [redacted]: 60%
  6. I sit zazen on at least 80% of days: 10%
  7. I sit zazen on at least 50% of days: 30%
  8. I sit zazen on at least 25% of days: 40%
  9. I write 2021 goals: 95%
  10. I complete all 2021 goals: 10%
  11. I complete more than 50% of 2021 goals: 50%
  12. We begin kitchen renovation: 15%
  13. [redacted]: 60%
  14. I read more than 10 books: 20%
  15. I read more than 5 books: 90%
  16. I read more than 4 novels: 15%
  17. I travel anywhere on an airliner: 10%
  18. I install radio transceiver in back lock: 60%
  19. I install USB charger outlet behind office cabinet: 25%
  20. I can play Rachmaninoff partita transcription from memory: 30%

Extracting ID3 tags from the command line - two methods

As part of a Hazel rule to process downloaded mp3 files, I worked out a couple different methods for extracting the ID3 title tag. Not rocket science, but it took a little time to sort out. Both rely on non-standard third-party tools, both for parsing the text and for extracting the ID3 tags.

Extracting ID3 title with ffprobe

ffprobe is part of the ffmpeg suite of tools which on macOS can be installed with Homebrew. If you don’t have the latter, go install it now; because it opens up so many tools for your use. In this case, it makes ffmpeg available via brew install ffmpeg.

Using variables in Keyboard Maestro scripts

Having fallen in love with Keyboard Maestro for its flexibility in macOS automation, I began experimenting with scripting in various languages, like my old favourite Perl. That’s when the fun began. How do we access KM variables inside a Perl script.

Let’s see what the documentation says:

So the documentation clearly states that this script

#!/usr/bin/perl

print scalar reverse $KMVAR_MyVar;

should work if I have a KM variable named MyVar. But, you guessed it - it does not.

Hugo cache busting

Justification

Although caching can make page loads notably faster, it comes with a cost. Browsers aren’t always capable of taking note when a cached resource has changed. I’ve noticed recently that Safari utterly refuses to reload .css files even after emptying the browser cache and clearing the web history.

Background

With a lot of help from the a pair of articles written by Ukiah Smith, I’ve developed a workflow for dealing with this problem during the deployment process. He describes two approaches to the problem of static asset caching, one an improvement on the other. I’ve implemented something like what he describes using the git file hash to modify the filename of the css files. When the client browser sees a new filename, it always reloads the resource. So the problem is to figure out how to only change the filename when the contents have changed. Let’s say you tweak a css parameter and want to ensure that client browsers load the correct version. We can use the git file hash, and append it on the filename. Then the only remaining problem is to make sure that the page head template knows how to find the correct version to bake into the pages. Here, our approach is the same as Smith’s.

iOS shortcut to clear Safari

Ios

(N.B. The next installment in my obsessional interest in thwarting surveillance capitalism. Read Shoshana Zuboff’s seminal work on the subject and you’ll see.)

Justification

Last week I outlined my evolving comprehensive approach to thwarting surveillance capitalism - that is the extraction, repurposing and selling of online behavioural surplus for the purposes of altering future behaviour.

This is a simple iOS shortcut to the embedded Safari setting for clearing Safari history and website data. It turns out that when iOS Safari is presented with a URL in a certain format, it will execute preference settings on the device. After a little trial and error, I noted that the setting Settings → Safari → Clear History and Website Data has its own URL: prefs:root=SAFARI&path=prefs:root=SAFARI&path=CLEAR_HISTORY_AND_DATA. By loading that URL through an iOS Shortcut, you can quickly sanitize iOS Safari.

My macOS and iOS security setup - Update 2020

(N.B. I am not a security expert. I’ve implemented a handful of reasonable measures to prevent cross-site tracking and limit data collection about my preferences and actions online.)

Surveillance capitalism is a real and destructive force in contemporary economics, politics and culture. Whatever utopian visions that Silicon Valley may have had about the transformative power of ubiquitous network technologies have been overwhelmed by the pernicious and opaque forces that profit from amplifying divisions between people. While I can’t change the system, I can change my own practices and reduce the degree to which surveillance capitalists, state actors and others who have no rights to my data.