Search in sources :

Example 6 with Counts

use of com.ichi2.libanki.sched.Counts in project AnkiChinaAndroid by ankichinateam.

the class Collection method deleteNotesWithWrongFieldCounts.

private ArrayList<String> deleteNotesWithWrongFieldCounts(Runnable notifyProgress, JSONObject m) throws JSONException {
    Timber.d("deleteNotesWithWrongFieldCounts");
    ArrayList<String> problems = new ArrayList<>();
    // notes with invalid field counts
    ArrayList<Long> ids;
    ids = new ArrayList<>();
    Cursor cur = null;
    try {
        notifyProgress.run();
        cur = mDb.getDatabase().query("select id, flds from notes where mid = " + m.getLong("id"), null);
        Timber.i("cursor size: %d", cur.getCount());
        int currentRow = 0;
        // Since we loop through all rows, we only want one exception
        @Nullable Exception firstException = null;
        while (cur.moveToNext()) {
            try {
                String flds = cur.getString(1);
                long id = cur.getLong(0);
                int fldsCount = 0;
                for (int i = 0; i < flds.length(); i++) {
                    if (flds.charAt(i) == 0x1f) {
                        fldsCount++;
                    }
                }
                if (fldsCount + 1 != m.getJSONArray("flds").length()) {
                    ids.add(id);
                }
            } catch (IllegalStateException ex) {
                // DEFECT: Theory that is this an OOM is discussed in #5852
                // We store one exception to stop excessive logging
                Timber.i(ex, "deleteNotesWithWrongFieldCounts - Exception on row %d. Columns: %d", currentRow, cur.getColumnCount());
                if (firstException == null) {
                    String details = String.format(Locale.ROOT, "deleteNotesWithWrongFieldCounts row: %d col: %d", currentRow, cur.getColumnCount());
                    AnkiDroidApp.sendExceptionReport(ex, details);
                    firstException = ex;
                }
            }
            currentRow++;
        }
        Timber.i("deleteNotesWithWrongFieldCounts - completed successfully");
        notifyProgress.run();
        if (ids.size() > 0) {
            problems.add("Deleted " + ids.size() + " note(s) with wrong field count.");
            _remNotes(ids);
        }
    } finally {
        if (cur != null && !cur.isClosed()) {
            cur.close();
        }
    }
    return problems;
}
Also used : ArrayList(java.util.ArrayList) Cursor(android.database.Cursor) SuppressLint(android.annotation.SuppressLint) Nullable(androidx.annotation.Nullable) JSONException(com.ichi2.utils.JSONException) SQLiteDatabaseLockedException(android.database.sqlite.SQLiteDatabaseLockedException) ConfirmModSchemaException(com.ichi2.anki.exception.ConfirmModSchemaException) IOException(java.io.IOException) NoSuchDeckException(com.ichi2.libanki.exception.NoSuchDeckException)

Example 7 with Counts

use of com.ichi2.libanki.sched.Counts in project AnkiChinaAndroid by ankichinateam.

the class SchedV2 method _walkingCount.

protected int _walkingCount(@NonNull LimitMethod limFn, @NonNull CountMethod cntFn) {
    int tot = 0;
    HashMap<Long, Integer> pcounts = new HashMap<>();
    // for each of the active decks
    for (long did : mCol.getDecks().active()) {
        // get the individual deck's limit
        int lim = limFn.operation(mCol.getDecks().get(did));
        if (lim == 0) {
            continue;
        }
        // check the parents
        List<Deck> parents = mCol.getDecks().parents(did);
        for (Deck p : parents) {
            // add if missing
            long id = p.getLong("id");
            if (!pcounts.containsKey(id)) {
                pcounts.put(id, limFn.operation(p));
            }
            // take minimum of child and parent
            lim = Math.min(pcounts.get(id), lim);
        }
        // see how many cards we actually have
        int cnt = cntFn.operation(did, lim);
        // if non-zero, decrement from parents counts
        for (Deck p : parents) {
            long id = p.getLong("id");
            pcounts.put(id, pcounts.get(id) - cnt);
        }
        // we may also be a parent
        pcounts.put(did, lim - cnt);
        // and add to running total
        tot += cnt;
    }
    Timber.e("walking deck count:" + pcounts.size() + ",today new  card count:" + tot);
    return tot;
}
Also used : HashMap(java.util.HashMap) Deck(com.ichi2.libanki.Deck)

Example 8 with Counts

use of com.ichi2.libanki.sched.Counts 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 9 with Counts

use of com.ichi2.libanki.sched.Counts in project AnkiChinaAndroid by ankichinateam.

the class SchedTest method test_forgetV1.

@Test
public void test_forgetV1() throws Exception {
    Collection col = getColV1();
    Note note = col.newNote();
    note.setItem("Front", "one");
    col.addNote(note);
    Card c = note.cards().get(0);
    c.setQueue(QUEUE_TYPE_REV);
    c.setType(CARD_TYPE_REV);
    c.setIvl(100);
    c.setDue(0);
    c.flush();
    col.reset();
    assertArrayEquals(new int[] { 0, 0, 1 }, col.getSched().counts());
    col.getSched().forgetCards(new long[] { c.getId() });
    col.reset();
    assertArrayEquals(new int[] { 1, 0, 0 }, col.getSched().counts());
}
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 10 with Counts

use of com.ichi2.libanki.sched.Counts in project AnkiChinaAndroid by ankichinateam.

the class SchedV2Test method test_review_limits.

@Test
public void test_review_limits() throws Exception {
    Collection col = getColV2();
    Deck parent = col.getDecks().get(col.getDecks().id("parent"));
    Deck child = col.getDecks().get(col.getDecks().id("parent::child"));
    DeckConfig pconf = col.getDecks().getConf(col.getDecks().confId("parentConf"));
    DeckConfig cconf = col.getDecks().getConf(col.getDecks().confId("childConf"));
    pconf.getJSONObject("rev").put("perDay", 5);
    col.getDecks().updateConf(pconf);
    col.getDecks().setConf(parent, pconf.getLong("id"));
    cconf.getJSONObject("rev").put("perDay", 10);
    col.getDecks().updateConf(cconf);
    col.getDecks().setConf(child, cconf.getLong("id"));
    Model m = col.getModels().current();
    m.put("did", child.getLong("id"));
    col.getModels().save(m, false);
    // add some cards
    for (int i = 0; i < 20; i++) {
        Note note = col.newNote();
        note.setItem("Front", "one");
        note.setItem("Back", "two");
        col.addNote(note);
        // make them reviews
        Card c = note.cards().get(0);
        c.setQueue(CARD_TYPE_REV);
        c.setType(QUEUE_TYPE_REV);
        c.setDue(0);
        c.flush();
    }
    // position 0 is default deck. Different from upstream
    DeckDueTreeNode tree = col.getSched().deckDueTree().get(1);
    // (('parent', 1514457677462, 5, 0, 0, (('child', 1514457677463, 5, 0, 0, ()),)))
    assertEquals("parent", tree.getFullDeckName());
    // paren, tree.review_count)t
    assertEquals(5, tree.getRevCount());
    assertEquals(5, tree.getChildren().get(0).getRevCount());
    // .counts() should match
    col.getDecks().select(child.getLong("id"));
    col.reset();
    assertArrayEquals(new int[] { 0, 0, 5 }, col.getSched().counts());
    // answering a card in the child should decrement parent count
    Card c = col.getSched().getCard();
    col.getSched().answerCard(c, 3);
    assertArrayEquals(new int[] { 0, 0, 4 }, col.getSched().counts());
    tree = col.getSched().deckDueTree().get(1);
    assertEquals(4, tree.getRevCount());
    assertEquals(4, tree.getChildren().get(0).getRevCount());
}
Also used : Note(com.ichi2.libanki.Note) Model(com.ichi2.libanki.Model) Collection(com.ichi2.libanki.Collection) Deck(com.ichi2.libanki.Deck) DeckConfig(com.ichi2.libanki.DeckConfig) Card(com.ichi2.libanki.Card) RobolectricTest(com.ichi2.anki.RobolectricTest) Test(org.junit.Test)

Aggregations

Collection (com.ichi2.libanki.Collection)47 Card (com.ichi2.libanki.Card)43 Test (org.junit.Test)39 RobolectricTest (com.ichi2.anki.RobolectricTest)38 Note (com.ichi2.libanki.Note)38 Deck (com.ichi2.libanki.Deck)12 DeckConfig (com.ichi2.libanki.DeckConfig)11 JSONArray (com.ichi2.utils.JSONArray)11 JSONObject (com.ichi2.utils.JSONObject)10 JSONException (com.ichi2.utils.JSONException)6 HashMap (java.util.HashMap)6 Resources (android.content.res.Resources)4 Nullable (androidx.annotation.Nullable)4 Model (com.ichi2.libanki.Model)4 AbstractDeckTreeNode (com.ichi2.libanki.sched.AbstractDeckTreeNode)4 IOException (java.io.IOException)4 Matchers.containsString (org.hamcrest.Matchers.containsString)4 JSONObject (org.json.JSONObject)4 Cursor (android.database.Cursor)3 ConfirmModSchemaException (com.ichi2.anki.exception.ConfirmModSchemaException)3