CORVO-AI commited on
Commit
b83571a
·
verified ·
1 Parent(s): 4b93063

Upload 135 files

Browse files
This view is limited to 50 files because it contains too many changes.   See raw diff
Files changed (50) hide show
  1. .gitattributes +26 -0
  2. FINAL/it.txt +1082 -0
  3. FINAL/literary_studies_2007/conversion_log.txt +24 -0
  4. FINAL/literary_studies_2007/page_0001.png +3 -0
  5. FINAL/literary_studies_2007/page_0002.png +3 -0
  6. FINAL/literary_studies_2007/page_0003.png +3 -0
  7. FINAL/literary_studies_2007/page_0004.png +3 -0
  8. FINAL/literary_studies_2007/page_0005.png +3 -0
  9. FINAL/literary_studies_2007/page_0006.png +3 -0
  10. FINAL/literary_studies_2007/page_0007.png +3 -0
  11. FINAL/literary_studies_2007/page_0008.png +3 -0
  12. FINAL/physics_mechanic.txt +1631 -0
  13. auth/__init__.py +3 -0
  14. auth/__pycache__/__init__.cpython-314.pyc +0 -0
  15. auth/__pycache__/helpers.cpython-314.pyc +0 -0
  16. auth/__pycache__/routes.cpython-314.pyc +0 -0
  17. auth/helpers.py +37 -0
  18. auth/routes.py +176 -0
  19. board/__init__.py +4 -0
  20. board/__pycache__/__init__.cpython-314.pyc +0 -0
  21. board/__pycache__/engine.cpython-314.pyc +0 -0
  22. board/__pycache__/icons.cpython-314.pyc +0 -0
  23. board/__pycache__/pages.cpython-314.pyc +0 -0
  24. board/__pycache__/routes.cpython-314.pyc +0 -0
  25. board/__pycache__/tts.cpython-314.pyc +0 -0
  26. board/engine.py +569 -0
  27. board/icons.py +93 -0
  28. board/pages.py +70 -0
  29. board/routes.py +252 -0
  30. board/tts.py +78 -0
  31. chat/__init__.py +4 -0
  32. chat/__pycache__/__init__.cpython-314.pyc +0 -0
  33. chat/__pycache__/agent.cpython-314.pyc +0 -0
  34. chat/__pycache__/history.cpython-314.pyc +0 -0
  35. chat/__pycache__/routes.cpython-314.pyc +0 -0
  36. chat/agent.py +410 -0
  37. chat/history.py +187 -0
  38. chat/routes.py +424 -0
  39. database/__init__.py +4 -0
  40. database/__pycache__/__init__.cpython-314.pyc +0 -0
  41. database/__pycache__/cards.cpython-314.pyc +0 -0
  42. database/__pycache__/chat_history.cpython-314.pyc +0 -0
  43. database/__pycache__/telegram.cpython-314.pyc +0 -0
  44. database/__pycache__/users.cpython-314.pyc +0 -0
  45. database/cards.py +26 -0
  46. database/chat_history.py +107 -0
  47. database/telegram.py +19 -0
  48. database/users.py +31 -0
  49. exam/__init__.py +4 -0
  50. exam/__pycache__/__init__.cpython-314.pyc +0 -0
.gitattributes CHANGED
@@ -33,3 +33,29 @@ saved_model/**/* filter=lfs diff=lfs merge=lfs -text
33
  *.zip filter=lfs diff=lfs merge=lfs -text
34
  *.zst filter=lfs diff=lfs merge=lfs -text
35
  *tfevents* filter=lfs diff=lfs merge=lfs -text
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
33
  *.zip filter=lfs diff=lfs merge=lfs -text
34
  *.zst filter=lfs diff=lfs merge=lfs -text
35
  *tfevents* filter=lfs diff=lfs merge=lfs -text
36
+ FINAL/literary_studies_2007/page_0001.png filter=lfs diff=lfs merge=lfs -text
37
+ FINAL/literary_studies_2007/page_0002.png filter=lfs diff=lfs merge=lfs -text
38
+ FINAL/literary_studies_2007/page_0003.png filter=lfs diff=lfs merge=lfs -text
39
+ FINAL/literary_studies_2007/page_0004.png filter=lfs diff=lfs merge=lfs -text
40
+ FINAL/literary_studies_2007/page_0005.png filter=lfs diff=lfs merge=lfs -text
41
+ FINAL/literary_studies_2007/page_0006.png filter=lfs diff=lfs merge=lfs -text
42
+ FINAL/literary_studies_2007/page_0007.png filter=lfs diff=lfs merge=lfs -text
43
+ FINAL/literary_studies_2007/page_0008.png filter=lfs diff=lfs merge=lfs -text
44
+ static/audio/voice_2bb5d17d5601.mp3 filter=lfs diff=lfs merge=lfs -text
45
+ static/audio/voice_2d9d103aab0a.mp3 filter=lfs diff=lfs merge=lfs -text
46
+ static/audio/voice_34d88cdb4b92.mp3 filter=lfs diff=lfs merge=lfs -text
47
+ static/audio/voice_655c86563efc.mp3 filter=lfs diff=lfs merge=lfs -text
48
+ static/audio/voice_7ce607589c2c.mp3 filter=lfs diff=lfs merge=lfs -text
49
+ static/audio/voice_918f32635636.mp3 filter=lfs diff=lfs merge=lfs -text
50
+ static/audio/voice_94d62e7239e9.mp3 filter=lfs diff=lfs merge=lfs -text
51
+ static/audio/voice_9749ec6e0bf4.mp3 filter=lfs diff=lfs merge=lfs -text
52
+ static/audio/voice_9769d2ebd905.mp3 filter=lfs diff=lfs merge=lfs -text
53
+ static/audio/voice_a29b2f9e805c.mp3 filter=lfs diff=lfs merge=lfs -text
54
+ static/audio/voice_a31899eb0351.mp3 filter=lfs diff=lfs merge=lfs -text
55
+ static/audio/voice_a9e67f679652.mp3 filter=lfs diff=lfs merge=lfs -text
56
+ static/audio/voice_bcd76332724e.mp3 filter=lfs diff=lfs merge=lfs -text
57
+ static/audio/voice_c9d854703f35.mp3 filter=lfs diff=lfs merge=lfs -text
58
+ static/audio/voice_df8cdbf8bd84.mp3 filter=lfs diff=lfs merge=lfs -text
59
+ static/audio/voice_e364309dbee2.mp3 filter=lfs diff=lfs merge=lfs -text
60
+ static/audio/voice_e3b02a4b2432.mp3 filter=lfs diff=lfs merge=lfs -text
61
+ static/audio/voice_fdc7f7d43420.mp3 filter=lfs diff=lfs merge=lfs -text
FINAL/it.txt ADDED
@@ -0,0 +1,1082 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # أسئلة امتحان مادة تقنية المعلومات
2
+ ### الدور الأول للعام الدراسي 2022 - 2023
3
+
4
+ ---
5
+
6
+ ## أولاً: أسئلة الصواب أو الخطأ
7
+
8
+ **س1:** عند كتابة الإجراء الفرعي في الجزء (General) بذلك يمكن استدعاؤه من أي أداة على النموذج.
9
+
10
+ **س2:** يمكن ضبط خصائص الأدوات أثناء تشغيل البرنامج.
11
+
12
+ **س3:** أدوات التحكم هي برامج جاهزة معدة مسبقاً من قبل المبرمجين لتوفير الوقت والجهد.
13
+
14
+ **س4:** يجب أن يكون عدد المعاملات في جملة الإعلان عن الدالة هو نفس عدد المعاملات في جملة استدعائها.
15
+
16
+ **س5:** يعد فيروس الحاسوب من البرمجيات.
17
+
18
+ **س6:** تشفير المعلومات هو تحوير البيانات الأصلية قبل إرسالها عبر شبكات المعلومات بطريقة مشفرة وغير مفهومة لمستلم هذه البيانات.
19
+
20
+ **س7:** يُعد التواصل الشخصي مع أنظمة الحكومة الإلكترونية هو الوسيلة الوحيدة لإنجاز الأعمال والحصول على الخدمات الحكومية.
21
+
22
+ **س8:** يتم إزالة أي نموذج من المشروع من خلال نافذة شكل النموذج.
23
+
24
+ **س9:** يتم استدعاء الإجراء الفرعي الخاص بالحدث Dblclick عندما ينقر المستخدم نقراً مزدوجاً فوق الأداة.
25
+
26
+ **س10:** الحدث LostFocus يجبر المؤشر على البقاء داخل صندوق النص Text إذا كان الصندوق فارغاً.
27
+
28
+ **س11:** الحكومة الإلكترونية تستلزم توفر بنية تحتية متقدمة لتقنيات المعلومات والاتصالات الوطنية.
29
+
30
+ **س12:** تتكون دوال المستخدم من مجموعة من الجمل المكتوبة بلغة البيسك المرئي وتؤدي وظيفة محددة.
31
+
32
+ ---
33
+
34
+ ## ثانياً: أسئلة الاختيار من متعدد
35
+
36
+ **س13:** في حالة اختيار أكثر من أداة من نفس النوع فإن نافذة الخصائص تعرض:
37
+ - أ) الخصائص بترتيب معين
38
+ - ب) خصائص الأداة الأخيرة
39
+ - ج) الخصائص المشتركة فيما بينها
40
+ - د) خصائص الأداة الأولى
41
+
42
+ ---
43
+
44
+ **س14:** قيام شخص باستخدام الحاسوب في مهام غير المنصوص عليها ضمن اختصاصه الوظيفي يعد من جرائم الحاسوب وتسمى:
45
+ - أ) الاستغلال الخاطئ
46
+ - ب) العمل عن بعد
47
+ - ج) سرقة الوظيفة
48
+ - د) سرقة وقت الحاسوب
49
+
50
+ ---
51
+
52
+ **س15:** من مزايا الخدمات الإلكترونية:
53
+ - أ) السفر إلى مسافات بعيدة
54
+ - ب) رفع معدلات أمية الحاسوب
55
+ - ج) ارتفاع تكاليف إنجاز الخدمات
56
+ - د) رفع معدل رفاهية المواطنين
57
+
58
+ ---
59
+
60
+ **س16:** لتخزين المشروع في لغة البيسك المرئي فإننا نقوم بـ:
61
+ - أ) النقر على زر Save Project من القائمة ملف File
62
+ - ب) النقر على زر Save من القائمة المشروع Project
63
+ - ج) تنفيذ البرنامج كإجراء كامل
64
+ - د) تنفيذ البرنامج خطوة خطوة
65
+
66
+ ---
67
+
68
+ **س17:** تستطيع وضع أي أداة من أدوات التحكم على نافذة النموذج عن طريق:
69
+ - أ) القائمة عرض View ثم نختار الأداة المطلوبة
70
+ - ب) النقر المزدوج على الأداة المطلوبة من شريط أدوات التحكم
71
+ - ج) النقر المزدوج على الأداة المطلوبة من نافذة النموذج
72
+ - د) القائمة إدراج Insert ثم النقر على الأداة المطلوبة
73
+
74
+ ---
75
+
76
+ **س18:** تتم إضافة البرامج الفرعية والدوال في بيئة البيسك المرئي من شريط القوائم خلال قائمة:
77
+ - أ) المشروع Project
78
+ - ب) الإضافات Add Ins
79
+ - ج) ملف File
80
+ - د) الأدوات Tools
81
+
82
+ ---
83
+
84
+ **س19:** عند وضع أول صندوق نص على نافذة النموذج يكون تلقائياً اسمه البرمجي:
85
+ - أ) Text1
86
+ - ب) Command1
87
+ - ج) Label1
88
+ - د) TextBox1
89
+
90
+ ---
91
+
92
+ **س20:** تستخدم الدالة Str في:
93
+ - أ) إرجاع عدد معين من الأحرف بداية النص
94
+ - ب) تحويل المتغير الرقمي إلى صيغة نصية
95
+ - ج) إرجاع عدد معين من الأحرف نهاية النص
96
+ - د) تحويل المتغير النصي إلى صيغة رقمية
97
+
98
+ ---
99
+
100
+ **س21:** القيمة المعادة من الدالة بالجملة `A = Left("Good Morning", 4)` هي:
101
+ - أ) Morning
102
+ - ب) Morn
103
+ - ج) ning
104
+ - د) Good
105
+
106
+ ---
107
+
108
+ **س22:** لإظهار وإخفاء زر الأوامر Command فإننا نستخدم الخاصية:
109
+ - أ) Visible
110
+ - ب) Setfocus
111
+ - ج) Style
112
+ - د) Enabled
113
+
114
+ ---
115
+
116
+ **س23:** تشمل معاملات الحكومة الإلكترونية:
117
+ - أ) التجارة الإلكترونية
118
+ - ب) الاتصال الإلكتروني
119
+ - ج) صيانة المعدات الإلكترونية
120
+ - د) البريد الإلكتروني
121
+
122
+ ---
123
+
124
+ **س24:** من الأمور المهمة التي تميز الدالة عن الإجراء الفرعي:
125
+ - أ) يمكن استدعاؤها أكثر من مرة
126
+ - ب) تؤدي وظائف متعددة
127
+ - ج) تعيد قيمة واحدة تقوم بتخزينها في اسم الدالة
128
+ - د) تتكون من مجموعة من الجمل المكتوبة بلغة البيسك المرئي
129
+
130
+ ---
131
+
132
+ **س25:** المكان الرئيسي الذي يتم فيه تصميم البرامج والتطبيقات في لغة البيسك المرئي هو:
133
+ - أ) شريط الأدوات Tools Bar
134
+ - ب) نافذة المشروع Project
135
+ - ج) نافذة النموذج Form
136
+ - د) شريط القوائم Menu Bar
137
+
138
+ ---
139
+
140
+ **س26:** تُعد بيانات الصفة الشخصية أكثر دقة في تمييز المستخدمين لـ:
141
+ - أ) استخدامها لبيانات مشفرة
142
+ - ب) وجود جدار ناري بها
143
+ - ج) استحالة تزويرها أو تقليدها
144
+ - د) سهولة استخدامها وحفظها
145
+
146
+ ---
147
+
148
+ **س27:** تُعد التعاملات بين الحكومة والمصارف الأهلية من تعاملات الحكومة الإلكترونية التي تتم من:
149
+ - أ) الحكومة إلى الحكومة
150
+ - ب) المواطن إلى الحكومة
151
+ - ج) القطاع الخاص إلى الحكومة
152
+ - د) الحكومة إلى المواطن
153
+
154
+ ---
155
+
156
+ **س28:** أي مما يلي يُعد أول وأهم جزء في حل المشاكل البرمجية:
157
+ - أ) تنفيذ الحل
158
+ - ب) تحديد الأدوات المطلوبة
159
+ - ج) تعريف المشكلة
160
+ - د) كتابة الخوارزميات
161
+
162
+ ---
163
+
164
+ **س29:** تُعد الدالة Format من الدوال الجاهزة:
165
+ - أ) الرياضية
166
+ - ب) النصية
167
+ - ج) التاريخ والوقت
168
+ - د) الحرفية
169
+
170
+ ---
171
+
172
+ **س30:** متغيرات لأداة معينة تأخذ قيماً في أثناء تصميم البرنامج أو أثناء تشغيل البرنامج:
173
+ - أ) النوافذ Windows
174
+ - ب) الأحداث Events
175
+ - ج) الخصائص Properties
176
+ - د) الطرق Methods
177
+
178
+ ---
179
+
180
+ **س31:** لإضافة أو تغيير العنوان الذي يظهر على زر الأمر فإننا نكتب الصيغة:
181
+ - أ) `Command1.Caption = "نعم"`
182
+ - ب) `Command1.label = "نعم"`
183
+ - ج) `Command1.Name = "نعم"`
184
+ - د) `Command1 = "نعم"`
185
+
186
+ ---
187
+
188
+ **س32:** تعد جميع معاملات الدالة Function:
189
+ - أ) مدخلات فقط
190
+ - ب) من نوع واحد
191
+ - ج) مخرجات فقط
192
+ - د) مدخلات ومخرجات
193
+
194
+ ---
195
+
196
+ **س33:** لإنهاء استكمال تنفيذ جمل الدالة الوظيفية في أي موقع قبل الوصول إلى الجملة End Function فإننا نستخدم الجملة:
197
+ - أ) Goto Exit
198
+ - ب) End
199
+ - ج) Exit Function
200
+ - د) Exit Sub
201
+
202
+ ---
203
+
204
+ **س34:** أي مما يلي من المخاطر التي يستغلها القراصنة لتعطيل عمل الشبكة أو خفض أدائها:
205
+ - أ) أعطال الشبكة
206
+ - ب) الكوارث الطبيعية
207
+ - ج) الفيروسات
208
+ - د) تشفير المعلومات
209
+
210
+ ---
211
+
212
+ **س35:** النافذة التي تعطيك فكرة عن مكان ظهور النموذج على الشاشة بعد تنفيذ التطبيق هي نافذة:
213
+ - أ) مستكشف المشروع Project Explorer
214
+ - ب) شكل النموذج The Form Layout
215
+ - ج) المشروع Project
216
+ - د) النموذج Form
217
+
218
+ ---
219
+
220
+ **س36:** أي مما يلي لا يعد من أعراض الإصابة بالفيروسات:
221
+ - أ) تغير شكل أيقونات الملفات
222
+ - ب) تغير شاشة التوقف بشكل متكرر
223
+ - ج) توقف النظام بدون سبب
224
+ - د) البطء المفاجئ في أداء الحاسوب
225
+
226
+ ---
227
+
228
+ **س37:** يمكن طباعة محتويات المشروع من خلال القائمة:
229
+ - أ) العرض View
230
+ - ب) التنفيذ Run
231
+ - ج) المشروع Project
232
+ - د) ملف File
233
+
234
+ ---
235
+
236
+ **س38:** من أهم الأدوات المستخدمة التي يمكن بواسطتها تنفيذ الكثير من التطبيقات والإجراءات هي أداة:
237
+ - أ) التحكم بالتطبيقات OLE
238
+ - ب) زر الخيار Option Button
239
+ - ج) الإطار Frame
240
+ - د) زر الأمر Command Button
241
+
242
+ ---
243
+
244
+ **س39:** أي فعل يقوم به المستخدم ينتج عنه رد فعل معين مثل تنفيذ إجراء معين يسمى:
245
+ - أ) حدث Event
246
+ - ب) أمر Command
247
+ - ج) وظيفة Method
248
+ - د) خاصية Property
249
+
250
+ ---
251
+
252
+ **س40:** سميت الدوال الجاهزة بهذا الاسم لأنه:
253
+ - أ) تقوم بوظيفة محددة مسبقاً
254
+ - ب) يقوم المبرمج بكتابتها بكل سهولة
255
+ - ج) يمكن استدعاؤها من الجزء العام فقط
256
+ - د) يمكن استدعاؤها دون كتابة برامجها
257
+
258
+ ---
259
+
260
+ **س41:** لإيجاد الجذر التربيعي لرقم معين (X) فإننا نستخدم الدالة:
261
+ - أ) Sgn(X)
262
+ - ب) Int(X)
263
+ - ج) Sqr(X)
264
+ - د) ABS(X)
265
+
266
+ ---
267
+
268
+ **س42:** من مكونات بيئة التطوير للبيسك المرئي التي تسهل على المبرمج التعامل مع بعض العناصر الموجودة في شريط القوائم بشكل مباشر:
269
+ - أ) شريط الأدوات
270
+ - ب) صندوق أدوات التحكم
271
+ - ج) نافذة الخصائص
272
+ - د) نافذة مستكشف المشروع
273
+
274
+ ---
275
+
276
+ **س43:** يبدأ تحديث المعلومات المنشورة على المواقع الحكومية بشكل دوري في مرحلة:
277
+ - أ) التفاعل وتبادل البيانات
278
+ - ب) النشر الإلكتروني
279
+ - ج) الظهور الحكومي
280
+ - د) تكامل الخدمات وإنجاز المعاملات
281
+
282
+ ---
283
+
284
+ **س44:** من أهم الأحداث الخاصة بالنموذج والذي ينفذ تلقائياً عند تحميل النموذج هو:
285
+ - أ) Event
286
+ - ب) Load
287
+ - ج) Click
288
+ - د) Show
289
+
290
+ ---
291
+
292
+ **س45:** الأداة التي تستخدم لإدخال البيانات الرقمية أو الحرفية في وقت التصميم أو في وقت التشغيل هي أداة:
293
+ - أ) العنوان Label
294
+ - ب) السرد Combo Box
295
+ - ج) زر الأمر Command
296
+ - د) صندوق النص Text Box
297
+
298
+ ---
299
+
300
+ **س46:** آخر جملة في الإجراء الفرعي Sub هي:
301
+ - أ) End Sub
302
+ - ب) End Function
303
+ - ج) Exit
304
+ - د) End
305
+
306
+ ---
307
+
308
+ **س47:** تستخدم طريقة النموذج Cls في:
309
+ - أ) تحديد اسم النموذج في مرحلة التصميم
310
+ - ب) مسح ما هو مطبوع على النموذج
311
+ - ج) حركة النموذج
312
+ - د) إظهار النموذج
313
+
314
+ ---
315
+
316
+ **س48:** من دوال التاريخ والوقت الدالة Now التي تعطي:
317
+ - أ) التاريخ والوقت الحاليين
318
+ - ب) التاريخ الحالي فقط
319
+ - ج) الوقت الحالي فقط
320
+ - د) رقم اليوم من أيام الأسبوع
321
+
322
+ ---
323
+ ***** انتهت الأسئلة *****
324
+
325
+ # أسئلة امتحان مادة تقنية المعلومات
326
+ ### الدور الأول للعام الدراسي 2023 - 2024
327
+
328
+ ---
329
+
330
+ ## أولاً: أسئلة الصواب أو الخطأ
331
+
332
+ **س1:** تمثل كلمات العبور أحد المخاطر الأمنية العالية لأنظمة الشبكات والاتصالات والتي مصدرها برمجيات الشبكات.
333
+
334
+ **س2:** يجب أن يكون هناك توافق في نوع البيانات للمعاملات في جملة الإعلان وجملة الاستدعاء للإجراء الفرعي أو الدالة.
335
+
336
+ **س3:** تمثل الحكومة الإلكترونية عين المواطنين على اختبار سرعة أداء الحكومة وشفافية إجراءاتها.
337
+
338
+ **س4:** المصفوفة هي مجموعة متجاورة من المواقع في الذاكرة تحتوي على عناصر من نفس النوع.
339
+
340
+ **س5:** يمكن ربط أدوات التحكم بأوامر البرمجة لتعالج البيانات المدخلة حتى تخرج لنا العملية المطلوبة.
341
+
342
+ **س6:** أداة الصورة (Image) هي أداة لعرض الصورة وتستعمل كحاوية للعناصر والأدوات الأخرى.
343
+
344
+ **س7:** تقسيم أي مشروع إلى مجموعة من الأجزاء ينتج عنه ضياع للوقت وصعوبة في التعديل.
345
+
346
+ **س8:** رخصة متعددة الاستخدام تمنح للمؤسسات التي سوف يقوم عدد كبير من موظفيها باستخدام نفس التطبيق البرمجي.
347
+
348
+ **س9:** يتم تحديد عناصر المصفوفة ذات البعدين في جمل البرنامج باستخدام دليل واحد.
349
+
350
+ **س10:** المعلومات الشخصية المدخلة في قواعد بيانات المؤسسات العامة والخاصة هي ملك لهذه المؤسسات ولها الحق في استغلالها بأي طريقة كبيعها أو تبادلها مع مؤسسات أخرى.
351
+
352
+ **س11:** يتم استدعاء الأحداث بكتابة الاسم البرمجي للأداة ثم النقطة ثم اسم الحدث.
353
+
354
+ **س12:** تشمل لوائح أمن قواعد البيانات ضمان إتاحة الوصول للبيانات من قبل المخولين بذلك في أي وقت.
355
+
356
+ **س13:** إمكانية إنجاز الخدمات من أي مكان ��تاح فيه وسائل الاتصالات في أوقات الدوام الرسمية فقط من مزايا الخدمات الإلكترونية.
357
+
358
+ **س14:** يمكن تغيير النص المعروض بأداة العنوان (Label) في وقت التنفيذ داخل البرنامج.
359
+
360
+ **س15:** فتح أي ملف مرفق ضمن رسالة بريد إلكتروني لا يُعرف مصدرها من طرق الوقاية من الفيروسات.
361
+
362
+ **س16:** إن تأشير أحد أزرار الخيارات (Option Buttons) يلغي تأشير الأزرار الأخرى.
363
+
364
+ ---
365
+
366
+ ## ثانياً: أسئلة الاختيار من متعدد
367
+
368
+ **س17:** يمكن عند تنفيذ الدالة باستخدام النافذة السريعة Immediate Window معرفة:
369
+ - أ) جملة الإعلان عن الدالة
370
+ - ب) حجم الدالة
371
+ - ج) نوع الدالة
372
+ - د) قيم المتغيرات بالدالة
373
+
374
+ ---
375
+
376
+ **س18:** عند وضع أول صندوق نص على نافذة النموذج يكون اسمه البرمجي:
377
+ - أ) Label1
378
+ - ب) Box1
379
+ - ج) txt
380
+ - د) Text1
381
+
382
+ ---
383
+
384
+ **س19:** من شريط القوائم يمكن إضافة أي عنصر من عناصر المشروع من خلال القائمة:
385
+ - أ) الأدوات Tools
386
+ - ب) الإضافات Add Ins
387
+ - ج) ملف File
388
+ - د) المشروع Project
389
+
390
+ ---
391
+
392
+ **س20:** لإيجاد الجذر التربيعي لرقم معين نستخدم الدالة:
393
+ - أ) Int
394
+ - ب) Sqr
395
+ - ج) Math
396
+ - د) Abs
397
+
398
+ ---
399
+
400
+ **س21 و س22:** بناءً على المقطع البرمجي التالي:
401
+ ```
402
+ For i = 0 To 2
403
+ For j = 0 To 2
404
+ a(i,j) = inputbox(" ")
405
+ Next j
406
+ Next i
407
+ ```
408
+
409
+ **س21:** من خلال المقطع السابق المصفوفة a هي مصفوفة:
410
+ - أ) ذات عمود واحد
411
+ - ب) أحادية البعد
412
+ - ج) ذات بعدين
413
+ - د) ذات صف واحد
414
+
415
+ ---
416
+
417
+ **س22:** وظيفة المقطع السابق:
418
+ - أ) قراءة عناصر قطر المصفوفة a
419
+ - ب) إدخال عناصر المصفوفة a
420
+ - ج) طباعة عناصر المصفوفة a
421
+ - د) طباعة عناصر قطر المصفوفة a
422
+
423
+ ---
424
+
425
+ **س23:** في مراحل تطور الحكومة، يبدأ التفاعل المباشر بين المواطن والإدارة الحكومية الموفرة للخدمة في مرحلة:
426
+ - أ) الظهور الحكومي
427
+ - ب) تكامل الخدمات
428
+ - ج) النشر الإلكتروني
429
+ - د) التفاعل وتبادل البيانات
430
+
431
+ ---
432
+
433
+ **س24:** القيمة الوحيدة من الدالة تكون في:
434
+ - أ) معاملات الدالة
435
+ - ب) نوع الدالة
436
+ - ج) اسم الدالة
437
+ - د) جملة الإعلان عن الدالة
438
+
439
+ ---
440
+
441
+ **س25:** جزء من المشروع يتم فيه كتابة أي إجراء فرعي أو دالة أو إعلان عن متغيرات بحيث تصبح متاحة للاستخدام من أي نموذج أو أداة في المشروع بالكامل:
442
+ - أ) General
443
+ - ب) Private
444
+ - ج) Public
445
+ - د) Module
446
+
447
+ ---
448
+
449
+ **س26:** للتأكد من عدم وجود أي مخاطر أمنية تدخل البيانات المستقبلة فإننا نستخدم:
450
+ - أ) مبدأ الشفافية
451
+ - ب) الجدار الناري
452
+ - ج) حماية البرمجيات
453
+ - د) قرصنة المعلومات
454
+
455
+ ---
456
+
457
+ **س27:** اعتماد مبدأ تشفير البيانات من الأمثلة على:
458
+ - أ) طرق الوقاية من الفيروسات
459
+ - ب) طرق تحديد صلاحيات المستخدم
460
+ - ج) وسائل مكافحة جرائم الحاسوب
461
+ - د) وسائل تأمين البيانات المرسلة
462
+
463
+ ---
464
+
465
+ **س28:** لإضافة عنصر لصندوق القائمة (List) نستخدم الخاصية:
466
+ - أ) AddItem
467
+ - ب) AppendItem
468
+ - ج) InsertItem
469
+ - د) IndextItem
470
+
471
+ ---
472
+
473
+ **س29:** الجملة التالية `Dim x(1 To 4 , 1 To 4) As single` تنشئ مصفوفة ذات بعدين تحتوي على:
474
+ - أ) أربعة صفوف فقط
475
+ - ب) ثلاثة صفوف وثلاثة أعمدة
476
+ - ج) ثلاثة أعمدة فقط
477
+ - د) أربعة صفوف وأربعة أعمدة
478
+
479
+ ---
480
+
481
+ **س30:** يمكن تنفيذ التطبيق في لغة البيسك المرئي من لوحة المفاتيح بالضغط على المفتاح:
482
+ - أ) F5
483
+ - ب) F4
484
+ - ج) Ctrl
485
+ - د) Enter
486
+
487
+ ---
488
+
489
+ **س31:** الحصول على المعلومات المملوكة للدولة هي حق تشريعي للمواطنين وهي أحد مؤشرات:
490
+ - أ) الشفافية
491
+ - ب) الخصوصية
492
+ - ج) الملكية الفكرية
493
+ - د) الفساد الإداري
494
+
495
+ ---
496
+
497
+ **س32:** من أهم الأحداث الخاصة بالنموذج والذي ينفذ تلقائياً عند تحميله هو:
498
+ - أ) Click
499
+ - ب) Show
500
+ - ج) Load
501
+ - د) Setfocus
502
+
503
+ ---
504
+
505
+ **س33:** عند تنفيذ الأمر `FORM1.Cls` ينتج عنه:
506
+ - أ) حركة للنموذج
507
+ - ب) رسم خط مستقيم على النموذج
508
+ - ج) إظهار للنموذج
509
+ - د) مسح ما هو مطبوع على النموذج
510
+
511
+ ---
512
+
513
+ **س34:** بناءً على المقطع البرمجي التالي:
514
+ ```
515
+ Dim x,y as integer
516
+ y = abs(x)
517
+ ```
518
+ قيمة المتغير y بعد التنفيذ هي:
519
+ - أ) y
520
+ - ب) Null
521
+ - ج) x
522
+ - د) صفر
523
+
524
+ ---
525
+
526
+ **س35:** Multiline هو:
527
+ - أ) حدث
528
+ - ب) طريقة
529
+ - ج) خاصية
530
+ - د) وظيفة
531
+
532
+ ---
533
+
534
+ **س36:** يجمع بين مزايا صندوق النص (Text) وصندوق القائمة (List) هو:
535
+ - أ) الصندوق المركب Combo Box
536
+ - ب) أزرار الأوامر Command Buttons
537
+ - ج) زر الخيار Option Buttons
538
+ - د) صناديق التحقق Check Boxes
539
+
540
+ ---
541
+
542
+ **س37:** جملة الإعلان لتخزين أسماء (30) طالباً في مصفوفة ذات بعد واحد هي:
543
+ - أ) `Dim a(29) as single`
544
+ - ب) `Dim a(29) as String`
545
+ - ج) `Dim a(30) as integer`
546
+ - د) `Dim a(30) as String`
547
+
548
+ ---
549
+
550
+ **س38:** أي العبارات التالية صحيح فيما يتعلق بالإجراء الفرعي (Sub):
551
+ - أ) يمكن أن يكون بدون معاملات
552
+ - ب) يعيد قيمة واحدة فقط
553
+ - ج) جميع معاملاته مدخلات فقط
554
+ - د) يجب تحديد نوعه
555
+
556
+ ---
557
+
558
+ **س39:** لإضافة عنوان لأداة الإطار (Frame) نستخدم الخاصية:
559
+ - أ) Label
560
+ - ب) Name
561
+ - ج) Caption
562
+ - د) Title
563
+
564
+ ---
565
+
566
+ **س40:** أداة تستخدم لإدخال البيانات الرقمية أو الحرفية في وقت التصميم أو في وقت التشغيل:
567
+ - أ) العنوان Label
568
+ - ب) النموذج Form
569
+ - ج) صندوق النص Text Box
570
+ - د) الأمر Command
571
+
572
+ ---
573
+
574
+ **س41:** يعد نموذجاً من خدمات ومعاملات الحكومة الإلكترونية:
575
+ - أ) تنظيم البريد الإلكتروني
576
+ - ب) صيانة المعدات الإلكترونية
577
+ - ج) دورات رفع أمية الحاسوب
578
+ - د) الأحوال الشخصية الإلكترونية
579
+
580
+ ---
581
+
582
+ **س42:** الخاصية التي تجعل زر الأوامر فعالاً بحيث يقبل الأحداث مثل النقر هي:
583
+ - أ) Enabled
584
+ - ب) LostFocus
585
+ - ج) Visible
586
+ - د) GotFocus
587
+
588
+ ---
589
+
590
+ **س43:** برامج تقوم بشيء آخر غير ما يعتقده مشغل البرنامج:
591
+ - أ) فيروس حصان طروادة
592
+ - ب) برمجيات تجارية
593
+ - ج) برمجيات مفتوحة المصدر
594
+ - د) برامج مكافحة الفيروسات
595
+
596
+ ---
597
+
598
+ **س44:** برمجيات يمكن استغلالها كما هي أو تعديلها وتطويرها لتعمل بصورة مغايرة لنسختها الأصلية:
599
+ - أ) تجارية
600
+ - ب) مجانية
601
+ - ج) تجريبية
602
+ - د) مفتوحة المصدر
603
+
604
+ ---
605
+
606
+ **س45:** يطلق على جميع التعاملات الممكن إنجازها عبر تقنية المعلومات اسم:
607
+ - أ) الحكومة الإلكترونية
608
+ - ب) المفتاح العام
609
+ - ج) التواصل الإلكتروني
610
+ - د) الخدمات الإلكترونية
611
+
612
+ ---
613
+
614
+ **س46:** أهم خاصية تتميز بها أداة القائمة المنسدلة (Combo Box) وتأخذ ثلاث قيم هي:
615
+ - أ) Change
616
+ - ب) Style
617
+ - ج) ListIndex
618
+ - د) List
619
+
620
+ ---
621
+
622
+ **س47:** يتم تحديد النماذج، الأزرار والقوائم في لغة الفيجوال بيسك المطلوبة لحل المسألة في مرحلة:
623
+ - أ) تحديد الأدوات المطلوبة
624
+ - ب) تعريف المشكلة
625
+ - ج) كتابة الخوارزميات
626
+ - د) تنفيذ الحل
627
+
628
+ ---
629
+
630
+ **س48:** عند قيام شخص ما باستخدام الحاسوب في مهام غير المنصوص عليها ضمن اختصاصه الوظيفي فإن ذلك يُعد جريمة من جرائم الحاسوب تسمى:
631
+ - أ) سرقة كلمات العبور
632
+ - ب) سرقة وقت الحاسوب
633
+ - ج) القرصنة الإلكترونية
634
+ - د) التشفير الإلكتروني
635
+
636
+ ---
637
+
638
+ **س49:** توفر أنظمة الحكومة الإلكترونية للمواطنين والإدارات فرصة التواصل عبر:
639
+ - أ) الأكشاك الإلكترونية للخدمات الشاملة
640
+ - ب) التشفير الإلكتروني
641
+ - ج) التدريب الإلكتروني
642
+ - د) التوقيع الإلكتروني
643
+
644
+ ---
645
+
646
+ **س50:** تُعد الدالة الجاهزة (Val) من الدوال:
647
+ - أ) التاريخ / الوقت
648
+ - ب) الحرفية
649
+ - ج) الرياضية
650
+ - د) الوظيفية
651
+
652
+ ---
653
+
654
+ **س51:** يمكن التبديل بين نافذة النموذج وبين شاشة محرر الكود من خلال نافذة:
655
+ - أ) الكود Code
656
+ - ب) المشروع Project
657
+ - ج) مستكشف المشروع Project Explorer
658
+ - د) النموذج Form
659
+
660
+ ---
661
+
662
+ **س52:** تستخدم صناديق التحقق Check Box لعرض مجموعة خيارات على المستخدم ليختار منها في نفس الوقت:
663
+ - أ) ثلاثة خيارات فقط
664
+ - ب) خيار واحد فأكثر
665
+ - ج) خيار واحد فقط
666
+ - د) خياران فقط
667
+
668
+ ---
669
+
670
+ **س53:** تستخدم جملة الإعلان عن المصفوفة لتحديد:
671
+ - أ) طريقة تنفيذ التطبيق
672
+ - ب) طريقة استدعاء البيانات
673
+ - ج) عدد ونوع البيانات المراد تخزينها
674
+ - د) أداة التحكم المرتبطة بالبيانات
675
+
676
+ ---
677
+
678
+ **س54:** لتغيير حجم أداة التحكم ولونها فإننا نستخدم:
679
+ - أ) شريط الأدوات Tool Bar
680
+ - ب) نافذة النموذج Form
681
+ - ج) نافذة الخصائص Properties Windows
682
+ - د) شريط أدوات التحكم Toolbox Control
683
+
684
+ ---
685
+
686
+ **س55:** من طرق أداة العنوان Label:
687
+ - أ) Move
688
+ - ب) Change
689
+ - ج) Caption
690
+ - د) Dblclick
691
+
692
+ ---
693
+
694
+ **س56:** يشكل الهوية الإلكترونية للمواطن:
695
+ - أ) التوقيع الإلكتروني
696
+ - ب) المفتاح العام
697
+ - ج) المفتاح الخاص
698
+ - د) البريد الإلكتروني
699
+
700
+ ---
701
+ ***** انتهت الأسئلة *****
702
+
703
+ # أسئلة امتحان مادة تقنية المعلومات
704
+ ### الدور الأول للعام الدراسي 2024 - 2025
705
+
706
+ ---
707
+
708
+ ## أولاً: أسئلة الصواب أو الخطأ
709
+
710
+ **س1:** `Form1.Show` تستخدم هذه الصيغة لإظهار النموذج Form1 عن طريق استدعاء الوظيفة التابعة لها (Show).
711
+
712
+ **س2:** الفيروسات لا يمكن أن تصيب المكونات المادية للحاسوب (Hardware).
713
+
714
+ **س3:** يمكن استدعاء الدالة بجملة الاستدعاء (Call).
715
+
716
+ **س4:** تمثل كلمات العبور أحد المخاطر العالية لأنظمة الشبكات والاتصالات.
717
+
718
+ **س5:** لجعل صندوق النص (Text Box) يستخدم لعرض النصوص دون السماح بتعديلها نجعل الخاصية (Locked) مساوية للقيمة (True).
719
+
720
+ **س6:** التوظيف الإلكتروني إحدى نماذج الخدمات الإلكترونية.
721
+
722
+ **س7:** الأحداث هي وظائف جاهزة ترتبط بأداة معينة من خلال اسمها.
723
+
724
+ **س8:** تتميز مرحلة التفاعل وتبادل البيانات بتنظيم الوصول إلى مواقع الحكومة الإلكترونية عبر البوابة الإلكترونية.
725
+
726
+ **س9:** يمكن أن يكون الإجراء الفرعي من دون معاملات.
727
+
728
+ **س10:** تُمنح رخصة متعددة الاستخدام للمؤسسات التي سوف تستخدم أكثر من تطبيق برمجي على حاسوب واحد فقط.
729
+
730
+ **س11:** الحصول على المعلومات المملوكة للدولة إحدى مؤشرات الشفافية التي تميز الحكومة الديمقراطية.
731
+
732
+ **س12:** الاحتفاظ بنسخ احتياطية من البرامج والبيانات المخزنة بالحاسوب هي إحدى طرق الوقاية من الفيروسات.
733
+
734
+ **س13:** القطاع الخاص هو أحد عناصر التفاعلات التي تتم ضمن تعاملات الحكومة الإلكترونية.
735
+
736
+ **س14:** عند استدعاء إجراء فرعي أو دالة يجب أن يكون عدد المعاملات في جملة الإعلان مساوياً لعدد المعاملات في جملة الاستدعاء.
737
+
738
+ **س15:** يشترط في استخدام الطريقة (Setfocus) أن تكون الأداة المطلوب تركيزها ظاهرة وغير فعالة.
739
+
740
+ **س16:** لإظهار نافذة الخصائص (Properties Windows) في برنامج بيسك المرئي Visual Basic نضغط على المفتاح (F4) من لوحة المفاتيح.
741
+
742
+ ---
743
+
744
+ ## ثانياً: أسئلة الاختيار من متعدد
745
+
746
+ **س17:** الخدمات الإلكترونية لها مزايا عديدة باستثناء:
747
+ - أ) خفض تكاليف إنجاز الخدمات لجميع الأطراف
748
+ - ب) توفر الجهد والوقت وتكاليف إنجاز المعاملات بالطريقة التقليدية
749
+ - ج) رفع معدلات أمية الحاسوب لدى مواطني الدولة
750
+ - د) إمكانية إنجاز الخدمات على مدار الساعة
751
+
752
+ ---
753
+
754
+ **س18:** خاصية صندوق النص ScrollBars وظيفتها:
755
+ - أ) لعرض أو إخفاء أشرطة التمرير
756
+ - ب) تحديد أعلى طولاً للنص
757
+ - ج) عندما تكون True فإن الصندوق يستخدم لعرض النصوص
758
+ - د) إضافة نص للصندوق
759
+
760
+ ---
761
+
762
+ **س19:** القيمة التي سيتم تخصيصها لمربع النص (Text1) بعد تنفيذ جزء البرنامج التالي هي:
763
+ ```
764
+ Number = Sqr(100)
765
+ Text1.text = Number
766
+ ```
767
+ - أ) 1
768
+ - ب) 10
769
+ - ج) 10000
770
+ - د) 100
771
+
772
+ ---
773
+
774
+ **س20:** من التحديات التقنية التي تواجه فرص نجاح تجارب الحكومة الإلكترونية في العالم الثالث:
775
+ - أ) حرص الحكومات الاستبدادية على سرية المعلومات الحكومية
776
+ - ب) تخلف البنية التحتية في قطاع الاتصالات
777
+ - ج) ارتفاع معدل أمية الحاسوب لدى المواطنين
778
+ - د) عدم امتلاك المواطنين مهارات التعامل مع تقنيات المعلومات
779
+
780
+ ---
781
+
782
+ **س21:** لا تشمل إجراءات تأمين قواعد البيانات:
783
+ - أ) دفع أجور عالية للمسؤولين عن صيانة قاعدة البيانات
784
+ - ب) تجنب الدخول والاستغلال غير المصرح للبيانات من قبل غير المخولين
785
+ - ج) توفير أقصى درجات السرية لبيانات الولوج للبيانات
786
+ - د) حماية قاعدة البيانات من التلف أو الضياع
787
+
788
+ ---
789
+
790
+ **س22:** لتشكيل التاريخ بطريقة معينة تستخدم الدالة:
791
+ - أ) Format
792
+ - ب) Month
793
+ - ج) Weekday
794
+ - د) Year
795
+
796
+ ---
797
+
798
+ **س23:** في برنامج بيسك المرئي:
799
+ - أ) يستخدم Module كنموذج بدء التشغيل تلقائياً لمشروعك
800
+ - ب) لا يمكنك تغيير نموذج بدء التشغيل لمشروعك
801
+ - ج) يستخدم البرنامج النموذج الثاني (FORM2) في مشروعك كنموذج بدء التشغيل تلقائياً
802
+ - د) يمكنك تغيير نموذج بدء التشغيل لمشروعك
803
+
804
+ ---
805
+
806
+ **س24:** وظيفة الجدار الناري هي:
807
+ - أ) تحويل البيانات الأصلية إلى شكل غير مفهوم
808
+ - ب) تحديد شخصية المستخدم
809
+ - ج) تحديد صلاحيات المستخدم
810
+ - د) حماية شبكة الحاسوب والتأكد من عدم وجود أي مخاطر أمنية
811
+
812
+ ---
813
+
814
+ **س25 و س26:** بناءً على جزء البرنامج التالي:
815
+ ```
816
+ Private function Max(a , b as integer) as integer
817
+ if a > b Then
818
+ Max = a
819
+ else
820
+ Max = b
821
+ End if
822
+ End function
823
+ ```
824
+
825
+ **س25:** نوع البيانات المعادة من الدالة السابقة هي:
826
+ - أ) كسري
827
+ - ب) حرفي
828
+ - ج) صحيح
829
+ - د) حقيقي
830
+
831
+ ---
832
+
833
+ **س26:** ناتج تنفيذ الدالة حسب جملة الاستدعاء `X=Max(3,10)` هو:
834
+ - أ) 3
835
+ - ب) 7
836
+ - ج) 13
837
+ - د) 10
838
+
839
+ ---
840
+
841
+ **س27:** أحد هذه الخيارات ليست من الطرق:
842
+ - أ) الإظهار Show
843
+ - ب) السحب Drag
844
+ - ج) النقر Click
845
+ - د) النقل Move
846
+
847
+ ---
848
+
849
+ **س28:** من خلالها يتم تشغيل برامج من خارج بيئة البرمجة ووظيفتها خلق تكامل مع اللغة هي قائمة:
850
+ - أ) التنفيذ
851
+ - ب) الإضافات
852
+ - ج) التنقيح
853
+ - د) الأدوات
854
+
855
+ ---
856
+
857
+ **س29:** في برنامج بيسك المرئي عند كتابة اسم الأداة ثم النقطة يتم عرض قائمة بـ:
858
+ - أ) الوظائف فقط
859
+ - ب) الخصائص والأحداث
860
+ - ج) الخصائص فقط
861
+ - د) الخصائص والوظائف
862
+
863
+ ---
864
+
865
+ **س30:** أداة تستخدم لاختيار البدائل من قائمة منسدلة على اختيارات محددة سلفاً:
866
+ - أ) صندوق الاختيارات
867
+ - ب) زر الاختيار
868
+ - ج) زر الأوامر
869
+ - د) السرد
870
+
871
+ ---
872
+
873
+ **س31:** يقصد به نشر معلومات مضللة أو كاذبة عن المؤسسات أو الشخصيات العامة:
874
+ - أ) الاصطياد الإلكتروني
875
+ - ب) قرصنة المعلومات
876
+ - ج) سرقة وقت الحاسوب
877
+ - د) التشهير الإلكتروني
878
+
879
+ ---
880
+
881
+ **س32:** لتحديد جيب تمام الزاوية تستخدم الدالة الجاهزة:
882
+ - أ) Log(x)
883
+ - ب) Sin(x)
884
+ - ج) Cos(x)
885
+ - د) Tan(x)
886
+
887
+ ---
888
+
889
+ **س33:** الصيغة `Move x1 , y1` تستخدم لـ:
890
+ - أ) رسم دائرة
891
+ - ب) إظهار النموذج
892
+ - ج) مسح ما هو مطبوع على النموذج
893
+ - د) حركة النموذج
894
+
895
+ ---
896
+
897
+ **س34:** القيمة التي سيتم تخصيصها للمتغير M بعد تنفيذ الجملة `M= Right ("Microsoft_Visual_Basic", 6)` هي:
898
+ - أ) -Basic
899
+ - ب) Basic
900
+ - ج) Micros
901
+ - د) Visual
902
+
903
+ ---
904
+
905
+ **س35:** أحد الأضرار التالية لا يحدثه فيروس الحاسوب:
906
+ - أ) توقف بعض التطبيقات البرمجية عن العمل
907
+ - ب) بطء مفاجئ في أداء الحاسوب
908
+ - ج) توقف النظام بلا سبب
909
+ - د) عدم تذكر كلمة العبور
910
+
911
+ ---
912
+
913
+ **س36:** لتغيير حجم أداة العنوان ليتلاءم مع حجم النص الموجود بداخلها نجعل الخاصية مساوية للقيمة (True):
914
+ - أ) Alignment
915
+ - ب) Backstyle
916
+ - ج) Autosize
917
+ - د) Wordwrap
918
+
919
+ ---
920
+
921
+ **س37:** الخاصية التي تعطي عنواناً ظاهرياً للنموذج أو نصاً داخل الأداة على الواجهة:
922
+ - أ) Enabled
923
+ - ب) Visible
924
+ - ج) Name
925
+ - د) Caption
926
+
927
+ ---
928
+
929
+ **س38:** للتصديق على صحة بيانات المعاملات الإلكترونية يجب إسنادها بـ:
930
+ - أ) التوقيع اليدوي
931
+ - ب) التوقيع الإلكتروني
932
+ - ج) نسخة من البطاقة الشخصية
933
+ - د) نسخة من جواز السفر الإلكتروني
934
+
935
+ ---
936
+
937
+ **س39:** تسهم قرصنة البرمجيات في:
938
+ - أ) تنظيم عمالة الصناعات الإلكترونية بالبلاد
939
+ - ب) إفلاس العديد من مؤسسات إنتاج البرمجيات
940
+ - ج) تطور صناعة البرمجيات العالمية
941
+ - د) تعزيز القدرات البشرية لمبرمجي دول العالم الفقيرة
942
+
943
+ ---
944
+
945
+ **س40:** عند النقر على الأمر Remove Form2 يتم:
946
+ - أ) اعتماد Form2 نموذج بدء التشغيل
947
+ - ب) إضافة النموذج Form2 إلى المشروع
948
+ - ج) إزالة النموذج Form2 من المشروع
949
+ - د) فتح النموذج Form2
950
+
951
+ ---
952
+
953
+ **س41:** في مرحلة يمكن للمواطنين تنزيل نسخ إلكترونية من المستندات الحكومية وملؤها إلكترونياً ثم إرسالها إلى الدائرة الحكومية عبر البريد الإلكتروني:
954
+ - أ) الظهور الإلكتروني
955
+ - ب) تكامل الخدمة
956
+ - ج) النشر
957
+ - د) التفاعل
958
+
959
+ ---
960
+
961
+ **س42:** ينتقل مع البرامج التطبيقية مثل Microsoft Word و Microsoft Excel ويعمل بشكل تلقائي عند تشغيل هذا التطبيق هو فيروس:
962
+ - أ) الدودة
963
+ - ب) الماكرو
964
+ - ج) بدء التشغيل
965
+ - د) حصان طروادة
966
+
967
+ ---
968
+
969
+ **س43:** ليست من طرق تنفيذ التطبيق في البيسك المرئي:
970
+ - أ) الضغط على مفتاح F3 من لوحة المفاتيح
971
+ - ب) النقر على الأمر Start من قائمة Run
972
+ - ج) النقر على زر Start الموجود في شريط الأدوات
973
+ - د) الضغط على مفتاح F5 من لوحة المفاتيح
974
+
975
+ ---
976
+
977
+ **س44:** برمجيات يمكن استغلالها كما هي أو تعديلها وتطويرها لتعمل بصورة مغايرة لنسختها الأصلية هي برمجيات:
978
+ - أ) تجريبية
979
+ - ب) مجانية
980
+ - ج) تجارية
981
+ - د) مفتوحة المصدر
982
+
983
+ ---
984
+
985
+ **س45:** أداة تستخدم لإدخال البيانات الرقمية أو الحرفية في وقت التصميم أو في وقت التشغيل:
986
+ - أ) صندوق النص
987
+ - ب) صندوق قائمة الملفات
988
+ - ج) صندوق القائمة
989
+ - د) العنوان
990
+
991
+ ---
992
+
993
+ **س46:** مرحلة تسمى بمرحلة التواصل ذي الاتجاه الواحد، حيث يمكن للمواطنين الحصول على المعلومات دون إمكانية إرسال أي معلومة من قبل المواطن:
994
+ - أ) التطور الحكومي
995
+ - ب) التفاعل وتبادل البيانات
996
+ - ج) النشر الإلكتروني
997
+ - د) تكامل الخدمة وإنجاز المعاملات
998
+
999
+ ---
1000
+
1001
+ **س47:** عملية تحديد المكونات الرئيسية الواجب استخدامها لحل المشكلة هي مرحلة:
1002
+ - أ) المراجعة والتصحيح
1003
+ - ب) كتابة الخوارزمية
1004
+ - ج) تعريف المشكلة
1005
+ - د) تحديد الأدوات المطلوبة
1006
+
1007
+ ---
1008
+
1009
+ **س48:** هي متغيرات لأداة معينة تأخذ قيماً معينة في أثناء تصميم البرنامج أو أثناء تشغيل البرنامج:
1010
+ - أ) الأحداث
1011
+ - ب) الخاصية
1012
+ - ج) الطريقة
1013
+ - د) المشكلة
1014
+
1015
+ ---
1016
+
1017
+ **س49:** نافذة تعرض قائمة بجميع مكونات المشروع من نماذج (Forms) ووحدات برمجية (Modules) وملفات (Files):
1018
+ - أ) النموذج Form
1019
+ - ب) مستكشف المشروع Project Explorer
1020
+ - ج) شكل النموذج Form Layout Window
1021
+ - د) الخصائص Properties Window
1022
+
1023
+ ---
1024
+
1025
+ **س50:** القيمة التي سيتم تخصيصها للمتغير (C) بعد تنفيذ الجملة التالية هي:
1026
+ `C = Day(#25/5/2025#)`
1027
+ - أ) 2025
1028
+ - ب) 25 5 2025
1029
+ - ج) 5
1030
+ - د) 25
1031
+
1032
+ ---
1033
+
1034
+ **س51:** حصول شركات التأمين على البيانات الصحية للمرضى دون إذن أصحابها:
1035
+ - أ) يعد أمراً قانونياً ويخدم المصلحة العامة
1036
+ - ب) يفقد المرضى فرص الحصول على تأمين صحي
1037
+ - ج) يساهم في كشف مسائل تهدد أمن المواطنين أو البلد
1038
+ - د) جميع الإجابات السابقة خاطئة
1039
+
1040
+ ---
1041
+
1042
+ **س52:** لمحو المسافات من بداية النص نستخدم الدالة الجاهزة:
1043
+ - أ) Len(s)
1044
+ - ب) Trim(s)
1045
+ - ج) LTrim(s)
1046
+ - د) RTrim(s)
1047
+
1048
+ ---
1049
+
1050
+ **س53:** ينتهي الإجراء الفرعي بالجملة:
1051
+ - أ) End
1052
+ - ب) End Function
1053
+ - ج) End Sub
1054
+ - د) End If
1055
+
1056
+ ---
1057
+
1058
+ **س54:** تحدد هذه الخاصية لون النص المكتوب:
1059
+ - أ) BackColor
1060
+ - ب) Visible
1061
+ - ج) ForeColor
1062
+ - د) Font
1063
+
1064
+ ---
1065
+
1066
+ **س55:** لتحويل المتغير النصي إلى صيغة رقمية نستخدم الدالة:
1067
+ - أ) Val(string)
1068
+ - ب) Str(string)
1069
+ - ج) Chr( )
1070
+ - د) Mid(string)
1071
+
1072
+ ---
1073
+
1074
+ **س56:** تسمح هذه الأداة للمستخدم باختيار قيمة من عدة قيم مثل الألوان أو القيم العددية بشكل عمودي:
1075
+ - أ) Horizontal Scroll Bar
1076
+ - ب) File List Box
1077
+ - ج) Drive List Box
1078
+ - د) Vertical Scroll Bar
1079
+
1080
+ ---
1081
+ ***** انتهت الأسئلة *****
1082
+
FINAL/literary_studies_2007/conversion_log.txt ADDED
@@ -0,0 +1,24 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ [2026-04-01 15:34:06] [INFO] ============================================================
2
+ [2026-04-01 15:34:06] [INFO] Starting PDF to Image Conversion
3
+ [2026-04-01 15:34:06] [INFO] ============================================================
4
+ [2026-04-01 15:34:06] [SUCCESS] Poppler found: C:\Program Files\poppler-25.12.0\Library\bin\pdfinfo.exe
5
+ [2026-04-01 15:34:06] [SUCCESS] PDF validated: literary_studies_2007.pdf (1,606,903 bytes)
6
+ [2026-04-01 15:34:06] [SUCCESS] Output folder created: FINAL\literary_studies_2007_20260401_153406
7
+ [2026-04-01 15:34:06] [INFO] Converting PDF with DPI=300, Format=PNG
8
+ [2026-04-01 15:34:06] [INFO] Please wait...
9
+ [2026-04-01 15:34:25] [SUCCESS] PDF loaded successfully: 8 page(s) found
10
+ [2026-04-01 15:34:25] [PROGRESS] Saved [1/8] (12.5%): page_0001.png
11
+ [2026-04-01 15:34:26] [PROGRESS] Saved [2/8] (25.0%): page_0002.png
12
+ [2026-04-01 15:34:26] [PROGRESS] Saved [3/8] (37.5%): page_0003.png
13
+ [2026-04-01 15:34:27] [PROGRESS] Saved [4/8] (50.0%): page_0004.png
14
+ [2026-04-01 15:34:27] [PROGRESS] Saved [5/8] (62.5%): page_0005.png
15
+ [2026-04-01 15:34:27] [PROGRESS] Saved [6/8] (75.0%): page_0006.png
16
+ [2026-04-01 15:34:28] [PROGRESS] Saved [7/8] (87.5%): page_0007.png
17
+ [2026-04-01 15:34:28] [PROGRESS] Saved [8/8] (100.0%): page_0008.png
18
+ [2026-04-01 15:34:28] [INFO] ============================================================
19
+ [2026-04-01 15:34:28] [SUCCESS] Conversion completed successfully!
20
+ [2026-04-01 15:34:28] [INFO] Total pages converted: 8
21
+ [2026-04-01 15:34:28] [INFO] Output location: FINAL\literary_studies_2007_20260401_153406
22
+ [2026-04-01 15:34:28] [INFO] Image format: PNG
23
+ [2026-04-01 15:34:28] [INFO] Resolution: 300 DPI
24
+ [2026-04-01 15:34:28] [INFO] ============================================================
FINAL/literary_studies_2007/page_0001.png ADDED

Git LFS Details

  • SHA256: 8c421780246b42b056044d9f6e449ca49ae53370c3ba36bd1bc41cc1a2ee9863
  • Pointer size: 132 Bytes
  • Size of remote file: 2.2 MB
FINAL/literary_studies_2007/page_0002.png ADDED

Git LFS Details

  • SHA256: da046da00e7ec273bab46083b2750cb6f3a89548eb412a93eee1a185afdac4eb
  • Pointer size: 132 Bytes
  • Size of remote file: 1.2 MB
FINAL/literary_studies_2007/page_0003.png ADDED

Git LFS Details

  • SHA256: 742e10f7942f7c0ecc91866447350f5b574d92341c566a1b141e47bf90efd8f9
  • Pointer size: 132 Bytes
  • Size of remote file: 1.7 MB
FINAL/literary_studies_2007/page_0004.png ADDED

Git LFS Details

  • SHA256: 0c1b1af2889a3a00bf622e4a505559576215c155ccd43db61dfc7f5930d7cdaa
  • Pointer size: 132 Bytes
  • Size of remote file: 1.19 MB
FINAL/literary_studies_2007/page_0005.png ADDED

Git LFS Details

  • SHA256: 408460f09c81ad72e1202ee8d758addeed6b775b08886e67e778c588920ce0ae
  • Pointer size: 132 Bytes
  • Size of remote file: 1.12 MB
FINAL/literary_studies_2007/page_0006.png ADDED

Git LFS Details

  • SHA256: d2a3500f2bcb21b010e460bd0878ff32026064697c500fa8391142f7dbc5dae6
  • Pointer size: 132 Bytes
  • Size of remote file: 1.13 MB
FINAL/literary_studies_2007/page_0007.png ADDED

Git LFS Details

  • SHA256: b4512d4d1566705f7639d6b38a9bc2bfcaec4badc16fdf34daaf2bded97add85
  • Pointer size: 132 Bytes
  • Size of remote file: 1.01 MB
FINAL/literary_studies_2007/page_0008.png ADDED

Git LFS Details

  • SHA256: 5e2dfc92b00fc6d134e4b0aff731dcc61d012077502d3df5097563e24b048334
  • Pointer size: 131 Bytes
  • Size of remote file: 575 kB
FINAL/physics_mechanic.txt ADDED
@@ -0,0 +1,1631 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # أسئلة امتحان الفيزياء (الميكانيكا)
2
+ ## الدور الأول - العام الدراسي 2022-2023
3
+
4
+ ---
5
+
6
+ > **ملاحظة:** اعتبر عجلة الجاذبية الأرضية g = 10 m/s²
7
+
8
+ ---
9
+
10
+ ## أولاً: أسئلة الصواب والخطأ
11
+
12
+ ---
13
+
14
+ **س (1)** معامل الاحتكاك هو النسبة بين قوة الاحتكاك وقوة الاتصال العمودية
15
+
16
+ - (أ) صح
17
+ - (ب) خطأ
18
+
19
+ ---
20
+
21
+ **س (2)** عجلة صعود الجسم على السطح المائل الأملس تساوي عجلة هبوطه
22
+
23
+ - (أ) صح
24
+ - (ب) خطأ
25
+
26
+ ---
27
+
28
+ **س (3)** قوة الجاذبية الأرضية تجعل القمر يتحرك في خط مستقيم
29
+
30
+ - (أ) صح
31
+ - (ب) خطأ
32
+
33
+ ---
34
+
35
+ **س (4)** عند قذف جسم إلى أسفل فإن سرعته الابتدائية لا تساوي صفر
36
+
37
+ - (أ) صح
38
+ - (ب) خطأ
39
+
40
+ ---
41
+
42
+ **س (5)** تتساوى طاقة الحركة مع طاقة الوضع عندما يقذف جسم رأسياً لأعلى عند أي نقطة
43
+
44
+ - (أ) صح
45
+ - (ب) خطأ
46
+
47
+ ---
48
+
49
+ **س (6)** وحدة قياس القدرة هي J s⁻¹
50
+
51
+ - (أ) صح
52
+ - (ب) خطأ
53
+
54
+ ---
55
+
56
+ **س (7)** قوة الاحتكاك دائماً مع اتجاه الحركة
57
+
58
+ - (أ) صح
59
+ - (ب) خطأ
60
+
61
+ ---
62
+
63
+ **س (8)** إذا قذف جسم على سطح أفقي خشن فإن مقدار العجلة التقصيرية يساوي μg
64
+
65
+ - (أ) صح
66
+ - (ب) خطأ
67
+
68
+ ---
69
+
70
+ **س (9)** الفرق بين الشغل المبذول بواسطة قوة المقاومة والشغل المبذول بواسطة القوة المؤثرة يساوي معدل التغير في طاقة الحركة
71
+
72
+ - (أ) صح
73
+ - (ب) خطأ
74
+
75
+ ---
76
+
77
+ **س (10)** حد الاحتكاك يتناسب طردياً مع قوة الاتصال العمودية فكلما زادت قوة الاتصال العمودية زادت قوة الاحتكاك
78
+
79
+ - (أ) صح
80
+ - (ب) خطأ
81
+
82
+ ---
83
+
84
+ **س (11)** عند وضع جسم على مستوى مائل على الأفقي بزاوية (θ) فإن الزاوية المحصورة بين خط عمل قوة الوزن (mg) وخط عمل مركبة الوزن الموازية للمستوى تساوي الزاوية (θ)
85
+
86
+ - (أ) صح
87
+ - (ب) خطأ
88
+
89
+ ---
90
+
91
+ **س (12)** لكل فعل رد فعل مساوٍ له في المقدار ومضاد له في الاتجاه يسمى القانون الثالث لنيوتن
92
+
93
+ - (أ) صح
94
+ - (ب) خطأ
95
+
96
+ ---
97
+
98
+ ## ثانياً: أسئلة الاختيار من متعدد
99
+
100
+ ---
101
+
102
+ **س (13)** إذا كان الشد في خيط متساوياً فإن:
103
+
104
+ - (أ) نقطة التلامس بين الخيط والبكرة ملساء
105
+ - (ب) الكتل المعلقة في الخيط متساوية
106
+ - (ج) الكتل المعلقة في الخيط مختلفة
107
+ - (د) نقطة التلامس بين الخيط والبكرة خشنة
108
+
109
+ ---
110
+
111
+ **س (14)** عندما يقذف جسم إلى أقصى ارتفاع عن سطح الأرض تنعدم السرعة وتكون الطاقة الحركية تساوي صفر وتكون طاقة الوضع:
112
+
113
+ - (أ) مساوية للصفر
114
+ - (ب) أصغر ما يمكن
115
+ - (ج) أكبر ما يمكن
116
+ - (د) متضاعفة
117
+
118
+ ---
119
+
120
+ **س (15)** شاحنة كتلتها (40 Kg) تجر شاحنة كتلتها (20 Kg) بواسطة كابل بقوة قدرها (120 N) فإن العجلة المشتركة لهما تساوي:
121
+
122
+ - (أ) 2 m/s²
123
+ - (ب) 3 m/s²
124
+ - (ج) 4 m/s²
125
+ - (د) 1.5 m/s²
126
+
127
+ ---
128
+
129
+ **س (16)** معدل الشغل المبذول أو الطاقة المحولة هي:
130
+
131
+ - (أ) السرعة
132
+ - (ب) الوزن
133
+ - (ج) القدرة
134
+ - (د) الإزاحة
135
+
136
+ ---
137
+
138
+ **س (17)** في الشكل التالي المنظومة تتحرك بعجلة (1.3 m/s²) وكانت الكتلة (6 Kg) على سطح خشن بينما الأخرى على سطح أملس فإن معامل الاحتكاك يساوي:
139
+
140
+ *(الشكل: كتلتان 6 Kg و 7 Kg على مستويين مائلين بزاويتي 30° و 60° متصلتان بحبل يمر على بكرة)*
141
+
142
+ - (أ) 0.2
143
+ - (ب) 0.3
144
+ - (ج) 0.4
145
+ - (د) 0.5
146
+
147
+ ---
148
+
149
+ **س (18)** يتسلق رجل كتلته (70 Kg) جبلاً إلى ارتفاع (3 Km)، تكون طاقة وضعه:
150
+
151
+ - (أ) 2.10 × 10⁵ J
152
+ - (ب) 2.10 × 10⁶ J
153
+ - (ج) 2.10 × 10⁴ J
154
+ - (د) 2.10 × 10³ J
155
+
156
+ ---
157
+
158
+ **س (19)** في الشكل التالي: إذا تحركت المجموعة بعجلة مقدارها (2 m/s²) وكانت قوة الاحتكاك للسطح (18 N) والسلك غير مرن فإن الكتلة (m) تساوي:
159
+
160
+ *(الشكل: كتلة m على مستوى مائل 30° متصلة بكتلة معلقة 4 Kg)*
161
+
162
+ - (أ) 2 Kg
163
+ - (ب) 0.5 Kg
164
+ - (ج) 4 Kg
165
+ - (د) 3 Kg
166
+
167
+ ---
168
+
169
+ **س (20)** إذا انزلق طفل على سطح خشن مائل على العمودي بزاوية (θ) فإن عجلة انزلاقه تساوي:
170
+
171
+ - (أ) g(cos θ − μ sin θ)
172
+ - (ب) g(sin θ − μ cos θ)
173
+ - (ج) g(sin θ + μ cos θ)
174
+ - (د) g(cos θ + μ sin θ)
175
+
176
+ ---
177
+
178
+ **س (21)** آلة قدرتها (100 W) فإن الشغل الذي تبذله هذه الآلة في زمن قدره (5 min) هو:
179
+
180
+ - (أ) 25000 J
181
+ - (ب) 30000 J
182
+ - (ج) 1500 J
183
+ - (د) 4200 J
184
+
185
+ ---
186
+
187
+ **س (22)** سيارة كتلتها (m) تنزلق من السكون على منحدر ارتفاعه (h) يميل بزاوية (θ) مع الأفقي، فإن الزمن المستغرق لتصل السيارة أسفل المنحدر:
188
+
189
+ - (أ) √(2h / g sin²θ)
190
+ - (ب) 2h / g sin²θ
191
+ - (ج) g sin²θ / 2h
192
+ - (د) h / g sin²θ
193
+
194
+ ---
195
+
196
+ **س (23)** يتحرك دراج بسرعة (6 m/s) وعندما استعمل المكابح فتوقف بعد أن قطع مسافة قدرها (4 m)، فإذا كانت كتلة الدراج والدراجة (80 Kg) فإن معامل الاحتكاك يساوي:
197
+
198
+ - (أ) 4.5
199
+ - (ب) 0.45
200
+ - (ج) 0.54
201
+ - (د) 5.4
202
+
203
+ ---
204
+
205
+ **س (24)** يتسارع جسم بمقدار (1.5 m/s²) على سطح أفقي خشن بفعل قوة أفقية مقدارها (40 N)، وكان معامل الاحتكاك بين الجسم والسطح (0.25)، فإن مقدار الكتلة يساوي:
206
+
207
+ - (أ) 20 Kg
208
+ - (ب) 10 Kg
209
+ - (ج) 40 Kg
210
+ - (د) 30 Kg
211
+
212
+ ---
213
+
214
+ **س (25)** من الشكل التالي تكون العجلة:
215
+
216
+ *(الشكل: كتلة m₁ على سطح مائل بزاوية θ متصلة عبر بكرة بكتلة m₂ على سطح أفقي)*
217
+
218
+ - (أ) a = (m₁ − m₂) / m₁g sinθ
219
+ - (ب) a = m₁g sinθ / (m₁ + m₂)
220
+ - (ج) a = (m₁ + m₂) / m₁g sinθ
221
+ - (د) a = m₁g sinθ / (m₁ − m₂)
222
+
223
+ ---
224
+
225
+ **س (26)** تدفع رافعة صندوقاً وزنه (800 N) لأعلى مستوى يميل بزاوية مقدارها (θ) مع الأفقي بسرعة ثابتة قدرها (4 m/s) وكانت قدرة الرافعة (720 W) فإن زاوية ميل المستوى:
226
+
227
+ - (أ) 15°
228
+ - (ب) 14°
229
+ - (ج) 16°
230
+ - (د) 13°
231
+
232
+ ---
233
+
234
+ **س (27)** عند استخدام كابل للتوصيل بين شاحنتين فإن طول الكابل أثناء حركة الشاحنتين:
235
+
236
+ - (أ) يقل
237
+ - (ب) يتضاعف
238
+ - (ج) يبقى ثابتاً
239
+ - (د) يزداد
240
+
241
+ ---
242
+
243
+ **س (28)** جسم كتلته (20 Kg) على مستوى يميل بزاوية قدرها (35°) مع الأفقي فإن قوة الاحتكاك التي تجعل الجسم مستقراً تساوي:
244
+
245
+ - (أ) 116.7 N
246
+ - (ب) 115.7 N
247
+ - (ج) 114.7 N
248
+ - (د) 113.7 N
249
+
250
+ ---
251
+
252
+ **س (29)** في الشكل التالي جسم متزن تحت تأثير ثلاثة قوى فإن (F , T) على التوالي هما:
253
+
254
+ *(الشكل: قوة 4 N أفقية، قوة F رأسية لأسفل، قوة T مائلة تصنع زاوية 60° مع الرأسي)*
255
+
256
+ - (أ) (1.25 N , 2.5 N)
257
+ - (ب) (2.31 N , 4.62 N)
258
+ - (ج) (1.155 N , 2.31 N)
259
+ - (د) (4.62 N , 9.24 N)
260
+
261
+ ---
262
+
263
+ **س (30)** إذا كانت القوة المؤثرة على جسم تميل بزاوية (θ) مع اتجاه الحركة فإن الشغل المبذول يساوي:
264
+
265
+ - (أ) F.S
266
+ - (ب) F tan(θ).S
267
+ - (ج) F sin(θ).S
268
+ - (د) F cos(θ).S
269
+
270
+ ---
271
+
272
+ **س (31)** سحب جسم كتلته (4 Kg) على سطح أفقي بواسطة حبل يصنع زاوية (30°) مع الأفقي وكان الشد في الحبل (25 N) وتحرك الجسم بعجلة مقدارها (2 m/s²) فإن معامل الاحتكاك بين الجسم والسطح يساوي:
273
+
274
+ - (أ) 9.04
275
+ - (ب) 0.50
276
+ - (ج) 4.9
277
+ - (د) 4.09
278
+
279
+ ---
280
+
281
+ **س (32)** قذفت كرة رأسياً إلى أعلى بسرعة (20 m/s) فعادت إلى نقطة القذف بعد (4 s) فإن أقصى ارتفاع تصل إليه الكرة هو:
282
+
283
+ - (أ) 30 m
284
+ - (ب) 20 m
285
+ - (ج) 25 m
286
+ - (د) 15 m
287
+
288
+ ---
289
+
290
+ **س (33)** يزداد حد الاحتكاك بزيادة:
291
+
292
+ - (أ) كتلة الجسم
293
+ - (ب) وزن الجسم
294
+ - (ج) قوة الاتصال العمودية
295
+ - (د) جميع الإجابات السابقة صحيحة
296
+
297
+ ---
298
+
299
+
300
+ **س (34)** أي من الآتي ليس لها وحدة قياس:**
301
+
302
+ - (أ) العجلة
303
+ - (ب) القوة
304
+ - (ج) الإزاحة
305
+ - (د) معامل الاحتكاك
306
+
307
+ ---
308
+
309
+ **س (35)** وضع قفص كتلته (5 Kg) فوق قفص آخر كتلته (10 Kg) فوق سطح الأرض، فإن مقدار واتجاه القوة المبذولة من الأرض على القفص السفلي هي:
310
+
311
+ - (أ) 150 N إلى أعلى
312
+ - (ب) 100 N إلى أعلى
313
+ - (ج) 100 N إلى أسفل
314
+ - (د) 150 N إلى أسفل
315
+
316
+ ---
317
+
318
+ **س (36)** إذا اتزن الجسم تحت تأثير القوى الثلاثة الموضحة بالشكل، فإن الزاوية (θ°) تساوي:
319
+
320
+ *(الشكل: قوة 20 N، قوة 10 N، قوة 17.33 N)*
321
+
322
+ - (أ) 60°
323
+ - (ب) 30°
324
+ - (ج) 50°
325
+ - (د) 45°
326
+
327
+ ---
328
+
329
+ **س (37)** يتحرك الجسم المقذوف رأسياً إلى أعلى بسرعة:
330
+
331
+ - (أ) تناقصية
332
+ - (ب) كبيرة
333
+ - (ج) تزايدية
334
+ - (د) ثابتة
335
+
336
+ ---
337
+
338
+ **س (38)** قوة تنشأ عند تلامس سطحين، وهي دائماً عمودية على السطح هي قوة:
339
+
340
+ - (أ) المقاومة
341
+ - (ب) الاتصال العمودية
342
+ - (ج) الجاذبية الأرضية
343
+ - (د) الاحتكاك
344
+
345
+ ---
346
+
347
+ **س (39)** جسم كتلته (6 tonnes) وطاقة حركته (300 kJ) فإن السرعة التي يتحرك بها الجسم مقدارها:
348
+
349
+ - (أ) 300 m/s
350
+ - (ب) 10 m/s
351
+ - (ج) 50 m/s
352
+ - (د) 100 m/s
353
+
354
+ ---
355
+
356
+ **س (40)** يستقر صندوق كتلته (2 Kg) على مستوى مائل بزاوية (70°) مع الرأسي بواسطة قوة أفقية مقدارها (20 N) فإن قوة الاحتكاك:
357
+
358
+ - (أ) 58.93 N
359
+ - (ب) 72.62 N
360
+ - (ج) 25.63 N
361
+ - (د) 11.95 N
362
+
363
+ ---
364
+
365
+ **س (41)** علقت كرة معدنية وزنها (6 N) في نقطة ثابتة بواسطة خيط ثم سحبت أفقياً بقوة (F) واتزنت بعد أن صنع الخيط زاوية (30°) مع الرأسي فإن قوة الشد في الخيط:
366
+
367
+ - (أ) 8 N
368
+ - (ب) 7 N
369
+ - (ج) 5 N
370
+ - (د) 6 N
371
+
372
+ ---
373
+
374
+ **س (42)** جسم كتلته (3 Kg) ينزلق على مستوى مائل بزاوية (30°) مع الأفقي ومعامل الاحتكاك بين الجسم والسطح (0.2) فإذا كانت عجلة الجاذبية الأرضية هي (g) فإن العجلة التي يتحرك بها الجسم تساوي:
375
+
376
+ - (أ) 0.33g m/s²
377
+ - (ب) 0.67g m/s²
378
+ - (ج) 0.2g m/s²
379
+ - (د) 0.5g m/s²
380
+
381
+ ---
382
+
383
+ **س (43)** الوحدة التي تعادل وحدة قياس طاقة الحركة هي:
384
+
385
+ - (أ) Kg m² . s⁻²
386
+ - (ب) Kg m . s⁻²
387
+ - (ج) Kg m³ / s²
388
+ - (د) Kg m² . s⁻³
389
+
390
+ ---
391
+
392
+ **س (44)** إذا كان رد فعل الأرض عند وضع صندوقين متماثلين عليها هو (10 N) فإن كتلة كل صندوق تساوي:
393
+
394
+ - (أ) 500 Kg
395
+ - (ب) 1 g
396
+ - (ج) 1 Kg
397
+ - (د) 500 g
398
+
399
+ ---
400
+
401
+ **س (45)** تدفع رافعة قدرتها (2 KW) صندوقاً وزنه (10³ N) على مستوى مائل بسرعة منتظمة مقدارها (4 m/s) فإن زاوية ميل المستوى مع الأفقي هي:
402
+
403
+ - (أ) 30°
404
+ - (ب) 25°
405
+ - (ج) 60°
406
+ - (د) 45°
407
+
408
+ ---
409
+
410
+ **س (46)** قذفت كرة رأسياً إلى أعلى بسرعة (15 m/s) فإن أقصى ارتفاع تصل إليه هو:
411
+
412
+ - (أ) 10 m
413
+ - (ب) 1.125 m
414
+ - (ج) 11.25 m
415
+ - (د) 20 m
416
+
417
+ ---
418
+
419
+ **س (47)** يعتمد حد الاحتكاك على العوامل التالية ما عدا:
420
+
421
+ - (أ) قوة الاتصال العمودية
422
+ - (ب) شكل ومساحة المناطق المتلامسة
423
+ - (ج) نوع المواد التي تتلامس أسطحها
424
+ - (د) سرعة الجسم
425
+
426
+ ---
427
+
428
+ **س (48)** من الشكل التالي:
429
+
430
+ *(الشكل: كتلة 4 Kg أفقية بين بكرتين، كتلة 8 Kg معلقة يساراً، كتلة 2 Kg معلقة يميناً)*
431
+
432
+ العجلة التي تتحرك بها المجموعة هي:
433
+
434
+ - (أ) 0.23 m/s²
435
+ - (ب) 4.3 m/s²
436
+ - (ج) 0.43 m/s²
437
+ - (د) 3.4 m/s²
438
+
439
+ ---
440
+
441
+ **س (49)** قذف حجر بسرعة (20 m/s) على مستوى خشن مائل على الأفقي بزاوية (θ) ومعامل الاحتكاك له (0.15) فإن مقدار العجلة التقصيرية التي يتحرك بها هي:
442
+
443
+ - (أ) 7.2 m/s²
444
+ - (ب) 1.2 m/s²
445
+ - (ج) 6 m/s²
446
+ - (د) 13 m/s²
447
+
448
+ ---
449
+
450
+ **س (50)** تنزلق قطعة خشبية كتلتها (8 Kg) من السكون على مستوى يميل بزاوية (30°) مع الأفقي فإن سرعتها بعد أن تقطع مسافة قدرها (6 m):
451
+
452
+ - (أ) 7.47 m/s
453
+ - (ب) 77.4 m/s
454
+ - (ج) 7.75 m/s
455
+ - (د) 4.77 m/s
456
+
457
+ ---
458
+
459
+ **س (51)** كرة بندول بسيط كتلتها (m Kg) فإذا كان طول خيط البندول (10 m) وجذبت الكرة جانبياً حتى صنع الخيط زاوية (30°) مع الأفقي ثم أطلقت، فإن سرعة البندول عندما يكون الخيط عمودياً هي:
460
+
461
+ - (أ) 26.7 m/s
462
+ - (ب) 10 m/s
463
+ - (ج) 5.2 m/s
464
+ - (د) 100 m/s
465
+
466
+ ---
467
+
468
+ **س (52)** إذا كانت قدرة آلة (200 W) فإن هذه الآلة تبذل شغلاً في (10 min) قدره:
469
+
470
+ - (أ) 120 KJ
471
+ - (ب) 40×10³ KJ
472
+ - (ج) 150 KJ
473
+ - (د) 16×10³ KJ
474
+
475
+ ---
476
+
477
+ **س (53)** الطاقة التي يكتسبها الجسم نتيجة ارتفاعه عن سطح الأرض هي:
478
+
479
+ - (أ) طاقة الحركة
480
+ - (ب) القوة
481
+ - (ج) القدرة
482
+ - (د) طاقة الوضع
483
+
484
+ ---
485
+
486
+ **س (54)** إذا تضاعفت سرعة الجسم فإن طاقة حركته:
487
+
488
+ - (أ) تقل أربع أضعاف
489
+ - (ب) تزداد إلى النصف
490
+ - (ج) تقل إلى النصف
491
+ - (د) تزداد أربع أضعاف
492
+
493
+ ---
494
+
495
+ **س (55)** سقطت كرة في بئر ووصلت إلى قاع البئر وكانت سرعتها النهائية (20 m/s) فإن عمق البئر:
496
+
497
+ - (أ) 40 m
498
+ - (ب) 30 m
499
+ - (ج) 25 m
500
+ - (د) 20 m
501
+
502
+ ---
503
+
504
+ **س (56)** ربط جسمان كتلتهما (2 Kg) و (4 Kg) بخيط خفيف يمر على بكرة خفيفة، فإن الشد في الخيط:
505
+
506
+ - (أ) 266.6 N
507
+ - (ب) 26.66 N
508
+ - (ج) 2.65 N
509
+ - (د) 2.666 N
510
+
511
+ ---
512
+
513
+ **س (57)** يعتمد وزن الجسم على:
514
+
515
+ - (أ) قوة الاتصال العمودية
516
+ - (ب) قوة الشد
517
+ - (ج) كتلة الجسم
518
+ - (د) الإجابتان (أ) و (ج) صحيحتان
519
+
520
+ ---
521
+
522
+ **س (58)** تغيرت سرعة سيارة كتلتها (500 Kg) من (3 m/s) إلى (9 m/s) بعجلة ثابتة وكانت المسافة المقطوعة خلال هذه الفترة (100 m)، تكون قوة المحرك:
523
+
524
+ - (أ) 300 N
525
+ - (ب) 36 N
526
+ - (ج) 180 N
527
+ - (د) 18 N
528
+
529
+ ---
530
+
531
+ **س (59)** قذفت كرة رأسياً إلى أسفل من ارتفاع (40 m) فوق سطح الأرض فوصلت الأرض بعد زمن قدره (25 s) فإن سرعتها لحظة الاصطدام بالأرض:
532
+
533
+ - (أ) 30 m/s
534
+ - (ب) 10 m/s
535
+ - (ج) 40 m/s
536
+ - (د) 20 m/s
537
+
538
+ ---
539
+
540
+ **س (60)** إذا سقطت كرة من ارتفاع (h) فوق سطح الأرض فإن سرعة الكرة لحظة اصطدامها بالأرض تساوي:
541
+
542
+ - (أ) gh
543
+ - (ب) 2gh
544
+ - (ج) ½ gh
545
+ - (د) √2gh
546
+
547
+ ---
548
+
549
+ > **✦✦✦ انتهت الأسئلة ✦✦✦**
550
+
551
+ # أسئلة امتحان الفيزياء (الميكانيكا)
552
+ ## الدور الأول - العام الدراسي 2023-2024
553
+
554
+ ---
555
+
556
+ > **ملاحظة:** اعتبر عجلة الجاذبية الأرضية g = 10 m/s²
557
+
558
+ ---
559
+
560
+ ## أولاً: أسئلة الصواب والخطأ
561
+
562
+ ---
563
+
564
+ **س (1)** دلت التجارب العملية على أن شكل ومساحة الأسطح المتلامسة تغير تغيراً كبيراً في قيمة النهاية القصوى لقوة الاحتكاك
565
+
566
+ - (أ) صح
567
+ - (ب) خطأ
568
+
569
+ ---
570
+
571
+ **س (2)** إذا حدثت الحركة بسرعة ثابتة أو بعجلة منتظمة، فإن قوة الاحتكاك تكون في نهاية قيمتها وتؤثر في اتجاه عكس الحركة
572
+
573
+ - (أ) صح
574
+ - (ب) خطأ
575
+
576
+ ---
577
+
578
+ **س (3)** عندما تميل قوة بزاوية ما مع اتجاه معين، فإن المركبة الأفقية للقوة تزداد في هذا الاتجاه بزيادة الزاوية
579
+
580
+ - (أ) صح
581
+ - (ب) خطأ
582
+
583
+ ---
584
+
585
+ **س (4)** الأجسام التي يمكن لها أن تبذل عند طرفيها على الأجسام المتصلة بها قوة اتجاهها إلى الخارج هي السلاسل
586
+
587
+ - (أ) صح
588
+ - (ب) خطأ
589
+
590
+ ---
591
+
592
+ **س (5)** لا تعتمد كل من قوة الاحتكاك ومقاومة الهواء على سرعة الجسم
593
+
594
+ - (أ) صح
595
+ - (ب) خطأ
596
+
597
+ ---
598
+
599
+ **س (6)** إذا أثرت قوة مائلة على جسم ولم تحركه، فإن مقدار قوة الاحتكاك تكون مساوية لمقدار هذه القوة المؤثرة
600
+
601
+ - (أ) صح
602
+ - (ب) خطأ
603
+
604
+ ---
605
+
606
+ **س (7)** في السقوط الحر، فإن جميع الأجسام الكبيرة أو الصغيرة تزداد سرعتها بنفس المعدل
607
+
608
+ - (أ) صح
609
+ - (ب) خطأ
610
+
611
+ ---
612
+
613
+ **س (8)** الجسم المتزن على مستوى مائل مع الأفقي بفعل قوة أفقية مؤثرة عليه، هذه القوة الأفقية تميل مع المستوى بنفس زاوية ميل وزن الجسم مع المستوى
614
+
615
+ - (أ) صح
616
+ - (ب) خطأ
617
+
618
+ ---
619
+
620
+ **س (9)** حسب قانون نيوتن الثاني: إذا سقط حجر فإنه يجذب الأرض بقوة مساوية لقوة جذب الأرض له وفي الاتجاه المعاكس
621
+
622
+ - (أ) صح
623
+ - (ب) خطأ
624
+
625
+ ---
626
+
627
+ **س (10)** عندما يمر خيط حول بكرة تدور حول محور ثابت وكان السطح خشناً فإن البكرة تدور مع الخيط
628
+
629
+ - (أ) صح
630
+ - (ب) خطأ
631
+
632
+ ---
633
+
634
+ **س (11)** لا يبذل شغل عندما تكون الزاوية بين القوة المؤثرة على الجسم وإزاحتها تساوي صفراً
635
+
636
+ - (أ) صح
637
+ - (ب) خطأ
638
+
639
+ ---
640
+
641
+ **س (12)** إذا قذف جسم رأسياً لأعلى بسرعة ابتدائية (U) ثم عاد لنفس النقطة التي قذف منها، فإن الزمن المستغرق لذلك هو (u/5)
642
+
643
+ - (أ) صح
644
+ - (ب) خطأ
645
+
646
+ ---
647
+
648
+ ## ثانياً: أسئلة الاختيار من متعدد
649
+
650
+ ---
651
+
652
+ **س (13)** قذف حجر رأسياً لأعلى بسرعة (20 m/s) من نقطة أعلى من سطح الأرض بمقدار (15 m)، فإن الإزاحة الكلية التي يقطعها الحجر عندما يصل إلى سطح الأرض تساوي:
653
+
654
+ - (أ) 55 m
655
+ - (ب) 15 m
656
+ - (ج) صفراً
657
+ - (د) 35 m
658
+
659
+ ---
660
+
661
+ **س (14)** تستقر كتلة وزنها (20 N) على سطح أفقي، أثرت عليها قوة شد (12 N) في اتجاه يصنع زاوية (60°) مع الرأسي وكانت الكتلة على وشك الحركة، فإن النسبة بين حد الاحتكاك ومعامله تساوي:
662
+
663
+ - (أ) 26 N
664
+ - (ب) 20 N
665
+ - (ج) 10 N
666
+ - (د) 14 N
667
+
668
+ ---
669
+
670
+ **س (15)** يجر صندوق كتلته (12 kg) إلى أعلى منحدر يميل بزاوية (30°) مع الأفقي بسرعة ثابتة بفعل قوة مقدارها (60 N) تميل على الأفقي بزاوية (40°)، فإن قوة الاتصال العمودية المؤثرة على الصندوق تساوي:
671
+
672
+ - (أ) 142.5 N
673
+ - (ب) 59.7 N
674
+ - (ج) 120 N
675
+ - (د) 93.5 N
676
+
677
+ ---
678
+
679
+ **س (16)** في الشكل التالي:
680
+
681
+ *(الشكل: جسم كتلته m على مستوى مائل بزاوية 30° متصل عبر بكرة ملساء بجسم كتلته 1 Kg على سطح أفقي أملس، والخيط مشدود)*
682
+
683
+ البكرة ملساء والسطح أملس والخيط مشدود فإذا تحركت المجموعة بعجلة (4 m/s²)، فإن مقدار الكتلة (m) يساوي:
684
+
685
+ - (أ) 2 kg
686
+ - (ب) 4 kg
687
+ - (ج) 5 kg
688
+ - (د) 3 kg
689
+
690
+ ---
691
+
692
+ **س (17)** يقف رجل على ميزان مثبت على أرضية مصعد فإذا كان وزن الرجل (700 N) فإن قراءة الميزان:
693
+
694
+ - (أ) صفراً إذا انقطع حبل المصعد
695
+ - (ب) أكبر من (700 N) عندما يكون المصعد صاعداً بسرعة ثابتة
696
+ - (ج) أقل من (700 N) عندما يكون المصعد صاعداً بعجلة تزايدية
697
+ - (د) أكبر من (700 N) عندما يكون المصعد هابطاً بعجلة تزايدية
698
+
699
+ ---
700
+
701
+ **س (18)** في الشكل التالي:
702
+
703
+ *(الشكل: نقطة P تؤثر عليها ثلاث قوى: قوة أفقية إلى اليسار مقدارها 4 N، وقوة رأسية إلى أسفل مقدارها 8 N، وقوة شد مائلة T تصنع زاوية θ° مع الأفقي)*
704
+
705
+ ثلاث قوى تؤثر على جسم متزن (P) فإن مقدار الشد (T) يساوي:
706
+
707
+ - (أ) 9.85 N
708
+ - (ب) 4 N
709
+ - (ج) 8 N
710
+ - (د) 8.95 N
711
+
712
+ ---
713
+
714
+ **س (19)** عند أقصى ارتفاع تكون طاقة الوضع للجسم أكبر ما يمكن وتساوي:
715
+
716
+ - (أ) الطاقة الحركية عند أقصى ارتفاع
717
+ - (ب) الطاقة الحركية لحظة انطلاق الجسم من سطح الأرض
718
+ - (ج) طاقة الوضع لحظة انطلاق الجسم من سطح الأرض
719
+ - (د) الإجابتان (ب) و(ج) صحيحتان
720
+
721
+ ---
722
+
723
+ **س (20)** في الشكل التالي:
724
+
725
+ *(الشكل: جسم كتلته 6 Kg على مستوى مائل بزاوية 30° متصل بخيط يمر على بكرة ملساء، والطرف الآخر معلق به جسم كتلته 4 Kg)*
726
+
727
+ البكرة ملساء والخيط مشدود والسطح أملس فإن عجلة المجموعة والشد في الخيط هما على الترتيب:
728
+
729
+ - (أ) 2 m/s² ، 72 N
730
+ - (ب) 1 m/s² ، 36 N
731
+ - (ج) 7 m/s² ، 36 N
732
+ - (د) 7 m/s² ، 72 N
733
+
734
+ ---
735
+
736
+ **س (21)** وضع صندوق على عربة كتلتها (1 tonne)، وكان رد فعل العربة على الصندوق (200 N) فإن كتلة الصندوق تساوي:
737
+
738
+ - (أ) 120 kg
739
+ - (ب) 20 kg
740
+ - (ج) 10 kg
741
+ - (د) 12 kg
742
+
743
+ ---
744
+
745
+ **س (22)** ينحدر طفل على مستوى مائل طوله (40 m) ويصل أسفل المستوى بسرعة (15 m/s) فإن الزاوية التي يميل بها المستوى على الأفقي هي:
746
+
747
+ - (أ) 60°
748
+ - (ب) 16.33°
749
+ - (ج) 30°
750
+ - (د) 20.15°
751
+
752
+ ---
753
+
754
+ **س (23)** أثرت قوة (F) تميل مع المستوى الأفقي بزاوية (θ) على جسم يستقر على سطح أفقي، مما جعل قوة الاتصال العمودية أكبر من وزن الجسم (W) فإن مقدار هذه القوة المؤثرة هو:
755
+
756
+ - (أ) F = R + mg
757
+ - (ب) F = R
758
+ - (ج) F = (R − mg) / cos(90 − θ)
759
+ - (د) F = (R + mg) / sinθ
760
+
761
+ ---
762
+
763
+ **س (24)** قذف حجر إلى أسفل من ارتفاع (15 m) اصطدم بالأرض بعد (1.5 sec) فإن سرعة الحجر لحظة اصطدامه بالأرض تساوي:
764
+
765
+ - (أ) 20 m/s
766
+ - (ب) 10 m/s
767
+ - (ج) 15 m/s
768
+ - (د) 17.5 m/s
769
+
770
+ ---
771
+
772
+ **س (25)** سيارة كتلتها (1 tonne) تُدفع على سطح أفقي من السكون حتى تصل سرعتها إلى (4 m/s)، فإن مقدار الشغل المبذول يساوي:
773
+
774
+ - (أ) 8 kJ
775
+ - (ب) 6 kJ
776
+ - (ج) 4 kJ
777
+ - (د) 5 kJ
778
+
779
+ ---
780
+
781
+ **س (26)** في الشكل التالي:
782
+
783
+ *(الشكل: كتلة خشبية مضغوطة أفقياً بقوة 25 N على حائط رأسي)*
784
+
785
+ تستند كتلة خشبية على حائط بفعل قوة مقدارها (25 N) فإذا كان معامل الاحتكاك بين الكتلة والحائط (0.4)، فإن وزن الكتلة الخشبية هو:
786
+
787
+ - (أ) 25 N
788
+ - (ب) 20 N
789
+ - (ج) 40 N
790
+ - (د) 10 N
791
+
792
+ ---
793
+
794
+ **س (27)** حاول رجل دفع خزانة كت�� وزنها (1200 N) بقوة مقدارها (400 N) فإذا كان معامل الاحتكاك بين الخزانة وسطح الأرض (0.4) فإن مقدار قوة الاحتكاك تساوي:
795
+
796
+ - (أ) 1200 N
797
+ - (ب) 480 N
798
+ - (ج) 400 N
799
+ - (د) 3000 N
800
+
801
+ ---
802
+
803
+ **س (28)** عندما تصبح طاقة الوضع لجسم نصف طاقته الحركية، فإن سرعة الجسم تساوي:
804
+
805
+ - (أ) V = √(gh)
806
+ - (ب) V = gh
807
+ - (ج) V = 2√(gh)
808
+ - (د) V = √(½ gh)
809
+
810
+ ---
811
+
812
+ **س (29)** قذفت كرة إلى أعلى بسرعة قدرها (17 m/s)، فإن الزمن الذي تقضيه الكرة فوق الارتفاع (12 m) هو:
813
+
814
+ - (أ) 2.8 sec
815
+ - (ب) 0.7 sec
816
+ - (ج) 1.1 sec
817
+ - (د) 1.4 sec
818
+
819
+ ---
820
+
821
+ **س (30)** إذا بذل شغل قدره (200 J) على جسم لمدة (4 sec) بواسطة قوة فتحرك بسرعة منتظمة مقدارها (5 m/s) فإن مقدار القوة هو:
822
+
823
+ - (أ) 50 N
824
+ - (ب) 40 N
825
+ - (ج) 60 N
826
+ - (د) 10 N
827
+
828
+ ---
829
+
830
+ **س (31)** عندما يتكون جسم من جزئين كلا منهما يتحرك بسرعة وعجلة واحدة يمكن استخدام قانون ........... للجسم كاملاً أو لكل من الأجزاء المنفصلة:
831
+
832
+ - (أ) نيوتن الأول
833
+ - (ب) نيوتن الثاني
834
+ - (ج) الثالث
835
+ - (د) جميع الإجابات السابقة صحيحة
836
+
837
+ ---
838
+
839
+ **س (32)** بدأ مظلي كتلته (m kg) بالسقوط من طائرة وتعرض لمقاومة هواء بمقدار (m/40) V²، فإن مقدار سرعته النهائية تساوي:
840
+
841
+ - (أ) 10 m/s
842
+ - (ب) 40 m/s
843
+ - (ج) 20 m/s
844
+ - (د) 16 m/s
845
+
846
+ ---
847
+
848
+ **س (33)** إذا كانت طاقة الوضع لجسم على ارتفاع (2 m) هي (40 J) فعندما يتم تحريك الجسم أفقياً مسافة (6 m) بفعل قوة (50 N) فإن مقدار التغير في طاقة الوضع للجسم هو:
849
+
850
+ - (أ) 40 J
851
+ - (ب) صفر
852
+ - (ج) 90 J
853
+ - (د) 80 J
854
+
855
+ ---
856
+
857
+ **س (34)** دُفع جسم على سطح أفقي خشن بقوة P(N) وتسارع بعجلة a(m/s²) فإن معامل الاحتكاك (μ) هو:
858
+
859
+ - (أ) (1/g)(a + P/m)
860
+ - (ب) (P/g − a/m)
861
+ - (ج) (P/m − a/g)
862
+ - (د) (1/g)(P/m − a)
863
+
864
+ ---
865
+
866
+ **س (35)** في الشكل التالي:
867
+
868
+ *(الشكل: كتلة m₁ على سطح أفقي أملس متصلة بخيط يمر على بكرة ملساء بكتلة معلقة m₂، تُركت المجموعة تتحرك من السكون)*
869
+
870
+ البكرة ملساء والخيط مشدود والسطح أملس تُركت المجموعة تتحرك من السكون، فإن مقدار الشد في الخيط:
871
+
872
+ - (أ) (m₁ m₂ / m₁ + m₂) g
873
+ - (ب) (m₂ / m₁ + m₂) g
874
+ - (ج) (m₂) g
875
+ - (د) (m₁ m₂ / m₁ − m₂) g
876
+
877
+ ---
878
+
879
+ **س (36)** عند أقصى ارتفاع يصل إليه الجسم تنعدم كل من ما عدا:
880
+
881
+ - (أ) مقاومة الهواء
882
+ - (ب) عجلة الجسم
883
+ - (ج) سرعة الجسم
884
+ - (د) طاقة حركته
885
+
886
+ ---
887
+
888
+ **س (37)** سيارة كتلتها (1 tonne) تجر مقطورة كتلتها (250 kg) على طريق يميل بزاوية (sin⁻¹ 0.03) مع الأفقي وهناك مقاومة ثابتة للحركة على السيارة والمقطورة (100 N) و(50 N) على التوالي، وقيمة القوة الدافعة (900 N) وتتحرك السيارة إلى أعلى الهضبة، فإن الشد في ساق الجر يساوي:
889
+
890
+ - (أ) 200 N
891
+ - (ب) 170 N
892
+ - (ج) 900 N
893
+ - (د) 1000 N
894
+
895
+ ---
896
+
897
+ **س (38)** جسم كتلته (3 kg) ينزلق على مستوى مائل بزاوية (60°) مع الرأسي ومعامل الاحتكاك بين الجسم والسطح (0.2) فإن العجلة التي يتحرك بها هذا الجسم هي:
898
+
899
+ - (أ) 5 m/s²
900
+ - (ب) 6.7 m/s²
901
+ - (ج) 3.3 m/s²
902
+ - (د) 2 m/s²
903
+
904
+ ---
905
+
906
+ **س (39)** ينزلق طفل من السكون على مستوى مائل بزاوية (30°) مع الأفقي لتصل سرعته أسفل المستوى إلى (40 m/s) فإذا كان معامل الاحتكاك بين الطفل والمستوى (√3 / 5) فإن الزمن المستغرق للوصول لأسفل المستوى هو:
907
+
908
+ - (أ) 20 sec
909
+ - (ب) 40 sec
910
+ - (ج) 30 sec
911
+ - (د) 10 sec
912
+
913
+ ---
914
+
915
+ **س (40)** سباحة كتلتها (50 kg) وطاقة حركتها (100 J) وعند دخولها إلى الماء فقدت نصف سرعتها، فإن مقدار طاقة حركتها داخل الماء تصبح:
916
+
917
+ - (أ) 100 J
918
+ - (ب) 50 J
919
+ - (ج) 25 J
920
+ - (د) 200 J
921
+
922
+ ---
923
+
924
+ **س (41)** مضخة ترفع الماء من عمق ثابت (36 m) بمعدل (10³ kg) في الدقيقة ثم تدفعه أفقياً بسرعة (18 m/s)، فإن قدرة المضخة تساوي:
925
+
926
+ - (أ) 6 kW
927
+ - (ب) 2.7 kW
928
+ - (ج) 8.7 kW
929
+ - (د) 162 kW
930
+
931
+ ---
932
+
933
+ **س (42)** قذف جسم على لوح خشن مستند إلى حائط وكان طرف اللوح العلوي يصنع زاوية (60°) مع الحائط، ومعامل الاحتكاك بين الجسم واللوح (1/√5)، وأقصى ارتفاع يصل إليه الجسم (7 m) من سطح الأرض فإن السرعة التي قذف بها الجسم تساوي:
934
+
935
+ - (أ) 11.1 m/s
936
+ - (ب) 10.2 m/s
937
+ - (ج) 17.5 m/s
938
+ - (د) 15.8 m/s
939
+
940
+ ---
941
+
942
+ **س (43)** تدحرجت كرة وزنها (5 N) على أرضية مسافة (10 m) فالشغل الذي يبذله وزنها هو:
943
+
944
+ - (أ) صفر
945
+ - (ب) 2 J
946
+ - (ج) 0.5 J
947
+ - (د) 50 J
948
+
949
+ ---
950
+
951
+ **س (44)** من الشكل التالي:
952
+
953
+ *(الشكل: كتلة 12 kg على سطح خشن متصلة بحبل مائل بزاوية 42° إلى السقف، والطرف الآخر رأسي يحمل وزناً معلقاً W)*
954
+
955
+ إذا كان معامل الاحتكاك بين الكتلة (12 kg) والسطح (0.31)، وكانت المنظومة في حالة اتزان فإن وزن الجسم المعلق (W) يساوي:
956
+
957
+ - (أ) 33.5 N
958
+ - (ب) 37.2 N
959
+ - (ج) 3.32 N
960
+ - (د) 3.72 N
961
+
962
+ ---
963
+
964
+ **س (45)** سقط حجر كتلته (0.5 kg) من ارتفاع (10 m) فوق سطح الأرض فإن طاقته الكلية بعد أن يقطع نصف المسافة تساوي:
965
+
966
+ - (أ) 75 J
967
+ - (ب) 25 J
968
+ - (ج) 50 J
969
+ - (د) 100 J
970
+
971
+ ---
972
+
973
+ **س (46)** جسم طاقة وضعه (400 J) عند ارتفاع (5 m) عن سطح الأرض فإن:
974
+
975
+ - (أ) كتلة الجسم = 80 kg
976
+ - (ب) قوة جذب الأرض للجسم = 8 N
977
+ - (ج) الشغل المبذول مع قوة الجاذبية = 400 J
978
+ - (د) الشغل المبذول ضد قوة الجاذبية = 400 J
979
+
980
+ ---
981
+
982
+ **س (47)** في الشكل التالي:
983
+
984
+ *(الشكل: جسمان كتلتهما m₁ و m₂ حيث m₂ < m₁ في طرفي خيط خفيف يمر على بكرة ملساء، تحركت المجموعة من السكون وبعد ثانية واحدة أصبح البعد الرأسي بين الجسمين 2 m)*
985
+
986
+ علق جسمان كتلتهما (m₁ , m₂) حيث m₂ < m₁ في طرفي خيط خفيف يمر على بكرة ملساء، فإذا تحركت المجموعة من السكون عندما كان الجسمان في مستوى أفقي واحد، وبعد ثانية واحدة أصبح البعد الرأسي بين الجسمين (2 m)، فإن النسبة بين الكتلتين:
987
+
988
+ - (أ) 1 : 2
989
+ - (ب) 3 : 1
990
+ - (ج) 2 : 3
991
+ - (د) 5 : 3
992
+
993
+ ---
994
+
995
+ **س (48)** في الشكل التالي:
996
+
997
+ *(الشكل: كتلة 200 g على مستوى مائل أملس بزاوية 60° تؤثر عليها قوة أفقية F = √X نيوتن)*
998
+
999
+ تستقر الكتلة على مستوى مائل أملس بفعل قوة مقدارها (F = √X N) فإن مقدار القيمة (x) يساوي:
1000
+
1001
+ - (أ) 3
1002
+ - (ب) 4
1003
+ - (ج) 12
1004
+ - (د) 6
1005
+
1006
+ ---
1007
+
1008
+ **س (49)** معادلة حركة جسم موضوع داخل مصعد يتحرك لأسفل بعجلة تناقصية هي:
1009
+
1010
+ - (أ) R = mg
1011
+ - (ب) R = m(g − a)
1012
+ - (ج) R = m(g + a)
1013
+ - (د) جميع الإجابات السابقة خاطئة
1014
+
1015
+ ---
1016
+
1017
+ **س (50)** في الشكل التالي:
1018
+
1019
+ *(الشكل: رسم بياني للعلاقة بين السرعة V والزمن t لجسم مقذوف في الهواء)*
1020
+
1021
+ العلاقة البيانية بين السرعة والزمن لجسم مقذوف في الهواء ومنها يتضح أن:
1022
+
1023
+ - (أ) الجسم تعرض لمقاومة هواء
1024
+ - (ب) الجسم لم يتعرض لمقاومة هواء
1025
+ - (ج) عجلة الصعود تساوي الهبوط
1026
+ - (د) جميع الإجابات السابقة خاطئة
1027
+
1028
+ ---
1029
+
1030
+ **س (51)** عندما يتحرك جسم بأقصى سرعة له فإن:
1031
+
1032
+ - (أ) عجلة حركته تزايدية
1033
+ - (ب) سرعته تزداد بمرور الزمن
1034
+ - (ج) عجلة حركته تناقصية
1035
+ - (د) محصلة القوى المؤثرة فيه تساوي صفراً
1036
+
1037
+ ---
1038
+
1039
+ **س (52)** تستخدم قاعدة أو نظرية (الشغل - الطاقة) في الحالات التي:
1040
+
1041
+ - (أ) تكون فيها القوة ثابتة
1042
+ - (ب) لا تكون فيها القوة ثابتة
1043
+ - (ج) يكون فيها مسار الجسم منحني
1044
+ - (د) جميع الإجابات السابقة صحيحة
1045
+
1046
+ ---
1047
+
1048
+ **س (53)** في الشكل التالي:
1049
+
1050
+ *(الشكل: جسمان A كتلته 2 kg و B كتلته 3 kg متلامسان على سطح أفقي، تؤثر قوة 10 N على الجسم A)*
1051
+
1052
+ جسمان (A , B) كتلتيهما على الترتيب (2 kg , 3 kg) دفع الجسم (A) بقوة مقدارها (10 N) فإن القوة التي يؤثر بها الجسم (B) على الجسم (A) تساوي:
1053
+
1054
+ - (أ) 6 N
1055
+ - (ب) 8 N
1056
+ - (ج) 12 N
1057
+ - (د) 10 N
1058
+
1059
+ ---
1060
+
1061
+ **س (54)** ركل شاب حجر كتلته (320 g) على أرضية فناء بسرعة قدرها (9 m/s) وتوقف الحجر بعد أن قطع مسافة (17 m) فإن معامل الاحتكاك بين الحجر وأرضية الفناء هو:
1062
+
1063
+ - (أ) 0.18
1064
+ - (ب) 0.38
1065
+ - (ج) 0.48
1066
+ - (د) 0.24
1067
+
1068
+ ---
1069
+
1070
+ **س (55)** تدفع دراجة كتلتها (30 kg) بسرعة ثابتة إلى أعلى مسار يميل بزاوية (30°) مع الأفقي ضد قوة مقاومة (50 N) فإن الشغل المبذول لدفع الدراجة مسافة (65 m) هو:
1071
+
1072
+ - (أ) 9.7 kJ
1073
+ - (ب) 6.5 kJ
1074
+ - (ج) 3.2 kJ
1075
+ - (د) 13 kJ
1076
+
1077
+ ---
1078
+
1079
+ **س (56)** في الشكل التالي:
1080
+
1081
+ *(الشكل: كتلة 8 kg على سطح أفقي خشن متصلة بكتلتين معلقتين 3 kg و 4 kg عبر بكرتين ملساوين من طرفي الخيط)*
1082
+
1083
+ الكتل مستقرة والبكرات ملساء والخيوط مشدودة فإن معامل الاحتكاك بين الكتلة (8 kg) والسطح هو:
1084
+
1085
+ - (أ) 0.125
1086
+ - (ب) 0.31
1087
+ - (ج) 0.8
1088
+ - (د) 0.375
1089
+
1090
+ ---
1091
+
1092
+ > **✦✦✦ انتهت الأسئلة ✦✦✦**
1093
+
1094
+ # أسئلة امتحان الفيزياء (الميكانيكا)
1095
+ ## الدور الأول - العام الدراسي 2024-2025
1096
+
1097
+ ---
1098
+
1099
+ > **ملاحظة:** اعتبر عجلة الجاذبية الأرضية g = 10 m/s²
1100
+
1101
+ ---
1102
+
1103
+ ## أولاً: أسئلة الصواب والخطأ
1104
+
1105
+ ---
1106
+
1107
+ **س (1)** عندما ينزلق جسم على سطح ثابت تكون قيمة قوة الاحتكاك مساوية للنهاية القصوى
1108
+
1109
+ - (أ) صح
1110
+ - (ب) خطأ
1111
+
1112
+ ---
1113
+
1114
+ **س (2)** الجسم الموضوع على سطح مائل تكون قوة اتصاله العمودية مساوية لوزن الجسم
1115
+
1116
+ - (أ) صح
1117
+ - (ب) خطأ
1118
+
1119
+ ---
1120
+
1121
+ **س (3)** يمكن للجسم أن يمتلك طاقة حركة دون أن يكون له طاقة وضع عندما تنعدم القوة المؤثرة
1122
+
1123
+ - (أ) صح
1124
+ - (ب) خطأ
1125
+
1126
+ ---
1127
+
1128
+ **س (4)** تزداد قوة الاحتكاك كلما زادت سرعة الجسم المتحرك
1129
+
1130
+ - (أ) صح
1131
+ - (ب) خطأ
1132
+
1133
+ ---
1134
+
1135
+ **س (5)** السيارة التي تسير بسرعة ثابتة على أرض أفقية تستفيد من الشغل المبذول من قوة محركها
1136
+
1137
+ - (أ) صح
1138
+ - (ب) خطأ
1139
+
1140
+ ---
1141
+
1142
+ **س (6)** إذا انزلق جسم وزنه (15 N) بسرعة ثابتة إلى أسفل سطح مائل بزاوية (50°) مع الرأسي فإن معامل الاحتكاك بين الجسم والسطح (tan 50°)
1143
+
1144
+ - (أ) صح
1145
+ - (ب) خطأ
1146
+
1147
+ ---
1148
+
1149
+ **س (7)** إذا قذف جسم إلى أعلى بسرعة 20 (m/s) فإن إزاحته بعد 4 (s) هي صفر
1150
+
1151
+ - (أ) صح
1152
+ - (ب) خطأ
1153
+
1154
+ ---
1155
+
1156
+ **س (8)** إذا أثرت قوة مائلة على جسم ولم يتحرك فإن مقدار قوة الاحتكاك تكون مساوية لمقدار هذه القوة
1157
+
1158
+ - (أ) صح
1159
+ - (ب) خطأ
1160
+
1161
+ ---
1162
+
1163
+ **س (9)** تجعل قوة الجاذبية للأرض القمر يدور حولها وحسب قانون نيوتن الأول سوف يتحرك القمر في خط مستقيم إذا لم توجد هذه الجاذبية
1164
+
1165
+ - (أ) صح
1166
+ - (ب) خطأ
1167
+
1168
+ ---
1169
+
1170
+ **س (10)** عند سقوط جسمين من ارتفاع في نفس الوقت سقوطاً حراً فإن الجسم الأكبر كتلة يصل أولاً
1171
+
1172
+ - (أ) صح
1173
+ - (ب) خطأ
1174
+
1175
+ ---
1176
+
1177
+ **س (11)** تعرف قدرة الجسم على أنها حاصل ضرب القوة المؤثرة في سرعته غير المنتظمة
1178
+
1179
+ - (أ) صح
1180
+ - (ب) خطأ
1181
+
1182
+ ---
1183
+
1184
+ **س (12)** عندما تدور البكرة حول محور أملس فإن عجلة الدلو الفارغ المتحرك لأعلى أقل من عجلة الدلو المعبأ المتحرك لأسفل عند إهمال كتلة كل من الحبل والبكرة
1185
+
1186
+ - (أ) صح
1187
+ - (ب) خطأ
1188
+
1189
+ ---
1190
+
1191
+ ## ثانياً: أسئلة الاختيار من متعدد
1192
+
1193
+ ---
1194
+
1195
+ **س (13)** قذفت كرة إلى أعلى وعادت إلى نقطة القذف بعد زمن قدره 3 (s) فإن السرعة التي قذفت بها هي:
1196
+
1197
+ - (أ) 15 m/s
1198
+ - (ب) 10 m/s
1199
+ - (ج) 30 m/s
1200
+ - (د) 20 m/s
1201
+
1202
+ ---
1203
+
1204
+ **س (14)** إذا كانت القوة المقاومة لحركة سيارة كتلتها (1.2 tonne) هي (250 N) فإن قدرة السيارة عندما تكون سرعتها (8 m/s) وعجلتها (0.5 m/s²) هي:
1205
+
1206
+ - (أ) 6.8 KW
1207
+ - (ب) 0.12 KW
1208
+ - (ج) 7.8 KW
1209
+ - (د) 2.8 KW
1210
+
1211
+ ---
1212
+
1213
+ **س (15)** تتحرك عربة كتلتها (500 kg) بعجلة قدرها (2 m/s²) إلى أعلى طريق مستقيم يميل بزاوية مقدارها (80°) مع الرأسي فإن مقدار القوة المحركة للعربة هي:
1214
+
1215
+ - (أ) 1868.2 N
1216
+ - (ب) 14924 N
1217
+ - (ج) 1086.8 N
1218
+ - (د) 492.4 N
1219
+
1220
+ ---
1221
+
1222
+ **س (16)** في الشكل المبين:
1223
+
1224
+ *(الشكل: صندوق كتلته 6.5 kg على سطح أفقي، قام شخص بسحبه أفقياً بقوة 12 N ولم يتحرك، ثم قام شخص آخر بسحبه عمودياً بالتدريج)*
1225
+
1226
+ صندوق كتلته (6.5 kg) في حالة سكون قام شخص ما بسحبه أفقياً بقوة قدرها (12 N) ولم يتحرك الصندوق ثم قام شخص آخر بسحبه عمودياً بالتدريج، فإذا كان معامل الاحتكاك بين الصندوق والسطح (0.35) فإن أصغر قوة عمودية يسحب بها الشخص الثاني الصندوق حتى يكون على وشك الحركة هي:
1227
+
1228
+ - (أ) 34 N
1229
+ - (ب) 12 N
1230
+ - (ج) 31 N
1231
+ - (د) 53 N
1232
+
1233
+ ---
1234
+
1235
+ **س (17)** في الشكل التالي:
1236
+
1237
+ *(الشكل: كتلة 1 Kg على سطح خشن يساراً وكتلة 2 Kg على سطح يميناً، وبينهما كتلة معلقة 4 Kg متصلة بحبلين عبر بكرتين بشدين T1 و T2)*
1238
+
1239
+ معامل الاحتكاك بين الكتلة (1 Kg) والسطح (0.2) إذا تحركت المنظومة بعجلة ثابتة فإن الشد في كل سلك يساوي:
1240
+
1241
+ - (أ) T2 = 7.43 N ، T1 = 10.86 N
1242
+ - (ب) T2 = 8.5 N ، T1 = 12.5 N
1243
+ - (ج) T2 = 7.7 N ، T1 = 11.42 N
1244
+ - (د) T2 = 7.14 N ، T1 = 12.28 N
1245
+
1246
+ ---
1247
+
1248
+ **س (18)** تحركت كتلة (5 kg) من أسفل مستوى مائل بزاوية (30°) على الأفقي، بعد أن قطعت مسافة (3 m) على طول المستوى، فإن مقدار التغير في طاقة وضعها يساوي:
1249
+
1250
+ - (أ) 100 J
1251
+ - (ب) 150 J
1252
+ - (ج) 75 J
1253
+ - (د) 50 J
1254
+
1255
+ ---
1256
+
1257
+ **س (19)** عند وضع صندوقين متماثلين فوق بعض وكان رد فعل الأرض على الصندوق السفلي (4 N) فإن كتلة كل صندوق هي:
1258
+
1259
+ - (أ) 2 kg
1260
+ - (ب) 2 g
1261
+ - (ج) 200 g
1262
+ - (د) 1 kg
1263
+
1264
+ ---
1265
+
1266
+ **س (20)** كل العبارات صحيحة ما عدا:
1267
+
1268
+ - (أ) تزداد مقاومة الهواء مع زيادة سرعة الجسم
1269
+ - (ب) حد الاحتكاك هو النسبة بين معامل الاحتكاك وقوة الاتصال العمودية
1270
+ - (ج) يزداد معامل الاحتكاك بزيادة خشونة السطح
1271
+ - (د) تعتمد مقاومة الهواء على شكل الجسم ومساحته
1272
+
1273
+ ---
1274
+
1275
+ **س (21)** يدفع صندوق كتلته (27 kg) على مستوى مائل لمسافة (65 m) فكان الشغل المبذول (5300 J) فإن زاوية ميل المستوى مع الرأسي تساوي:
1276
+
1277
+ - (أ) 17.6°
1278
+ - (ب) 30°
1279
+ - (ج) 72.4°
1280
+ - (د) 60°
1281
+
1282
+ ---
1283
+
1284
+ **س (22)** قذف جسم كتلته (m kg) لأعلى بسرعة (10 m/s) على سطح خشن معامل الاحتكاك له (0.25) يميل بزاوية (60°) مع الرأسي فإن السرعة التي يعود بها إلى نقطة القذف:
1285
+
1286
+ - (أ) 10 m/s
1287
+ - (ب) 39.56 m/s
1288
+ - (ج) 6.29 m/s
1289
+ - (د) 6.1 m/s
1290
+
1291
+ ---
1292
+
1293
+ **س (23)** شاحنة كتلتها (60 kg) تجر بقوة (150 N) شاحنة أخرى كتلتها (40 kg) بواسطة كابل موصل بين الشاحنتين فإن الشد في الكابل يساوي:
1294
+
1295
+ - (أ) 54 N
1296
+ - (ب) 60 N
1297
+ - (ج) 90 N
1298
+ - (د) 900 N
1299
+
1300
+ ---
1301
+
1302
+ **س (24)** قذف حجر رأسياً لأعلى من فوق سطح عمارة مكونة من عدة طوابق بسرعة (20 m/s) ووصل إلى سطح الأرض بعد أن قطع مسافة (100 m) فإذا كان ارتفاع كل طابق (2.5 m) فإن عدد طوابق العمارة هو:
1303
+
1304
+ - (أ) 32 طابقاً
1305
+ - (ب) 24 طابقاً
1306
+ - (ج) 18 طابقاً
1307
+ - (د) 40 طابقاً
1308
+
1309
+ ---
1310
+
1311
+ **س (25)** يقف رجل داخل مصعد يهبط لأسفل فإذا كانت القوة التي تبذل بواسطة الرجل على أرضية المصعد تساوي (3/4 وزن الرجل) فإن عجلة المصعد تساوي:
1312
+
1313
+ - (أ) 3/4 g
1314
+ - (ب) 1/2 g
1315
+ - (ج) 1/4 g
1316
+ - (د) 1/3 g
1317
+
1318
+ ---
1319
+
1320
+ **س (26)** في الشكل المبين:
1321
+
1322
+ *(الشكل: ثلاث كتل A كتلته 2 kg و B كتلته 1 kg و C كتلته 3 kg على سطح أملس، تؤثر قوة 12 N على الكتلة A)*
1323
+
1324
+ الكتل (A , B , C) موضوعة على سطح أملس وتؤثر القوة (12 N) على الكتلة (A) فإن محصلة القوى المؤثرة على الكتلة (B) تساوي:
1325
+
1326
+ - (أ) صفراً
1327
+ - (ب) 2 N
1328
+ - (ج) 12 N
1329
+ - (د) 8 N
1330
+
1331
+ ---
1332
+
1333
+ **س (27)** يتأرجح بندول طول خيطه (1.5 m) وكتلة كرته (2 kg) فإذا كانت أقصى زاوية يصنعها الخيط مع العمودي أثناء التأرجح هي (30°) فإن سرعة الكرة عند أدنى نقطة في مسارها تساوي:
1334
+
1335
+ - (أ) 2 m/s
1336
+ - (ب) 5.3 m/s
1337
+ - (ج) 3.87 m/s
1338
+ - (د) 1.5 m/s
1339
+
1340
+ ---
1341
+
1342
+ **س (28)** يسقط جسم كتلته (2 kg) من ارتفاع وتتعرض لمقاومة هواء بمقدار (0.06 V²) حيث (V) السرعة بوحدة (m/s) فإن السرعة النهائية للجسم هي:
1343
+
1344
+ - (أ) 333 m/s
1345
+ - (ب) 1.83 m/s
1346
+ - (ج) 18.25 m/s
1347
+ - (د) 33.3 m/s
1348
+
1349
+ ---
1350
+
1351
+ **س (29)** في الشكل التالي:
1352
+
1353
+ *(الشكل: بكرة يتدلى منها جسمان أحدهما كتلته 2 Kg والآخر كتلته m)*
1354
+
1355
+ إذا تحركت المنظومة في اتجاه الكتلة (m) وكان الشد في السلك (30 N) فإن قيمة (m):
1356
+
1357
+ - (أ) m = 4 kg
1358
+ - (ب) m = 6 N
1359
+ - (ج) m = 6 kg
1360
+ - (د) m = 5 N
1361
+
1362
+ ---
1363
+
1364
+ **س (30)** عند جر جسم كتلته (m) على سطح أفقي بفعل قوة F(N) تصنع زاوية (θ) مع الرأسي فإن قوة الاتصال العمودية تساوي:
1365
+
1366
+ - (أ) mg
1367
+ - (ب) mg − F sinθ
1368
+ - (ج) mg − F cosθ
1369
+ - (د) mg + F sinθ
1370
+
1371
+ ---
1372
+
1373
+ **س (31)** إذا زادت قوة الاتصال العمودية إلى الضعف فإن معامل الاحتكاك:
1374
+
1375
+ - (أ) يبقى ثابتاً
1376
+ - (ب) يزداد أربع أمثال
1377
+ - (ج) يقل إلى النصف
1378
+ - (د) يزداد إلى الضعف
1379
+
1380
+ ---
1381
+
1382
+ **س (32)** يتحرك جسم بسرعة ابتدائية (u) على سطح خشن معامل الاحتكاك بينه وبين السطح (μ)، فإن المسافة المقطوعة للجسم حتى يقف:
1383
+
1384
+ - (أ) S = (½ μg)
1385
+ - (ب) S = (u² / μg)
1386
+ - (ج) S = (2u / μg)
1387
+ - (د) S = ½ (u² / μg)
1388
+
1389
+ ---
1390
+
1391
+ **س (33)** في الشكل التالي:
1392
+
1393
+ *(الشكل: جسم A عند نقطة تؤثر عليه قوى: 400 N مائلة بزاوية 30°، و 200 N مائلة بزاوية 30°، و 300 N أفقية، و 173.2 N لأسفل)*
1394
+
1395
+ إذا كان الجسم (A) تحت تأثير القوى المبينة بالرسم، فإنه:
1396
+
1397
+ - (أ) يتحرك إلى أسفل (−y)
1398
+ - (ب) في حالة اتزان
1399
+ - (ج) يتحرك إلى أعلى (+y)
1400
+ - (د) يتحرك باتجاه القوة (300 N)
1401
+
1402
+ ---
1403
+
1404
+ **س (34)** سقط جسم كتلته (m) من ارتفاع وتعرض لمقاومة هواء مقدارها (KV²) فإذا كانت سرعته النهائية (30 m/s) فإن العجلة التي يتحرك بها عندما تكون سرعته (20 m/s) هي:
1405
+
1406
+ - (أ) 10 m/s²
1407
+ - (ب) 8 m/s²
1408
+ - (ج) 9.65 m/s²
1409
+ - (د) 5.55 m/s²
1410
+
1411
+ ---
1412
+
1413
+ **س (35)** تجلس طالبة كتلتها (50 kg) على كرسي وزنه (200 N) فإن رد فعل الكرسي على الطالبة:
1414
+
1415
+ - (أ) 50 N
1416
+ - (ب) 200 N
1417
+ - (ج) 500 N
1418
+ - (د) 700 N
1419
+
1420
+ ---
1421
+
1422
+ **س (36)** بفرض إهمال مقاومة الهواء، تتحرك سيارة كتلتها (1 tonne) وكان الزمن الذي تتغير فيه سرعتها من (14 m/s) إلى (20 m/s) هو (2.5 sec)، فإن معدل التغير في الطاقة الحركية للسيارة يساوي:
1423
+
1424
+ - (أ) 10.2 KW
1425
+ - (ب) 102 KW
1426
+ - (ج) 4.8 KW
1427
+ - (د) 40.8 KW
1428
+
1429
+ ---
1430
+
1431
+ **س (37)** قوة تنشأ عند تلامس سطحين وهي دائماً عمودية على السطح هي:
1432
+
1433
+ - (أ) قوة المقاومة
1434
+ - (ب) الوزن
1435
+ - (ج) قوة الاحتكاك
1436
+ - (د) قوة الاتصال العمودية
1437
+
1438
+ ---
1439
+
1440
+ **س (38)** سقط جسم كتلته (2 kg) من ارتفاع قدره (50 m) فإن سرعته بعد أن يقطع مسافة (20 m) هي:
1441
+
1442
+ - (أ) 31.6 m/s
1443
+ - (ب) 400 m/s
1444
+ - (ج) 20 m/s
1445
+ - (د) 24.5 m/s
1446
+
1447
+ ---
1448
+
1449
+ **س (39)** تتحرك سيارة بسرعة (27 km/hr) عندما استعملت المكابح توقفت السيارة بعد أن قطعت مسافة (6 m) فإذا كانت كتلة السيارة (1.5 tonne) فإن معامل الاحتكاك بين السيارة والطريق والزمن المستغرق حتى تقف:
1450
+
1451
+ - (أ) 0.74 ، 1.6 sec
1452
+ - (ب) 0.93 ، 2 sec
1453
+ - (ج) 0.47 ، 0.6 sec
1454
+ - (د) 0.47 ، 1.6 sec
1455
+
1456
+ ---
1457
+
1458
+ **س (40)** ترفع كرة وزنها (200 N) عمودياً لأعلى لمسافة (2 m)، فإن مقدار الشغل المبذول لذلك:
1459
+
1460
+ - (أ) 400 J
1461
+ - (ب) 4000 J
1462
+ - (ج) 100 J
1463
+ - (د) صفر
1464
+
1465
+ ---
1466
+
1467
+ **س (41)** إذا كانت المركبة الأفقية للقوة (F) التي تصنع زاوية مقدارها (15°) هي (20 N) فإن مركبتها الرأسية تساوي:
1468
+
1469
+ - (أ) 5.36 N
1470
+ - (ب) 5.17 N
1471
+ - (ج) 20.7 N
1472
+ - (د) 19.31 N
1473
+
1474
+ ---
1475
+
1476
+ **س (42)** يجر رجل صندوق كتلته (20 kg) بقوة (60 N) بزاوية (30°) مع الأفقي ويدفع آخر الصندوق بقوة (75 N) بزاوية (30°) مع العمودي ليتحرك بعجلة مقدارها (4.47 m/s²) فإن قوة الاتصال العمودية تساوي:
1477
+
1478
+ - (أ) 294.95 N
1479
+ - (ب) 105.05 N
1480
+ - (ج) 200 N
1481
+ - (د) 234.95 N
1482
+
1483
+ ---
1484
+
1485
+ **س (43)** تُجذب لعبة كتلتها (2.2 kg) على سطح أفقي بواسطة سلك يصنع زاوية قدرها (30°) مع الأفقي فإذا كانت قوة الشد (15 N) ومعامل الاحتكاك بين اللعبة والسطح (0.1) فإن العجلة التي تتحرك بها اللعبة هي:
1486
+
1487
+ - (أ) 5.24 m/s²
1488
+ - (ب) 5.8 m/s²
1489
+ - (ج) 1.5 m/s²
1490
+ - (د) 4.9 m/s²
1491
+
1492
+ ---
1493
+
1494
+ **س (44)** يسقط جسم كتلته (4 kg) من ارتفاع قدره (25 m) فإن طاقة وضعه بعد أن يقطع مسافة قدرها (10 m) هي:
1495
+
1496
+ - (أ) 1000 J
1497
+ - (ب) 600 J
1498
+ - (ج) 60 J
1499
+ - (د) 400 J
1500
+
1501
+ ---
1502
+
1503
+ **س (45)** قذف جسم كتلته (m kg) من النقطة (0) على مستوى أملس يميل بزاوية (sin⁻¹ 0.6) بسرعة (15 m/s) فإن أقصى مسافة يصل إليها هي:
1504
+
1505
+ - (أ) 1.25 m
1506
+ - (ب) 37.5 m
1507
+ - (ج) 18.75 m
1508
+ - (د) 11.25 m
1509
+
1510
+ ---
1511
+
1512
+ **س (46)** عند استخدام الحبال والسلاسل أي العبارات الآتية غير صحيحة:
1513
+
1514
+ - (أ) تبذل قوة اتجاهها إلى الخارج
1515
+ - (ب) غير قابلة للتمدد
1516
+ - (ج) يمكن إهمال وزنها مقارنة مع القوة المؤثرة
1517
+ - (د) تبذل قوة اتجاهها إلى الداخل
1518
+
1519
+ ---
1520
+
1521
+ **س (47)** كل مما يلي ميزات للفعل ورد الفعل ما عدا:
1522
+
1523
+ - (أ) لا يقعان على استقامة واحدة
1524
+ - (ب) يؤثران على جسمين مختلفين
1525
+ - (ج) متعاكسين في الاتجاه
1526
+ - (د) متساويين في المقدار
1527
+
1528
+ ---
1529
+
1530
+ **س (48)** في الشكل التالي:
1531
+
1532
+ *(الشكل: كتلة 4 Kg تستند على حائط رأسي خشن، تؤثر عليها قوة F مائلة بزاوية 30° مع الأفقي)*
1533
+
1534
+ مقدار القوة (F) التي تجعل الكتلة (4 Kg) التي تستند على حائط رأسي خشن تتحرك بعجلة (3.5 m/s²)، علماً بأن معامل الاحتكاك بين الكتلة والحائط (0.2):
1535
+
1536
+ - (أ) 30 N
1537
+ - (ب) 60.5 N
1538
+ - (ج) 70.5 N
1539
+ - (د) 40 N
1540
+
1541
+ ---
1542
+
1543
+ **س (49)** في الشكل التالي:
1544
+
1545
+ *(الشكل: كتلتان m1 على سطح أفقي و m2 على مستوى مائل بزاوية θ متصلتان بحبل يمر على بكرة)*
1546
+
1547
+ الأسطح ملساء والكتل غير مستقرة فإن مقدار الشد في الحبل يساوي:
1548
+
1549
+ - (أ) T = m₂g sinθ [ 1 − m₂ / (m₁ + m₂) ]
1550
+ - (ب) T = ( m₁ / (m₁ + m₂) ) g sinθ
1551
+ - (ج) T = ( m₁ m₂ / (m₁ − m₂) ) g sinθ
1552
+ - (د) T = ( m₁ m₂ / (m₁ + m₂) )
1553
+
1554
+ ---
1555
+
1556
+ **س (50)** عند قذف جسم إلى أعلى في عدم وجود مقاومة هواء فإن:
1557
+
1558
+ - (أ) مجموع طاقة حركته وطاقة وضعه مقدار ثابت
1559
+ - (ب) طاقة حركته تزيد وطاقة وضعه تقل
1560
+ - (ج) تزداد كل من طاقة حركته وطاقة وضعه
1561
+ - (د) تقل كل من طاقة حركته وطاقة وضعه
1562
+
1563
+ ---
1564
+
1565
+ **س (51)** في الشكل المبين:
1566
+
1567
+ *(الشكل: كتلتان فوق بعضهما، العلوية 1.5 Kg والسفلية 2.5 Kg، تُسحب السفلية بقوة 35 N أفقية)*
1568
+
1569
+ تسحب الكتلة السفلية بقوة مقدارها (35 N)، وكان معامل الاحتكاك بينها وبين الأرض (0.25)، وبافتراض أن الكتلة العلوية لا تنزلق، فإن مقدار تسارع الكتلتين يساوي:
1570
+
1571
+ - (أ) 7.8 m/s²
1572
+ - (ب) 7.2 m/s²
1573
+ - (ج) 8.75 m/s²
1574
+ - (د) 6.25 m/s²
1575
+
1576
+ ---
1577
+
1578
+ **س (52)** يستقر صندوق كتلته (5 kg) على مستوى مائل بزاوية قدرها (70°) مع الرأسي بواسطة قوة أفقية (F)، فإن مقدار هذه القوة:
1579
+
1580
+ - (أ) 18.2 N
1581
+ - (ب) 137.37 N
1582
+ - (ج) 46.98 N
1583
+ - (د) 17.1 N
1584
+
1585
+ ---
1586
+
1587
+ **س (53)** في الشكل التالي:
1588
+
1589
+ *(الشكل: كتلة 4 Kg على مستوى مائل بزاوية 30° وكتلة 2 Kg على مستوى مائل بزاوية 60°، متصلتان بخيط يمر على بكرة، الكتلة 4 Kg على سطح أملس والكتلة 2 Kg على سطح خشن معامل احتكاكه 0.2)*
1590
+
1591
+ كانت الكتلة (4 kg) على سطح أملس والكتلة (2 kg) على سطح خشن معامل الاحتكاك له (0.2)، فإن الشد في الخيط يساوي:
1592
+
1593
+ - (أ) 19.5 N
1594
+ - (ب) 18.5 N
1595
+ - (ج) 20.5 N
1596
+ - (د) 22 N
1597
+
1598
+ ---
1599
+
1600
+ **س (54)** وحدة قياس الشغل في النظام الدولي هي (الجول) وتعادل:
1601
+
1602
+ - (أ) kg . m³ . s⁻²
1603
+ - (ب) kg . m² . s⁻³
1604
+ - (ج) kg . m . s⁻¹
1605
+ - (د) kg . m² . s⁻²
1606
+
1607
+ ---
1608
+
1609
+ **س (55)** تقذف كرتان من سطح مبنى واحدة لأعلى والأخرى لأسفل في نفس اللحظة وبسرعة ابتدائية متساوية لكل منهما، فإن المسافة بين الكرتين بدلالة الزمن والسرعة الابتدائية:
1610
+
1611
+ - (أ) ut
1612
+ - (ب) ½ ut
1613
+ - (ج) 4 ut
1614
+ - (د) 2 ut
1615
+
1616
+ ---
1617
+
1618
+ **س (56)** في الشكل التالي:
1619
+
1620
+ *(الشكل: كتلة m1 على سطح أفقي خشن معامل احتكاكه μ وفوقها كتلة إضافية m، متصلة بخيط يمر على بكرة ملساء بكتلة معلقة m2)*
1621
+
1622
+ كتلتان (m1 , m2) متصلتان بخيط يمر فوق بكرة ملساء توجد الكتلة (m1) على سطح أفقي خشن معامل احتكاكه (μ) كما هو موضح بالرسم، فإن مقدار الكتلة الإضافية (m) التي يجب وضعها على الكتلة (m1) حتى لا يتسارع النظام:
1623
+
1624
+ - (أ) m = m2 − m1/μ
1625
+ - (ب) m = m2/μ − m1
1626
+ - (ج) m = (m2 − m1)/μ
1627
+ - (د) m = μ(m2 − m1)
1628
+
1629
+ ---
1630
+
1631
+ > **✦✦✦ انتهت الأسئلة ✦✦✦**
auth/__init__.py ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ """
2
+ Authentication package.
3
+ """
auth/__pycache__/__init__.cpython-314.pyc ADDED
Binary file (187 Bytes). View file
 
auth/__pycache__/helpers.cpython-314.pyc ADDED
Binary file (1.51 kB). View file
 
auth/__pycache__/routes.cpython-314.pyc ADDED
Binary file (8.07 kB). View file
 
auth/helpers.py ADDED
@@ -0,0 +1,37 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """
2
+ Session and authentication helpers.
3
+ """
4
+
5
+ import uuid
6
+ from flask import session
7
+ from database.users import load_users_db
8
+
9
+ # Active WebSocket connections per user
10
+ active_connections = {}
11
+
12
+
13
+ def generate_session_id():
14
+ return str(uuid.uuid4())
15
+
16
+
17
+ def is_session_valid():
18
+ if 'username' not in session or 'session_id' not in session:
19
+ return False
20
+ username = session['username']
21
+ session_id = session['session_id']
22
+ users_db = load_users_db()
23
+ if username not in users_db:
24
+ return False
25
+ if users_db[username].get('session_id') != session_id:
26
+ return False
27
+ return True
28
+
29
+
30
+ def notify_logout(username, socketio, exclude_sid=None):
31
+ """Notify all connections for a user to logout."""
32
+ if username in active_connections:
33
+ for sid in active_connections[username]:
34
+ if sid != exclude_sid:
35
+ socketio.emit('force_logout', {
36
+ 'message': 'لقد تم تسجيل خروجك لأن شخصاً آخر قام بتسجيل الدخول.'
37
+ }, room=sid)
auth/routes.py ADDED
@@ -0,0 +1,176 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """
2
+ Authentication routes: signup, login, logout, verification.
3
+ """
4
+
5
+ from flask import Blueprint, render_template, request, redirect, url_for, session, flash
6
+ from datetime import datetime
7
+ from auth.helpers import is_session_valid, generate_session_id, notify_logout, active_connections
8
+ from database.users import load_users_db, save_users_db
9
+ from database.telegram import load_telegram_db, save_telegram_db
10
+
11
+ auth_bp = Blueprint('auth', __name__)
12
+
13
+ # Store socketio reference - set from app.py
14
+ _socketio = None
15
+
16
+
17
+ def init_auth_socketio(socketio):
18
+ global _socketio
19
+ _socketio = socketio
20
+
21
+
22
+ @auth_bp.route('/signup', methods=['GET', 'POST'])
23
+ def signup():
24
+ if request.method == 'POST':
25
+ username = request.form.get('username', '').strip()
26
+ password = request.form.get('password', '')
27
+ confirm_password = request.form.get('confirm_password', '')
28
+ student_type = request.form.get('student_type', '').strip()
29
+
30
+ if not username or not password or not confirm_password:
31
+ flash('جميع الحقول مطلوبة!', 'error')
32
+ return render_template('signup.html')
33
+
34
+ if not student_type or student_type not in ['أدبي', 'علمي']:
35
+ flash('يرجى اختيار نوع الدراسة!', 'error')
36
+ return render_template('signup.html')
37
+
38
+ if len(username) < 3:
39
+ flash('اسم المستخدم قصير جداً!', 'error')
40
+ return render_template('signup.html')
41
+
42
+ if password != confirm_password:
43
+ flash('كلمات المرور غير متطابقة!', 'error')
44
+ return render_template('signup.html')
45
+
46
+ if len(password) < 6:
47
+ flash('كلمة المرور قصيرة جداً (6 أحرف على الأقل)!', 'error')
48
+ return render_template('signup.html')
49
+
50
+ users_db = load_users_db()
51
+ if username in users_db:
52
+ flash('اسم المستخدم موجود مسبقاً!', 'error')
53
+ return render_template('signup.html')
54
+
55
+ session['temp_username'] = username
56
+ session['temp_password'] = password
57
+ session['temp_student_type'] = student_type
58
+
59
+ return redirect(url_for('auth.verification'))
60
+
61
+ return render_template('signup.html')
62
+
63
+
64
+ @auth_bp.route('/verification', methods=['GET', 'POST'])
65
+ def verification():
66
+ if 'temp_username' not in session:
67
+ flash('يرجى بدء عملية التسجيل من البداية.', 'error')
68
+ return redirect(url_for('auth.signup'))
69
+
70
+ if request.method == 'POST':
71
+ code = request.form.get('code', '').strip()
72
+
73
+ if not code:
74
+ flash('يرجى إدخال رمز التحقق!', 'error')
75
+ return render_template('verification.html')
76
+
77
+ telegram_db = load_telegram_db()
78
+ user_found = False
79
+ user_id = None
80
+
81
+ for uid, user_data in telegram_db.items():
82
+ if user_data.get('code') == code and user_data.get('code') != "DONE":
83
+ user_found = True
84
+ user_id = uid
85
+ break
86
+
87
+ if not user_found:
88
+ flash('رمز التحقق غير صحيح أو تم استخدامه!', 'error')
89
+ return render_template('verification.html')
90
+
91
+ telegram_db[user_id]['code'] = "DONE"
92
+ telegram_db[user_id]['status'] = "verified"
93
+ telegram_db[user_id]['verified_at'] = datetime.now().isoformat()
94
+ save_telegram_db(telegram_db)
95
+
96
+ new_session_id = generate_session_id()
97
+ users_db = load_users_db()
98
+ username = session['temp_username']
99
+ password = session['temp_password']
100
+ student_type = session['temp_student_type']
101
+
102
+ users_db[username] = {
103
+ "username": username,
104
+ "password": password,
105
+ "student_type": student_type,
106
+ "telegram_user_id": user_id,
107
+ "session_id": new_session_id,
108
+ "created_at": datetime.now().isoformat(),
109
+ "verified": True,
110
+ "last_login": datetime.now().isoformat(),
111
+ "balance": 0,
112
+ "purchased_subjects": ['islamic']
113
+ }
114
+ save_users_db(users_db)
115
+
116
+ session.pop('temp_username', None)
117
+ session.pop('temp_password', None)
118
+ session.pop('temp_student_type', None)
119
+
120
+ session['username'] = username
121
+ session['user_id'] = user_id
122
+ session['session_id'] = new_session_id
123
+
124
+ flash('تم إنشاء الحساب وتسجيل الدخول بنجاح!', 'success')
125
+ return redirect(url_for('dashboard'))
126
+
127
+ return render_template('verification.html')
128
+
129
+
130
+ @auth_bp.route('/login', methods=['GET', 'POST'])
131
+ def login():
132
+ if request.method == 'POST':
133
+ username = request.form.get('username', '').strip()
134
+ password = request.form.get('password', '')
135
+
136
+ users_db = load_users_db()
137
+
138
+ if username in users_db and users_db[username]['password'] == password:
139
+ new_session_id = generate_session_id()
140
+ if _socketio:
141
+ notify_logout(username, _socketio)
142
+
143
+ users_db[username]['session_id'] = new_session_id
144
+ users_db[username]['last_login'] = datetime.now().isoformat()
145
+ save_users_db(users_db)
146
+
147
+ session['username'] = username
148
+ session['user_id'] = users_db[username].get('telegram_user_id')
149
+ session['session_id'] = new_session_id
150
+
151
+ flash('تم تسجيل الدخول بنجاح!', 'success')
152
+ return redirect(url_for('dashboard'))
153
+ else:
154
+ flash('اسم المستخدم أو كلمة المرور خطأ!', 'error')
155
+
156
+ return render_template('login.html')
157
+
158
+
159
+ @auth_bp.route('/logout')
160
+ def logout():
161
+ if 'username' in session:
162
+ username = session['username']
163
+ if username in active_connections:
164
+ active_connections[username] = []
165
+ users_db = load_users_db()
166
+ if username in users_db:
167
+ users_db[username]['session_id'] = None
168
+ save_users_db(users_db)
169
+ session.clear()
170
+ flash('تم تسجيل الخروج.', 'success')
171
+ return redirect(url_for('auth.login'))
172
+
173
+
174
+ @auth_bp.route('/forgot-password')
175
+ def forgot_password():
176
+ return render_template('forgot_password.html')
board/__init__.py ADDED
@@ -0,0 +1,4 @@
 
 
 
 
 
1
+ """
2
+ Board package.
3
+ Interactive whiteboard with AI, TTS, icons, and page images.
4
+ """
board/__pycache__/__init__.cpython-314.pyc ADDED
Binary file (240 Bytes). View file
 
board/__pycache__/engine.cpython-314.pyc ADDED
Binary file (23.5 kB). View file
 
board/__pycache__/icons.cpython-314.pyc ADDED
Binary file (4.48 kB). View file
 
board/__pycache__/pages.cpython-314.pyc ADDED
Binary file (2.59 kB). View file
 
board/__pycache__/routes.cpython-314.pyc ADDED
Binary file (10.3 kB). View file
 
board/__pycache__/tts.cpython-314.pyc ADDED
Binary file (4.2 kB). View file
 
board/engine.py ADDED
@@ -0,0 +1,569 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """
2
+ Board AI Engine.
3
+ Handles the interactive whiteboard: XML generation, parsing,
4
+ icon/page resolution, TTS, and board state management.
5
+
6
+ Now supports MULTIPLE SUBJECTS dynamically.
7
+ Each subject loads its own folder, pages_base_url, etc.
8
+ """
9
+
10
+ import re
11
+ import json
12
+ import requests
13
+ from config import GPT_URL, MAX_CHAT_HISTORY
14
+ from board.tts import TTSEngine
15
+ from board.icons import IconResolver
16
+ from board.pages import resolve_page_tags
17
+ from subjects.loader import subject_loader
18
+ from json_processor import BoardProcessor
19
+
20
+
21
+ class BoardEngine:
22
+ """
23
+ Board AI Engine for a specific user session.
24
+ Supports any subject dynamically.
25
+ """
26
+
27
+ def __init__(self):
28
+ self.gpt_url = GPT_URL
29
+ self.board_processor = BoardProcessor()
30
+ self.tts_engine = TTSEngine()
31
+ self.icon_resolver = IconResolver()
32
+
33
+ # Per-user state: { username: { subject_id, conversation_history, last_sequence } }
34
+ self._user_sessions = {}
35
+
36
+ print("✅ BoardEngine initialized (multi-subject)")
37
+
38
+ # ─── User session management ───
39
+
40
+ def _get_user_session(self, username):
41
+ """Get or create a user's board session."""
42
+ if username not in self._user_sessions:
43
+ self._user_sessions[username] = {
44
+ "subject_id": None,
45
+ "conversation_history": [],
46
+ "last_sequence": [],
47
+ }
48
+ return self._user_sessions[username]
49
+
50
+ def set_subject(self, username, subject_id):
51
+ """Set the active subject for a user's board session."""
52
+ us = self._get_user_session(username)
53
+
54
+ # If switching subjects, clear history
55
+ if us["subject_id"] and us["subject_id"] != subject_id:
56
+ us["conversation_history"] = []
57
+ us["last_sequence"] = []
58
+ print(f" 🔄 Board subject switched: {us['subject_id']} → {subject_id} for {username}")
59
+
60
+ us["subject_id"] = subject_id
61
+ print(f" 📋 Board subject set: {subject_id} for {username}")
62
+
63
+ def get_subject(self, username):
64
+ """Get the active subject for a user."""
65
+ us = self._get_user_session(username)
66
+ return us.get("subject_id")
67
+
68
+ # ─── GPT call ───
69
+
70
+ def _call_gpt5(self, user_message, system_prompt, temperature=0.7, max_tokens=4000):
71
+ payload = {
72
+ "user_input": user_message,
73
+ "chat_history": [
74
+ {"role": "system", "content": system_prompt}
75
+ ],
76
+ "temperature": temperature,
77
+ "top_p": 0.95,
78
+ "max_completion_tokens": max_tokens
79
+ }
80
+ try:
81
+ response = requests.post(self.gpt_url, json=payload, timeout=120)
82
+ response.raise_for_status()
83
+ return response.json().get("assistant_response", "")
84
+ except requests.exceptions.Timeout:
85
+ print(" ❌ GPT timeout")
86
+ return None
87
+ except requests.exceptions.ConnectionError:
88
+ print(" ❌ GPT connection error")
89
+ return None
90
+ except Exception as e:
91
+ print(f" ❌ GPT error: {e}")
92
+ return None
93
+
94
+ # ─── Chat history formatting ───
95
+
96
+ def _format_chat_history(self, username):
97
+ us = self._get_user_session(username)
98
+ history = us.get("conversation_history", [])
99
+ if not history:
100
+ return ""
101
+
102
+ recent = history[-10:]
103
+ parts = []
104
+ for msg in recent:
105
+ if msg["role"] == "user":
106
+ parts.append(f"الطالب: {msg['content']}")
107
+ elif msg["role"] == "assistant":
108
+ parts.append(f"المدرس: {msg['content']}")
109
+
110
+ return (
111
+ "\n\n══ سجل المحادثة السابقة ══\n"
112
+ + "\n".join(parts)
113
+ + "\n══ نهاية السجل ══"
114
+ )
115
+
116
+ # ─── Step 1: Route message ───
117
+
118
+ def _route_message(self, user_message, username):
119
+ us = self._get_user_session(username)
120
+ subject_id = us["subject_id"]
121
+ if not subject_id:
122
+ return "main.txt"
123
+
124
+ subject_data = subject_loader.load(subject_id)
125
+ if not subject_data:
126
+ return "main.txt"
127
+
128
+ structure = subject_data.get("structure.txt", "")
129
+ p_files = subject_data.get("_p_files", [])
130
+ chat_history_text = self._format_chat_history(username)
131
+
132
+ p_files_desc = "\n".join([f"- {f}: الفصل {i+1}" for i, f in enumerate(p_files)])
133
+
134
+ routing_prompt = f"""أنت نظام توجيه ذكي لمساعد تعليمي.
135
+
136
+ مهمتك: تحليل رسالة الطالب واختيار الملف المناسب للرد.
137
+
138
+ الملفات المتاحة:
139
+ - main.txt: للتحيات، الأسئلة العامة، أي شيء لا يتعلق بفصل محدد
140
+ {p_files_desc}
141
+
142
+ فهرس الكتاب (للمساعدة في التوجيه):
143
+ {structure}
144
+ {chat_history_text}
145
+
146
+ تعليمات:
147
+ 1. إذا كانت الرسالة تحية أو سؤال عام → main.txt
148
+ 2. إذا كانت تسأل عن موضوع في فصل محدد → الملف المناسب
149
+ 3. استخدم الفهرس لتحديد الفصل الصحيح
150
+ 4. مهم جداً: إذا قال الطالب "اشرح أكثر" أو "وضح" أو أي طلب متابعة، ارجع لسجل المحادثة لتعرف الموضوع الحالي واختر نفس الملف
151
+ 5. أجب فقط باسم الملف (مثال: p1.txt أو main.txt) بدون أي كلام إضافي
152
+
153
+ رسالة الطالب: {user_message}
154
+
155
+ الملف المناسب:"""
156
+
157
+ chosen = self._call_gpt5(
158
+ user_message, routing_prompt,
159
+ temperature=0.2, max_tokens=50
160
+ )
161
+
162
+ if not chosen:
163
+ return "main.txt"
164
+
165
+ chosen = chosen.strip().lower()
166
+ valid_files = ["main.txt"] + p_files
167
+
168
+ for v in valid_files:
169
+ if v in chosen:
170
+ return v
171
+
172
+ return "main.txt"
173
+
174
+ # ─── Step 2: Generate XML response ───
175
+
176
+ def _generate_xml_response(self, user_message, chosen_file, username):
177
+ us = self._get_user_session(username)
178
+ subject_id = us["subject_id"]
179
+ if not subject_id:
180
+ return None
181
+
182
+ subject_data = subject_loader.load(subject_id)
183
+ if not subject_data:
184
+ return None
185
+
186
+ file_content = subject_data.get(chosen_file, "")
187
+ chat_history_text = self._format_chat_history(username)
188
+
189
+ system_prompt = f"""انتي مدرسة خبيرة ومحترفة في هذه المادة. تشرح على سبورة تفاعلية رقمية.
190
+
191
+ ═══ صيغة الرد ═══
192
+
193
+ يجب أن تردي بصيغة XML خاصة تحتوي على:
194
+
195
+ 1. <board>عناصر السبورة</board> - ما سيُرسم/يُضاف على السبورة أولاً
196
+ 2. <voice>نص الكلام</voice> - النص الذي سيُقرأ بصوت عالٍ للطالب بعد رسم العناصر (عربي طبيعي)
197
+
198
+ ═══ عناصر السبورة المتاحة (داخل <board>) ═══
199
+
200
+ • <note>محتوى الملاحظة</note>
201
+
202
+ • <text>نص مباشر على السبورة بدون خلفية</text>
203
+
204
+ • <shape type="نوع_الشكل"/>
205
+ الأنواع: circle, triangle, star, arrow-right, arrow-left, arrow-up, arrow-down,
206
+ rectangle, diamond, hexagon, square, oval, arrow-double-h, checkmark, cross,
207
+ heart, cloud, lightning, speech, process, decision
208
+
209
+ • <svg>كلمة_بحث_بالإنجليزية</svg>
210
+ سيتم البحث عن أيقونة مرسومة يدوياً (مثل: ball, car, force, spring, weight, rope, pulley)
211
+
212
+ • <page>رقم_الصفحة</page>
213
+ لعرض صفحة محددة من الكتاب كصورة على السبورة
214
+ مثال: <page>12</page> لعرض الصفحة 12 من الكتاب
215
+ استخدمها عندما تحتاج تعرض للطالب صفحة معينة من الكتاب
216
+
217
+ ═══ قواعد مهمة جداً ═══
218
+
219
+ 1. اشرح خطوة بخطوة: ابدأ بـ <board> ثم <voice> ثم <board> ثم <voice> وهكذا
220
+ 2. اجعل الشرح متدرجاً كأنك تشرح على سبورة حقيقية أمام الطلاب
221
+ 3. <board> = ما يظهر على السبورة أولاً (ملاحظات، نصوص، أشكال، صور، صفحات الكتاب)
222
+ 4. <voice> = الكلام المسموع بعد رسم العناصر (طبيعي، ودود، واضح، يشرح ما تم رسمه)
223
+ 5. لا تضع كل شيء دفعة واحدة - اجعله تسلسلياً
224
+ 7. <svg> فقط بكلمات إنجليزية بسيطة ومعبرة
225
+ 8. السبورة تعمل بنظام الإضافة - العناصر السابقة تبقى
226
+ 9. استخدم <text> للعناوين والمعادلات المهمة (بدون خلفية)
227
+ 10. استخدم <note> للتوضيحات والملاحظات (مع خلفية ملونة)
228
+ 11. لا تستخدم أكثر من 3-4 عناصر في كل <board>
229
+ 12. اجعل النص في <voice> طبيعياً كأنك تتحدث مع طالب ويشرح ما تم رسمه على السبورة
230
+ 13. ارسم أولاً ثم تكلم - هذا مهم جداً!
231
+ 14. راجع سجل المحادثة السابقة لتعرف ما تم شرحه وتكمل من حيث توقفت - لا تكرر ما قلته سابقاً
232
+ 15. استخدم <page> عندما تريد عرض صفحة من الكتاب - مثلاً إذا الطالب سأل عن تمرين أو شكل في صفحة معينة
233
+
234
+ when user talk about something not about the subject or something funny etc... you can actually answer without the board just VOICE and be funny smart perfect girl also:
235
+ when you explain something dont make all your explain on the NOTE make the note for important point use the TEXT direct on the board and the ICONS/SHAPES
236
+
237
+ ═══ محتوى المادة ═══
238
+ {file_content}
239
+ {chat_history_text}
240
+
241
+ ═══ الآن أجب على سؤال الطالب ═══
242
+
243
+ رسالة الطالب: {user_message}"""
244
+
245
+ response = self._call_gpt5(
246
+ user_message, system_prompt,
247
+ temperature=0.8, max_tokens=4000
248
+ )
249
+ return response
250
+
251
+ # ─── Resolve tags ───
252
+
253
+ def _resolve_svg_tags(self, xml_response):
254
+ if not xml_response:
255
+ return xml_response
256
+ return self.icon_resolver.resolve_all_in_xml(xml_response)
257
+
258
+ def _resolve_page_tags(self, xml_response, username):
259
+ if not xml_response:
260
+ return xml_response
261
+
262
+ us = self._get_user_session(username)
263
+ subject_id = us.get("subject_id")
264
+ if not subject_id:
265
+ return xml_response
266
+
267
+ base_url = subject_loader.get_pages_base_url(subject_id)
268
+ if not base_url:
269
+ print(f" ⚠️ No pages_base_url for subject {subject_id}")
270
+ return xml_response
271
+
272
+ return resolve_page_tags(xml_response, base_url)
273
+
274
+ # ─── Build sequence from XML ───
275
+
276
+ def _build_sequence_from_xml(self, xml_response, frontend_board_state):
277
+ sequence = []
278
+
279
+ if not xml_response:
280
+ return sequence, frontend_board_state
281
+
282
+ pattern = r'<(voice|board)>(.*?)</\1>'
283
+ matches = list(re.finditer(pattern, xml_response, re.DOTALL))
284
+
285
+ if not matches:
286
+ cleaned = re.sub(r'<[^>]+>', '', xml_response).strip()
287
+ if cleaned:
288
+ sequence.append({
289
+ "type": "voice",
290
+ "text": cleaned,
291
+ "audio_url": None
292
+ })
293
+ return sequence, frontend_board_state
294
+
295
+ current_board_state = list(frontend_board_state)
296
+
297
+ for match in matches:
298
+ tag_type = match.group(1)
299
+ content = match.group(2).strip()
300
+
301
+ if tag_type == "voice":
302
+ cleaned = re.sub(r'<[^>]+>', '', content).strip()
303
+ if cleaned:
304
+ sequence.append({
305
+ "type": "voice",
306
+ "text": cleaned,
307
+ "audio_url": None
308
+ })
309
+
310
+ elif tag_type == "board":
311
+ existing_json_str = json.dumps(
312
+ current_board_state, ensure_ascii=False, indent=2
313
+ )
314
+
315
+ processor_input = (
316
+ f"BOARD NOW (make sure no X Y error):\n"
317
+ f"{existing_json_str}\n\n"
318
+ f"new board need to add :\n"
319
+ f"<board>{content}</board>"
320
+ )
321
+
322
+ print(f" 🔧 Sending to json_processor...")
323
+ print(f" Current board items: {len(current_board_state)}")
324
+
325
+ try:
326
+ json_text = self.board_processor.convert_xml_to_json(
327
+ processor_input
328
+ )
329
+
330
+ if json_text:
331
+ new_items = json.loads(json_text)
332
+
333
+ if isinstance(new_items, list) and new_items:
334
+ added_items = []
335
+ existing_ids = set()
336
+ for item in current_board_state:
337
+ item_key = json.dumps(
338
+ item, sort_keys=True, ensure_ascii=False
339
+ )
340
+ existing_ids.add(item_key)
341
+
342
+ for item in new_items:
343
+ item_key = json.dumps(
344
+ item, sort_keys=True, ensure_ascii=False
345
+ )
346
+ if item_key not in existing_ids:
347
+ added_items.append(item)
348
+
349
+ if added_items:
350
+ sequence.append({
351
+ "type": "board_update",
352
+ "action": "add",
353
+ "items": added_items
354
+ })
355
+
356
+ current_board_state.extend(added_items)
357
+ print(
358
+ f" ✅ json_processor: "
359
+ f"{len(new_items)} total, "
360
+ f"{len(added_items)} new"
361
+ )
362
+
363
+ elif isinstance(new_items, dict):
364
+ added_items = [new_items]
365
+ current_board_state.append(new_items)
366
+ sequence.append({
367
+ "type": "board_update",
368
+ "action": "add",
369
+ "items": added_items
370
+ })
371
+ print(f" ✅ json_processor: 1 item")
372
+
373
+ else:
374
+ print(f" ⚠️ json_processor: unexpected format")
375
+
376
+ except json.JSONDecodeError as e:
377
+ print(f" ❌ json_processor invalid JSON: {e}")
378
+ raw_preview = json_text[:200] if json_text else 'None'
379
+ print(f" Raw: {raw_preview}")
380
+ except Exception as e:
381
+ print(f" ❌ json_processor error: {e}")
382
+
383
+ return sequence, current_board_state
384
+
385
+ # ─── MAIN PIPELINE ───
386
+
387
+ def process_message(self, user_message, username, frontend_board_state=None):
388
+ """
389
+ Main board pipeline for any subject.
390
+
391
+ Args:
392
+ user_message: Student's text
393
+ username: User identifier
394
+ frontend_board_state: Current board items from frontend (source of truth)
395
+
396
+ Returns:
397
+ dict with success, sequence, board_state, chosen_file
398
+ """
399
+ us = self._get_user_session(username)
400
+ subject_id = us.get("subject_id")
401
+
402
+ print(f"\n{'═' * 60}")
403
+ print(f" 👤 Student ({username}): {user_message}")
404
+ print(f" 📚 Subject: {subject_id}")
405
+ print(f"{'═' * 60}")
406
+
407
+ if not subject_id:
408
+ return {
409
+ "success": False,
410
+ "error": "لم يتم تحديد المادة للسبورة",
411
+ "sequence": [{
412
+ "type": "voice",
413
+ "text": "يرجى اختيار المادة أولاً.",
414
+ "audio_url": None
415
+ }],
416
+ "board_state": frontend_board_state or []
417
+ }
418
+
419
+ if frontend_board_state is None:
420
+ frontend_board_state = []
421
+
422
+ print(f" 📋 Board state from frontend: {len(frontend_board_state)} items")
423
+ print(f" 💬 Chat history: {len(us.get('conversation_history', []))} messages")
424
+
425
+ # Step 1: Route
426
+ print("\n 📝 Step 1: Routing message...")
427
+ chosen_file = self._route_message(user_message, username)
428
+ print(f" 📂 Chosen file: {chosen_file}")
429
+
430
+ # Step 2: Generate XML
431
+ print(f" 🤖 Step 2: Generating XML response...")
432
+ xml_response = self._generate_xml_response(user_message, chosen_file, username)
433
+
434
+ if not xml_response:
435
+ print(" ❌ Failed to generate response")
436
+ error_seq = [{
437
+ "type": "voice",
438
+ "text": "عذراً، حدث خطأ في النظام. حاول مرة أخرى.",
439
+ "audio_url": None
440
+ }]
441
+ return {
442
+ "success": False,
443
+ "error": "Failed to generate response",
444
+ "sequence": error_seq,
445
+ "board_state": frontend_board_state
446
+ }
447
+
448
+ print(f" 📝 XML response: {len(xml_response)} chars")
449
+
450
+ # Step 3: Resolve <page> tags
451
+ print(" 📄 Step 3: Resolving <page> tags...")
452
+ xml_response = self._resolve_page_tags(xml_response, username)
453
+
454
+ # Step 4: Resolve <svg> tags
455
+ print(" 🎨 Step 4: Resolving <svg> tags...")
456
+ xml_response = self._resolve_svg_tags(xml_response)
457
+
458
+ # Step 5: Parse XML + convert boards
459
+ print(" 🔧 Step 5: Parsing XML & converting boards...")
460
+ sequence, updated_board_state = self._build_sequence_from_xml(
461
+ xml_response, frontend_board_state
462
+ )
463
+
464
+ voice_count = sum(1 for s in sequence if s['type'] == 'voice')
465
+ board_count = sum(1 for s in sequence if s['type'] == 'board_update')
466
+ print(f" 📊 {len(sequence)} segments ({voice_count} voice, {board_count} board)")
467
+
468
+ # Step 6: Convert voice → audio
469
+ print(" 🔊 Step 6: Converting voice to audio...")
470
+ for item in sequence:
471
+ if item["type"] == "voice" and item.get("text"):
472
+ text_preview = item['text'][:50]
473
+ print(f" 🎙️ Converting: '{text_preview}...'")
474
+ audio_file = self.tts_engine.convert(item["text"])
475
+ if audio_file:
476
+ item["audio_url"] = f"/static/{audio_file}"
477
+ else:
478
+ item["audio_url"] = None
479
+ print(f" ⚠️ TTS failed for this segment")
480
+
481
+ # Step 7: Save chat history
482
+ us["conversation_history"].append({
483
+ "role": "user",
484
+ "content": user_message
485
+ })
486
+
487
+ voice_texts = [
488
+ s["text"] for s in sequence
489
+ if s["type"] == "voice" and s.get("text")
490
+ ]
491
+ assistant_text = " ".join(voice_texts)
492
+ if assistant_text:
493
+ us["conversation_history"].append({
494
+ "role": "assistant",
495
+ "content": assistant_text
496
+ })
497
+
498
+ # Keep history manageable
499
+ if len(us["conversation_history"]) > MAX_CHAT_HISTORY:
500
+ us["conversation_history"] = us["conversation_history"][-MAX_CHAT_HISTORY:]
501
+
502
+ # Step 8: Store sequence for replay
503
+ us["last_sequence"] = sequence
504
+
505
+ # Cleanup old audio
506
+ self.tts_engine.cleanup_old_files()
507
+
508
+ print(f"\n ✅ Response ready!")
509
+ print(f" Sequence: {voice_count} voice + {board_count} board")
510
+ print(f" Board items: {len(updated_board_state)}")
511
+ print(f"{'═' * 60}\n")
512
+
513
+ return {
514
+ "success": True,
515
+ "chosen_file": chosen_file,
516
+ "sequence": sequence,
517
+ "board_state": updated_board_state
518
+ }
519
+
520
+ # ─── Replay ───
521
+
522
+ def get_replay_sequence(self, username):
523
+ us = self._get_user_session(username)
524
+ last_seq = us.get("last_sequence", [])
525
+
526
+ if not last_seq:
527
+ return {
528
+ "success": False,
529
+ "error": "No previous response to replay",
530
+ "sequence": []
531
+ }
532
+
533
+ voice_only = []
534
+ for item in last_seq:
535
+ if item["type"] == "voice":
536
+ voice_only.append({
537
+ "type": "voice",
538
+ "text": item.get("text", ""),
539
+ "audio_url": item.get("audio_url")
540
+ })
541
+
542
+ print(f" 🔄 Replay: {len(voice_only)} voice segments (no board items)")
543
+
544
+ return {
545
+ "success": True,
546
+ "sequence": voice_only
547
+ }
548
+
549
+ # ─── Clear ───
550
+
551
+ def clear_board(self, username):
552
+ us = self._get_user_session(username)
553
+ us["last_sequence"] = []
554
+ print(f" 🗑️ Board cleared for {username}")
555
+ return {"success": True, "board_state": []}
556
+
557
+ def clear_chat_history(self, username):
558
+ us = self._get_user_session(username)
559
+ us["conversation_history"] = []
560
+ us["last_sequence"] = []
561
+ print(f" 🗑️ Board chat history cleared for {username}")
562
+ return {"success": True}
563
+
564
+ def clear_user_session(self, username):
565
+ """Fully clear a user's board session."""
566
+ if username in self._user_sessions:
567
+ del self._user_sessions[username]
568
+ print(f" 🗑️ Full board session cleared for {username}")
569
+ return {"success": True}
board/icons.py ADDED
@@ -0,0 +1,93 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """
2
+ Icon resolver using Icons8 API.
3
+ Resolves <svg>keyword</svg> tags to real image URLs.
4
+ """
5
+
6
+ import re
7
+ import requests
8
+ from config import ICONS8_SEARCH_URL, ICONS8_IMAGE_URL
9
+
10
+
11
+ class IconResolver:
12
+ """Resolves <svg>keyword</svg> tags to Icons8 hand-drawn icon URLs."""
13
+
14
+ def __init__(self):
15
+ self._cache = {}
16
+ print(" ✔ IconResolver initialized (Icons8 hand-drawn)")
17
+
18
+ def resolve(self, search_term):
19
+ if not search_term or not search_term.strip():
20
+ return None
21
+
22
+ term = search_term.strip().lower()
23
+
24
+ if term in self._cache:
25
+ cached = self._cache[term]
26
+ print(f" 🎨 Icon cache hit: '{term}' → {cached}")
27
+ return cached
28
+
29
+ url = ICONS8_SEARCH_URL.format(term=requests.utils.quote(term))
30
+
31
+ try:
32
+ resp = requests.get(url, timeout=15)
33
+ resp.raise_for_status()
34
+ data = resp.json()
35
+
36
+ if data.get("success") and data.get("icons"):
37
+ first_icon = data["icons"][0]
38
+ icon_id = first_icon["id"]
39
+ icon_name = first_icon.get("name", term)
40
+ image_url = ICONS8_IMAGE_URL.format(icon_id=icon_id)
41
+ self._cache[term] = image_url
42
+ print(f" 🎨 Icon found: '{term}' → '{icon_name}' (id={icon_id})")
43
+ return image_url
44
+ else:
45
+ print(f" ⚠️ No icon found for: '{term}'")
46
+ self._cache[term] = None
47
+ return None
48
+
49
+ except requests.exceptions.Timeout:
50
+ print(f" ❌ Icon search timeout for: '{term}'")
51
+ return None
52
+ except requests.exceptions.ConnectionError:
53
+ print(f" ❌ Icon search connection error for: '{term}'")
54
+ return None
55
+ except Exception as e:
56
+ print(f" ❌ Icon search error for '{term}': {e}")
57
+ return None
58
+
59
+ def resolve_all_in_xml(self, xml_text):
60
+ """Replace all <svg>keyword</svg> tags with <img> tags."""
61
+ if not xml_text:
62
+ return xml_text
63
+
64
+ pattern = r'<svg>(.*?)</svg>'
65
+ matches = list(re.finditer(pattern, xml_text, re.DOTALL))
66
+
67
+ if not matches:
68
+ return xml_text
69
+
70
+ print(f" 📝 Found {len(matches)} <svg> tag(s) to resolve...")
71
+
72
+ result = xml_text
73
+ for match in reversed(matches):
74
+ keyword = match.group(1).strip()
75
+ start = match.start()
76
+ end = match.end()
77
+
78
+ image_url = self.resolve(keyword)
79
+
80
+ if image_url:
81
+ replacement = (
82
+ f'<img src="{image_url}" alt="{keyword}" '
83
+ f'w="100" h="100"/>'
84
+ )
85
+ else:
86
+ replacement = (
87
+ f'<note color="white" w="120" h="80">'
88
+ f'🖼️ {keyword}</note>'
89
+ )
90
+
91
+ result = result[:start] + replacement + result[end:]
92
+
93
+ return result
board/pages.py ADDED
@@ -0,0 +1,70 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """
2
+ Page URL builder.
3
+ Converts <page>NUMBER</page> tags to real image URLs.
4
+ Each subject can have its own pages_base_url.
5
+ """
6
+
7
+ import re
8
+
9
+
10
+ def build_page_url(page_number, base_url):
11
+ """
12
+ Convert a page number to the full image URL using the subject's base URL.
13
+ base_url must contain {page_num} placeholder.
14
+ Example base_url:
15
+ https://huggingface.co/.../page_{page_num}.png
16
+ """
17
+ if not base_url:
18
+ print(f" ❌ No pages_base_url configured")
19
+ return None
20
+
21
+ try:
22
+ num = int(str(page_number).strip())
23
+ page_str = str(num).zfill(4)
24
+ url = base_url.format(page_num=page_str)
25
+ print(f" 📄 Page {num} → {url}")
26
+ return url
27
+ except (ValueError, TypeError):
28
+ print(f" ❌ Invalid page number: {page_number}")
29
+ return None
30
+
31
+
32
+ def resolve_page_tags(xml_text, base_url):
33
+ """
34
+ Find all <page>NUMBER</page> tags in the XML and replace them
35
+ with <img> tags using the subject's base URL.
36
+ """
37
+ if not xml_text:
38
+ return xml_text
39
+
40
+ pattern = r'<page>\s*(.*?)\s*</page>'
41
+ matches = list(re.finditer(pattern, xml_text, re.DOTALL))
42
+
43
+ if not matches:
44
+ return xml_text
45
+
46
+ print(f" 📖 Found {len(matches)} <page> tag(s) to resolve...")
47
+
48
+ result = xml_text
49
+ for match in reversed(matches):
50
+ page_num_raw = match.group(1).strip()
51
+ start = match.start()
52
+ end = match.end()
53
+
54
+ url = build_page_url(page_num_raw, base_url)
55
+
56
+ if url:
57
+ replacement = (
58
+ f'<img ubtype="upload" src="{url}" '
59
+ f'alt="صفحة {page_num_raw}" '
60
+ f'w="600" h="800"/>'
61
+ )
62
+ else:
63
+ replacement = (
64
+ f'<note color="white" w="200" h="80">'
65
+ f'📄 صفحة {page_num_raw}</note>'
66
+ )
67
+
68
+ result = result[:start] + replacement + result[end:]
69
+
70
+ return result
board/routes.py ADDED
@@ -0,0 +1,252 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """
2
+ Board API routes.
3
+ Interactive whiteboard endpoints.
4
+ Now supports multiple subjects per user.
5
+ """
6
+
7
+ from flask import Blueprint, request, jsonify, session, render_template, redirect, url_for, flash, send_from_directory
8
+ from auth.helpers import is_session_valid
9
+ from database.users import get_user
10
+ from subjects.access import validate_user_subject_access
11
+ from subjects.definitions import get_subject_name, is_board_enabled, SUBJECTS
12
+ from subjects.loader import subject_loader
13
+
14
+ board_bp = Blueprint('board', __name__)
15
+
16
+ # Reference to board engine - set from app.py
17
+ _board_engine = None
18
+
19
+
20
+ def init_board_engine(engine):
21
+ global _board_engine
22
+ _board_engine = engine
23
+
24
+
25
+ @board_bp.route('/board/<subject_id>')
26
+ def board_page(subject_id):
27
+ """
28
+ Render the board page for a specific subject.
29
+ URL: /board/physics_mechanic
30
+ """
31
+ if not is_session_valid():
32
+ session.clear()
33
+ flash('انتهت الجلسة، يرجى تسجيل الدخول مرة أخرى.', 'error')
34
+ return redirect(url_for('auth.login'))
35
+
36
+ username = session['username']
37
+ user_data = get_user(username)
38
+
39
+ if not user_data or not user_data.get('verified', False):
40
+ flash('حسابك غير مفعّل. تواصل مع الإدارة.', 'error')
41
+ return redirect(url_for('dashboard'))
42
+
43
+ # Validate access
44
+ has_access, access_error = validate_user_subject_access(username, subject_id)
45
+ if not has_access:
46
+ flash(access_error, 'error')
47
+ return redirect(url_for('dashboard'))
48
+
49
+ # Check if subject supports board
50
+ if not is_board_enabled(subject_id):
51
+ flash('هذه المادة لا تدعم السبورة التفاعلية حالياً.', 'error')
52
+ return redirect(url_for('dashboard'))
53
+
54
+ # Load subject data
55
+ subject_data = subject_loader.load(subject_id)
56
+ if not subject_data:
57
+ flash(f"مجلد المادة '{subject_id}' غير موجود على الخادم.", 'error')
58
+ return redirect(url_for('dashboard'))
59
+
60
+ # Set subject in board engine
61
+ _board_engine.set_subject(username, subject_id)
62
+
63
+ # Get subject display name
64
+ student_type = user_data.get('student_type', 'علمي')
65
+ subject_name = get_subject_name(student_type, subject_id)
66
+
67
+ return render_template('board.html',
68
+ username=username,
69
+ subject_id=subject_id,
70
+ subject_name=subject_name)
71
+
72
+
73
+ @board_bp.route('/api/board/message', methods=['POST'])
74
+ def handle_board_message():
75
+ """
76
+ Process a student message on the board.
77
+
78
+ EXPECTS JSON:
79
+ {
80
+ "message": "student text",
81
+ "board_state": [... current board items from frontend ...],
82
+ "subject_id": "physics_mechanic" (optional, uses current if not sent)
83
+ }
84
+ """
85
+ if not is_session_valid():
86
+ return jsonify({"error": "غير مصرح", "code": "unauthorized"}), 401
87
+
88
+ data = request.get_json()
89
+ if not data:
90
+ return jsonify({"error": "No JSON data"}), 400
91
+
92
+ username = session['username']
93
+ user_message = (data.get('message', '') or '').strip()
94
+
95
+ if not user_message:
96
+ return jsonify({"error": "Empty message"}), 400
97
+
98
+ # Validate user
99
+ user = get_user(username)
100
+ if not user or not user.get('verified', False):
101
+ return jsonify({"error": "غير مصرح"}), 403
102
+
103
+ # Handle subject_id - can be sent with each request or use current
104
+ subject_id = data.get('subject_id', '').strip()
105
+ if subject_id:
106
+ # Validate access
107
+ has_access, access_error = validate_user_subject_access(username, subject_id)
108
+ if not has_access:
109
+ return jsonify({"error": access_error, "code": "no_access"}), 403
110
+
111
+ # Check board support
112
+ if not is_board_enabled(subject_id):
113
+ return jsonify({"error": "هذه المادة لا تدعم السبورة التفاعلية"}), 400
114
+
115
+ # Set/switch subject
116
+ _board_engine.set_subject(username, subject_id)
117
+ else:
118
+ # Use current subject
119
+ subject_id = _board_engine.get_subject(username)
120
+ if not subject_id:
121
+ return jsonify({"error": "لم يتم تحديد المادة للسبورة", "need_subject": True}), 400
122
+
123
+ # Get board state from frontend
124
+ frontend_board_state = data.get('board_state', [])
125
+ if not isinstance(frontend_board_state, list):
126
+ frontend_board_state = []
127
+
128
+ print(f"\n 📥 Board message from {username}:")
129
+ print(f" Subject: {subject_id}")
130
+ print(f" Message: {user_message[:80]}...")
131
+ print(f" Board state: {len(frontend_board_state)} items")
132
+
133
+ try:
134
+ result = _board_engine.process_message(
135
+ user_message, username, frontend_board_state
136
+ )
137
+ return jsonify(result)
138
+ except Exception as e:
139
+ print(f"❌ Error processing board message: {e}")
140
+ import traceback
141
+ traceback.print_exc()
142
+ return jsonify({
143
+ "success": False,
144
+ "error": str(e),
145
+ "sequence": [{
146
+ "type": "voice",
147
+ "text": "عذراً، حدث خطأ غير متوقع.",
148
+ "audio_url": None
149
+ }],
150
+ "board_state": frontend_board_state
151
+ }), 500
152
+
153
+
154
+ @board_bp.route('/api/board/replay', methods=['POST'])
155
+ def replay_last():
156
+ """Replay the last response. Returns ONLY voice segments."""
157
+ if not is_session_valid():
158
+ return jsonify({"error": "غير مصرح"}), 401
159
+
160
+ username = session['username']
161
+ result = _board_engine.get_replay_sequence(username)
162
+ return jsonify(result)
163
+
164
+
165
+ @board_bp.route('/api/board/state', methods=['GET'])
166
+ def get_board_state():
167
+ """Get board state (frontend is source of truth)."""
168
+ if not is_session_valid():
169
+ return jsonify({"error": "غير مصرح"}), 401
170
+ return jsonify({"board_state": []})
171
+
172
+
173
+ @board_bp.route('/api/board/clear', methods=['POST'])
174
+ def clear_board():
175
+ """Clear the board completely."""
176
+ if not is_session_valid():
177
+ return jsonify({"error": "غير مصرح"}), 401
178
+
179
+ username = session['username']
180
+ result = _board_engine.clear_board(username)
181
+ return jsonify(result)
182
+
183
+
184
+ @board_bp.route('/api/board/chat/clear', methods=['POST'])
185
+ def clear_board_chat():
186
+ """Clear board conversation history."""
187
+ if not is_session_valid():
188
+ return jsonify({"error": "غير مصرح"}), 401
189
+
190
+ username = session['username']
191
+ result = _board_engine.clear_chat_history(username)
192
+ return jsonify(result)
193
+
194
+
195
+ @board_bp.route('/api/board/sync', methods=['POST'])
196
+ def sync_board_state():
197
+ """Sync board state from frontend (compatibility endpoint)."""
198
+ if not is_session_valid():
199
+ return jsonify({"error": "غير مصرح"}), 401
200
+ return jsonify({"success": True})
201
+
202
+
203
+ @board_bp.route('/api/board/set-subject', methods=['POST'])
204
+ def set_board_subject():
205
+ """
206
+ Set/switch the board subject.
207
+
208
+ EXPECTS JSON:
209
+ {
210
+ "subject_id": "physics_mechanic"
211
+ }
212
+ """
213
+ if not is_session_valid():
214
+ return jsonify({"error": "غير مصرح"}), 401
215
+
216
+ data = request.get_json()
217
+ if not data:
218
+ return jsonify({"error": "No JSON data"}), 400
219
+
220
+ username = session['username']
221
+ subject_id = data.get('subject_id', '').strip()
222
+
223
+ if not subject_id:
224
+ return jsonify({"error": "يرجى تحديد المادة"}), 400
225
+
226
+ # Validate access
227
+ has_access, access_error = validate_user_subject_access(username, subject_id)
228
+ if not has_access:
229
+ return jsonify({"error": access_error, "code": "no_access"}), 403
230
+
231
+ # Check board support
232
+ if not is_board_enabled(subject_id):
233
+ return jsonify({"error": "هذه المادة لا تدعم السبورة التفاعلية"}), 400
234
+
235
+ # Load subject
236
+ subject_data = subject_loader.load(subject_id)
237
+ if not subject_data:
238
+ return jsonify({"error": f"مجلد المادة '{subject_id}' غير موجود"}), 404
239
+
240
+ # Set subject
241
+ _board_engine.set_subject(username, subject_id)
242
+
243
+ user = get_user(username)
244
+ student_type = user.get('student_type', 'علمي')
245
+ subject_name = get_subject_name(student_type, subject_id)
246
+
247
+ return jsonify({
248
+ "success": True,
249
+ "subject_id": subject_id,
250
+ "subject_name": subject_name,
251
+ "message": f"تم تحديد مادة '{subject_name}' للسبورة"
252
+ })
board/tts.py ADDED
@@ -0,0 +1,78 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """
2
+ Text-to-Speech engine.
3
+ Converts Arabic text to audio files.
4
+ """
5
+
6
+ import os
7
+ import uuid
8
+ import requests
9
+ from pathlib import Path
10
+ from config import TTS_URL, AUDIO_OUTPUT_DIR, MAX_AUDIO_FILES
11
+
12
+
13
+ class TTSEngine:
14
+ def __init__(self):
15
+ self.synthesize_endpoint = f"{TTS_URL}/synthesize"
16
+ self.output_dir = AUDIO_OUTPUT_DIR
17
+ Path(self.output_dir).mkdir(parents=True, exist_ok=True)
18
+ print(" ✔ TTSEngine initialized")
19
+
20
+ def convert(self, text, voice_id=None):
21
+ if not text or not text.strip():
22
+ return None
23
+
24
+ clean_text = text.strip()
25
+ if len(clean_text) < 2:
26
+ return None
27
+
28
+ file_id = uuid.uuid4().hex[:12]
29
+ filename = f"audio/voice_{file_id}.mp3"
30
+ filepath = os.path.join("static", filename)
31
+
32
+ payload = {"text": clean_text}
33
+ if voice_id:
34
+ payload["voice_id"] = voice_id
35
+
36
+ headers = {"Content-Type": "application/json"}
37
+
38
+ try:
39
+ response = requests.post(
40
+ self.synthesize_endpoint,
41
+ headers=headers,
42
+ json=payload,
43
+ timeout=60
44
+ )
45
+
46
+ if response.status_code == 200 and len(response.content) > 500:
47
+ with open(filepath, 'wb') as f:
48
+ f.write(response.content)
49
+ file_size = os.path.getsize(filepath)
50
+ print(f" 🔊 TTS saved: {filename} ({file_size} bytes)")
51
+ return filename
52
+ else:
53
+ print(
54
+ f" ❌ TTS error: status={response.status_code}, "
55
+ f"size={len(response.content)}"
56
+ )
57
+ return None
58
+
59
+ except requests.exceptions.Timeout:
60
+ print(" ❌ TTS timeout")
61
+ return None
62
+ except Exception as e:
63
+ print(f" ❌ TTS error: {e}")
64
+ return None
65
+
66
+ def cleanup_old_files(self):
67
+ audio_dir = Path(self.output_dir)
68
+ files = sorted(
69
+ audio_dir.glob("voice_*.mp3"),
70
+ key=lambda f: f.stat().st_mtime
71
+ )
72
+ if len(files) > MAX_AUDIO_FILES:
73
+ for f in files[:len(files) - MAX_AUDIO_FILES]:
74
+ try:
75
+ f.unlink()
76
+ print(f" 🗑️ Cleaned: {f.name}")
77
+ except Exception:
78
+ pass
chat/__init__.py ADDED
@@ -0,0 +1,4 @@
 
 
 
 
 
1
+ """
2
+ Chat package.
3
+ Handles text chat with AI (non-board mode).
4
+ """
chat/__pycache__/__init__.cpython-314.pyc ADDED
Binary file (221 Bytes). View file
 
chat/__pycache__/agent.cpython-314.pyc ADDED
Binary file (19.4 kB). View file
 
chat/__pycache__/history.cpython-314.pyc ADDED
Binary file (10.7 kB). View file
 
chat/__pycache__/routes.cpython-314.pyc ADDED
Binary file (19.3 kB). View file
 
chat/agent.py ADDED
@@ -0,0 +1,410 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """
2
+ AI Agent for text chat mode.
3
+ Handles routing, GPT responses, Mistral streaming,
4
+ voice transcription, and image analysis.
5
+ """
6
+
7
+ import json
8
+ import requests
9
+ from datetime import datetime, timezone
10
+ from config import GPT_URL, MISTRAL_COOKIE, TRANSCRIPT_URL, CLOUDINARY_URL, CLOUDINARY_PRESET
11
+ from chat.history import ChatHistory
12
+ from subjects.loader import subject_loader
13
+ from database.chat_history import save_user_chat_to_db, load_user_chat_from_db
14
+
15
+
16
+ class AIAgent:
17
+ def __init__(self):
18
+ self.gpt_url = GPT_URL
19
+ self.mistral_cookie = MISTRAL_COOKIE
20
+ self.transcript_base_url = TRANSCRIPT_URL
21
+ self.cloudinary_url = CLOUDINARY_URL
22
+ self.cloudinary_preset = CLOUDINARY_PRESET
23
+
24
+ self.chat_history = ChatHistory()
25
+
26
+ # Exam sessions (in-memory)
27
+ self.exam_sessions = {}
28
+ self.exam_lock = __import__('threading').Lock()
29
+
30
+ print("✅ AIAgent initialized")
31
+
32
+ # ─── GPT call ───
33
+
34
+ def _call_gpt5(self, user_message, system_prompt, temperature=0.7):
35
+ payload = {
36
+ "user_input": user_message,
37
+ "chat_history": [{"role": "system", "content": system_prompt}],
38
+ "temperature": temperature,
39
+ "top_p": 0.95,
40
+ "max_completion_tokens": 4000
41
+ }
42
+ try:
43
+ response = requests.post(self.gpt_url, json=payload, timeout=120)
44
+ response.raise_for_status()
45
+ return response.json().get("assistant_response", "")
46
+ except Exception as e:
47
+ print(f"❌ GPT-5 Error: {e}")
48
+ return None
49
+
50
+ def _call_gpt5_multipart(self, image_url, text_prompt, system_prompt, temperature=0.7):
51
+ payload = {
52
+ "user_input": None,
53
+ "chat_history": [
54
+ {"role": "system", "content": system_prompt},
55
+ {
56
+ "role": "user",
57
+ "type": "multipart",
58
+ "content": [
59
+ {"type": "image", "url": image_url},
60
+ {"type": "text", "text": text_prompt}
61
+ ]
62
+ }
63
+ ],
64
+ "temperature": temperature,
65
+ "top_p": 0.95,
66
+ "max_completion_tokens": 4000
67
+ }
68
+ try:
69
+ response = requests.post(self.gpt_url, json=payload, timeout=120)
70
+ response.raise_for_status()
71
+ return response.json().get("assistant_response", "")
72
+ except Exception as e:
73
+ print(f"❌ GPT-5 Multipart Error: {e}")
74
+ return None
75
+
76
+ # ─── Mistral streaming ───
77
+
78
+ def _call_mistral_stream(self, user_message, file_content, session_id):
79
+ chat_context = self.chat_history.get_full_context(session_id)
80
+
81
+ full_prompt = f"""{file_content}
82
+
83
+ === سياق المحادثة ===
84
+ {chat_context if chat_context else "هذه بداية المحادثة مع الطالب."}
85
+ === نهاية السياق ===
86
+
87
+ سؤال الطالب الحالي: {user_message}
88
+
89
+ إجابتك:"""
90
+
91
+ headers = {
92
+ "Content-Type": "application/json",
93
+ "Cookie": self.mistral_cookie,
94
+ "user-agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36"
95
+ }
96
+
97
+ payload = {
98
+ "inputs": [{
99
+ "object": "entry",
100
+ "type": "message.input",
101
+ "created_at": datetime.now(timezone.utc).isoformat(),
102
+ "role": "user",
103
+ "content": full_prompt,
104
+ "prefix": False
105
+ }],
106
+ "stream": True,
107
+ "instructions": "",
108
+ "tools": [],
109
+ "completion_args": {
110
+ "temperature": 0.7,
111
+ "top_p": 0.95,
112
+ "max_tokens": 4096
113
+ },
114
+ "model": "mistral-medium-latest"
115
+ }
116
+
117
+ try:
118
+ response = requests.post(
119
+ "https://console.mistral.ai/api-ui/bora/v1/conversations",
120
+ headers=headers,
121
+ json=payload,
122
+ stream=True,
123
+ timeout=120
124
+ )
125
+
126
+ if response.status_code not in [200, 201]:
127
+ error_msg = f"Mistral Error: {response.status_code} - {response.text[:500]}"
128
+ yield json.dumps({"error": error_msg}) + "\n"
129
+ return
130
+
131
+ full_response = ""
132
+ for line in response.iter_lines():
133
+ if line:
134
+ line = line.decode('utf-8')
135
+ if line.startswith('data: '):
136
+ try:
137
+ data = json.loads(line[6:])
138
+ if data.get('type') == 'message.output.delta':
139
+ content = data.get('content', '')
140
+ if content:
141
+ full_response += content
142
+ yield json.dumps({"chunk": content}) + "\n"
143
+ except json.JSONDecodeError:
144
+ continue
145
+
146
+ if full_response:
147
+ self.chat_history.add_message(session_id, "assistant", full_response)
148
+
149
+ yield json.dumps({"done": True, "full_response": full_response}) + "\n"
150
+
151
+ except requests.exceptions.Timeout:
152
+ yield json.dumps({"error": "انتهت مهلة الاتصال بالخادم. حاول مرة أخرى."}) + "\n"
153
+ except requests.exceptions.ConnectionError:
154
+ yield json.dumps({"error": "خطأ في الاتصال بالخادم."}) + "\n"
155
+ except Exception as e:
156
+ yield json.dumps({"error": str(e)}) + "\n"
157
+
158
+ # ─── Routing ───
159
+
160
+ def route_message(self, user_message, session_id):
161
+ subject_id = self.chat_history.get_subject(session_id)
162
+ subject_data = subject_loader.load(subject_id) if subject_id else None
163
+ if not subject_data:
164
+ return "main.txt"
165
+
166
+ structure_content = subject_data.get("structure.txt", "")
167
+ chat_context = self.chat_history.get_full_context(session_id)
168
+ last_file = self.chat_history.get_last_file(session_id)
169
+ p_files = subject_data.get("_p_files", [])
170
+ p_files_list = "\n".join([f"- {f}" for f in p_files])
171
+
172
+ routing_prompt = f"""{structure_content}
173
+
174
+ **الملفات المتاحة:**
175
+ - main.txt: للتحيات والأسئلة العامة
176
+ {p_files_list}
177
+
178
+ **سياق المحادثة:**
179
+ {chat_context if chat_context else "لا يوجد سياق سابق"}
180
+
181
+ **الملف الأخير المستخدم:** {last_file if last_file else "لا يوجد"}
182
+
183
+ **تعليمات:**
184
+ - إذا كانت الرسالة متابعة لموضوع سابق → استخدم نفس الملف الأخير: {last_file if last_file else "main.txt"}
185
+ - إذا قال الطالب "استمر" أو "أكمل" → استخدم نفس الملف الأخير
186
+ - أجب **فقط** باسم الملف (مثال: p1.txt أو main.txt)
187
+
188
+ رسالة الطالب: {user_message}
189
+
190
+ الملف المناسب:"""
191
+
192
+ chosen_file = self._call_gpt5(user_message, routing_prompt, temperature=0.2)
193
+
194
+ if not chosen_file:
195
+ return last_file if last_file else "main.txt"
196
+
197
+ chosen_file = chosen_file.strip().lower()
198
+ valid_files = ["main.txt"] + p_files
199
+
200
+ for vf in valid_files:
201
+ if vf in chosen_file:
202
+ return vf
203
+
204
+ return last_file if last_file else "main.txt"
205
+
206
+ # ─── GPT response ───
207
+
208
+ def respond_gpt(self, user_message, chosen_file, session_id):
209
+ subject_id = self.chat_history.get_subject(session_id)
210
+ subject_data = subject_loader.load(subject_id) if subject_id else None
211
+ if not subject_data:
212
+ return "عذراً، لم يتم تحديد المادة. يرجى اختيار المادة أولاً."
213
+
214
+ main_content = subject_data.get("main.txt", "")
215
+ chat_context = self.chat_history.get_full_context(session_id)
216
+
217
+ system_prompt = f"""{main_content}
218
+
219
+ === سياق المحادثة السابقة ===
220
+ {chat_context if chat_context else "هذه بداية المحادثة."}
221
+ === نهاية السياق ==="""
222
+
223
+ self.chat_history.add_message(session_id, "user", user_message)
224
+ response = self._call_gpt5(user_message, system_prompt, temperature=0.8)
225
+
226
+ if response:
227
+ self.chat_history.add_message(session_id, "assistant", response)
228
+ return response
229
+ else:
230
+ err = "عذراً، حدث خطأ في النظام. حاول مرة أخرى."
231
+ self.chat_history.add_message(session_id, "assistant", err)
232
+ return err
233
+
234
+ # ─── Mistral response ───
235
+
236
+ def respond_mistral_stream(self, user_message, chosen_file, session_id):
237
+ subject_id = self.chat_history.get_subject(session_id)
238
+ subject_data = subject_loader.load(subject_id) if subject_id else None
239
+ if not subject_data:
240
+ def error_gen():
241
+ yield json.dumps({"error": "عذراً، لم يتم تحديد المادة."}) + "\n"
242
+ return error_gen()
243
+
244
+ file_content = subject_data.get(chosen_file, "")
245
+ self.chat_history.add_message(session_id, "user", user_message)
246
+ return self._call_mistral_stream(user_message, file_content, session_id)
247
+
248
+ # ─── Process message (route + decide) ───
249
+
250
+ def process_message(self, user_message, session_id):
251
+ subject = self.chat_history.get_subject(session_id)
252
+ if not subject:
253
+ return None, "no_subject"
254
+
255
+ subject_data = subject_loader.load(subject)
256
+ if not subject_data:
257
+ return None, "subject_not_found"
258
+
259
+ chosen_file = self.route_message(user_message, session_id)
260
+ self.chat_history.set_last_file(session_id, chosen_file)
261
+
262
+ print(f"📀 Subject: {subject} | Routed to: {chosen_file} | Session: {session_id}")
263
+ return chosen_file, "ok"
264
+
265
+ # ─── Subject session management ───
266
+
267
+ def select_subject(self, username, session_id, subject_id):
268
+ """Select a subject and load/restore chat history."""
269
+ current_subject = self.chat_history.get_subject(session_id)
270
+
271
+ # Save current subject chat before switching
272
+ if current_subject and current_subject != subject_id:
273
+ raw = self.chat_history.get_raw_session(session_id)
274
+ save_user_chat_to_db(username, current_subject, raw)
275
+
276
+ # Clear and set new subject
277
+ self.chat_history.clear_session(session_id)
278
+ self.chat_history.set_subject(session_id, subject_id)
279
+
280
+ # Try to restore saved chat
281
+ saved = load_user_chat_from_db(username, subject_id)
282
+ if saved:
283
+ self.chat_history.restore_session(session_id, saved)
284
+
285
+ # Save immediately
286
+ raw = self.chat_history.get_raw_session(session_id)
287
+ save_user_chat_to_db(username, subject_id, raw)
288
+
289
+ def save_current_chat(self, username, session_id):
290
+ """Save current session to DB."""
291
+ subject_id = self.chat_history.get_subject(session_id)
292
+ if subject_id:
293
+ raw = self.chat_history.get_raw_session(session_id)
294
+ save_user_chat_to_db(username, subject_id, raw)
295
+
296
+ # ─── Audio ───
297
+
298
+ def upload_audio(self, audio_file_path, original_filename):
299
+ try:
300
+ with open(audio_file_path, 'rb') as f:
301
+ files = {'audio': (original_filename, f, 'audio/webm')}
302
+ response = requests.post(
303
+ f"{self.transcript_base_url}/upload",
304
+ files=files,
305
+ timeout=60
306
+ )
307
+ response.raise_for_status()
308
+ data = response.json()
309
+ if 'file_url' in data:
310
+ return data['file_url'], None
311
+ else:
312
+ return None, data.get('error', 'Upload failed')
313
+ except Exception as e:
314
+ print(f"❌ Audio upload error: {e}")
315
+ return None, str(e)
316
+
317
+ def transcribe_audio(self, file_url):
318
+ try:
319
+ payload = {
320
+ "file_url": file_url,
321
+ "prompt": "هذا تسجيل صوتي لطالب يسأل سؤالاً دراسياً"
322
+ }
323
+ response = requests.post(
324
+ f"{self.transcript_base_url}/transcribe",
325
+ json=payload,
326
+ timeout=120
327
+ )
328
+ response.raise_for_status()
329
+ data = response.json()
330
+ if 'transcription' in data:
331
+ return data['transcription'], None
332
+ else:
333
+ return None, data.get('error', 'Transcription failed')
334
+ except Exception as e:
335
+ print(f"❌ Transcription error: {e}")
336
+ return None, str(e)
337
+
338
+ # ─── Image ───
339
+
340
+ def upload_image_to_cloudinary(self, image_path):
341
+ try:
342
+ with open(image_path, 'rb') as image_file:
343
+ files = {'file': image_file}
344
+ data = {'upload_preset': self.cloudinary_preset}
345
+ response = requests.post(
346
+ self.cloudinary_url,
347
+ files=files,
348
+ data=data,
349
+ timeout=60
350
+ )
351
+ if response.status_code == 200:
352
+ result = response.json()
353
+ image_url = result.get('url') or result.get('secure_url')
354
+ return image_url, None
355
+ else:
356
+ return None, f"Cloudinary error: {response.status_code}"
357
+ except Exception as e:
358
+ return None, str(e)
359
+
360
+ def analyze_image(self, image_url, session_id):
361
+ system_prompt = """أنت مساعد تعليمي ذكي متخصص في تحليل الصور الدراسية.
362
+
363
+ مهمتك:
364
+ 1. إذا كانت الصورة تحتوي على محتوى دراسي (معادلات، نصوص، مسائل، رسوم بيانية، جداول، شروحات، كتب، أوراق امتحانات):
365
+ - استخرج كل المحتوى من الصورة بدقة تامة
366
+ - اكتب المعادلات بصيغة LaTeX
367
+ - اكتب النصوص كما هي
368
+ - اشرح الرسوم البيانية إن وجدت
369
+ - قدم المحتوى بشكل منظم ومفيد
370
+
371
+ 2. إذا كانت الصورة لا تحتوي على محتوى دراسي:
372
+ - أجب فقط بالكلمة: <unsupported>
373
+
374
+ لا تضف أي تعليق إضافي."""
375
+
376
+ result = self._call_gpt5_multipart(
377
+ image_url=image_url,
378
+ text_prompt="حلل هذه الصورة واستخرج محتواها الدراسي",
379
+ system_prompt=system_prompt,
380
+ temperature=0.3
381
+ )
382
+ return result
383
+
384
+ # ─── Exam session management ───
385
+
386
+ def create_exam_session(self, username, subject_id, door_file, question_count, difficulty):
387
+ with self.exam_lock:
388
+ self.exam_sessions[username] = {
389
+ "subject_id": subject_id,
390
+ "door_file": door_file,
391
+ "question_count": question_count,
392
+ "difficulty": difficulty,
393
+ "questions": [],
394
+ "current_index": 0,
395
+ "score": 0,
396
+ "answers": [],
397
+ "started_at": datetime.now().isoformat(),
398
+ "status": "generating",
399
+ }
400
+ return self.exam_sessions[username]
401
+
402
+ def get_exam_session(self, username):
403
+ with self.exam_lock:
404
+ return self.exam_sessions.get(username, None)
405
+
406
+ def clear_exam_session(self, username):
407
+ with self.exam_lock:
408
+ if username in self.exam_sessions:
409
+ del self.exam_sessions[username]
410
+ print(f"🗑️ Cleared exam session for {username}")
chat/history.py ADDED
@@ -0,0 +1,187 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """
2
+ In-memory chat history manager with auto-summarization.
3
+ Per-session, thread-safe.
4
+ """
5
+
6
+ import threading
7
+ import requests
8
+ from datetime import datetime, timezone
9
+ from config import GPT_URL, SUMMARY_TRIGGER_COUNT
10
+
11
+
12
+ class ChatHistory:
13
+ def __init__(self):
14
+ self.gpt_url = GPT_URL
15
+ self.sessions = {}
16
+ self.lock = threading.Lock()
17
+ print(" ✔ ChatHistory initialized")
18
+
19
+ def get_or_create_session(self, session_id):
20
+ with self.lock:
21
+ if session_id not in self.sessions:
22
+ self.sessions[session_id] = {
23
+ "messages": [],
24
+ "full_messages": [],
25
+ "summary": "",
26
+ "message_count": 0,
27
+ "last_file": None,
28
+ "subject": None,
29
+ }
30
+ return self.sessions[session_id]
31
+
32
+ def set_subject(self, session_id, subject):
33
+ s = self.get_or_create_session(session_id)
34
+ with self.lock:
35
+ s["subject"] = subject
36
+
37
+ def get_subject(self, session_id):
38
+ s = self.get_or_create_session(session_id)
39
+ return s.get("subject", None)
40
+
41
+ def add_message(self, session_id, role, content):
42
+ s = self.get_or_create_session(session_id)
43
+ msg = {
44
+ "role": role,
45
+ "content": content,
46
+ "timestamp": datetime.now(timezone.utc).isoformat()
47
+ }
48
+ with self.lock:
49
+ s["messages"].append(msg)
50
+ s["full_messages"].append(msg)
51
+ s["message_count"] += 1
52
+
53
+ if len(s["messages"]) >= SUMMARY_TRIGGER_COUNT:
54
+ self._trigger_summary(session_id)
55
+
56
+ def _trigger_summary(self, session_id):
57
+ s = self.sessions[session_id]
58
+ with self.lock:
59
+ msgs = s["messages"].copy()
60
+ s["messages"] = []
61
+
62
+ if not msgs:
63
+ return
64
+
65
+ conv_text = ""
66
+ for m in msgs:
67
+ if m["role"] == "user":
68
+ conv_text += f"الطالب: {m['content']}\n\n"
69
+ elif m["role"] == "assistant":
70
+ conv_text += f"المدرس: {m['content']}\n\n"
71
+
72
+ prev_summary = s.get("summary", "")
73
+ summary_prompt = f"""أنت نظام تلخيص ذكي لمحادثات تعليمية.
74
+ مهمتك: تلخيص المحادثة التالية بشكل دقيق ومفيد.
75
+
76
+ **التعليمات:**
77
+ 1. لخّص النقاط الرئيسية التي ناقشها الطالب والمدرس
78
+ 2. حدد المواضيع التي سأل عنها الطالب
79
+ 3. قيّم مستوى فهم الطالب (مبتدئ / متوسط / متقدم)
80
+ 4. اذكر أي نقاط ضعف أو قوة لاحظتها
81
+ 5. اذكر آخر موضوع كان يُناقش
82
+ 6. اجعل التلخيص مختصراً لكن شاملاً
83
+
84
+ {"**التلخيص السابق:**" + chr(10) + prev_summary + chr(10) if prev_summary else ""}
85
+
86
+ **المحادثة الجديدة:**
87
+ {conv_text}
88
+
89
+ **التلخيص الشامل:**"""
90
+
91
+ try:
92
+ payload = {
93
+ "user_input": "قم بتلخيص المحادثة",
94
+ "chat_history": [{"role": "system", "content": summary_prompt}],
95
+ "temperature": 0.3,
96
+ "top_p": 0.95,
97
+ "max_completion_tokens": 1500
98
+ }
99
+ resp = requests.post(self.gpt_url, json=payload, timeout=60)
100
+ resp.raise_for_status()
101
+ new_summary = resp.json().get("assistant_response", "")
102
+ if new_summary:
103
+ with self.lock:
104
+ s["summary"] = new_summary
105
+ else:
106
+ with self.lock:
107
+ s["messages"] = msgs + s["messages"]
108
+ except Exception as e:
109
+ print(f"❌ Summary error: {e}")
110
+ with self.lock:
111
+ s["messages"] = msgs + s["messages"]
112
+
113
+ def get_full_context(self, session_id):
114
+ s = self.get_or_create_session(session_id)
115
+ parts = []
116
+ if s["summary"]:
117
+ parts.append(f"**ملخص المحادثة السابقة:**\n{s['summary']}")
118
+ if s["messages"]:
119
+ recent = ""
120
+ for m in s["messages"]:
121
+ if m["role"] == "user":
122
+ recent += f"الطالب: {m['content']}\n\n"
123
+ elif m["role"] == "assistant":
124
+ recent += f"المدرس: {m['content']}\n\n"
125
+ if recent:
126
+ parts.append(f"**المحادثة الحالية:**\n{recent}")
127
+ return "\n\n".join(parts)
128
+
129
+ def get_messages_for_display(self, session_id):
130
+ s = self.get_or_create_session(session_id)
131
+ return s["full_messages"].copy()
132
+
133
+ def get_summary(self, session_id):
134
+ s = self.get_or_create_session(session_id)
135
+ return s.get("summary", "")
136
+
137
+ def set_last_file(self, session_id, filename):
138
+ s = self.get_or_create_session(session_id)
139
+ with self.lock:
140
+ s["last_file"] = filename
141
+
142
+ def get_last_file(self, session_id):
143
+ s = self.get_or_create_session(session_id)
144
+ return s.get("last_file", None)
145
+
146
+ def clear_session(self, session_id):
147
+ with self.lock:
148
+ if session_id in self.sessions:
149
+ current_subject = self.sessions[session_id].get("subject", None)
150
+ self.sessions[session_id] = {
151
+ "messages": [],
152
+ "full_messages": [],
153
+ "summary": "",
154
+ "message_count": 0,
155
+ "last_file": None,
156
+ "subject": current_subject,
157
+ }
158
+
159
+ def restore_session(self, session_id, saved_data):
160
+ """Restore a session from saved DB data."""
161
+ s = self.get_or_create_session(session_id)
162
+ with self.lock:
163
+ s["messages"] = saved_data.get("messages", [])
164
+ s["full_messages"] = saved_data.get("full_messages", saved_data.get("messages", []))
165
+ s["summary"] = saved_data.get("summary", "")
166
+ s["message_count"] = saved_data.get("message_count", 0)
167
+ s["last_file"] = saved_data.get("last_file", None)
168
+ s["subject"] = saved_data.get("subject", s.get("subject"))
169
+
170
+ def get_session_info(self, session_id):
171
+ s = self.get_or_create_session(session_id)
172
+ return {
173
+ "total_messages": s["message_count"],
174
+ "current_messages": len(s["messages"]),
175
+ "has_summary": bool(s["summary"]),
176
+ "last_file": s["last_file"],
177
+ "subject": s["subject"],
178
+ "summary_preview": (
179
+ s["summary"][:200] + "..."
180
+ if len(s.get("summary", "")) > 200
181
+ else s.get("summary", "")
182
+ )
183
+ }
184
+
185
+ def get_raw_session(self, session_id):
186
+ """Get raw session dict for saving to DB."""
187
+ return self.get_or_create_session(session_id)
chat/routes.py ADDED
@@ -0,0 +1,424 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """
2
+ Chat API routes for text-based AI chat.
3
+ """
4
+
5
+ import json
6
+ import os
7
+ import tempfile
8
+ from datetime import datetime
9
+ from flask import Blueprint, request, jsonify, Response, stream_with_context, session, render_template, redirect, url_for, flash
10
+ import requests as http_requests
11
+
12
+ from auth.helpers import is_session_valid
13
+ from database.users import get_user
14
+ from database.chat_history import (
15
+ save_user_chat_to_db, clear_user_subject_chat_from_db,
16
+ get_all_user_chats_from_db
17
+ )
18
+ from subjects.access import validate_user_subject_access, get_user_accessible_subjects
19
+ from subjects.definitions import SUBJECTS, get_subject_name
20
+ from subjects.loader import subject_loader
21
+
22
+ chat_bp = Blueprint('chat', __name__)
23
+
24
+ # Reference to agent - set from app.py
25
+ _agent = None
26
+
27
+
28
+ def init_chat_agent(agent):
29
+ global _agent
30
+ _agent = agent
31
+
32
+
33
+ @chat_bp.route('/chat_page')
34
+ def chat_page():
35
+ if not is_session_valid():
36
+ session.clear()
37
+ flash('انتهت الجلسة، يرجى تسجيل الدخول مرة أخرى.', 'error')
38
+ return redirect(url_for('auth.login'))
39
+
40
+ username = session['username']
41
+ user_data = get_user(username)
42
+
43
+ if not user_data or not user_data.get('verified', False):
44
+ flash('حسابك غير مفعّل. تواصل مع الإدارة.', 'error')
45
+ return redirect(url_for('dashboard'))
46
+
47
+ return render_template('chat.html', username=username)
48
+
49
+
50
+ @chat_bp.route('/me', methods=['GET'])
51
+ def get_me():
52
+ if not is_session_valid():
53
+ return jsonify({"error": "غير مصرح", "code": "unauthorized"}), 401
54
+
55
+ username = session['username']
56
+ user = get_user(username)
57
+
58
+ if not user:
59
+ return jsonify({"error": "المستخدم غير موجود", "code": "user_not_found"}), 404
60
+ if not user.get('verified', False):
61
+ return jsonify({"error": "الحساب غير مفعّل", "code": "not_verified"}), 403
62
+
63
+ subjects, error = get_user_accessible_subjects(username)
64
+ if error:
65
+ return jsonify({"error": error}), 400
66
+
67
+ return jsonify({
68
+ "username": username,
69
+ "student_type": user.get('student_type', ''),
70
+ "balance": user.get('balance', 0),
71
+ "session_id": user.get('session_id', username),
72
+ "subjects": subjects
73
+ })
74
+
75
+
76
+ @chat_bp.route('/subjects', methods=['GET'])
77
+ def get_subjects():
78
+ if not is_session_valid():
79
+ return jsonify({"error": "غير مصرح", "code": "unauthorized"}), 401
80
+
81
+ username = session['username']
82
+ subjects, error = get_user_accessible_subjects(username)
83
+ if error:
84
+ return jsonify({"error": error}), 400
85
+
86
+ return jsonify({
87
+ "subjects": subjects,
88
+ "count": len(subjects),
89
+ "accessible_count": len([s for s in subjects if s['accessible']])
90
+ })
91
+
92
+
93
+ @chat_bp.route('/select-subject', methods=['POST'])
94
+ def select_subject():
95
+ if not is_session_valid():
96
+ return jsonify({"error": "غير مصرح", "code": "unauthorized"}), 401
97
+
98
+ data = request.json
99
+ username = session['username']
100
+ subject_id = data.get('subject', '').strip()
101
+
102
+ if not subject_id:
103
+ return jsonify({"error": "يرجى تحديد المادة", "code": "no_subject"}), 400
104
+
105
+ has_access, access_error = validate_user_subject_access(username, subject_id)
106
+ if not has_access:
107
+ return jsonify({"error": access_error, "code": "no_access"}), 403
108
+
109
+ subject_data = subject_loader.load(subject_id)
110
+ if not subject_data:
111
+ return jsonify({"error": f"مجلد المادة '{subject_id}' غير موجود على الخادم"}), 404
112
+
113
+ session_id = username
114
+ _agent.select_subject(username, session_id, subject_id)
115
+
116
+ user = get_user(username)
117
+ student_type = user.get('student_type', '')
118
+ subject_name = get_subject_name(student_type, subject_id)
119
+ p_files = subject_data.get("_p_files", [])
120
+
121
+ s = _agent.chat_history.get_or_create_session(session_id)
122
+ full_messages = s.get("full_messages", [])
123
+
124
+ return jsonify({
125
+ "success": True,
126
+ "subject_id": subject_id,
127
+ "subject_name": subject_name,
128
+ "chapters_count": len(p_files),
129
+ "files": ["main.txt"] + p_files,
130
+ "message": f"تم تحميل مادة '{subject_name}' بنجاح! ({len(p_files)} فصول)",
131
+ "chat_history": full_messages,
132
+ "history_count": len(full_messages)
133
+ })
134
+
135
+
136
+ @chat_bp.route('/switch-subject', methods=['POST'])
137
+ def switch_subject():
138
+ if not is_session_valid():
139
+ return jsonify({"error": "غير مصرح", "code": "unauthorized"}), 401
140
+
141
+ data = request.json
142
+ username = session['username']
143
+ new_subject_id = data.get('subject', '').strip()
144
+
145
+ if not new_subject_id:
146
+ return jsonify({"error": "يرجى تحديد اسم المادة الجديدة"}), 400
147
+
148
+ has_access, access_error = validate_user_subject_access(username, new_subject_id)
149
+ if not has_access:
150
+ return jsonify({"error": access_error, "code": "no_access"}), 403
151
+
152
+ subject_data = subject_loader.load(new_subject_id)
153
+ if not subject_data:
154
+ return jsonify({"error": f"مجلد المادة '{new_subject_id}' غير موجود على الخادم"}), 404
155
+
156
+ session_id = username
157
+ _agent.select_subject(username, session_id, new_subject_id)
158
+
159
+ user = get_user(username)
160
+ student_type = user.get('student_type', '')
161
+ subject_name = get_subject_name(student_type, new_subject_id)
162
+ p_files = subject_data.get("_p_files", [])
163
+
164
+ s = _agent.chat_history.get_or_create_session(session_id)
165
+ full_messages = s.get("full_messages", [])
166
+
167
+ return jsonify({
168
+ "success": True,
169
+ "subject_id": new_subject_id,
170
+ "subject_name": subject_name,
171
+ "chapters_count": len(p_files),
172
+ "files": ["main.txt"] + p_files,
173
+ "message": f"تم التبديل إلى مادة '{subject_name}' بنجاح!",
174
+ "chat_history": full_messages,
175
+ "history_count": len(full_messages)
176
+ })
177
+
178
+
179
+ @chat_bp.route('/chat', methods=['POST'])
180
+ def chat():
181
+ if not is_session_valid():
182
+ return jsonify({"error": "غير مصرح", "code": "unauthorized"}), 401
183
+
184
+ data = request.json
185
+ user_message = data.get('message', '').strip()
186
+ username = session['username']
187
+
188
+ if not user_message:
189
+ return jsonify({"error": "رسالة فارغة"}), 400
190
+
191
+ session_id = username
192
+ user = get_user(username)
193
+
194
+ if not user:
195
+ return jsonify({"error": "المستخدم غير موجود", "code": "user_not_found"}), 404
196
+ if not user.get('verified', False):
197
+ return jsonify({"error": "الحساب غير مفعّل", "code": "not_verified"}), 403
198
+
199
+ current_subject = _agent.chat_history.get_subject(session_id)
200
+ if not current_subject:
201
+ return jsonify({"error": "لم يتم اختيار المادة بعد", "need_subject": True}), 400
202
+
203
+ has_access, access_error = validate_user_subject_access(username, current_subject)
204
+ if not has_access:
205
+ return jsonify({"error": access_error, "code": "no_access"}), 403
206
+
207
+ try:
208
+ chosen_file, status = _agent.process_message(user_message, session_id)
209
+
210
+ if status == "no_subject":
211
+ return jsonify({"error": "يرجى اختيار المادة أولاً", "need_subject": True}), 400
212
+ if status == "subject_not_found":
213
+ return jsonify({"error": f"مجلد المادة '{current_subject}' غير موجود"}), 404
214
+
215
+ if chosen_file == "main.txt":
216
+ response = _agent.respond_gpt(user_message, chosen_file, session_id)
217
+ _agent.save_current_chat(username, session_id)
218
+ session_info = _agent.chat_history.get_session_info(session_id)
219
+ return jsonify({
220
+ "type": "gpt",
221
+ "subject": current_subject,
222
+ "chosen_file": chosen_file,
223
+ "response": response,
224
+ "session_info": session_info
225
+ })
226
+ else:
227
+ session_info = _agent.chat_history.get_session_info(session_id)
228
+ return jsonify({
229
+ "type": "mistral",
230
+ "subject": current_subject,
231
+ "chosen_file": chosen_file,
232
+ "stream_url": (
233
+ f"/stream?file={chosen_file}"
234
+ f"&session={http_requests.utils.quote(session_id)}"
235
+ f"&message={http_requests.utils.quote(user_message)}"
236
+ ),
237
+ "session_info": session_info
238
+ })
239
+
240
+ except Exception as e:
241
+ print(f"❌ Chat error: {e}")
242
+ return jsonify({"error": str(e)}), 500
243
+
244
+
245
+ @chat_bp.route('/stream')
246
+ def stream():
247
+ if not is_session_valid():
248
+ def auth_error():
249
+ yield f"data: {json.dumps({'error': 'غير مصرح'})}\n\n"
250
+ return Response(auth_error(), mimetype='text/event-stream')
251
+
252
+ username = session['username']
253
+ user_message = request.args.get('message', '')
254
+ chosen_file = request.args.get('file', 'main.txt')
255
+ session_id = request.args.get('session', username)
256
+
257
+ user = get_user(username)
258
+ if not user or not user.get('verified', False):
259
+ def auth_error():
260
+ yield f"data: {json.dumps({'error': 'غير مصرح'})}\n\n"
261
+ return Response(auth_error(), mimetype='text/event-stream')
262
+
263
+ current_subject = _agent.chat_history.get_subject(session_id)
264
+ if current_subject:
265
+ has_access, _ = validate_user_subject_access(username, current_subject)
266
+ if not has_access:
267
+ def access_error():
268
+ yield f"data: {json.dumps({'error': 'ليس لديك صلاحية الوصول لهذه المادة'})}\n\n"
269
+ return Response(access_error(), mimetype='text/event-stream')
270
+
271
+ def generate():
272
+ try:
273
+ for chunk in _agent.respond_mistral_stream(user_message, chosen_file, session_id):
274
+ try:
275
+ parsed = json.loads(chunk.strip())
276
+ if parsed.get("done"):
277
+ _agent.save_current_chat(username, session_id)
278
+ except Exception:
279
+ pass
280
+ yield f"data: {chunk}\n\n"
281
+ except Exception as e:
282
+ yield f"data: {json.dumps({'error': str(e)})}\n\n"
283
+
284
+ return Response(
285
+ stream_with_context(generate()),
286
+ mimetype='text/event-stream',
287
+ headers={
288
+ 'Cache-Control': 'no-cache',
289
+ 'X-Accel-Buffering': 'no',
290
+ 'Connection': 'keep-alive'
291
+ }
292
+ )
293
+
294
+
295
+ @chat_bp.route('/clear', methods=['POST'])
296
+ def clear_history():
297
+ if not is_session_valid():
298
+ return jsonify({"error": "غير مصرح", "code": "unauthorized"}), 401
299
+
300
+ username = session['username']
301
+ session_id = username
302
+
303
+ current_subject = _agent.chat_history.get_subject(session_id)
304
+ _agent.chat_history.clear_session(session_id)
305
+
306
+ if current_subject:
307
+ clear_user_subject_chat_from_db(username, current_subject)
308
+
309
+ return jsonify({
310
+ "success": True,
311
+ "message": "تم مسح سجل المحادثة للمادة الحالية",
312
+ "subject_kept": current_subject
313
+ })
314
+
315
+
316
+ @chat_bp.route('/session-info', methods=['POST'])
317
+ def session_info():
318
+ if not is_session_valid():
319
+ return jsonify({"error": "غير مصرح", "code": "unauthorized"}), 401
320
+
321
+ username = session['username']
322
+ session_id = username
323
+ info = _agent.chat_history.get_session_info(session_id)
324
+ return jsonify(info)
325
+
326
+
327
+ @chat_bp.route('/summary', methods=['POST'])
328
+ def get_summary():
329
+ if not is_session_valid():
330
+ return jsonify({"error": "غير مصرح", "code": "unauthorized"}), 401
331
+
332
+ username = session['username']
333
+ session_id = username
334
+ summary = _agent.chat_history.get_summary(session_id)
335
+ subject = _agent.chat_history.get_subject(session_id)
336
+
337
+ return jsonify({
338
+ "username": username,
339
+ "subject": subject,
340
+ "summary": summary if summary else "لا يوجد ملخص بعد. سيتم إنشاء ملخص تلقائياً بعد 10 رسائل."
341
+ })
342
+
343
+
344
+ @chat_bp.route('/reload-subject', methods=['POST'])
345
+ def reload_subject():
346
+ if not is_session_valid():
347
+ return jsonify({"error": "غير مصرح", "code": "unauthorized"}), 401
348
+
349
+ data = request.json
350
+ username = session['username']
351
+ subject_id = data.get('subject', '').strip()
352
+
353
+ if not subject_id:
354
+ return jsonify({"error": "يرجى تحديد اسم المادة"}), 400
355
+
356
+ has_access, access_error = validate_user_subject_access(username, subject_id)
357
+ if not has_access:
358
+ return jsonify({"error": access_error, "code": "no_access"}), 403
359
+
360
+ subject_data = subject_loader.reload(subject_id)
361
+ if not subject_data:
362
+ return jsonify({"error": f"مجلد المادة '{subject_id}' غير موجود على الخادم"}), 404
363
+
364
+ p_files = subject_data.get("_p_files", [])
365
+ return jsonify({
366
+ "success": True,
367
+ "subject_id": subject_id,
368
+ "chapters_count": len(p_files),
369
+ "message": f"تم إعادة تحميل المادة '{subject_id}' بنجاح!"
370
+ })
371
+
372
+
373
+ @chat_bp.route('/get-chat-history', methods=['GET'])
374
+ def get_chat_history():
375
+ if not is_session_valid():
376
+ return jsonify({"error": "غير مصرح", "code": "unauthorized"}), 401
377
+
378
+ username = session['username']
379
+ session_id = username
380
+
381
+ s = _agent.chat_history.get_or_create_session(session_id)
382
+ full_messages = s.get("full_messages", s.get("messages", []))
383
+ subject = s.get("subject", None)
384
+
385
+ subject_name = None
386
+ if subject:
387
+ user = get_user(username)
388
+ student_type = user.get('student_type', '')
389
+ subject_name = get_subject_name(student_type, subject)
390
+
391
+ return jsonify({
392
+ "messages": full_messages,
393
+ "subject": subject,
394
+ "subject_name": subject_name,
395
+ "count": len(full_messages)
396
+ })
397
+
398
+
399
+ @chat_bp.route('/get-all-chats', methods=['GET'])
400
+ def get_all_chats():
401
+ if not is_session_valid():
402
+ return jsonify({"error": "غير مصرح", "code": "unauthorized"}), 401
403
+
404
+ username = session['username']
405
+ all_chats = get_all_user_chats_from_db(username)
406
+ user = get_user(username)
407
+ student_type = user.get('student_type', '')
408
+
409
+ result = []
410
+ for subject_id, chat_data in all_chats.items():
411
+ subject_name = get_subject_name(student_type, subject_id)
412
+ full_msgs = chat_data.get("full_messages", [])
413
+ result.append({
414
+ "subject_id": subject_id,
415
+ "subject_name": subject_name,
416
+ "message_count": len(full_msgs),
417
+ "last_saved": chat_data.get("saved_at", ""),
418
+ "has_summary": bool(chat_data.get("summary", ""))
419
+ })
420
+
421
+ return jsonify({
422
+ "chats": result,
423
+ "total": len(result)
424
+ })
database/__init__.py ADDED
@@ -0,0 +1,4 @@
 
 
 
 
 
1
+ """
2
+ Database package.
3
+ Handles all JSON file persistence.
4
+ """
database/__pycache__/__init__.cpython-314.pyc ADDED
Binary file (220 Bytes). View file
 
database/__pycache__/cards.cpython-314.pyc ADDED
Binary file (1.62 kB). View file
 
database/__pycache__/chat_history.cpython-314.pyc ADDED
Binary file (5.19 kB). View file
 
database/__pycache__/telegram.cpython-314.pyc ADDED
Binary file (1.14 kB). View file
 
database/__pycache__/users.cpython-314.pyc ADDED
Binary file (1.83 kB). View file
 
database/cards.py ADDED
@@ -0,0 +1,26 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """
2
+ Cards database operations.
3
+ """
4
+
5
+ import os
6
+ import json
7
+ from config import CARDS_DB_FILE
8
+
9
+
10
+ def init_cards_db():
11
+ if not os.path.exists(CARDS_DB_FILE):
12
+ with open(CARDS_DB_FILE, 'w', encoding='utf-8') as f:
13
+ json.dump({}, f, ensure_ascii=False)
14
+
15
+
16
+ def load_cards_db():
17
+ try:
18
+ with open(CARDS_DB_FILE, 'r', encoding='utf-8') as f:
19
+ return json.load(f)
20
+ except Exception:
21
+ return {}
22
+
23
+
24
+ def save_cards_db(data):
25
+ with open(CARDS_DB_FILE, 'w', encoding='utf-8') as f:
26
+ json.dump(data, f, indent=4, ensure_ascii=False)
database/chat_history.py ADDED
@@ -0,0 +1,107 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """
2
+ Persistent chat history database.
3
+ Stores per-user per-subject chat data.
4
+ """
5
+
6
+ import os
7
+ import json
8
+ from config import CHAT_HISTORY_DB_FILE
9
+
10
+
11
+ def init_chat_history_db():
12
+ if not os.path.exists(CHAT_HISTORY_DB_FILE):
13
+ with open(CHAT_HISTORY_DB_FILE, 'w', encoding='utf-8') as f:
14
+ json.dump({}, f, ensure_ascii=False)
15
+
16
+
17
+ def load_chat_history_db():
18
+ try:
19
+ with open(CHAT_HISTORY_DB_FILE, 'r', encoding='utf-8') as f:
20
+ return json.load(f)
21
+ except Exception:
22
+ return {}
23
+
24
+
25
+ def save_chat_history_db(data):
26
+ with open(CHAT_HISTORY_DB_FILE, 'w', encoding='utf-8') as f:
27
+ json.dump(data, f, indent=4, ensure_ascii=False)
28
+
29
+
30
+ def make_chat_db_key(username, subject_id):
31
+ return f"{username}__{subject_id}"
32
+
33
+
34
+ def save_user_chat_to_db(username, subject_id, session_data):
35
+ """
36
+ Save a user's chat session for a specific subject.
37
+ session_data is the dict from ChatHistory session.
38
+ """
39
+ try:
40
+ from datetime import datetime
41
+ chat_db = load_chat_history_db()
42
+ db_key = make_chat_db_key(username, subject_id)
43
+
44
+ chat_db[db_key] = {
45
+ "username": username,
46
+ "subject_id": subject_id,
47
+ "messages": session_data.get("messages", []),
48
+ "full_messages": session_data.get("full_messages", []),
49
+ "summary": session_data.get("summary", ""),
50
+ "message_count": session_data.get("message_count", 0),
51
+ "last_file": session_data.get("last_file", None),
52
+ "subject": session_data.get("subject", subject_id),
53
+ "saved_at": datetime.now().isoformat()
54
+ }
55
+ save_chat_history_db(chat_db)
56
+ msg_count = len(session_data.get('full_messages', []))
57
+ print(f"✅ Saved chat for {username} / subject={subject_id} ({msg_count} messages)")
58
+ except Exception as e:
59
+ print(f"❌ Error saving chat to DB: {e}")
60
+
61
+
62
+ def load_user_chat_from_db(username, subject_id):
63
+ """
64
+ Load saved chat data for a user+subject.
65
+ Returns dict or None.
66
+ """
67
+ try:
68
+ chat_db = load_chat_history_db()
69
+ db_key = make_chat_db_key(username, subject_id)
70
+
71
+ if db_key not in chat_db:
72
+ print(f"ℹ️ No saved chat found for {username} / subject={subject_id}")
73
+ return None
74
+
75
+ saved = chat_db[db_key]
76
+ print(f"✅ Loaded chat for {username} / subject={subject_id}")
77
+ return saved
78
+ except Exception as e:
79
+ print(f"❌ Error loading chat from DB: {e}")
80
+ return None
81
+
82
+
83
+ def clear_user_subject_chat_from_db(username, subject_id):
84
+ try:
85
+ chat_db = load_chat_history_db()
86
+ db_key = make_chat_db_key(username, subject_id)
87
+ if db_key in chat_db:
88
+ del chat_db[db_key]
89
+ save_chat_history_db(chat_db)
90
+ print(f"🗑️ Cleared DB chat for {username} / subject={subject_id}")
91
+ except Exception as e:
92
+ print(f"❌ Error clearing chat from DB: {e}")
93
+
94
+
95
+ def get_all_user_chats_from_db(username):
96
+ try:
97
+ chat_db = load_chat_history_db()
98
+ prefix = f"{username}__"
99
+ result = {}
100
+ for key, val in chat_db.items():
101
+ if key.startswith(prefix):
102
+ subject_id = key[len(prefix):]
103
+ result[subject_id] = val
104
+ return result
105
+ except Exception as e:
106
+ print(f"❌ Error getting all user chats: {e}")
107
+ return {}
database/telegram.py ADDED
@@ -0,0 +1,19 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """
2
+ Telegram verification database operations.
3
+ """
4
+
5
+ import json
6
+ from config import TELEGRAM_DB_FILE
7
+
8
+
9
+ def load_telegram_db():
10
+ try:
11
+ with open(TELEGRAM_DB_FILE, 'r', encoding='utf-8') as f:
12
+ return json.load(f)
13
+ except Exception:
14
+ return {}
15
+
16
+
17
+ def save_telegram_db(data):
18
+ with open(TELEGRAM_DB_FILE, 'w', encoding='utf-8') as f:
19
+ json.dump(data, f, indent=4, ensure_ascii=False)
database/users.py ADDED
@@ -0,0 +1,31 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """
2
+ Users database operations.
3
+ """
4
+
5
+ import os
6
+ import json
7
+ from config import USERS_DB_FILE
8
+
9
+
10
+ def init_users_db():
11
+ if not os.path.exists(USERS_DB_FILE):
12
+ with open(USERS_DB_FILE, 'w', encoding='utf-8') as f:
13
+ json.dump({}, f, ensure_ascii=False)
14
+
15
+
16
+ def load_users_db():
17
+ try:
18
+ with open(USERS_DB_FILE, 'r', encoding='utf-8') as f:
19
+ return json.load(f)
20
+ except Exception:
21
+ return {}
22
+
23
+
24
+ def save_users_db(data):
25
+ with open(USERS_DB_FILE, 'w', encoding='utf-8') as f:
26
+ json.dump(data, f, indent=4, ensure_ascii=False)
27
+
28
+
29
+ def get_user(username):
30
+ users = load_users_db()
31
+ return users.get(username, None)
exam/__init__.py ADDED
@@ -0,0 +1,4 @@
 
 
 
 
 
1
+ """
2
+ Exam package.
3
+ MCQ exam generation and scoring.
4
+ """
exam/__pycache__/__init__.cpython-314.pyc ADDED
Binary file (210 Bytes). View file