Skip to content

Commit

Permalink
Calculate interrupted & non-interrupted wrong answers differently (#5)
Browse files Browse the repository at this point in the history
  • Loading branch information
kubk authored Nov 9, 2023
1 parent 3c4a68f commit 072c0f6
Show file tree
Hide file tree
Showing 10 changed files with 245 additions and 17 deletions.
7 changes: 4 additions & 3 deletions functions/lib/handle-error/handle-error.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,11 @@ const reportErrorToTelegram = (error: unknown, env: unknown) => {
message: (error as Error)?.message,
name: (error as Error)?.name,
stack: (error as Error)?.stack,
databaseException: error && error instanceof DatabaseException ? error.error : null,
databaseException:
error && error instanceof DatabaseException ? error.error : null,
zodError: error && error instanceof ZodError ? error.issues : null,
error: JSON.stringify(error, null, 2)
}
error: JSON.stringify(error, null, 2),
};

const bot = new Bot(envSafe.data.BOT_ERROR_REPORTING_TOKEN);
return bot.api
Expand Down
10 changes: 9 additions & 1 deletion functions/review-cards.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ const requestSchema = z.object({
outcome: z.enum(["correct", "wrong"]),
}),
),
isInterrupted: z.boolean().optional(),
});

export type ReviewCardsRequest = z.infer<typeof requestSchema>;
Expand Down Expand Up @@ -57,11 +58,18 @@ export const onRequestPost = handleError(async ({ env, request }) => {
(review) => review.card_id === card.id,
)?.interval;

const reviewResult = reviewCard(
now,
previousInterval,
card.outcome,
input.data.isInterrupted,
);

return {
user_id: user.id,
card_id: card.id,
last_review_date: now.toJSDate(),
interval: reviewCard(now, previousInterval, card.outcome).interval,
interval: reviewResult.interval,
};
}),
)
Expand Down
23 changes: 21 additions & 2 deletions functions/services/review-card.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,16 +38,35 @@ test("hit yes all the time", () => {
]);
});

test("forgetting resets interval", () => {
test("forgetting resets interval - non interrupted", () => {
const date = DateTime.fromSQL("2021-05-20 10:00:00");

const { interval: newInterval1 } = reviewCard(date, undefined, "correct");
expect(newInterval1).toBe(1);

const { interval: newInterval2 } = reviewCard(date, 1, "wrong");
expect(newInterval2).toBe(0);
expect(newInterval2).toBe(0.4);

const { interval: newInterval3 } = reviewCard(date, 0, "wrong");
expect(newInterval3).toBe(0.4);

const { interval: newInterval4 } = reviewCard(date, 0, "correct");
expect(newInterval4).toBe(0.4);

const { interval: newInterval5 } = reviewCard(date, 0.4, "correct");
expect(newInterval5).toBe(1);
});

test("forgetting resets interval - interrupted", () => {
const date = DateTime.fromSQL("2021-05-20 10:00:00");

const { interval: newInterval1 } = reviewCard(date, undefined, "correct");
expect(newInterval1).toBe(1);

const { interval: newInterval2 } = reviewCard(date, 1, "wrong", true);
expect(newInterval2).toBe(0);

const { interval: newInterval3 } = reviewCard(date, 0, "wrong", true);
expect(newInterval3).toBe(0);

const { interval: newInterval4 } = reviewCard(date, 0, "correct");
Expand Down
3 changes: 2 additions & 1 deletion functions/services/review-card.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ export const reviewCard = (
now: DateTime,
interval: number | undefined,
reviewOutcome: ReviewOutcome,
isInterrupted = false,
): Result => {
let calculatedInterval = interval === undefined ? startInterval : interval;

Expand All @@ -26,7 +27,7 @@ export const reviewCard = (
calculatedInterval *= easeFactor;
}
} else if (reviewOutcome === "wrong") {
calculatedInterval = 0;
calculatedInterval = isInterrupted ? 0 : startInterval;
}

const nextReviewDate = now.plus({ day: calculatedInterval });
Expand Down
179 changes: 179 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 3 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,9 @@
"dev:api:start": "npx wrangler pages dev /functions --compatibility-date=2023-09-22",
"dev:tunnel": "../ngrok http --domain=causal-magpie-closing.ngrok-free.app 5173",
"test:api": "npx vitest --dir functions/",
"test:api:coverage:": "npx vitest run --dir functions/ --coverage",
"test:frontend": "npx vitest --dir src/",
"test:frontend:coverage": "npx vitest run --dir src/ --coverage",
"prod:api:logs": "npx wrangler pages deployment tail",
"prod:deploy": "npx wrangler pages publish functions --project-name=memo-card"
},
Expand Down Expand Up @@ -45,6 +47,7 @@
"@typescript-eslint/eslint-plugin": "^6.0.0",
"@typescript-eslint/parser": "^6.0.0",
"@vitejs/plugin-react": "^4.0.3",
"@vitest/coverage-v8": "^0.34.6",
"eslint": "^8.45.0",
"eslint-plugin-react-hooks": "^4.6.0",
"eslint-plugin-react-refresh": "^0.4.3",
Expand Down
Loading

0 comments on commit 072c0f6

Please sign in to comment.