Search in sources :

Example 11 with INTERVAL

use of com.ichi2.anki.CardBrowser.Column.INTERVAL in project Anki-Android by ankidroid.

the class OverviewStatsBuilderTest method testInfoHtmlStringMonth.

@Test
@Config(qualifiers = "en")
public void testInfoHtmlStringMonth() {
    OverviewStatsBuilder statsTester = new OverviewStatsBuilder(new WebView(getTargetContext()), getCol(), 42L, Stats.AxisType.TYPE_MONTH);
    String HTML = statsTester.createInfoHtmlString();
    assertEquals(HTML, "<center><style>\n" + "h1, h3 { margin-bottom: 0; margin-top: 1em; text-transform: capitalize; }\n" + ".pielabel { text-align:center; padding:0px; color:white; }\n" + "body {color:#FFFFFF;}\n" + "</style><h1>Today</h1>Studied <b>0 cards</b> in <b>0 minutes</b> today<br>Again count: <b>0</b><br>Learn: <b>0</b>, review: <b>0</b>, relearn: <b>0</b>, filtered: <b>0</b><br>No mature cards were studied today<h1>1 month</h1><h3>FORECAST</h3>Total: <b>0</b> reviews<br>Average: <b>0.0</b> reviews/day<br>Due tomorrow: <b>0</b><br><h3>REVIEW COUNT</h3>Days studied: <b>0%</b> (0 of 30)<br>Total: <b>0</b> reviews<br>Average for days studied: <b>0.0</b> reviews/day<br>If you studied every day: <b>0.0</b> reviews/day<br><h3>REVIEW TIME</h3>Days studied: <b>0%</b> (0 of 30)<br>Total: <b>0</b> minutes<br>Average for days studied: <b>0.0</b> minutes/day<br>If you studied every day: <b>0.0</b> minutes/day<br>Average answer time: <b>0.0s</b> (<b>0.00</b> cards/minute)<br><h3>ADDED</h3>Total: <b>0</b> cards<br>Average: <b>0.0</b> cards/day<br><h3>INTERVALS</h3>Average interval: <b>0.0</b> hours<br>Longest interval: <b>0.0</b> hours<h3>ANSWER BUTTONS</h3>Learning: <b>0.00%</b> correct (0 of 0)<br>Young: <b>0.00%</b> correct (0 of 0)<br>Mature: <b>0.00%</b> correct (0 of 0)<h3>CARD TYPES</h3>Total cards: <b>0</b><br>Total notes: <b>0</b><br>Lowest ease: <b>0%</b><br>Average ease: <b>0%</b><br>Highest ease: <b>0%</b></center>");
}
Also used : WebView(android.webkit.WebView) RobolectricTest(com.ichi2.anki.RobolectricTest) Test(org.junit.Test) Config(org.robolectric.annotation.Config)

Example 12 with INTERVAL

use of com.ichi2.anki.CardBrowser.Column.INTERVAL in project Anki-Android by Ramblurr.

the class Storage method check.

/*
     * Upgrading ************************************************************
     */
// public void upgrade(String path) {
// // mPath = path;
// // _openDB(path);
// // upgradeSchema();
// // _openCol();
// // _upgradeRest();
// // return mCol;
// }
/*
     * Integrity checking ************************************************************
     */
public static boolean check(String path) {
    AnkiDb db = AnkiDatabaseManager.getDatabase(path);
    // corrupt?
    try {
        if (!db.queryString("PRAGMA integrity_check").equalsIgnoreCase("ok")) {
            return false;
        }
    } catch (SQLException _) {
        return false;
    }
    // old version?
    if (db.queryScalar("SELECT version FROM decks") < 65) {
        return false;
    }
    // ensure we have indices for checks below
    db.execute("create index if not exists ix_cards_factId on cards (factId)");
    db.execute("create index if not exists ix_fields_factId on fieldModels (factId)");
    db.execute("analyze");
    // fields missing a field model?
    if (db.queryColumn(Integer.class, "select id from fields where fieldModelId not in (" + "select distinct id from fieldModels)", 0).size() > 0) {
        return false;
    }
    // facts missing a field?
    if (db.queryColumn(Integer.class, "select distinct facts.id from facts, fieldModels where " + "facts.modelId = fieldModels.modelId and fieldModels.id not in " + "(select fieldModelId from fields where factId = facts.id)", 0).size() > 0) {
        return false;
    }
    // cards missing a fact?
    if (db.queryColumn(Integer.class, "select id from cards where factId not in (select id from facts)", 0).size() > 0) {
        return false;
    }
    // cards missing a card model?
    if (db.queryColumn(Integer.class, "select id from cards where cardModelId not in (select id from cardModels)", 0).size() > 0) {
        return false;
    }
    // cards with a card model from the wrong model?
    if (db.queryColumn(Integer.class, "select id from cards where cardModelId not in (select cm.id from " + "cardModels cm, facts f where cm.modelId = f.modelId and " + "f.id = cards.factId)", 0).size() > 0) {
        return false;
    }
    // facts missing a card?
    if (db.queryColumn(Integer.class, "select facts.id from facts " + "where facts.id not in (select distinct factId from cards)", 0).size() > 0) {
        return false;
    }
    // dangling fields?
    if (db.queryColumn(Integer.class, "select id from fields where factId not in (select id from facts)", 0).size() > 0) {
        return false;
    }
    // fields without matching interval
    if (db.queryColumn(Integer.class, "select id from fields where ordinal != (select ordinal from fieldModels " + "where id = fieldModelId)", 0).size() > 0) {
        return false;
    }
    // incorrect types
    if (db.queryColumn(Integer.class, "select id from cards where relativeDelay != (case " + "when successive then 1 when reps then 0 else 2 end)", 0).size() > 0) {
        return false;
    }
    if (db.queryColumn(Integer.class, "select id from cards where type != (case " + "when type >= 0 then relativeDelay else relativeDelay - 3 end)", 0).size() > 0) {
        return false;
    }
    return true;
}
Also used : AnkiDb(com.ichi2.anki.AnkiDb) SQLException(android.database.SQLException)

Example 13 with INTERVAL

use of com.ichi2.anki.CardBrowser.Column.INTERVAL in project AnkiChinaAndroid by ankichinateam.

the class Sched method _nextRevIvl.

/**
 * Interval management ******************************************************
 * *****************************************
 */
/**
 * Ideal next interval for CARD, given EASE.
 */
private int _nextRevIvl(@NonNull Card card, @Consts.BUTTON_TYPE int ease) {
    long delay = _daysLate(card);
    int interval = 0;
    JSONObject conf = _revConf(card);
    double fct = card.getFactor() / 1000.0;
    int ivl2 = _constrainedIvl((int) ((card.getIvl() + delay / 4) * 1.2), conf, card.getIvl());
    int ivl3 = _constrainedIvl((int) ((card.getIvl() + delay / 2) * fct), conf, ivl2);
    int ivl4 = _constrainedIvl((int) ((card.getIvl() + delay) * fct * conf.getDouble("ease4")), conf, ivl3);
    if (ease == Consts.BUTTON_TWO) {
        interval = ivl2;
    } else if (ease == Consts.BUTTON_THREE) {
        interval = ivl3;
    } else if (ease == Consts.BUTTON_FOUR) {
        interval = ivl4;
    }
    // interval capped?
    return Math.min(interval, conf.getInt("maxIvl"));
}
Also used : JSONObject(com.ichi2.utils.JSONObject)

Example 14 with INTERVAL

use of com.ichi2.anki.CardBrowser.Column.INTERVAL in project AnkiChinaAndroid by ankichinateam.

the class SchedV2Test method test_moveVersions.

@Test
public void test_moveVersions() throws Exception {
    Collection col = getColV2();
    col.changeSchedulerVer(1);
    Note n = col.newNote();
    n.setItem("Front", "one");
    col.addNote(n);
    // make it a learning card
    col.reset();
    Card c = col.getSched().getCard();
    col.getSched().answerCard(c, 1);
    // the move to v2 should reset it to new
    col.changeSchedulerVer(2);
    c.load();
    assertEquals(QUEUE_TYPE_NEW, c.getQueue());
    assertEquals(CARD_TYPE_NEW, c.getType());
    // fail it again, and manually bury it
    col.reset();
    c = col.getSched().getCard();
    col.getSched().answerCard(c, 1);
    col.getSched().buryCards(new long[] { c.getId() });
    c.load();
    assertEquals(QUEUE_TYPE_MANUALLY_BURIED, c.getQueue());
    // revert to version 1
    col.changeSchedulerVer(1);
    // card should have moved queues
    c.load();
    assertEquals(QUEUE_TYPE_SIBLING_BURIED, c.getQueue());
    // and it should be new again when unburied
    col.getSched().unburyCards();
    c.load();
    assertEquals(CARD_TYPE_NEW, c.getQueue());
    assertEquals(QUEUE_TYPE_NEW, c.getType());
    // make sure relearning cards transition correctly to v1
    col.changeSchedulerVer(2);
    // card with 100 day interval, answering again
    col.getSched().reschedCards(new long[] { c.getId() }, 100, 100);
    c.load();
    c.setDue(0);
    c.flush();
    DeckConfig conf = col.getSched()._cardConf(c);
    conf.getJSONObject("lapse").put("mult", 0.5);
    col.getDecks().save(conf);
    col.reset();
    c = col.getSched().getCard();
    col.getSched().answerCard(c, 1);
    c.load();
    assertEquals(50, c.getIvl());
    // due should be correctly set when removed from learning early
    col.changeSchedulerVer(1);
    c.load();
    assertEquals(QUEUE_TYPE_REV, c.getQueue());
    assertEquals(CARD_TYPE_REV, c.getType());
    assertEquals(50, c.getDue());
}
Also used : Note(com.ichi2.libanki.Note) 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 15 with INTERVAL

use of com.ichi2.anki.CardBrowser.Column.INTERVAL in project AnkiChinaAndroid by ankichinateam.

the class SchedV2Test method test_reviewsV2.

@Test
public void test_reviewsV2() throws Exception {
    Collection col = getColV2();
    // add a note
    Note note = col.newNote();
    note.setItem("Front", "one");
    note.setItem("Back", "two");
    col.addNote(note);
    // set the card up as a review card, due 8 days ago
    Card c = note.cards().get(0);
    c.setType(CARD_TYPE_REV);
    c.setQueue(QUEUE_TYPE_REV);
    c.setDue(col.getSched().getToday() - 8);
    c.setFactor(STARTING_FACTOR);
    c.setReps(3);
    c.setLapses(1);
    c.setIvl(100);
    c.startTimer();
    c.flush();
    // save it for later use as well
    Card cardcopy = c.clone();
    // try with an ease of 2
    // //////////////////////////////////////////////////////////////////////////////////////////////////
    c = cardcopy.clone();
    c.flush();
    col.reset();
    col.getSched().answerCard(c, 2);
    assertEquals(QUEUE_TYPE_REV, c.getQueue());
    // the new interval should be (100) * 1.2 = 120
    assertTrue(checkRevIvl(col, c, 120));
    assertEquals(col.getSched().getToday() + c.getIvl(), c.getDue());
    // factor should have been decremented
    assertEquals(2350, c.getFactor());
    // check counters
    assertEquals(1, c.getLapses());
    assertEquals(4, c.getReps());
    // ease 3
    // //////////////////////////////////////////////////////////////////////////////////////////////////
    c = cardcopy.clone();
    c.flush();
    col.getSched().answerCard(c, 3);
    // the new interval should be (100 + 8/2) * 2.5 = 260
    assertTrue(checkRevIvl(col, c, 260));
    assertEquals(col.getSched().getToday() + c.getIvl(), c.getDue());
    // factor should have been left alone
    assertEquals(STARTING_FACTOR, c.getFactor());
    // ease 4
    // //////////////////////////////////////////////////////////////////////////////////////////////////
    c = cardcopy.clone();
    c.flush();
    col.getSched().answerCard(c, 4);
    // the new interval should be (100 + 8) * 2.5 * 1.3 = 351
    assertTrue(checkRevIvl(col, c, 351));
    assertEquals(col.getSched().getToday() + c.getIvl(), c.getDue());
    // factor should have been increased
    assertEquals(2650, c.getFactor());
    // leech handling
    // //////////////////////////////////////////////////////////////////////////////////////////////////
    DeckConfig conf = col.getDecks().getConf(1);
    conf.getJSONObject("lapse").put("leechAction", LEECH_SUSPEND);
    col.getDecks().save(conf);
    c = cardcopy.clone();
    c.setLapses(7);
    c.flush();
/* todo hook
        // steup hook
        hooked = new [] {};

        def onLeech(card):
        hooked.append(1);

        hooks.card_did_leech.append(onLeech);
        col.getSched().answerCard(c, 1);
        assertTrue(hooked);
        assertEquals(QUEUE_TYPE_SUSPENDED, c.getQueue());
        c.load();
        assertEquals(QUEUE_TYPE_SUSPENDED, c.getQueue());
        */
}
Also used : Note(com.ichi2.libanki.Note) 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)15 Test (org.junit.Test)15 Card (com.ichi2.libanki.Card)12 Collection (com.ichi2.libanki.Collection)12 DeckConfig (com.ichi2.libanki.DeckConfig)12 Note (com.ichi2.libanki.Note)12 JSONArray (com.ichi2.utils.JSONArray)8 JSONObject (com.ichi2.utils.JSONObject)8 Cursor (android.database.Cursor)4 WebView (android.webkit.WebView)3 Config (org.robolectric.annotation.Config)3 NonNull (androidx.annotation.NonNull)2 SQLException (android.database.SQLException)1 AnkiDb (com.ichi2.anki.AnkiDb)1