Anki database adventures: Counting notes by model type

Continuing my series on accessing the Anki database outside of the Anki application environment, here’s a piece on accessing the note type model. You may wish to start here with the first article on accessing the Anki database. This is geared toward mac OS. (If you’re not on mac OS, then start here instead.)

The note type model

Since notes contain flexible fields in Anki, the model for a note type is in JSON. The best guess definition of the JSON is:

{
    "css": "CSS, shared for all templates",
    "did":
        "Long specifying the id of the deck that cards are added to by default",
    "flds": [
       "JSONArray containing object for each field in the model as follows:",
       {
         "font": "display font",
         "media": "array of media. appears to be unused",
         "name": "field name",
         "ord": "ordinal of the field - goes from 0 to num fields -1",
         "rtl": "boolean, right-to-left script",
         "size": "font size",
         "sticky": "sticky fields retain the value that was last added \
                    when adding new notes"
      }
    ],
    "id": "model ID, matches cards.mid",
    "latexPost": "String added to end of LaTeX expressions",
    "latexPre": "preamble for LaTeX expressions",
    "mod": "modification time in milliseconds",
    "name": "model name",
    "req": [
      "Array of arrays describing which fields are required \
       for each card to be generated",
      [
        "array index, 0, 1, ...",
        "? string, all",
        "another array",
        ["appears to be the array index again"]
      ]
    ],
    "sortf": "Integer specifying which field is used for sorting (browser)",
    "tags": "Anki saves the tags of the last added note to the current model",
    "tmpls": [
      "JSONArray containing object of CardTemplate for each card in model",
      {
        "afmt": "answer template string",
        "bafmt": "browser answer format: used for displaying answer in browser",
        "bqfmt": "browser question format: \
                  used for displaying question in browser",
        "did": "deck override (null by default)",
        "name": "template name",
        "ord": "template number, see flds",
        "qfmt": "question format string"
      }
    ],
    "type": "Integer specifying what type of model. 0 for standard, 1 for cloze",
    "usn": "Update sequence number: used in same way as other usn vales in db",
    "vers": "Legacy version number (unused)"
}

Our goal today is to count all of the notes that have a given note type. Fortunately, there’s a built-in method for this:

verbModel = col.models.byName(u'Русский - глагол')

Here we find the model object (a Python dictionary) named ‘Русский - глагол’ (that’s Russian verb, by the way.) To access its id:

modelID = verbModel['id']

Now we just have to count:

query = """SELECT COUNT(id) from notes WHERE mid = {}""".format(verbModel['id'])
verbNotes = col.db.scalar(query)

print 'There are {:.5g} verb notes.'.format(verbNotes)

And that’s it for this little adventure in the Anki database.

See also:

Accessing the Anki database with Python: Working with a specific deck

I previously wrote about accessing the Anki database using Python on mac OS. Extending that post, I’ll show how to work with a specific deck in this short post.

To use a named deck you’ll need its deck ID. Fortunately there’s a built-in method for finding a deck ID by name:

col = Collection(COLLECTION_PATH)
dID = col.decks.id(DECK_NAME)

Now in queries against the cards and notes tables we can apply the deck ID to restrict them to a certain deck. For example, to find all of the cards currently in the learning stage:

query = """SELECT COUNT(id) FROM cards where type = 1 AND did = dID"""
learningCards = col.db.scalar(query)

print 'There are {:.5g} learning cards.'.format(learningCards)

And close the collection:

col.close()

See also:

Working with the Anki database on mac OS using Python

Not long ago I ran across this post detailing a method for opening and inspecting the Anki database using Python outside the Anki application environment. However, the approach requires linking to the Anki code base which is inaccessible on mac OS since the Python code is packaged into a Mac app on this platform.

The solution I’ve found is inelegant; but just involves downloading the Anki code base to a location on your file system where you can link to it in your code. You can find the Anki code here on github.

Process automation in building Anki vocabulary cards

For the last two years, I’ve been working through a 10,000 word Russian vocabulary ordered by frequency. I have a goal of finishing the list before the end of 2019. This requires not only stubborn persistence but an efficient process of collecting the information that goes onto my Anki flash cards.

My manual process has been to work from a Numbers spreadsheet. As I collect information about each word from several websites, I log it in this table.

More Javascript with Anki

I wrote a piece previously about using JavaScript in Anki cards. Although I haven’t found many uses for employing this idea, it does come up from time-to-time including a recent use-case I’m writing about now.

After downloading a popular French frequency list deck for my daughter to use, I noticed that it omits the gender of nouns in the French prompt. In school, I was always taught to memorize the gender along with the noun. For example, when you memorize the word for law, “loi” you should mermorize it with either the definite article “la” or the indefinite article “une” so that the feminine gender of the noun is inseparable from the noun itself. But this deck has only the noun prompt and I was afraid that my daughter would fail to memorize the noun’s gender. JavaScript to the rescue.

An approach to dealing with spurious sensor data in Indigo

Spurious sensor data can wreak havoc in an otherwise finely-tuned home automation system. I use temperature data from an Aeotech Multisensor 6 to monitor the environment in our greenhouse. Living in Canada, I cannot rely solely on passive systems to maintain the temperature, particularly at night. So, using the temperature and humidity measurements transmitted back to the controller over Z-wave, I control devices inside the greenhouse that heat and humidify the environment.

Follow the intent.

With Trump the usual advice of “Follow the money.” doesn’t work because Congress refuses to force him to disclose his conflicts of interest. As enormous and material as those conflicts must be, I’m just going to focus on what I can see with my own eyes, the man’s apparent intent.

In his public life, Donald Trump has never done anything that did not personally and directly benefit him. Most of us, as we go through life, assemble a collection of acts that are variously self-serving and other-serving. This is the way of life. Normal life. With Trump, not so. Even his meager philanthropic acts are tainted with controversy. The man simply cannot act in sacrificial way. He is incurable.^[In a campaign event in Fort Dodge, Iowa on November 12, 2015, Trump claimed that rival Ben Carson was “pathological” and that “…if you’re pathological, there’s no cure for that, folks, okay? There’s no cure for that.” Since Trump’s own psychopathology is widely questioned, one wonders if he, too, is incurable. Given that narcissistic personality disorder is almost certainly among the potential diagnoses, he probably is incurable.]

They're just paid protesters

In an effort to strip protesters of their legitimacy, Trump and Fox News claim that protesters are simply there because they’re paid by powerful oppositional interests. Never mind that Trump has no evidence for his claim; he has no evidence for practically anything that emerges from his loud mouth. What is more interesting to me is that if money delegitimizes authenticity then presumably we can use this effect to come to additional conclusions.

@realDonaldTrump Russian Twitter bot

Someday, when I have time to burn, I’m going to write a Twitter bot that takes all of Trump’s vacuous tweets and translate them into Russian. It’ll look like this:

There’s something ludicrous about the idea of the Trump, who is distractible, impatient, and incurious being able to learn Russian, an incredibly difficult language.