Skip to content

Instantly share code, notes, and snippets.

@z1lc
Last active January 19, 2019 04:04
Show Gist options
  • Save z1lc/e9ef656af95aa88af75af4b1d9841a0f to your computer and use it in GitHub Desktop.
Save z1lc/e9ef656af95aa88af75af4b1d9841a0f to your computer and use it in GitHub Desktop.
Anki Add-on: Set the number of new cards due in a specified deck based on how much time total you want to spend in review
import math
from aqt import mw
from aqt.qt import *
DECK_EXACT_NAME = "z"
TOTAL_MINUTES = 50
# TODO: I can get this stuff from existing information in DB
CARDS_PER_MINUTE = 11.5
REPS_PER_NEW_CARD = 2.5
RETENTION = 0.85
def get_new_card_setting():
due_card_ids = mw.col.findCards('deck:{} -deck:{}::* is:due -is:suspended'.format(DECK_EXACT_NAME, DECK_EXACT_NAME))
total_reps_you_can_do = TOTAL_MINUTES * CARDS_PER_MINUTE
estimated_reps_for_review = int(len(due_card_ids) / RETENTION)
reps_still_available = total_reps_you_can_do - estimated_reps_for_review
new_card_setting = 0
if reps_still_available > 0:
new_card_setting = int(reps_still_available / REPS_PER_NEW_CARD)
return new_card_setting
def set_new_cards_in_deck(deck, new_card_setting):
deck_configuration = mw.col.decks.confForDid(deck['id'])
deck_configuration['new']['perDay'] = new_card_setting
# if we don't save both the deck and deck config,
# there will be a mismatch between the two and anki will force a full sync
mw.col.decks.save(deck)
mw.col.decks.save(deck_configuration)
def set_autoadd_deck_totals(total_new_setting):
autoadd_decks = [deck for deck in mw.col.decks.all() if '[autoadd]' in deck['name']]
autoadd_per_deck = 0
new_actually_available = len(mw.col.findNotes('deck:{} -deck:{}::* is:new -is:suspended'
.format(DECK_EXACT_NAME, DECK_EXACT_NAME)))
if total_new_setting > new_actually_available:
autoadd_total = total_new_setting - new_actually_available
non_empty_autoadd_deck_count = sum('EMPTY' not in s['name'] for s in autoadd_decks)
autoadd_per_deck = math.ceil(autoadd_total / non_empty_autoadd_deck_count)
# since all autoadd decks share the same options group, we only have to update one of them.
set_new_cards_in_deck(autoadd_decks[0], autoadd_per_deck)
def recalculate():
total_new_setting = get_new_card_setting()
set_new_cards_in_deck(mw.col.decks.byName(DECK_EXACT_NAME), total_new_setting)
set_autoadd_deck_totals(total_new_setting)
# if we don't reset the view, the configuration change will not be immediately visible in the UI
mw.reset()
recalculate_action = QAction("Recalculate new card setting", mw)
recalculate_action.triggered.connect(recalculate)
mw.form.menuTools.addAction(recalculate_action)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment