giovannihenriksen / Anki-Simulator

Simulator for Anki
GNU Affero General Public License v3.0
76 stars 11 forks source link

Bug in step calculation of SimulatedCard leads to Uncaught Exception #55

Closed baderj closed 3 years ago

baderj commented 3 years ago

Version Info

v.1.1.1 of Anki Simulator on Anki 2.1.42 (8eebfe18)

Description

When starting a simulation without changing any options, an exception is thrown:

Error
An error occurred. Please start Anki while holding down the shift key, which will temporarily disable the add-ons you have installed.
If the issue only occurs when add-ons are enabled, please use the Tools > Add-ons menu item to disable some add-ons and restart Anki, repeating until you discover the add-on that is causing the problem.
When you've discovered the add-on that is causing the problem, please report the issue on the add-on support site.
Debug info:
Anki 2.1.42 (8eebfe18) Python 3.8.6 Qt 5.14.2 PyQt 5.14.2
Platform: Windows 10
Flags: frz=True ao=True sv=2
Add-ons, last update check: 2021-04-30 09:36:01

Caught exception:
Traceback (most recent call last):
  File "C:\Users\Username\AppData\Roaming\Anki2\addons21\817108664\gui\dialogs.py", line 678, in run
    data = self._simulator.simulate(self)
  File "C:\Users\Username\AppData\Roaming\Anki2\addons21\817108664\review_simulator.py", line 218, in simulate
    review_answer = self.reviewAnswer(card.state, card.step)
  File "C:\Users\Username\AppData\Roaming\Anki2\addons21\817108664\review_simulator.py", line 117, in reviewAnswer
    percentage_good = percentage_good[step]
IndexError: list index out of range

Probable Cause

Adding additional debugging reveals that the bug affects card in state CARD_STATE_LEARNING. The percentage_good list has 11 elements. This matches both the length of the Learning steps in the GUI and the % correct learnings steps. However, the variable step is 11 and therefore causes the IndexError.

The step variable of a card seems to be set in the collection_simulator.py as follows:

review = SimulatedCard(
                    id=card.id,
                    ease=starting_ease,
                    state=CARD_STATE_LEARNING,
                    step=max(number_of_learning_steps - (card.left % 10), -1),
                )

Here again the number_of_learning_step is correctly set to 11. But this means that if card.left is a multiple of 10, the the step also turns out to be 11 which causes the index error.

giovannihenriksen commented 3 years ago

Thank you for your detailed report! It's a rare bug so it would have been difficult to find without your debugging. The simulator takes 'card.left' and then takes the last digit: card.left % 10 This usually returns the amount of learning steps left for a specific card. However, as you pointed out, this leads to errors when the amount of learning steps is larger than 9. If you'd have 15 learning steps left, then the simulator will only think you'd have 5 left. If you'd have 10 left, then the simulator will think you have 0 left, which will cause a crash. The solution is to take the last 3 digits instead. This should then be fixed by changing % 10 to % 1000

I will push an update soon!