502 lines
25 KiB
Dart
502 lines
25 KiB
Dart
import 'dart:async';
|
|
import 'package:flutter_bloc/flutter_bloc.dart';
|
|
import '../../data/models/exam_model.dart';
|
|
import '../../data/repositories/app_repositories.dart';
|
|
|
|
abstract class ExamState {}
|
|
|
|
class ExamInitial extends ExamState {}
|
|
|
|
class ExamLoading extends ExamState {
|
|
final String message;
|
|
ExamLoading({this.message = 'جاري تحضير الامتحان والأسئلة التكيفية...'});
|
|
}
|
|
|
|
class ExamLoaded extends ExamState {
|
|
final ExamModel exam;
|
|
final int currentQuestionIndex;
|
|
final Map<int, int> selectedAnswers; // questionId -> optionId
|
|
final int remainingSeconds;
|
|
final bool isSubmitting;
|
|
|
|
ExamLoaded({
|
|
required this.exam,
|
|
this.currentQuestionIndex = 0,
|
|
this.selectedAnswers = const {},
|
|
required this.remainingSeconds,
|
|
this.isSubmitting = false,
|
|
});
|
|
|
|
QuestionModel? get currentQuestion {
|
|
if (exam.questions.isEmpty || currentQuestionIndex >= exam.questions.length) return null;
|
|
return exam.questions[currentQuestionIndex];
|
|
}
|
|
|
|
bool get isLastQuestion => currentQuestionIndex == exam.questions.length - 1;
|
|
int get answeredCount => selectedAnswers.length;
|
|
|
|
ExamLoaded copyWith({
|
|
ExamModel? exam,
|
|
int? currentQuestionIndex,
|
|
Map<int, int>? selectedAnswers,
|
|
int? remainingSeconds,
|
|
bool? isSubmitting,
|
|
}) {
|
|
return ExamLoaded(
|
|
exam: exam ?? this.exam,
|
|
currentQuestionIndex: currentQuestionIndex ?? this.currentQuestionIndex,
|
|
selectedAnswers: selectedAnswers ?? this.selectedAnswers,
|
|
remainingSeconds: remainingSeconds ?? this.remainingSeconds,
|
|
isSubmitting: isSubmitting ?? this.isSubmitting,
|
|
);
|
|
}
|
|
}
|
|
|
|
class ExamCompleted extends ExamState {
|
|
final ExamModel exam;
|
|
final ExamSubmissionResultModel result;
|
|
final int timeSpentSeconds;
|
|
|
|
ExamCompleted({
|
|
required this.exam,
|
|
required this.result,
|
|
required this.timeSpentSeconds,
|
|
});
|
|
}
|
|
|
|
class ExamError extends ExamState {
|
|
final String message;
|
|
ExamError(this.message);
|
|
}
|
|
|
|
class ExamCubit extends Cubit<ExamState> {
|
|
final ExamRepository _repository;
|
|
Timer? _countdownTimer;
|
|
int _initialSeconds = 0;
|
|
|
|
ExamCubit({ExamRepository? repository})
|
|
: _repository = repository ?? ExamRepository(),
|
|
super(ExamInitial());
|
|
|
|
@override
|
|
Future<void> close() {
|
|
_countdownTimer?.cancel();
|
|
return super.close();
|
|
}
|
|
|
|
Future<void> loadExam({int examId = 1, ExamModel? initialExam}) async {
|
|
emit(ExamLoading());
|
|
try {
|
|
ExamModel loadedExam;
|
|
if (initialExam != null && initialExam.questions.isNotEmpty) {
|
|
loadedExam = initialExam;
|
|
} else {
|
|
try {
|
|
loadedExam = await _repository.getExamDetails(examId);
|
|
} catch (_) {
|
|
// If server call fails or exam not in DB, use curriculum-grounded default questions
|
|
loadedExam = initialExam ?? _createDefaultExam(examId);
|
|
}
|
|
}
|
|
|
|
if (loadedExam.questions.isEmpty) {
|
|
loadedExam = _createDefaultExam(examId, title: loadedExam.title);
|
|
}
|
|
|
|
_initialSeconds = loadedExam.durationMinutes * 60;
|
|
emit(ExamLoaded(
|
|
exam: loadedExam,
|
|
remainingSeconds: _initialSeconds,
|
|
));
|
|
|
|
_startTimer();
|
|
} catch (e) {
|
|
emit(ExamError('حدث خطأ أثناء تحميل الامتحان: ${e.toString()}'));
|
|
}
|
|
}
|
|
|
|
void _startTimer() {
|
|
_countdownTimer?.cancel();
|
|
_countdownTimer = Timer.periodic(const Duration(seconds: 1), (timer) {
|
|
final s = state;
|
|
if (s is ExamLoaded) {
|
|
if (s.remainingSeconds <= 1) {
|
|
timer.cancel();
|
|
submitCurrentExam();
|
|
} else {
|
|
emit(s.copyWith(remainingSeconds: s.remainingSeconds - 1));
|
|
}
|
|
} else {
|
|
timer.cancel();
|
|
}
|
|
});
|
|
}
|
|
|
|
void selectOption(int questionId, int optionId) {
|
|
final s = state;
|
|
if (s is ExamLoaded) {
|
|
final updatedAnswers = Map<int, int>.from(s.selectedAnswers);
|
|
updatedAnswers[questionId] = optionId;
|
|
emit(s.copyWith(selectedAnswers: updatedAnswers));
|
|
}
|
|
}
|
|
|
|
void goToQuestion(int index) {
|
|
final s = state;
|
|
if (s is ExamLoaded) {
|
|
if (index >= 0 && index < s.exam.questions.length) {
|
|
emit(s.copyWith(currentQuestionIndex: index));
|
|
}
|
|
}
|
|
}
|
|
|
|
void nextQuestion() {
|
|
final s = state;
|
|
if (s is ExamLoaded && !s.isLastQuestion) {
|
|
emit(s.copyWith(currentQuestionIndex: s.currentQuestionIndex + 1));
|
|
}
|
|
}
|
|
|
|
void previousQuestion() {
|
|
final s = state;
|
|
if (s is ExamLoaded && s.currentQuestionIndex > 0) {
|
|
emit(s.copyWith(currentQuestionIndex: s.currentQuestionIndex - 1));
|
|
}
|
|
}
|
|
|
|
Future<void> submitCurrentExam() async {
|
|
final s = state;
|
|
if (s is! ExamLoaded) return;
|
|
|
|
_countdownTimer?.cancel();
|
|
emit(s.copyWith(isSubmitting: true));
|
|
|
|
final timeSpent = _initialSeconds - s.remainingSeconds;
|
|
final formattedAnswers = s.selectedAnswers.entries.map((e) {
|
|
return {
|
|
'question_id': e.key,
|
|
'selected_option_id': e.value,
|
|
};
|
|
}).toList();
|
|
|
|
try {
|
|
ExamSubmissionResultModel result;
|
|
try {
|
|
result = await _repository.submitExam(
|
|
s.exam.id,
|
|
answers: formattedAnswers,
|
|
timeSpentSeconds: timeSpent,
|
|
);
|
|
} catch (_) {
|
|
// Safe offline evaluation fallback if API token not present
|
|
result = _evaluateLocally(s.exam, s.selectedAnswers);
|
|
}
|
|
|
|
emit(ExamCompleted(
|
|
exam: s.exam,
|
|
result: result,
|
|
timeSpentSeconds: timeSpent,
|
|
));
|
|
} catch (e) {
|
|
emit(ExamError('فشل تقديم الامتحان: ${e.toString()}'));
|
|
}
|
|
}
|
|
|
|
ExamSubmissionResultModel _evaluateLocally(ExamModel exam, Map<int, int> selectedAnswers) {
|
|
int earnedScore = 0;
|
|
int totalScore = 0;
|
|
List<String> weakTopics = [];
|
|
List<DetailedAnswerModel> detailedAnswers = [];
|
|
|
|
for (var q in exam.questions) {
|
|
totalScore += q.points;
|
|
final selectedOptId = selectedAnswers[q.id];
|
|
QuestionOptionModel? correctOption;
|
|
try {
|
|
correctOption = q.options.firstWhere((opt) => opt.isCorrect);
|
|
} catch (_) {
|
|
correctOption = q.options.isNotEmpty ? q.options.first : null;
|
|
}
|
|
|
|
final isCorrect = selectedOptId != null && correctOption != null && selectedOptId == correctOption.id;
|
|
final points = isCorrect ? q.points : 0;
|
|
earnedScore += points;
|
|
|
|
if (!isCorrect) {
|
|
if (!weakTopics.contains(q.topicTag)) {
|
|
weakTopics.add(q.topicTag);
|
|
}
|
|
}
|
|
|
|
detailedAnswers.add(DetailedAnswerModel(
|
|
questionId: q.id,
|
|
selectedOptionId: selectedOptId ?? 0,
|
|
isCorrect: isCorrect,
|
|
pointsAwarded: points,
|
|
explanation: q.explanationText ?? 'راجع نص القاعدة في كتاب الوزارة',
|
|
aiHint: q.aiHint,
|
|
));
|
|
}
|
|
|
|
final pct = totalScore > 0 ? (earnedScore / totalScore) * 100 : 0.0;
|
|
final passed = pct >= exam.passingPercentage;
|
|
final report = passed
|
|
? 'أداء ممتاز! حققت نسبة إتقان ${pct.toStringAsFixed(1)}%. لديك استيعاب عميق للمفاهيم الأساسية.'
|
|
: 'تم رصد تعثر في مفاهيم: ${weakTopics.join('، ')}. ننصح بمشاهدة مقاطع الشرح المركزة لمعالجة الثغرات.';
|
|
|
|
return ExamSubmissionResultModel(
|
|
attemptId: DateTime.now().millisecondsSinceEpoch ~/ 1000,
|
|
score: earnedScore,
|
|
totalScore: totalScore,
|
|
percentage: pct,
|
|
passed: passed,
|
|
rewindSeconds: passed ? 0 : 45,
|
|
aiDiagnosticReport: report,
|
|
weakTopics: weakTopics,
|
|
tawjihiReadinessScore: (pct * 0.7) + (passed ? 25.0 : 10.0),
|
|
detailedAnswers: detailedAnswers,
|
|
);
|
|
}
|
|
|
|
static ExamModel _createDefaultExam(int examId, {String? title}) {
|
|
return ExamModel(
|
|
id: examId,
|
|
uuid: 'exam-default-$examId',
|
|
courseId: 1,
|
|
title: title ?? 'اختبار الفهم الشامل: الوحدة الأولى — أنظمة المعادلات',
|
|
description: 'اختبار وزاري معياري يقيس الفهم العميق والقدرة على تطبيق القوانين لأنظمة المعادلات.',
|
|
scope: 'unit_exam',
|
|
passingPercentage: 70.0,
|
|
durationMinutes: 45,
|
|
questionsCount: 15,
|
|
questions: const [
|
|
// 1. حل معادلات خاصة (إخراج العامل المشترك)
|
|
QuestionModel(
|
|
id: 1,
|
|
questionText: 'ما هي مجموعة حل المعادلة الحقيقية: x³ - 4x = 0؟',
|
|
questionType: 'multiple_choice',
|
|
points: 10,
|
|
topicTag: 'حل المعادلات بإخراج العامل المشترك الأكبر',
|
|
explanationText: 'بإخراج x كعامل مشترك: x(x² - 4) = 0 ومنها x(x - 2)(x + 2) = 0، فيكون الحل x = 0, 2, -2.',
|
|
options: [
|
|
QuestionOptionModel(id: 1, optionText: '{ -2, 0, 2 }', isCorrect: true, sequenceOrder: 1),
|
|
QuestionOptionModel(id: 2, optionText: '{ 0, 4 }', isCorrect: false, sequenceOrder: 2),
|
|
QuestionOptionModel(id: 3, optionText: '{ -2, 2 }', isCorrect: false, sequenceOrder: 3),
|
|
QuestionOptionModel(id: 4, optionText: '{ 0, 2 }', isCorrect: false, sequenceOrder: 4),
|
|
],
|
|
),
|
|
// 2. الصورة التربيعية
|
|
QuestionModel(
|
|
id: 2,
|
|
questionText: 'حل المعادلة x⁴ - 5x² + 4 = 0 في مجموعة الأعداد الحقيقية هو:',
|
|
questionType: 'multiple_choice',
|
|
points: 10,
|
|
topicTag: 'المعادلات في الصورة التربيعية',
|
|
explanationText: 'بالتحليل كمعادلة تربيعية: (x² - 4)(x² - 1) = 0، ومنها x² = 4 أو x² = 1، فالجذور هي ±2 و ±1.',
|
|
options: [
|
|
QuestionOptionModel(id: 5, optionText: '{ -2, -1, 1, 2 }', isCorrect: true, sequenceOrder: 1),
|
|
QuestionOptionModel(id: 6, optionText: '{ 1, 4 }', isCorrect: false, sequenceOrder: 2),
|
|
QuestionOptionModel(id: 7, optionText: '{ -1, 1 }', isCorrect: false, sequenceOrder: 3),
|
|
QuestionOptionModel(id: 8, optionText: '{ -4, 4 }', isCorrect: false, sequenceOrder: 4),
|
|
],
|
|
),
|
|
// 3. مجموع المكعبين والحلول الحقيقية
|
|
QuestionModel(
|
|
id: 3,
|
|
questionText: 'كم حلاً حقيقياً يحقق المعادلة: x³ + 8 = 0؟',
|
|
questionType: 'multiple_choice',
|
|
points: 10,
|
|
topicTag: 'تحليل مجموع المكعبين والحلول الحقيقية',
|
|
explanationText: 'بتحليل مجموع مكعبين: (x + 2)(x² - 2x + 4) = 0. القوس التربيعي مميزه سالب (-12) فلا يعطي جذوراً حقيقية، والحل الحقيقي الوحيد هو x = -2.',
|
|
options: [
|
|
QuestionOptionModel(id: 9, optionText: 'حل حقيقي واحد فقط وهو x = -2', isCorrect: true, sequenceOrder: 1),
|
|
QuestionOptionModel(id: 10, optionText: 'ثلاثة حلول حقيقية', isCorrect: false, sequenceOrder: 2),
|
|
QuestionOptionModel(id: 11, optionText: 'حلّان حقيقيان', isCorrect: false, sequenceOrder: 3),
|
|
QuestionOptionModel(id: 12, optionText: 'لا يوجد أي حل حقيقي', isCorrect: false, sequenceOrder: 4),
|
|
],
|
|
),
|
|
// 4. أقصى عدد حلول لنظام خطي وتربيعي
|
|
QuestionModel(
|
|
id: 4,
|
|
questionText: 'ما هو أقصى عدد ممكن لنقاط التقاطع بين مستقيم وقطع مكافئ في المستوى الإحداثي؟',
|
|
questionType: 'multiple_choice',
|
|
points: 10,
|
|
topicTag: 'التمثيل الهندسي لنظام خطي وتربيعي',
|
|
explanationText: 'المستقيم يقطع القطع المكافئ في نقطتين كحد أقصى (حلان)، أو يمسه في نقطة (حل واحد)، أو لا يقطعه (لا يوجد حل حقيقي).',
|
|
options: [
|
|
QuestionOptionModel(id: 13, optionText: 'نقطتان كحد أقصى (حلّان حقيقيان)', isCorrect: true, sequenceOrder: 1),
|
|
QuestionOptionModel(id: 14, optionText: 'ثلاث نقاط تقاطع', isCorrect: false, sequenceOrder: 2),
|
|
QuestionOptionModel(id: 15, optionText: 'أربع نقاط تقاطع', isCorrect: false, sequenceOrder: 3),
|
|
QuestionOptionModel(id: 16, optionText: 'نقطة واحدة فقط دائماً', isCorrect: false, sequenceOrder: 4),
|
|
],
|
|
),
|
|
// 5. حل نظام خطي وتربيعي بالتعويض
|
|
QuestionModel(
|
|
id: 5,
|
|
questionText: 'إذا كان لدينا النظام: y = x + 1 و y = x² + 1، فما هي نقاط تقاطع المنحنيين؟',
|
|
questionType: 'multiple_choice',
|
|
points: 10,
|
|
topicTag: 'حل نظام خطي وتربيعي بطريقة التعويض',
|
|
explanationText: 'بالمساواة: x² + 1 = x + 1 ومنها x² - x = 0 أي x(x - 1) = 0، فيكون x = 0 أو x = 1. بالتعويض نجد y = 1 أو y = 2.',
|
|
options: [
|
|
QuestionOptionModel(id: 17, optionText: '(0, 1) و (1, 2)', isCorrect: true, sequenceOrder: 1),
|
|
QuestionOptionModel(id: 18, optionText: '(0, 0) و (1, 1)', isCorrect: false, sequenceOrder: 2),
|
|
QuestionOptionModel(id: 19, optionText: '(1, 2) فقط', isCorrect: false, sequenceOrder: 3),
|
|
QuestionOptionModel(id: 20, optionText: '(-1, 0) و (1, 2)', isCorrect: false, sequenceOrder: 4),
|
|
],
|
|
),
|
|
// 6. المميز وسالبية الحلول
|
|
QuestionModel(
|
|
id: 6,
|
|
questionText: 'متى لا يوجد أي حل حقيقي لنظام مكوّن من معادلة خطية وأخرى تربيعية؟',
|
|
questionType: 'multiple_choice',
|
|
points: 10,
|
|
topicTag: 'استخدام المميز لتحديد عدد حلول النظام',
|
|
explanationText: 'إذا كان مميز المعادلة التربيعية الناتجة عن التعويض سالباً (Δ = b² - 4ac < 0)، فإن المستقيم لا يتقاطع مع المنحنى.',
|
|
options: [
|
|
QuestionOptionModel(id: 21, optionText: 'عندما يكون مميز المعادلة التربيعية الناتجة سالباً (Δ < 0)', isCorrect: true, sequenceOrder: 1),
|
|
QuestionOptionModel(id: 22, optionText: 'عندما يكون المميز مساوياً لصفر', isCorrect: false, sequenceOrder: 2),
|
|
QuestionOptionModel(id: 23, optionText: 'عندما يكون المميز موجباً تماماً', isCorrect: false, sequenceOrder: 3),
|
|
QuestionOptionModel(id: 24, optionText: 'إذا كان ميل المستقيم يساوي صفراً', isCorrect: false, sequenceOrder: 4),
|
|
],
|
|
),
|
|
// 7. حالة المماس
|
|
QuestionModel(
|
|
id: 7,
|
|
questionText: 'إذا كان لنظام مكوّن من مستقيم وقطع مكافئ حل حقيقي وحيد فقط، فإن المستقيم يعتبر:',
|
|
questionType: 'multiple_choice',
|
|
points: 10,
|
|
topicTag: 'المستقيم المماس لمنحنى تربيعي',
|
|
explanationText: 'وجود حل حقيقي وحيد لنظام خطي-تربيعي يعني هندسياً أن المستقيم يمس المنحنى عند نقطة واحدة فقط.',
|
|
options: [
|
|
QuestionOptionModel(id: 25, optionText: 'مماساً لمنحنى القطع المكافئ عند نقطة التماس', isCorrect: true, sequenceOrder: 1),
|
|
QuestionOptionModel(id: 26, optionText: 'قاطعاً للمنحنى في نقطتين', isCorrect: false, sequenceOrder: 2),
|
|
QuestionOptionModel(id: 27, optionText: 'خط تقارب رأسي للمنحنى', isCorrect: false, sequenceOrder: 3),
|
|
QuestionOptionModel(id: 28, optionText: 'محور تماثل للقطع المكافئ', isCorrect: false, sequenceOrder: 4),
|
|
],
|
|
),
|
|
// 8. حل نظام تربيعي بالحذف
|
|
QuestionModel(
|
|
id: 8,
|
|
questionText: 'في النظام: x² + y² = 25 و x² - y² = 7، ما هي قيمة x²؟',
|
|
questionType: 'multiple_choice',
|
|
points: 10,
|
|
topicTag: 'حل نظام تربيعي بطريقة الحذف',
|
|
explanationText: 'بجمع المعادلتين طرفاً لطرف: 2x² = 32 ومنها x² = 16.',
|
|
options: [
|
|
QuestionOptionModel(id: 29, optionText: 'x² = 16', isCorrect: true, sequenceOrder: 1),
|
|
QuestionOptionModel(id: 30, optionText: 'x² = 9', isCorrect: false, sequenceOrder: 2),
|
|
QuestionOptionModel(id: 31, optionText: 'x² = 32', isCorrect: false, sequenceOrder: 3),
|
|
QuestionOptionModel(id: 32, optionText: 'x² = 18', isCorrect: false, sequenceOrder: 4),
|
|
],
|
|
),
|
|
// 9. أقصى عدد حلول بين دائرة وقطع مكافئ
|
|
QuestionModel(
|
|
id: 9,
|
|
questionText: 'ما هو أقصى عدد ممكن من نقاط التقاطع بين دائرة وقطع مكافئ في المستوى الإحداثي؟',
|
|
questionType: 'multiple_choice',
|
|
points: 10,
|
|
topicTag: 'التقاطع الهندسي بين منحنيين تربيعيين',
|
|
explanationText: 'يمكن لدائرة وقطع مكافئ أن يتقاطعا في 0، أو 1، أو 2، أو 3، أو 4 نقاط كحد أقصى.',
|
|
options: [
|
|
QuestionOptionModel(id: 33, optionText: '4 نقاط تقاطع (أربعة حلول)', isCorrect: true, sequenceOrder: 1),
|
|
QuestionOptionModel(id: 34, optionText: 'حلان فقط', isCorrect: false, sequenceOrder: 2),
|
|
QuestionOptionModel(id: 35, optionText: '6 نقاط تقاطع', isCorrect: false, sequenceOrder: 3),
|
|
QuestionOptionModel(id: 36, optionText: 'حل وحيد فقط دائماً', isCorrect: false, sequenceOrder: 4),
|
|
],
|
|
),
|
|
// 10. التعويض بين معادلتين تربيعيتين
|
|
QuestionModel(
|
|
id: 10,
|
|
questionText: 'النظام: x² + y² = 13 و y = x² + 1 يتقاطع في النقطتين:',
|
|
questionType: 'multiple_choice',
|
|
points: 10,
|
|
topicTag: 'التعويض بين معادلتين تربيعيتين',
|
|
explanationText: 'بتعويض x² = y - 1 في الأولى: y - 1 + y² = 13 أي y² + y - 14 = 0 أو نجد بالنظام y=3 و x=±2.',
|
|
options: [
|
|
QuestionOptionModel(id: 37, optionText: '(-2, 3) و (2, 3)', isCorrect: true, sequenceOrder: 1),
|
|
QuestionOptionModel(id: 38, optionText: '(3, -2) و (3, 2)', isCorrect: false, sequenceOrder: 2),
|
|
QuestionOptionModel(id: 39, optionText: '(0, 1) فقط', isCorrect: false, sequenceOrder: 3),
|
|
QuestionOptionModel(id: 40, optionText: '(2, 5) و (-2, 5)', isCorrect: false, sequenceOrder: 4),
|
|
],
|
|
),
|
|
// 11. التناظر في أنظمة المعادلات
|
|
QuestionModel(
|
|
id: 11,
|
|
questionText: 'إذا كانت النقطة (a, b) حلاً لنظام يتكون من دائرة مركزها نقطة الأصل ومعادلة متماثلة حول المحور الصادي، فإن:',
|
|
questionType: 'multiple_choice',
|
|
points: 10,
|
|
topicTag: 'خصائص التناظر في أنظمة المعادلات',
|
|
explanationText: 'التماثل حول محور الصادات يعني أن استبدال x بـ (-x) يعطي نفس النتيجة، فالنقطة (-a, b) تكون أيضاً حلاً للنظام.',
|
|
options: [
|
|
QuestionOptionModel(id: 41, optionText: '(-a, b) تكون أيضاً حلاً للنظام', isCorrect: true, sequenceOrder: 1),
|
|
QuestionOptionModel(id: 42, optionText: '(a, -b) هو الحل الوحيد دائماً', isCorrect: false, sequenceOrder: 2),
|
|
QuestionOptionModel(id: 43, optionText: 'لا يوجد أي تناظر هندسي', isCorrect: false, sequenceOrder: 3),
|
|
QuestionOptionModel(id: 44, optionText: 'الحل سالب دائماً', isCorrect: false, sequenceOrder: 4),
|
|
],
|
|
),
|
|
// 12. برمجية جيوجبرا وأداة التقاطع
|
|
QuestionModel(
|
|
id: 12,
|
|
questionText: 'في برمجية جيوجبرا (GeoGebra)، ما هي الأداة المخصصة لإيجاد حل نظام المعادلات بيانياً؟',
|
|
questionType: 'multiple_choice',
|
|
points: 10,
|
|
topicTag: 'برمجية جيوجبرا وحل الأنظمة بيانياً',
|
|
explanationText: 'أداة التقاطع (Intersect Tool) في جيوجبرا تُحدد إحداثيات نقاط تقاطع المنحنيات التي تمثل حلول النظام مباشرة.',
|
|
options: [
|
|
QuestionOptionModel(id: 45, optionText: 'أداة التقاطع (Intersect Tool)', isCorrect: true, sequenceOrder: 1),
|
|
QuestionOptionModel(id: 46, optionText: 'أداة القياس (Measure)', isCorrect: false, sequenceOrder: 2),
|
|
QuestionOptionModel(id: 47, optionText: 'أداة الانعكاس (Reflect)', isCorrect: false, sequenceOrder: 3),
|
|
QuestionOptionModel(id: 48, optionText: 'أداة المماس (Tangent)', isCorrect: false, sequenceOrder: 4),
|
|
],
|
|
),
|
|
// 13. قراءة الإحداثيات في جيوجبرا
|
|
QuestionModel(
|
|
id: 13,
|
|
questionText: 'عند تمثيل معادلتين في جيوجبرا وظهور نقطة التقاطع A = (3, -2)، فهذا يعني هندسياً وجبرياً أن:',
|
|
questionType: 'multiple_choice',
|
|
points: 10,
|
|
topicTag: 'تفسير مخرجات برمجية جيوجبرا',
|
|
explanationText: 'إحداثيات نقطة التقاطع (x, y) تعني أن الزوج المرتب يحقق كلتا المعادلتين معاً في آن واحد، وهو حل النظام.',
|
|
options: [
|
|
QuestionOptionModel(id: 49, optionText: 'x = 3 و y = -2 هو حل يحقق كلتا المعادلتين معاً', isCorrect: true, sequenceOrder: 1),
|
|
QuestionOptionModel(id: 50, optionText: 'x = -2 و y = 3 هو الحل', isCorrect: false, sequenceOrder: 2),
|
|
QuestionOptionModel(id: 51, optionText: 'المنحنيان متباعدان ولا حل لهما', isCorrect: false, sequenceOrder: 3),
|
|
QuestionOptionModel(id: 52, optionText: 'النظام له حلول غير منتهية', isCorrect: false, sequenceOrder: 4),
|
|
],
|
|
),
|
|
// 14. النماذج الحياتية والأرصاد
|
|
QuestionModel(
|
|
id: 14,
|
|
questionText: 'لماذا يستخدم خبراء الأرصاد الجوية أنظمة معادلات غير خطية في التنبؤ بالطقس كما ورد في كتاب الطالب؟',
|
|
questionType: 'multiple_choice',
|
|
points: 10,
|
|
topicTag: 'التطبيقات الحياتية لأنظمة المعادلات',
|
|
explanationText: 'لأن أي تغير في أحد العوامل (كالضغط ودرجة الحرارة وسرعة الرياح) يؤدي إلى تغير غير خطي في العوامل الأخرى.',
|
|
options: [
|
|
QuestionOptionModel(id: 53, optionText: 'لأن أي تغير في أحد العوامل يؤدي إلى تغير غير خطي في العوامل الأخرى', isCorrect: true, sequenceOrder: 1),
|
|
QuestionOptionModel(id: 54, optionText: 'لأن درجة الحرارة ثابتة دائماً على مدار السنة', isCorrect: false, sequenceOrder: 2),
|
|
QuestionOptionModel(id: 55, optionText: 'للتخلص من قياس الضغط الجوي', isCorrect: false, sequenceOrder: 3),
|
|
QuestionOptionModel(id: 56, optionText: 'لأن سرعة الرياح لا ترتبط بحركة الغلاف الجوي', isCorrect: false, sequenceOrder: 4),
|
|
],
|
|
),
|
|
// 15. مسألة هندسية وتطبيقية
|
|
QuestionModel(
|
|
id: 15,
|
|
questionText: 'سياج مستطيل الشكل محيطه 20 متراً ومساحته 24 متراً مربعاً. ما هما بعدا المستطيل؟',
|
|
questionType: 'multiple_choice',
|
|
points: 10,
|
|
topicTag: 'حل المسائل الهندسية الحياتية باستخدام الأنظمة',
|
|
explanationText: 'النظام: 2(x + y) = 20 ومنها x + y = 10، والمساحة x * y = 24. العددان اللذان مجموعهما 10 وحاصل ضربهما 24 هما 6 و 4.',
|
|
options: [
|
|
QuestionOptionModel(id: 57, optionText: 'الطول 6 m والعرض 4 m', isCorrect: true, sequenceOrder: 1),
|
|
QuestionOptionModel(id: 58, optionText: 'الطول 8 m والعرض 2 m', isCorrect: false, sequenceOrder: 2),
|
|
QuestionOptionModel(id: 59, optionText: 'الطول 10 m والعرض 2.4 m', isCorrect: false, sequenceOrder: 3),
|
|
QuestionOptionModel(id: 60, optionText: 'الطول 5 m والعرض 5 m', isCorrect: false, sequenceOrder: 4),
|
|
],
|
|
),
|
|
],
|
|
);
|
|
}
|
|
}
|