Skip to content

Instantly share code, notes, and snippets.

@eshapard
Last active February 11, 2023 20:18
Show Gist options
  • Star 9 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save eshapard/960f2508c2096ff663af3b6ebc925f16 to your computer and use it in GitHub Desktop.
Save eshapard/960f2508c2096ff663af3b6ebc925f16 to your computer and use it in GitHub Desktop.
Anki 2.0 addon to dynamically create learning steps. Starting at 15 minutes and then one day, each additional step is `easeFactor * lastStep` until we pass 20 days. Sets graduating and *Easy* interval to the next logical interval in the series. See this post for rationale: https://eshapard.github.io/anki/anki-learning-steps-with-feedback.html
# Auto Learning Steps
# Anki 2.0 addon
# Author EJS
# https://eshapard.github.io/
#
# Sets the learning steps sequence of each deck options group.
from anki.hooks import addHook
from aqt import mw
#from aqt.utils import showInfo
#import time
ignoreList = ['Default', 'OnHold', 'Parent Category'] #Deck options groups to ignore
# run this on profile load
def updateLearningSteps():
#find all deck option groups
dconf = mw.col.decks.dconf
#cycle through them one by one
for k in dconf:
if dconf[k]["name"] not in ignoreList:
#showInfo(dconf[k]["name"])
ease = dconf[k]["new"]["initialFactor"]/1000.0
#create learning steps
tempList = [15]
for i in range(10):
l = int(1440*ease**i)
if l < 28800:
tempList.append(l)
else:
gradInts = [int(l/1440),int(l/1440)]
break
#showInfo(str(tempList))
#showInfo(str(gradInts))
mw.col.decks.dconf[k]["new"]["delays"] = tempList
mw.col.decks.dconf[k]["new"]["ints"] = gradInts
mw.col.decks.save(mw.col.decks.dconf[k])
mw.reset()
# add hook to 'profileLoaded'
addHook("profileLoaded", updateLearningSteps)
@woolfog
Copy link

woolfog commented Dec 12, 2020

Here's an attempt at an updated version for 2.1.26, hopefully it also works as intended (did not do much testing, seems to be working tho):
EDIT1: Fixed graduation interval.

# Auto Learning Steps
# Anki 2.0 addon
# Author EJS 
# Update by woolfog
# https://eshapard.github.io/
#
# Sets the learning steps sequence of each deck options group.
from anki.hooks import addHook
from aqt import mw
#from aqt.utils import showInfo
#import time

ignoreList = ['Default', 'OnHold', 'Parent Category'] #Deck options groups to ignore

# run this on profile load
def updateLearningSteps():
    #find all deck option groups
    all_config = mw.col.decks.all_config()
    #cycle through them one by one
    for k in all_config:
        if k["name"] not in ignoreList:
            #showInfo(dconf[k]["name"])
            ease = k["new"]["initialFactor"]/1000.0
            #create learning steps
            tempList = [15]
            for i in range(10):
                l = int(1440*ease**i)
                if l < 28800:
                    tempList.append(l)
                else:
                    gradInts = [(int(l/1440)),(int(l/1440))]
                    gradInts.append(0)
                    break
            #showInfo(str(tempList))
            #showInfo(str(gradInts))
            k["new"]["delays"] = tempList
            k["new"]["ints"] = gradInts
            mw.col.decks.save(k)
    mw.reset()

# add hook to 'profileLoaded'
addHook("profileLoaded", updateLearningSteps)

@MetalFir
Copy link

@woolfog Thanks for spending your time to edit the addon. After using it for 2.1.26 the learning steps are produced are fine but oddly my graduating interval and easy interval change to "1" and "4" respectively. Any idea what is causing this?

@woolfog
Copy link

woolfog commented Jan 1, 2021

@woolfog Thanks for spending your time to edit the addon. After using it for 2.1.26 the learning steps are produced are fine but oddly my graduating interval and easy interval change to "1" and "4" respectively. Any idea what is causing this?

Thanks for the bug report, I've updated the code in my post above with a fix. Seems like Anki stores another value in the intervals list now, I have no idea what it is being used for though, I'm setting it to 0 for now, hopefully it does not break anything.

@jledesma28
Copy link

such an interesting thread here. So it work on the latest version of Anki?

@onekum
Copy link

onekum commented Nov 25, 2021

@woolfog Not sure if anyone here is still active, but I get an error with your code on Anki startup.

Caught exception:
Traceback (most recent call last):
File "aqt\progress.py", line 54, in handler
File "aqt\main.py", line 149, in on_window_init
File "aqt\main.py", line 197, in setupProfileAfterWebviewsLoaded
File "aqt\main.py", line 244, in setupProfile
File "aqt\main.py", line 425, in loadProfile
File "aqt\hooks_gen.py", line 2985, in call
File "anki\hooks.py", line 34, in runHook
File "C:\Users\******\AppData\Roaming\Anki2\addons21\autosteps_init_.py", line 37, in updateLearningSteps
k["new"]["ints"] = gradInts
UnboundLocalError: local variable 'gradInts' referenced before assignment

@galantra
Copy link

galantra commented Nov 4, 2022

such an interesting thread here. So it work on the latest version of Anki?

Yes

@Ankilli
Copy link

Ankilli commented Feb 10, 2023

In the article it says "Maybe I’ll add an option to select the number of learning steps you want to use." at the very end of it.
Is there a way to tweak the script that way?
I tried playing around with the 28.800 but it didn't change the amount of steps :/
(sry for noob question 😅)

@eshapard
Copy link
Author

eshapard commented Feb 10, 2023

In the article it says "Maybe I’ll add an option to select the number of learning steps you want to use." at the very end of it.
Is there a way to tweak the script that way?
I tried playing around with the 28.800 but it didn't change the amount of steps :/
(sry for noob question 😅)

You'd have to change the 'for i in range(10):" to a different number in the range() function and possibly change the maximum length of a learning step (currently set to 28800).

The number in the range() function defines the maximum learning steps that are generated. Learning steps keep being generated until you either reach that number, or the learning step goes beyond the maximum length.

@Ankilli
Copy link

Ankilli commented Feb 10, 2023

Ah yes, nice. Thanks a lot for the quick reply :)

And is there a way to cut out some of the steps while keeping the others?
So in the following the marked (->) steps would be taken out, could I do it with this script?
15
1440 (1 day)
-> 1440 * Starting Ease
1440 * Starting Ease^2
-> 1440 * Starting Ease^3
Graduating Interval = 1440 * Starting Ease^3

eventually becoming this:
15
1440 (1 day)
1440 * Starting Ease^2
Graduating Interval = 1440 * Starting Ease^3

regards 😄

@eshapard
Copy link
Author

you could do something like:

l = int(1440*ease**(i+1))

instead of

l = int(1440*ease**i)

@Ankilli
Copy link

Ankilli commented Feb 11, 2023

Thank you! 👍
Also helped me a lot to understand the code better! :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment