Search in sources :

Example 1 with SECONDS_PER_DAY

use of com.ichi2.libanki.stats.Stats.SECONDS_PER_DAY in project AnkiChinaAndroid by ankichinateam.

the class Sched method _updateCutoff.

/**
 * Daily cutoff ************************************************************* **********************************
 * This function uses GregorianCalendar so as to be sensitive to leap years, daylight savings, etc.
 */
@Override
public void _updateCutoff() {
    Integer oldToday = mToday;
    // days since col created
    mToday = (int) ((getTime().intTime() - mCol.getCrt()) / SECONDS_PER_DAY);
    // end of day cutoff
    mDayCutoff = mCol.getCrt() + ((mToday + 1) * SECONDS_PER_DAY);
    if (oldToday != mToday) {
        mCol.log(mToday, mDayCutoff);
    }
    // instead
    for (Deck deck : mCol.getDecks().all()) {
        update(deck);
    }
    // unbury if the day has rolled over
    int unburied = mCol.getConf().optInt("lastUnburied", 0);
    if (unburied < mToday) {
        SyncStatus.ignoreDatabaseModification(this::unburyCards);
    }
}
Also used : Deck(com.ichi2.libanki.Deck)

Example 2 with SECONDS_PER_DAY

use of com.ichi2.libanki.stats.Stats.SECONDS_PER_DAY in project AnkiChinaAndroid by ankichinateam.

the class SchedTest method test_learn_dayV1.

@Test
public void test_learn_dayV1() throws Exception {
    Collection col = getColV1();
    // add a note
    Note note = col.newNote();
    note.setItem("Front", "one");
    col.addNote(note);
    col.reset();
    Card c = col.getSched().getCard();
    DeckConfig conf = col.getSched()._cardConf(c);
    conf.getJSONObject("new").put("delays", new JSONArray(new double[] { 1, 10, 1440, 2880 }));
    col.getDecks().save(conf);
    // pass it
    col.getSched().answerCard(c, 2);
    // two reps to graduate, 1 more today
    assertEquals(3, c.getLeft() % 1000);
    assertEquals(1, c.getLeft() / 1000);
    assertArrayEquals(new int[] { 0, 1, 0 }, col.getSched().counts());
    c = col.getSched().getCard();
    assertEquals(SECONDS_PER_DAY, col.getSched().nextIvl(c, 2));
    // answering it will place it in queue 3
    col.getSched().answerCard(c, 2);
    assertEquals(col.getSched().getToday() + 1, c.getDue());
    assertEquals(QUEUE_TYPE_DAY_LEARN_RELEARN, c.getQueue());
    assertNull(col.getSched().getCard());
    // for testing, move it back a day
    c.setDue(c.getDue() - 1);
    c.flush();
    col.reset();
    assertArrayEquals(new int[] { 0, 1, 0 }, col.getSched().counts());
    c = col.getSched().getCard();
    // nextIvl should work
    assertEquals(SECONDS_PER_DAY * 2, col.getSched().nextIvl(c, 2));
    // if we fail it, it should be back in the correct queue
    col.getSched().answerCard(c, 1);
    assertEquals(QUEUE_TYPE_LRN, c.getQueue());
    col.undo();
    col.reset();
    c = col.getSched().getCard();
    col.getSched().answerCard(c, 2);
    // simulate the passing of another two days
    c.setDue(c.getDue() - 2);
    c.flush();
    col.reset();
    // the last pass should graduate it into a review card
    assertEquals(SECONDS_PER_DAY, col.getSched().nextIvl(c, 2));
    col.getSched().answerCard(c, 2);
    assertEquals(CARD_TYPE_REV, c.getType());
    assertEquals(QUEUE_TYPE_REV, c.getQueue());
    // if the lapse step is tomorrow, failing it should handle the counts
    // correctly
    c.setDue(0);
    c.flush();
    col.reset();
    assertArrayEquals(new int[] { 0, 0, 1 }, col.getSched().counts());
    conf = col.getSched()._cardConf(c);
    conf.getJSONObject("lapse").put("delays", new JSONArray(new double[] { 1440 }));
    col.getDecks().save(conf);
    c = col.getSched().getCard();
    col.getSched().answerCard(c, 1);
    assertEquals(CARD_TYPE_RELEARNING, c.getQueue());
    assertArrayEquals(new int[] { 0, 0, 0 }, col.getSched().counts());
}
Also used : Note(com.ichi2.libanki.Note) JSONArray(com.ichi2.utils.JSONArray) Collection(com.ichi2.libanki.Collection) DeckConfig(com.ichi2.libanki.DeckConfig) Card(com.ichi2.libanki.Card) RobolectricTest(com.ichi2.anki.RobolectricTest) Test(org.junit.Test)

Example 3 with SECONDS_PER_DAY

use of com.ichi2.libanki.stats.Stats.SECONDS_PER_DAY in project AnkiChinaAndroid by ankichinateam.

the class SchedTest method test_nextIvlV1.

@Test
public void test_nextIvlV1() throws Exception {
    Collection col = getColV1();
    Note note = col.newNote();
    note.setItem("Front", "one");
    note.setItem("Back", "two");
    col.addNote(note);
    col.reset();
    DeckConfig conf = col.getDecks().confForDid(1);
    conf.getJSONObject("new").put("delays", new JSONArray(new double[] { 0.5, 3, 10 }));
    conf.getJSONObject("lapse").put("delays", new JSONArray(new double[] { 1, 5, 9 }));
    col.getDecks().save(conf);
    Card c = col.getSched().getCard();
    // new cards
    // //////////////////////////////////////////////////////////////////////////////////////////////////
    assertEquals(30, col.getSched().nextIvl(c, 1));
    assertEquals(180, col.getSched().nextIvl(c, 2));
    assertEquals(4 * SECONDS_PER_DAY, col.getSched().nextIvl(c, 3));
    col.getSched().answerCard(c, 1);
    // cards in learning
    // //////////////////////////////////////////////////////////////////////////////////////////////////
    assertEquals(30, col.getSched().nextIvl(c, 1));
    assertEquals(180, col.getSched().nextIvl(c, 2));
    assertEquals(4 * SECONDS_PER_DAY, col.getSched().nextIvl(c, 3));
    col.getSched().answerCard(c, 2);
    assertEquals(30, col.getSched().nextIvl(c, 1));
    assertEquals(600, col.getSched().nextIvl(c, 2));
    assertEquals(4 * SECONDS_PER_DAY, col.getSched().nextIvl(c, 3));
    col.getSched().answerCard(c, 2);
    // normal graduation is tomorrow
    assertEquals(1 * SECONDS_PER_DAY, col.getSched().nextIvl(c, 2));
    assertEquals(4 * SECONDS_PER_DAY, col.getSched().nextIvl(c, 3));
    // lapsed cards
    // //////////////////////////////////////////////////////////////////////////////////////////////////
    c.setType(CARD_TYPE_REV);
    c.setIvl(100);
    c.setFactor(STARTING_FACTOR);
    assertEquals(60, col.getSched().nextIvl(c, 1));
    assertEquals(100 * SECONDS_PER_DAY, col.getSched().nextIvl(c, 2));
    assertEquals(100 * SECONDS_PER_DAY, col.getSched().nextIvl(c, 3));
    // review cards
    // //////////////////////////////////////////////////////////////////////////////////////////////////
    c.setQueue(QUEUE_TYPE_REV);
    c.setIvl(100);
    c.setFactor(STARTING_FACTOR);
    // failing it should put it at 60s
    assertEquals(60, col.getSched().nextIvl(c, 1));
    // or 1 day if relearn is false
    conf.getJSONObject("lapse").put("delays", new JSONArray(new double[] {}));
    col.getDecks().save(conf);
    assertEquals(1 * SECONDS_PER_DAY, col.getSched().nextIvl(c, 1));
    // (* 100 1.2 SECONDS_PER_DAY)10368000.0
    assertEquals(10368000, col.getSched().nextIvl(c, 2));
    // (* 100 2.5 SECONDS_PER_DAY)21600000.0
    assertEquals(21600000, col.getSched().nextIvl(c, 3));
    // (* 100 2.5 1.3 SECONDS_PER_DAY)28080000.0
    assertEquals(28080000, col.getSched().nextIvl(c, 4));
    assertThat(without_unicode_isolation(col.getSched().nextIvlStr(getTargetContext(), c, 4)), is("10.8 mo"));
}
Also used : Note(com.ichi2.libanki.Note) JSONArray(com.ichi2.utils.JSONArray) Collection(com.ichi2.libanki.Collection) DeckConfig(com.ichi2.libanki.DeckConfig) Card(com.ichi2.libanki.Card) RobolectricTest(com.ichi2.anki.RobolectricTest) Test(org.junit.Test)

Example 4 with SECONDS_PER_DAY

use of com.ichi2.libanki.stats.Stats.SECONDS_PER_DAY in project AnkiChinaAndroid by ankichinateam.

the class SchedV2Test method test_filt_reviewing_early_normal.

@Test
public void test_filt_reviewing_early_normal() throws Exception {
    Collection col = getColV2();
    Note note = col.newNote();
    note.setItem("Front", "one");
    col.addNote(note);
    Card c = note.cards().get(0);
    c.setIvl(100);
    c.setQueue(CARD_TYPE_REV);
    c.setType(QUEUE_TYPE_REV);
    // due in 25 days, so it's been waiting 75 days
    c.setDue(col.getSched().getToday() + 25);
    c.setMod(1);
    c.setFactor(STARTING_FACTOR);
    c.startTimer();
    c.flush();
    col.reset();
    assertArrayEquals(new int[] { 0, 0, 0 }, col.getSched().counts());
    // create a dynamic deck and refresh it
    long did = col.getDecks().newDyn("Cram");
    col.getSched().rebuildDyn(did);
    col.reset();
    // should appear as normal in the deck list
    /* todo sort
           assertEquals(1, sorted(col.getSched().deckDueTree().getChildren())[0].review_count);
        */
    // and should appear in the counts
    assertArrayEquals(new int[] { 0, 0, 1 }, col.getSched().counts());
    // grab it and check estimates
    c = col.getSched().getCard();
    assertEquals(4, col.getSched().answerButtons(c));
    assertEquals(600, col.getSched().nextIvl(c, 1));
    assertEquals(Math.round(75 * 1.2) * SECONDS_PER_DAY, col.getSched().nextIvl(c, 2));
    assertThat(col.getSched().nextIvl(c, 3), is((long) (75 * 2.5) * SECONDS_PER_DAY));
    assertThat(col.getSched().nextIvl(c, 4), is((long) (75 * 2.5 * 1.15) * SECONDS_PER_DAY));
    // answer 'good'
    col.getSched().answerCard(c, 3);
    checkRevIvl(col, c, 90);
    assertEquals(col.getSched().getToday() + c.getIvl(), c.getDue());
    assertEquals(0L, c.getODue());
    // should not be in learning
    assertEquals(QUEUE_TYPE_REV, c.getQueue());
    // should be logged as a cram rep
    assertEquals(3, col.getDb().queryLongScalar("select type from revlog order by id desc limit 1"));
    // due in 75 days, so it's been waiting 25 days
    c.setIvl(100);
    c.setDue(col.getSched().getToday() + 75);
    c.flush();
    col.getSched().rebuildDyn(did);
    col.reset();
    c = col.getSched().getCard();
    assertEquals(60 * SECONDS_PER_DAY, col.getSched().nextIvl(c, 2));
    assertEquals(100 * SECONDS_PER_DAY, col.getSched().nextIvl(c, 3));
    assertEquals(114 * SECONDS_PER_DAY, col.getSched().nextIvl(c, 4));
}
Also used : Note(com.ichi2.libanki.Note) Collection(com.ichi2.libanki.Collection) Card(com.ichi2.libanki.Card) RobolectricTest(com.ichi2.anki.RobolectricTest) Test(org.junit.Test)

Example 5 with SECONDS_PER_DAY

use of com.ichi2.libanki.stats.Stats.SECONDS_PER_DAY in project Anki-Android by ankidroid.

the class SchedTest method test_learn_dayV1.

@Test
public void test_learn_dayV1() throws Exception {
    Collection col = getColV1();
    // add a note
    Note note = col.newNote();
    note.setItem("Front", "one");
    col.addNote(note);
    col.reset();
    Card c = getCard();
    DeckConfig conf = col.getSched()._cardConf(c);
    conf.getJSONObject("new").put("delays", new JSONArray(new double[] { 1, 10, 1440, 2880 }));
    col.getDecks().save(conf);
    // pass it
    col.getSched().answerCard(c, BUTTON_TWO);
    // two reps to graduate, 1 more today
    assertEquals(3, c.getLeft() % 1000);
    assertEquals(1, c.getLeft() / 1000);
    assertEquals(new Counts(0, 1, 0), col.getSched().counts());
    c = getCard();
    assertEquals(SECONDS_PER_DAY, col.getSched().nextIvl(c, BUTTON_TWO));
    // answering it will place it in queue 3
    col.getSched().answerCard(c, BUTTON_TWO);
    assertEquals(col.getSched().getToday() + 1, c.getDue());
    assertEquals(QUEUE_TYPE_DAY_LEARN_RELEARN, c.getQueue());
    assertNull(getCard());
    // for testing, move it back a day
    c.setDue(c.getDue() - 1);
    c.flush();
    col.reset();
    assertEquals(new Counts(0, 1, 0), col.getSched().counts());
    c = getCard();
    // nextIvl should work
    assertEquals(SECONDS_PER_DAY * 2, col.getSched().nextIvl(c, BUTTON_TWO));
    // if we fail it, it should be back in the correct queue
    col.getSched().answerCard(c, BUTTON_ONE);
    assertEquals(QUEUE_TYPE_LRN, c.getQueue());
    col.undo();
    col.reset();
    c = getCard();
    col.getSched().answerCard(c, BUTTON_TWO);
    // simulate the passing of another two days
    c.setDue(c.getDue() - 2);
    c.flush();
    col.reset();
    // the last pass should graduate it into a review card
    assertEquals(SECONDS_PER_DAY, col.getSched().nextIvl(c, BUTTON_TWO));
    col.getSched().answerCard(c, BUTTON_TWO);
    assertEquals(CARD_TYPE_REV, c.getType());
    assertEquals(QUEUE_TYPE_REV, c.getQueue());
    // if the lapse step is tomorrow, failing it should handle the counts
    // correctly
    c.setDue(0);
    c.flush();
    col.reset();
    assertEquals(new Counts(0, 0, 1), col.getSched().counts());
    conf = col.getSched()._cardConf(c);
    conf.getJSONObject("lapse").put("delays", new JSONArray(new double[] { 1440 }));
    col.getDecks().save(conf);
    c = getCard();
    col.getSched().answerCard(c, BUTTON_ONE);
    assertEquals(CARD_TYPE_RELEARNING, c.getQueue());
    assertEquals(new Counts(0, 0, 0), col.getSched().counts());
}
Also used : Note(com.ichi2.libanki.Note) JSONArray(com.ichi2.utils.JSONArray) Collection(com.ichi2.libanki.Collection) DeckConfig(com.ichi2.libanki.DeckConfig) Card(com.ichi2.libanki.Card) RobolectricTest(com.ichi2.anki.RobolectricTest) Test(org.junit.Test)

Aggregations

RobolectricTest (com.ichi2.anki.RobolectricTest)14 Test (org.junit.Test)14 Card (com.ichi2.libanki.Card)12 Collection (com.ichi2.libanki.Collection)12 Note (com.ichi2.libanki.Note)12 JSONArray (com.ichi2.utils.JSONArray)10 DeckConfig (com.ichi2.libanki.DeckConfig)8 JSONObject (com.ichi2.utils.JSONObject)6 Deck (com.ichi2.libanki.Deck)4