Damien Elmes 2024-01-08 14:05:09 +10:00
parent bfea56c470
commit 66d0046b8a
5 changed files with 25 additions and 1 deletions

View File

@ -339,7 +339,7 @@ deck-config-must-have-1000-reviews =
{ $count -> { $count ->
[one] Only { $count } review was found. [one] Only { $count } review was found.
*[other] Only { $count } reviews were found. *[other] Only { $count } reviews were found.
} You must have at least 1000 reviews to generate custom parameters. } You must have at least 1000 reviews for this operation.
# Numbers that control how aggressively the FSRS algorithm schedules cards # Numbers that control how aggressively the FSRS algorithm schedules cards
deck-config-weights = FSRS parameters deck-config-weights = FSRS parameters
deck-config-compute-optimal-weights = Optimize FSRS parameters deck-config-compute-optimal-weights = Optimize FSRS parameters

View File

@ -48,6 +48,7 @@ impl AnkiError {
#[cfg(windows)] #[cfg(windows)]
AnkiError::WindowsError { .. } => Kind::OsError, AnkiError::WindowsError { .. } => Kind::OsError,
AnkiError::SchedulerUpgradeRequired => Kind::SchedulerUpgradeRequired, AnkiError::SchedulerUpgradeRequired => Kind::SchedulerUpgradeRequired,
AnkiError::FsrsInsufficientReviews { .. } => Kind::InvalidInput,
}; };
anki_proto::backend::BackendError { anki_proto::backend::BackendError {

View File

@ -114,7 +114,12 @@ pub enum AnkiError {
InvalidMethodIndex, InvalidMethodIndex,
InvalidServiceIndex, InvalidServiceIndex,
FsrsWeightsInvalid, FsrsWeightsInvalid,
// Returned by fsrs-rs; may happen even if 1000+ reviews
FsrsInsufficientData, FsrsInsufficientData,
// Generated by our backend if count < 1000
FsrsInsufficientReviews {
count: usize,
},
FsrsUnableToDetermineDesiredRetention, FsrsUnableToDetermineDesiredRetention,
SchedulerUpgradeRequired, SchedulerUpgradeRequired,
} }
@ -169,6 +174,9 @@ impl AnkiError {
AnkiError::InvalidInput { source } => source.message(), AnkiError::InvalidInput { source } => source.message(),
AnkiError::NotFound { source } => source.message(tr), AnkiError::NotFound { source } => source.message(tr),
AnkiError::FsrsInsufficientData => tr.deck_config_not_enough_history().into(), AnkiError::FsrsInsufficientData => tr.deck_config_not_enough_history().into(),
AnkiError::FsrsInsufficientReviews { count } => {
tr.deck_config_must_have_1000_reviews(*count).into()
}
AnkiError::FsrsWeightsInvalid => tr.deck_config_invalid_weights().into(), AnkiError::FsrsWeightsInvalid => tr.deck_config_invalid_weights().into(),
AnkiError::SchedulerUpgradeRequired => { AnkiError::SchedulerUpgradeRequired => {
tr.scheduling_update_required().replace("V2", "v3") tr.scheduling_update_required().replace("V2", "v3")

View File

@ -75,6 +75,11 @@ impl Collection {
.col .col
.storage .storage
.get_revlog_entries_for_searched_cards_in_card_order()?; .get_revlog_entries_for_searched_cards_in_card_order()?;
if revlogs.len() < 1000 {
return Err(AnkiError::FsrsInsufficientReviews {
count: revlogs.len(),
});
}
let first_rating_count = revlogs let first_rating_count = revlogs
.iter() .iter()

View File

@ -39,6 +39,11 @@ impl Collection {
let mut anki_progress = self.new_progress_handler::<ComputeWeightsProgress>(); let mut anki_progress = self.new_progress_handler::<ComputeWeightsProgress>();
let timing = self.timing_today()?; let timing = self.timing_today()?;
let revlogs = self.revlog_for_srs(search)?; let revlogs = self.revlog_for_srs(search)?;
if revlogs.len() < 1000 {
return Err(AnkiError::FsrsInsufficientReviews {
count: revlogs.len(),
});
}
let items = fsrs_items_for_training(revlogs, timing.next_day_at); let items = fsrs_items_for_training(revlogs, timing.next_day_at);
let fsrs_items = items.len() as u32; let fsrs_items = items.len() as u32;
anki_progress.update(false, |p| { anki_progress.update(false, |p| {
@ -118,6 +123,11 @@ impl Collection {
.col .col
.storage .storage
.get_revlog_entries_for_searched_cards_in_card_order()?; .get_revlog_entries_for_searched_cards_in_card_order()?;
if revlogs.len() < 1000 {
return Err(AnkiError::FsrsInsufficientReviews {
count: revlogs.len(),
});
}
anki_progress.state.fsrs_items = revlogs.len() as u32; anki_progress.state.fsrs_items = revlogs.len() as u32;
let items = fsrs_items_for_training(revlogs, timing.next_day_at); let items = fsrs_items_for_training(revlogs, timing.next_day_at);
let fsrs = FSRS::new(Some(weights))?; let fsrs = FSRS::new(Some(weights))?;