[Userscript] Self-Study Quiz

I didn’t have the link at the time, but this is the one I meant:

And this:

2 Likes

I’ve known about this script for quite a while now and about a week ago I finally decided to try it out. It’s been a blast - works smooth and fast.

One thing I’ve been trying to do with my studies is to learn all readings when I study a kanji (not only the main reading) which has helped me a ton with vocab. So to help with that I have a kanji-only preset that gives me a level (or ten) worth of kanji and I work through them. I tweaked a bit my local installation of the script to display all readings in the Help popup so I can review them after I try to guess them for myself.

But I’ve been wanting to type in all of the readings. I know I can type in the secondary reading, get an input shake, delete it and type the primary one. I could also make it so that it deletes it for me so that I don’t have to lose time on that. But is there an easy way to split the Kanji Reading question into multiple ones? I still want to have one question for a meaning, but also one question per each each reading (be that onyomi or kunyomi). Is there an array with data where I can split some of the objects to produce more questions in the quiz? I’m happy to work it out myself if you can point me to a piece of state or a function. I’ve looked through the code, but am unsure of where to make a tweak.

It would be a lot simpler to make a single Reading question accept multiple comma-separated answers (or space-separated).

You can use the following function to split your answer into an array of answers:

function split_list(str) {return str.replace(/、/g,',').replace(/[\s ]+/g,' ').trim().replace(/ *, */g, ',').split(',').filter(function(name) {return (name.length > 0);});}

In the script, search for the submit_answer() function, and do something like this:

case 'reading':
  answer = wanakana.toHiragana(answer);
  if (itype === 'kanji') {
    let answers = split_list(answer);
    let correct_count = answers.filter((ans) => (qinfo.answer.good.indexof(ans) >= 0)).length;
    let incorrect_count = answers.length - correct_count;
    if (correct_count === answers.length) {
      action = 'correct';
    } else if (correct_count > 0 && incorrect_count == 0) {
      action = 'shake';
      message = 'You entered '+correct_count+' out of '+answers.length+' readings.';
    } else {
      // Leave the "else" the same for wrong answers
    }
  } else {
   // Leave everything the same for vocab readings
  }

You’ll also need to change the question generator to not filter out Wanikani’s non-preferred readings. In the populate_qinfo() function, change:

if (qinfo.item.type === 'vocabulary' || reading.accepted_answer) {

to

if (true) {

Note: I’m just typing the above code from my tablet, so it’s not tested. It might need some debugging.

Also, you could add a setting to make this behavior selectable.

1 Like

I think that should be incorrect_count !== 0, but it also might be an implicitly covered case. But yeah, I’ll do some testing. You’re right, this approach might be easiest and it should fit my purpose. Sorry to have made you code on a tablet ;D I’ll try it out after work today. Thank you.

I’m not sure which line you mean, but if you’re referring to this one:

} else if (correct_count > 0 && incorrect_count == 0) {

I think it’s correct for what I intended, which is that it warns if all of the readings you gave were correct, but you didn’t give all of the ones that WK knows. If it contains any incorrect answers, it should go to the fail condition in the final ‘else’.

This is what I ended up with:

case 'reading':
    answer = wanakana.toHiragana(answer);
    if (itype === 'kanji') {
        let answers = split_list(answer);
        let correct_count = answers.filter((ans) => (qinfo.answer.good.indexOf(ans) >= 0)).length;
        let incorrect_count = answers.length - correct_count;
        if (correct_count === qinfo.answer.good.length) {
            action = 'correct';
        } else if (correct_count > 0 && incorrect_count == 0) {
            action = 'shake';
            message = 'You entered '+correct_count+' out of '+qinfo.answer.good.length+' readings.';
        } else {
            var bad = qinfo.answer.bad.map((english) => wanakana.toHiragana(english.toLowerCase()));
            if (answers.some(ans => bad.indexOf(ans) >= 0)) {
                action = 'shake';
                message = 'We\'re looking for the reading, not the meaning';
            } else if (answers.some(ans => !wanakana.isKana(ans))) {
                action = 'shake';
                message = 'Your answer contains invalid characters';
            } else {
                action = 'incorrect';
            }
        }
    } else {
        // Same for vocab readings
    }

The only difference being if (correct_count === answers.length) became if (correct_count === qinfo.answer.good.length) since otherwise it would mark your answer as correct if all your provided answers were correct, even if there were missing some.

The else for bad answers needed just a slight tweak to make it work with arrays, but otherwise is unchanged.

Also, you were right about incorrect_count == 0 (and yes, that’s what I was referring to). I guess I was thinking of a shake on providing some correct and some incorrect answers. But marking it as invalid makes more sense.

In all that code you wrote indexof was your only typo, so I’d say your coding skills on a tablet are top notch. I’ll probably look to add that setting to switch the behavior later this week since it can get taxing to have to recall everything. I’m pretty happy with the result. Thank you very much for the help!

1 Like

@rfindley A couple of points. First, if you pass a quiz from one source with errors, requiz it but don’t start a new round and switch to the other source while the Summary dialog is displayed, then the first round goes as expected, but on the second round it starts asking question from the previous source. Because original_items hasn’t been restored up to the second round from the other source.

Also, let me remind you about the click-to-open patch. And there’s a patch in that message that fixes the default speaker mode (Settings > Audio > Speaker > Rotate).

And here’s the patch. Along with the other two.

Sorry if sounds stupid but i see people using this script but i don’t understand the advantages of using it. I know it have some extra options but what’s the difference?

It’s good for selecting pretty much anything on Wanikani that you want to spend more time studying. This came before the Extra Study system that is now part of WaniKani, and it includes a lot more possibilities. You can do english-to-japanese, audio-to-english, leeches, study specific levels, etc.

What I originally created it for is to periodically review my past levels on a rotating schedule, just to help reinforce my memory.

2 Likes

How do you feel about those extra options?

For me, it can be important to review up-coming levels; and review by levels, like current and previous ones. Also, type of reviews, like EN=>JP, audio=>EN; so that I don’t have to set up Anki. Repeated exposure may help, rather than simply relying on SRS. (If you will forgot in 10 minutes, what’s the point of waiting to try to remember later?)

1 Like

I think it can be useful. I don’t personally feel really into some features, i like anki it helps me to have contact with differents words and it’s easier to learn a word/kanji when i found in a Wani Lesson. And i don’t give much importance to the levels, they are not organizaded by topic or frequency of use.
My main problem is the large amount of words that have the same meaning and not understanding what’s the difference.

But maybe i should give the scripy a try and looks how it goes. A feature could look not useful at first but after trying can be the thing i needed. Thanks for the response :slight_smile:

Is there a way to get the self study quiz to have a flashcard mode.

I’ve been using WK stats to study but don’t like the memory association per level that is forming.

thanks!

What do you mean by flashcard mode? If you mean not having to type an answer, you can use F1 to reveal the answer, then ctrl+ to move to the next question.

Hey, I’m a relatively new user. I’ve installed this today and have tried it out and it’s exactly what I needed, however sometimes it seems really unforgiving to the point where I don’t really know what’s wrong with my answer compared to the one it shows in the help.

For example it asked me for the meaning of 下げる. To my knowledge this means to lower, which was what I answered, but that was marked as incorrect, the help shows “To Lower Something, To Hang Something”. Is “to lower” not sufficient? Because it is sufficient during the reviews. :frowning:

The software isn’t smart enough to understand the difference (or lack of) between “to lower” and “to lower something”. If Self-Study rejects the answer, Wanikani probably will, too.

The solution is to add “to lower” as a synonym for that word on Wanikani’s item page for that word. (WaniKani / Vocabulary / 下げる)

[edit: ahh, as @prouleau said, Wanikani does implement an internal whitelist, and I’m guessing “to lower” is on that list. But Self-Study doesn’t have access to that list, so… out of luck, unfortunately]

2 Likes

Self-Study Quiz does not implement the whitelist feature of Wanikani. This is a separate list of answers that are allowed even though they are not on the main list of correct answers. When an answer is whitelisted Wanikani will give you a correct answer but not Self Study Quiz.

1 Like

I have verified that it is indeed on that list.

1 Like

Ah that makes sense. Thank you, @rfindley and @prouleau .

I just installed the scripts Open Framework and Self-Study quiz, and the self-study quiz window opens fine and is great; however, I keep getting the pop-up window that say:

“Self-study quiz requires WaniKani open framework. Do you want to be forwarded to the installation instructions?”

I already have it installed. How to stop getting this pop-up?