You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
96 lines
2.9 KiB
96 lines
2.9 KiB
import 'attempt_result.dart';
|
|
|
|
/// A historical record of a completed attempt.
|
|
class AttemptHistoryEntry {
|
|
/// Timestamp when the attempt was completed (milliseconds since epoch).
|
|
final int timestamp;
|
|
|
|
/// Total number of questions in the attempt.
|
|
final int totalQuestions;
|
|
|
|
/// Number of correct answers.
|
|
final int correctCount;
|
|
|
|
/// Percentage of correct answers.
|
|
final double percentageCorrect;
|
|
|
|
/// Time spent on the attempt in milliseconds.
|
|
final int timeSpent;
|
|
|
|
/// Percentage of questions in the deck that are not yet known (0-100).
|
|
/// This represents progress - as more questions become known, this decreases.
|
|
final double unknownPercentage;
|
|
|
|
const AttemptHistoryEntry({
|
|
required this.timestamp,
|
|
required this.totalQuestions,
|
|
required this.correctCount,
|
|
required this.percentageCorrect,
|
|
required this.timeSpent,
|
|
this.unknownPercentage = 0.0,
|
|
});
|
|
|
|
/// Creates a history entry from an attempt result.
|
|
factory AttemptHistoryEntry.fromAttemptResult({
|
|
required AttemptResult result,
|
|
required int totalQuestionsInDeck,
|
|
required int knownCount,
|
|
int? timestamp,
|
|
}) {
|
|
final unknownCount = totalQuestionsInDeck - knownCount;
|
|
final unknownPercentage = totalQuestionsInDeck > 0
|
|
? (unknownCount / totalQuestionsInDeck * 100.0)
|
|
: 0.0;
|
|
|
|
return AttemptHistoryEntry(
|
|
timestamp: timestamp ?? DateTime.now().millisecondsSinceEpoch,
|
|
totalQuestions: result.totalQuestions,
|
|
correctCount: result.correctCount,
|
|
percentageCorrect: result.percentageCorrect,
|
|
timeSpent: result.timeSpent,
|
|
unknownPercentage: unknownPercentage,
|
|
);
|
|
}
|
|
|
|
/// Creates a copy of this entry with the given fields replaced.
|
|
AttemptHistoryEntry copyWith({
|
|
int? timestamp,
|
|
int? totalQuestions,
|
|
int? correctCount,
|
|
double? percentageCorrect,
|
|
int? timeSpent,
|
|
double? unknownPercentage,
|
|
}) {
|
|
return AttemptHistoryEntry(
|
|
timestamp: timestamp ?? this.timestamp,
|
|
totalQuestions: totalQuestions ?? this.totalQuestions,
|
|
correctCount: correctCount ?? this.correctCount,
|
|
percentageCorrect: percentageCorrect ?? this.percentageCorrect,
|
|
timeSpent: timeSpent ?? this.timeSpent,
|
|
unknownPercentage: unknownPercentage ?? this.unknownPercentage,
|
|
);
|
|
}
|
|
|
|
@override
|
|
bool operator ==(Object other) =>
|
|
identical(this, other) ||
|
|
other is AttemptHistoryEntry &&
|
|
runtimeType == other.runtimeType &&
|
|
timestamp == other.timestamp &&
|
|
totalQuestions == other.totalQuestions &&
|
|
correctCount == other.correctCount &&
|
|
percentageCorrect == other.percentageCorrect &&
|
|
timeSpent == other.timeSpent &&
|
|
unknownPercentage == other.unknownPercentage;
|
|
|
|
@override
|
|
int get hashCode =>
|
|
timestamp.hashCode ^
|
|
totalQuestions.hashCode ^
|
|
correctCount.hashCode ^
|
|
percentageCorrect.hashCode ^
|
|
timeSpent.hashCode ^
|
|
unknownPercentage.hashCode;
|
|
}
|
|
|