Randomly change the order of two values on front

I have many cards that say something like “What is the difference between A and B?” on the front. The problem is that I sometimes feel that I might be learning the card rather than learning the difference. That is, I might learn that the first one is this and the second one is that, rather than learning what A and B are.

So, I am looking for a script that can randomly change the order of these two. That is, sometimes, the card will ask me “What is the difference between A and B?” and the other times, it will ask me “What is the difference between B and A?”

2 Likes

Have you seen these templates? Interactive_And_Randomize_Anki_Note_Types/Match Pairs and Randomized Cloze.apkg at main · Vilhelm-Ian/Interactive_And_Randomize_Anki_Note_Types · GitHub

With my request, Vilhelm also created a new template that switches the position of clozes. I can send that to you if you want to see it.

But it’s not ideal all the time so I asked him to create something that switches positions of string wrapped with the pipe character (or something similar).

(the conversations happened in discord).

The one you linked above also seems to switch the position of clozes. What is different in this one?

Is this ready now?

That one requires you to have seperate text with a pipe character. For example, something like this:

Lichens = {{c1:Phycobiont}} + {{c1:Mycobiont}} |
Lichens = {{c1:Mycobiont}} + {{c1:Phycobiont}}

The one he created later switches the position of clozes automatically, so you don’t need to type out the text once again. But it doesn’t work in all cases.

Nah, I’ll need to ask him again.

This one is also there in the above link. Maybe he added it later and you didn’t notice.

I have modified the notetype in the above link for the Basic notetype. Here is the edited one.

Front Template of notetype:

<div id='front'>{{Front}}</div>

<script>
function shuffleElements(...selectors) {
  const isFront = document.getElementById("back") == null
  const parent = document.querySelector(selectors[0]).parentElement;
  const elements = selectors.flatMap(selector => 
    Array.from(parent.querySelectorAll(selector))
  );
  
  // Create a copy of elements
  const elementsCopy = elements.map(el => el.cloneNode(true));
  let indexes = []
  // Fisher-Yates shuffle algorithm for the copy
  for (let i = elementsCopy.length - 1; i > 0; i--) {
    const j = Math.floor(Math.random() * (i + 1));
    [elementsCopy[i], elementsCopy[j]] = [elementsCopy[j], elementsCopy[i]];
    indexes.push([i,j])
  }
    localStorage.setItem("indexes",JSON.stringify(indexes))
  
  // Replace original elements with shuffled copies
  elementsCopy.forEach((shuffledEl, index) => {
    parent.replaceChild(shuffledEl, elements[index]);
  });
}
shuffleElements(".shuffle");
//

</script>

Front field:

What is the difference between <span class="shuffle">A</span> and <span class="shuffle">B</span>?

Thank you @sorata

1 Like

Wow! It’s brilliant! Do you have some button or automation to convert A into <span class="shuffle">A</span> ? I used Semantic HTML tags in editor for something similar, but it’s dead now.

I use this AutoHotKey script:

;------------------------------------------------------------------------
; Wrap selected text with class="shuffle" using Ctrl + Shift + A
;------------------------------------------------------------------------
#HotIf WinActive("ahk_exe anki.exe", )
^+a::
{
GetText(&TempText)
If TempText {
TempText := "<span class='shuffle'>" TempText "</span>"
PutText(TempText)
}
Return
}
#HotIf

; Handy function.
; Copies the selected text to a variable while preserving the clipboard.
GetText(&MyText := "")
{
   SavedClip := ClipboardAll() ; Store full version of Clipboard
   A_Clipboard := "" ; Empty the clipboard
   Send("^c")
   If !ClipWait(0.5)  ; Waits until the clipboard contains data with a timeout of 0.5 s
   {
      A_Clipboard := SavedClip ; Restore Clipboard
      MyText := ""
      MsgBox("No text was sent to clipboard")
      Return
   }
   MyText := A_Clipboard
   Sleep(10)
   A_Clipboard := SavedClip
}

; Pastes text from a variable while preserving the clipboard.
PutText(MyText)
{
   SavedClip := ClipboardAll() 
   A_Clipboard := ""              ; For better compatability
   Sleep(20)                 ; with Clipboard History
   A_Clipboard := MyText
   Send("^v")
   Sleep(100)
   A_Clipboard := SavedClip
   Return
}

Select the text in the HTML editor and press Ctrl + Shift + A.

This might look like a lot of code but I reuse the GetText and PutText functions in a lot of places. So, for me, this is just 11 lines of code.