Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Prevent load balancer from scheduling cards in the past #432

Merged
merged 4 commits into from
Jul 7, 2024
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 9 additions & 13 deletions schedule/reschedule.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@ class FSRS:
reviewed_today: int
card: Card
elapsed_days: int
allow_to_past: bool
apply_easy_days: bool

def __init__(self) -> None:
Expand All @@ -38,7 +37,6 @@ def __init__(self) -> None:
self.easy_specific_due_dates = []
self.p_obey_specific_due_dates = 1
self.elapsed_days = 0
self.allow_to_past = True
self.apply_easy_days = False

def set_load_balance(self, did_query=None):
Expand Down Expand Up @@ -88,21 +86,24 @@ def apply_fuzz(self, ivl):
else:
# Load balance
due = self.card.odue if self.card.odid else self.card.due
if due - self.card.ivl + max_ivl <= mw.col.sched.today:
last_review = get_last_review_date(self.card)
if last_review + max_ivl < mw.col.sched.today:
# If the latest possible due date is in the past, skip load balance
return ivl

if self.apply_easy_days:
last_review = get_last_review_date(self.card)
if due > last_review + max_ivl + 2:
current_ivl = due - last_review
min_ivl, max_ivl = get_fuzz_range(
current_ivl, self.elapsed_days, current_ivl
)

# Don't schedule the card in the past
min_ivl = max(min_ivl, mw.col.sched.today - last_review)

min_workload = math.inf
best_ivl = (max_ivl + min_ivl) // 2 if self.allow_to_past else max_ivl
step = (max_ivl - min_ivl) // 100 + 1
best_ivl = max_ivl
step = 1 + (max_ivl - min_ivl) // 100

if self.easy_days_review_ratio == 0:
obey_easy_days = True
Expand All @@ -114,17 +115,14 @@ def apply_fuzz(self, ivl):
)

for check_ivl in reversed(range(min_ivl, max_ivl + step, step)):
check_due = due - self.card.ivl + check_ivl
check_due = last_review + check_ivl
if (
obey_specific_due_dates
and check_due in self.easy_specific_due_dates
):
continue

day_offset = check_due - mw.col.sched.today
if not self.allow_to_past and day_offset < 0:
break

due_date = sched_current_date() + timedelta(days=day_offset)
if obey_easy_days and due_date.weekday() in self.easy_days:
# If the due date is on an easy day, skip
Expand All @@ -134,7 +132,7 @@ def apply_fuzz(self, ivl):
# If the due date is in the future, the workload is the number of cards due on that day
workload = self.due_cnt_per_day[check_due]
else:
# If the due date is in the past or today, the workload is the number of cards due today plus the number of cards learned today
# If the due date is today, the workload is the number of cards due today plus the number of cards learned today
workload = self.due_today + self.reviewed_today
if workload < min_workload:
best_ivl = check_ivl
Expand Down Expand Up @@ -230,8 +228,6 @@ def reschedule_background(
fsrs.p_obey_specific_due_dates = p_obey_specific_due_dates(
len(fsrs.easy_specific_due_dates), fsrs.easy_days_review_ratio
)
if len(easy_specific_due_dates) > 0 or current_date.weekday() in fsrs.easy_days:
fsrs.allow_to_past = False
fsrs.apply_easy_days = apply_easy_days

if recent:
Expand Down
Loading