use of com.ichi2.anim.ActivityTransitionAnimation.LEFT in project Anki-Android by ankidroid.
the class SchedV2Test method test_learnV2.
@Test
public void test_learnV2() throws Exception {
Collection col = getColV2();
// add a note
Note note = col.newNote();
note.setItem("Front", "one");
note.setItem("Back", "two");
col.addNote(note);
// set as a learn card and rebuild queues
col.getDb().execute("update cards set queue=0, type=0");
col.reset();
// sched.getCard should return it, since it's due in the past
Card c = getCard();
assertNotNull(c);
DeckConfig conf = col.getSched()._cardConf(c);
conf.getJSONObject("new").put("delays", new JSONArray(new double[] { 0.5, 3, 10 }));
col.getDecks().save(conf);
// fail it
col.getSched().answerCard(c, BUTTON_ONE);
// it should have three reps left to graduation
assertEquals(3, c.getLeft() % 1000);
assertEquals(3, c.getLeft() / 1000);
// it should be due in 30 seconds
long t = Math.round(c.getDue() - col.getTime().intTime());
assertThat(t, is(greaterThanOrEqualTo(25L)));
assertThat(t, is(lessThanOrEqualTo(40L)));
// pass it once
col.getSched().answerCard(c, BUTTON_THREE);
// it should be due in 3 minutes
long dueIn = c.getDue() - col.getTime().intTime();
assertThat(dueIn, is(greaterThanOrEqualTo(178L)));
assertThat(dueIn, is(lessThanOrEqualTo((long) (180 * 1.25))));
assertEquals(2, c.getLeft() % 1000);
assertEquals(2, c.getLeft() / 1000);
// check log is accurate
Cursor log = col.getDb().getDatabase().query("select * from revlog order by id desc");
assertTrue(log.moveToFirst());
assertEquals(3, log.getInt(3));
assertEquals(-180, log.getInt(4));
assertEquals(-30, log.getInt(5));
// pass again
col.getSched().answerCard(c, BUTTON_THREE);
// it should be due in 10 minutes
dueIn = c.getDue() - col.getTime().intTime();
assertThat(dueIn, is(greaterThanOrEqualTo(599L)));
assertThat(dueIn, is(lessThanOrEqualTo((long) (600 * 1.25))));
assertEquals(1, c.getLeft() % 1000);
assertEquals(1, c.getLeft() / 1000);
// the next pass should graduate the card
assertEquals(QUEUE_TYPE_LRN, c.getQueue());
assertEquals(CARD_TYPE_LRN, c.getType());
col.getSched().answerCard(c, BUTTON_THREE);
assertEquals(QUEUE_TYPE_REV, c.getQueue());
assertEquals(CARD_TYPE_REV, c.getType());
// should be due tomorrow, with an interval of 1
assertEquals(col.getSched().getToday() + 1, c.getDue());
assertEquals(1, c.getIvl());
// or normal removal
c.setType(CARD_TYPE_NEW);
c.setQueue(QUEUE_TYPE_LRN);
col.getSched().answerCard(c, BUTTON_FOUR);
assertEquals(CARD_TYPE_REV, c.getType());
assertEquals(QUEUE_TYPE_REV, c.getQueue());
assertTrue(checkRevIvl(col, c, 4));
// revlog should have been updated each time
assertEquals(5, col.getDb().queryScalar("select count() from revlog where type = 0"));
}
use of com.ichi2.anim.ActivityTransitionAnimation.LEFT in project Anki-Android by ankidroid.
the class SchedV2Test method filteredDeckSchedulingOptionsRegressionTest.
/**
* Reported by /u/CarelessSecretary9 on reddit:
*/
@Test
public void filteredDeckSchedulingOptionsRegressionTest() {
Collection col = getCol();
col.setCrt(1587852900L);
// 30 minutes learn ahead. required as we have 20m delay
col.set_config("collapseTime", 1800);
long homeDeckId = addDeck("Poorretention");
DeckConfig homeDeckConf = col.getDecks().confForDid(homeDeckId);
JSONObject lapse = homeDeckConf.getJSONObject("lapse");
lapse.put("minInt", 2);
lapse.put("mult", 0.7d);
lapse.put("delays", new JSONArray("[20]"));
col.getDecks().save(homeDeckConf);
ensureLapseMatchesSppliedAnkiDesktopConfig(lapse);
col.flush();
long dynId = addDynamicDeck("Dyn");
/*
>>> pp(self.reviewer.card)
{'data': '', 'did': 1587939535230, 'due': 0, 'factor': 1300, 'flags': 0, 'id': 1510928829863, 'ivl': 25,
'lapses': 5, 'left': 1004, 'mod': 1587921512, 'nid': 1510928805161, 'odid': 1587920944107,
'odue': 0, 'ord': 0, 'queue': 2, 'reps': 22, 'type': 2, 'usn': -1}
*/
Note n = addNoteUsingBasicModel("Hello", "World");
Card c = getOnlyElement(n.cards());
c.setType(CARD_TYPE_REV);
c.setQueue(QUEUE_TYPE_REV);
c.setIvl(25);
c.setDue(0);
c.setLapses(5);
c.setFactor(1300);
c.setLeft(1004);
c.setODid(homeDeckId);
c.setDid(dynId);
c.flush();
SchedV2 v2 = new SchedV2(col);
Card schedCard = v2.getCard();
assertThat(schedCard, Matchers.notNullValue());
v2.answerCard(schedCard, BUTTON_ONE);
assertThat("The lapsed card should now be counted as lrn", v2.mLrnCount, is(1));
Card after = v2.getCard();
assertThat("A card should be returned ", after, Matchers.notNullValue());
/* Data from Anki - pp(self.reviewer.card)
{'data': '', 'did': 1587939535230, 'due': 1587941137, 'factor': 1300,
'flags': 0, 'id': 1510928829863, 'ivl': 17, 'lapses': 6, 'left': 1001,
'mod': 1587939720, 'nid': 1510928805161, 'odid': 1587920944107, 'odue': 0,
'ord': 0, 'queue': 1, 'reps': 23, 'type': 3, 'usn': -1}
*/
assertThat(after.getType(), is(Consts.CARD_TYPE_RELEARNING));
assertThat(after.getQueue(), is(Consts.QUEUE_TYPE_LRN));
assertThat(after.getLeft(), is(1001));
assertThat("ivl is reduced by 70%", after.getIvl(), is(17));
assertThat("One lapse is added", after.getLapses(), is(6));
assertThat(v2.answerButtons(after), is(4));
long one = v2.nextIvl(after, BUTTON_ONE);
long two = v2.nextIvl(after, BUTTON_TWO);
long three = v2.nextIvl(after, BUTTON_THREE);
long four = v2.nextIvl(after, BUTTON_FOUR);
// 20 mins
assertThat("Again should pick the current step", one, is(1200L));
// 30 mins
assertThat("Repeating single step - 20 minutes * 1.5", two, is(1800L));
// 17 days
assertThat("Good should take the reduced interval (25 * 0.7)", three, is(1468800L));
// 18 days
assertThat("Easy should have a bonus day over good", four, is(1555200L));
}
use of com.ichi2.anim.ActivityTransitionAnimation.LEFT in project Anki-Android by ankidroid.
the class SchedTest method test_reviewsV1.
@Test
public void test_reviewsV1() throws Exception {
Collection col = getColV1();
// 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();
// failing it should put it in the learn queue with the default options
// //////////////////////////////////////////////////////////////////////////////////////////////////
// different delay to new
col.reset();
DeckConfig conf = col.getSched()._cardConf(c);
conf.getJSONObject("lapse").put("delays", new JSONArray(new double[] { 2, 20 }));
col.getDecks().save(conf);
col.getSched().answerCard(c, BUTTON_ONE);
assertEquals(QUEUE_TYPE_LRN, c.getQueue());
// it should be due tomorrow, with an interval of 1
assertEquals(col.getSched().getToday() + 1, c.getODue());
assertEquals(1, c.getIvl());
// but because it's in the learn queue, its current due time should be in
// the future
assertThat(c.getDue(), is(greaterThanOrEqualTo(col.getTime().intTime())));
assertThat(c.getDue() - col.getTime().intTime(), is(greaterThan(118L)));
// factor should have been decremented
assertEquals(2300, c.getFactor());
// check counters
assertEquals(2, c.getLapses());
assertEquals(4, c.getReps());
// check ests.
assertEquals(120, col.getSched().nextIvl(c, BUTTON_ONE));
assertEquals(20 * 60, col.getSched().nextIvl(c, BUTTON_TWO));
// try again with an ease of 2 instead
// //////////////////////////////////////////////////////////////////////////////////////////////////
c = cardcopy.clone();
c.flush();
col.getSched().answerCard(c, BUTTON_TWO);
assertEquals(QUEUE_TYPE_REV, c.getQueue());
// the new interval should be (100 + 8/4) * 1.2 = 122
assertTrue(checkRevIvl(col, c, 122));
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, BUTTON_THREE);
// 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, BUTTON_FOUR);
// 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());
}
use of com.ichi2.anim.ActivityTransitionAnimation.LEFT in project Anki-Android by ankidroid.
the class Media method maybeUpgrade.
public void maybeUpgrade() {
String oldpath = dir() + ".db";
File oldDbFile = new File(oldpath);
if (oldDbFile.exists()) {
mDb.execute(String.format(Locale.US, "attach \"%s\" as old", oldpath));
try {
String sql = "insert into media\n" + " select m.fname, csum, mod, ifnull((select 1 from log l2 where l2.fname=m.fname), 0) as dirty\n" + " from old.media m\n" + " left outer join old.log l using (fname)\n" + " union\n" + " select fname, null, 0, 1 from old.log where type=" + Consts.CARD_TYPE_LRN + ";";
mDb.execute(sql);
mDb.execute("delete from meta");
mDb.execute("insert into meta select dirMod, usn from old.meta");
mDb.commit();
} catch (Exception e) {
// if we couldn't import the old db for some reason, just start anew
StringWriter sw = new StringWriter();
e.printStackTrace(new PrintWriter(sw));
mCol.log("failed to import old media db:" + sw.toString());
}
mDb.execute("detach old");
File newDbFile = new File(oldpath + ".old");
if (newDbFile.exists()) {
newDbFile.delete();
}
oldDbFile.renameTo(newDbFile);
}
}
use of com.ichi2.anim.ActivityTransitionAnimation.LEFT in project Anki-Android by ankidroid.
the class SchedV2 method _delayForGrade.
protected int _delayForGrade(JSONObject conf, int left) {
left = left % 1000;
try {
double delay;
JSONArray delays = conf.getJSONArray("delays");
int len = delays.length();
try {
delay = delays.getDouble(len - left);
} catch (JSONException e) {
Timber.w(e);
if (conf.getJSONArray("delays").length() > 0) {
delay = conf.getJSONArray("delays").getDouble(0);
} else {
// user deleted final step; use dummy value
delay = 1.0;
}
}
return (int) (delay * 60.0);
} catch (JSONException e) {
throw new RuntimeException(e);
}
}
Aggregations