| Crates.io | fitts |
| lib.rs | fitts |
| version | 0.0.3 |
| created_at | 2025-03-25 04:11:37.303278+00 |
| updated_at | 2025-07-24 19:03:51.144439+00 |
| description | A Fitts‑based memory model integrated with the Free Spaced Repetition Scheduler (FSRS) for smarter review scheduling. |
| homepage | https://github.com/brenogonzaga/fitts |
| repository | https://github.com/brenogonzaga/fitts |
| max_upload_size | |
| id | 1604722 |
| size | 282,726 |
A sophisticated memory card review scheduler that applies Fitts' Law to optimize spaced repetition learning. This library provides an intelligent card ordering system based on user response patterns and cognitive difficulty prediction.
This library implements a memory card review scheduler that uses Fitts' Law principles to:
Traditional Fitts' Law (Motor Tasks):
Movement Time = a + b × log₂(Distance/Target_Width + 1)
Our Memory Adaptation:
Response Time = a + b × log₂(Memory_Distance/Memory_Accessibility + 1)
Where:
The main scheduler class that handles:
Cards are automatically classified based on predicted cognitive response time (exponential growth):
pub enum DifficultyLevel {
VeryEasy = 1, // < 2.0 seconds
Easy = 2, // 2.0s - 4.0s
Medium = 3, // 4.0s - 8.0s
Hard = 4, // 8.0s - 20.0s
VeryHard = 5, // ≥ 20.0s (sem limite superior)
}
```## Installation
Add this to your `Cargo.toml`:
```toml
[dependencies]
fitts = "0.1.0"
use fitts::scheduler::{FittsMemoryScheduler, SchedulerConfig};
use fitts::{CardState, Rating};
fn main() -> Result<(), String> {
// Create scheduler with optimized configuration
let mut scheduler = FittsMemoryScheduler::new(SchedulerConfig {
max_cards_per_session: 15,
max_session_duration_minutes: 20,
prioritize_error_prone: true, // Key: prioritize problem cards
balance_difficulty_levels: false, // Let user responses drive order
urgency_multiplier: 1.5,
new_cards_limit: 8,
})?;
// Add a card
let card_state = CardState {
memory_state: None,
review_count: 0,
lapse_count: 0,
stability: 1.0,
ease: 2.5,
interval_days: 1.0,
last_review: None,
};
scheduler.add_card("my_deck".to_string(), "card_1".to_string(), card_state);
// Generate review schedule (order based on priority)
let schedule = scheduler.generate_review_schedule("user_id", "my_deck")?;
// Process user response (this updates future card ordering)
let result = scheduler.review_card(
"user_id".to_string(),
"my_deck".to_string(),
"card_1".to_string(),
Rating::Hard, // User found it difficult
8.5 // Slow response time
)?;
// Next time, this card will have higher priority due to poor performance
let updated_schedule = scheduler.generate_review_schedule("user_id", "my_deck")?;
Ok(())
}
The scheduler uses user response patterns to optimize card ordering:
Priority = urgency_factor × difficulty_factor × error_factor × frequency_factor
Where:
- urgency_factor = 1.0 + (days_overdue × urgency_multiplier)
- difficulty_factor = difficulty_level.priority_multiplier()
- error_factor = 1.0 + error_rate (if prioritize_error_prone = true)
- frequency_factor = 1.0 / (reviews_since_update + 1.0)
See the examples/ directory for complete demonstrations:
memory_simulation_simple.rs - Basic scheduler usageresponse_driven_ordering.rs - How user responses affect card orderingcomprehensive_scheduler_demo.rs - Full feature demonstration// Get user performance statistics
if let Some(stats) = scheduler.get_user_stats("user_id") {
println!("Total reviews: {}", stats.total_reviews);
println!("Average response time: {:.2}s", stats.avg_response_time);
println!("Accuracy rate: {:.1}%", stats.accuracy_rate * 100.0);
}
// Generate deck optimization recommendations
let optimization = scheduler.generate_deck_optimization("deck_id")?;
println!("Total cards: {}", optimization.total_cards);
// Export complete review history for analysis
let revlog_json = scheduler.export_revlog();
// Each review creates a detailed revlog entry with:
// - Actual vs predicted response time
// - Rating and difficulty classification
// - Prediction error calculation
// - Context and metadata
pub struct SchedulerConfig {
pub max_cards_per_session: usize, // Limit cards per session
pub max_session_duration_minutes: usize, // Time limit per session
pub prioritize_error_prone: bool, // Boost priority for problem cards
pub balance_difficulty_levels: bool, // Balance vs pure response-driven
pub urgency_multiplier: f64, // How much to weight overdue cards
pub new_cards_limit: usize, // Max new cards per session
}
The scheduler is optimized for real-time use:
The scheduler seamlessly integrates with FSRS (Free Spaced Repetition Scheduler):
This project is licensed under the MIT OR Apache-2.0 license.
Contributions are welcome! Please see the examples/ directory for usage patterns and feel free to submit issues or pull requests.