mirror of
https://github.com/ankitects/anki.git
synced 2025-09-24 16:56:36 -04:00
Allow cards with no learning history when not training
This commit is contained in:
parent
93499d4182
commit
d16faacd0f
2 changed files with 64 additions and 6 deletions
|
@ -125,3 +125,58 @@ pub(crate) fn single_card_revlog_to_item(
|
||||||
let items = single_card_revlog_to_items(entries, next_day_at, false);
|
let items = single_card_revlog_to_items(entries, next_day_at, false);
|
||||||
items.and_then(|mut i| i.pop())
|
items.and_then(|mut i| i.pop())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use fsrs::MemoryState;
|
||||||
|
|
||||||
|
use super::super::weights::tests::fsrs_items;
|
||||||
|
use super::*;
|
||||||
|
use crate::revlog::RevlogReviewKind;
|
||||||
|
use crate::scheduler::fsrs::weights::tests::convert;
|
||||||
|
use crate::scheduler::fsrs::weights::tests::review;
|
||||||
|
use crate::scheduler::fsrs::weights::tests::revlog;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn bypassed_learning_is_handled() {
|
||||||
|
// cards without any learning steps due to truncated history still have memory
|
||||||
|
// state calculated
|
||||||
|
assert_eq!(
|
||||||
|
convert(
|
||||||
|
&[
|
||||||
|
RevlogEntry {
|
||||||
|
ease_factor: 2500,
|
||||||
|
..revlog(RevlogReviewKind::Manual, 7)
|
||||||
|
},
|
||||||
|
revlog(RevlogReviewKind::Review, 6),
|
||||||
|
],
|
||||||
|
false,
|
||||||
|
),
|
||||||
|
fsrs_items!([review(0)])
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn zero_history_is_handled() {
|
||||||
|
// when the history is empty, no items are produced
|
||||||
|
assert_eq!(convert(&[], false), None);
|
||||||
|
// but memory state should still be inferred, by using the card's current state
|
||||||
|
let mut card = Card {
|
||||||
|
ctype: CardType::Review,
|
||||||
|
interval: 100,
|
||||||
|
ease_factor: 1300,
|
||||||
|
..Default::default()
|
||||||
|
};
|
||||||
|
card.set_memory_state(&FSRS::new(Some(&[])).unwrap(), None);
|
||||||
|
assert_eq!(
|
||||||
|
card.memory_state,
|
||||||
|
Some(
|
||||||
|
MemoryState {
|
||||||
|
stability: 100.0,
|
||||||
|
difficulty: 9.692858
|
||||||
|
}
|
||||||
|
.into()
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -135,8 +135,8 @@ pub(crate) fn single_card_revlog_to_items(
|
||||||
if idx > 0 {
|
if idx > 0 {
|
||||||
entries.drain(..idx);
|
entries.drain(..idx);
|
||||||
}
|
}
|
||||||
} else {
|
} else if training {
|
||||||
// we ignore cards that don't have any learning steps
|
// when training, we ignore cards that don't have any learning steps
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -210,12 +210,12 @@ impl RevlogEntry {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
pub(crate) mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|
||||||
const NEXT_DAY_AT: TimestampSecs = TimestampSecs(86400 * 100);
|
const NEXT_DAY_AT: TimestampSecs = TimestampSecs(86400 * 100);
|
||||||
|
|
||||||
fn revlog(review_kind: RevlogReviewKind, days_ago: i64) -> RevlogEntry {
|
pub(crate) fn revlog(review_kind: RevlogReviewKind, days_ago: i64) -> RevlogEntry {
|
||||||
RevlogEntry {
|
RevlogEntry {
|
||||||
review_kind,
|
review_kind,
|
||||||
id: ((NEXT_DAY_AT.0 - days_ago * 86400) * 1000).into(),
|
id: ((NEXT_DAY_AT.0 - days_ago * 86400) * 1000).into(),
|
||||||
|
@ -224,14 +224,15 @@ mod tests {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn review(delta_t: u32) -> FSRSReview {
|
pub(crate) fn review(delta_t: u32) -> FSRSReview {
|
||||||
FSRSReview { rating: 3, delta_t }
|
FSRSReview { rating: 3, delta_t }
|
||||||
}
|
}
|
||||||
|
|
||||||
fn convert(revlog: &[RevlogEntry], training: bool) -> Option<Vec<FSRSItem>> {
|
pub(crate) fn convert(revlog: &[RevlogEntry], training: bool) -> Option<Vec<FSRSItem>> {
|
||||||
single_card_revlog_to_items(revlog.to_vec(), NEXT_DAY_AT, training)
|
single_card_revlog_to_items(revlog.to_vec(), NEXT_DAY_AT, training)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[macro_export]
|
||||||
macro_rules! fsrs_items {
|
macro_rules! fsrs_items {
|
||||||
($($reviews:expr),*) => {
|
($($reviews:expr),*) => {
|
||||||
Some(vec![
|
Some(vec![
|
||||||
|
@ -244,6 +245,8 @@ mod tests {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub(crate) use fsrs_items;
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn delta_t_is_correct() -> Result<()> {
|
fn delta_t_is_correct() -> Result<()> {
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
|
|
Loading…
Reference in a new issue