• الإعلانات

    • فيصل الحربي

      تسجيل عضوية جديدة في المنتدى   01/31/2016

      السلام عليكم ورحمة الله وبركاته  عزيزي العضو الجديد :  حاليا رسالة الإيميل لتأكيد صحة إيميلكم تذهب للبريد العشوائي ( جاري حل المشكلة )  فإذا لم تجد رسالة التحقق من إيميلكم في صندوق الوارد لديكم إتجه للبريد العشوائي ( JUNK)  وقم بتفعيل إشتراككم من هناك   

البحث في المنتدى

Showing results for tags 'object pascal'.

  • البحث بالتاقات

    اكتب الكلمات المفتاحيه بينها علامه الفاصله
  • البحث بكاتب الموضوع

تم إيجاد 17 نتيجة

  1. بسم الله الرحمن الرحيم  إنَّ الحَمْدَ لِلَّهِ نَحْمَدُهُ وَنَسْتَعِيُنُهُ وَنَسْتَغْفِرُهُ وَنَسْتَهْدِيهِ وَنَعُوذَ بِاللهِ مِن شُرُورِ أَنفُسِنَا وَسَيئَاتِ أَعْمَاِلَنَا، مَن يَهْدهِ اللهُ فَلا مُضلَّ لَه ، وَمَن يُضْلِل فَلا هَادِي لَه، وَأَشْهَدُ أَنَّ لاَ إِلهَ إلا اللهُ وَحدَهُ لاَ شَريكَ لَهُ، وَأَشْهدُ أنَّ مُحَمَّداً عَبدُهُ وَرَسُولُهُ . ----------------------------------------------------------------------------------------------   طوّرت شركة مايكروسوفت ( Microsoft ) منصّة عمل سمّتها دوت نت ( NET Framework. ) وبيئة عمل سمّتها ( Visual Studio IDE ) حيث أصبح بإمكان مطوّر التّطبيقات الإستعانة بهذين الأخيرين بالإضافة للغة برمجة تعمل تحت هذه المنصّة أن يطوّر التّطبيقات المكتبيّة وتطبيقات الويب والتّطبيقات الموزّعة أيضاً. سوف نتحدّث في هذه السلسلة التّعليميّة عن لغة السي شارب ( #C ) التي طوّرتها مايكروسوفت خصّيصاً لمنصّة ( NET. ). زوّدت #C بالعديد من الميّزات التي تجعلها من أقوى لغات البرمجة الغرضيّة التّوجّه ( Object Oriented Programming ) ومن أهمّ هذه الميّزات : أوّلاً : معالجة السّلاسل المحرفيّة ( Strings ). ثانياً : الرّسوميّات ( Graphics ). ثالثاً : الواجهات التّخاطبيّة ( Graphical User Interface ). رابعاً : معالجة الاستثناءات ( Exception Handling ). خامساً : النياسب المتعدّدة ( Multi Threading ). سادساً : التّعامل مع الملفّات ( File Streams ). سابعاً : الوسائط المتعدّدة ( صوت ،صورة ،فيديو ) ( Multimedia ). ثامناً : التّكامل مع قواعد البيانات ( ADO.NET ). تاسعاً : التّطبيقات الشّبكيّة ( Network Programming ). أخيراً : التّطبيقات الموزّعة ( Distributed Applications ). والكثير والكثير ..........                                        - الهدف الذي أطمح إليه من هذه السّلسلة :    تقديم محتوى تعليمي إلكتروني شامل حول هذه اللغة ( #C ) موجّه لمن لديه معرفة بسيطة أو لا يمتلك أيّ خبرة سابقة في البرمجةوالوصول به إلى مستوى عالٍ ومتقدّم .لذلك سوف تكون هذه السّلسلة شاملة بمحتواها من شرح نظري وأمثلة عمليّة وتمارين                 وأسئلة ومشاريع احترافيّة.....                     وأسأل الله تعالى أن يوفّقنا لما يحبّ ويرضى ، والله ولي التوفيق.                                   =============================================================================  الشرح فيديو على اليوتيوب ارجو ان يعجبكم الشرح     https://www.youtube.com/watch?v=G99wGpuSxwU   لجميع الفيديوهات ستجدون شرح مفصل لدورة لغة C# من A الي Z     https://www.youtube.com/channel/UCZx_t7YftSh9GCKqVadw2pQ/videos       
  2. بحاول أحصل على قيمة String من ملف JSON  بس المشكله ان القيمة عباره عن: Object > Array > String و حاولت بأكتر من طريق بس الطريقه الاخيره حاسس ان ناقص فيها حاجه بسيطه او فى جزء مش عامله صح, الكود مرفق, و ارجو منكم توضيح اين المشكله. انا بحاول اعمل iteration لل JsonObject  و بعديها بعمل مره كمان فوق الJsonArray علشان احصل على القيمه.  أنا عامل فى التطبيق بتاعى 3 ملفات. ملف MainActivity و دا اللى عامل فيه Parsing وبقرأ فيه ملف الJSON و بقرأ منه القيم. DetailActivity دا اللى هحتاج فيه الString بتاعة videoID. PostModel القائمة اللى فيها ال getter  و ال setter و كل الStrings اللى بحتاج لها فى الملفين الاخرين. JSON: { "status":"ok", "count":10, "count_total":184, "pages":19, "posts":[ { }, { "id":2413, , "categories":[ { "id":100, "slug":"logging", "title":"logging", "description":"", "parent":0, "post_count":1 } ], "comments":[ { "id":3564, "content":"<p>\u47 <\/p>\n", "parent":0 } ], "comment_count":1, "thumbnail":"http:\/\/www.5.com\/wtent\g", "custom_fields":{ "dsq_thread_id":[ "2365140" ], "videoID":[ "--ffwf92jvDFy" ] }, "thumbnail_images":{ "full":{ "url":"http:\/\/www.5.com\/jpg", "width":727, "height":454 }, "thumbnail":{ "url":"http:\/\/www.5.com\/wp-con50.jpg", "width":150, "height":150 } } } ] } القيمة المطلوب الحصول عليها هى قيمة الــ videoID    PostModel: private List<CategoryCast> categoryCastList; private List<VidCast> videoIDList private String videoID; private JSONObject obj; public JSONObject getObj() { return obj; } public void setObj(JSONObject obj) { this.obj = obj; } public String getVideoID() { return videoID; } public void setVideoID(String videoID) { this.videoID = videoID; } public List<VidCast> getvideoIDList() { return videoIDList; } public void setvideoIDList(List<VidCast> videoIDList) { this.videoIDList = videoIDList; } public List<CategoryCast> getCategoryCastList() { return categoryCastList; } public void setCategoryCastList(List<CategoryCast> categoryCastList) { this.categoryCastList = categoryCastList; } public static class CategoryCast { private String name; public String getName() { return name; } public void setName(String name) { this.name = name; } } public static class VidCast { private String name; public String getName() { return name; } public void setName(String name) { this.name = name; } }   MainActivity: List<PostModel.VidCast> videoIDList = new ArrayList<>(); for (int y = 0; y < finalObject.getJSONObject("custom_fields").length(); y++) { PostModel.VidCast vidCast = new PostModel.VidCast(); for (int s = 0; s < finalObject.getJSONArray("videoID").length(); s++){ { postModel.setVideoID(videoID); postModelList.add(postModel); }; } vidCast.setName(finalObject.getJSONObject("custom_fields").getJSONObject(y).get("0")); videoIDList.add(vidCast); } postModel.setvideoIDList(videoIDList); postModelList.add(postModel); List<PostModel.CategoryCast> categoryCastList = new ArrayList<>(); for (int j = 0; j < finalObject.getJSONArray("categories").length(); j++) { PostModel.CategoryCast categoryCast = new PostModel.CategoryCast(); categoryCast.setName(finalObject.getJSONArray("categories").getJSONObject(j).getString("title")); categoryCastList.add(categoryCast); } postModel.setCategoryCastList(categoryCastList); // adding the final object in the list postModelList.add(postModel); } return postModelList; DetailActivity: StringBuffer stringBuffer = new StringBuffer(); for(PostModel.CategoryCast categoryCast : postModel.getCategoryCastList()){ stringBuffer.append(categoryCast.getName() + ", "); } StringBuffer videoStringBuffer = new StringBuffer(); for(PostModel.VidCast videoIDList : postModel.getvideoIDList()) { videoStringBuffer.append(videoStringBuffer.toString()); } دا اللى هحتاج فيه الString بتاعة videoID. وشكراً
  3. سلام عليكم بعد ظهور lazarus في إصداراته الأولى أخذه مجموعة من المطورين وبنوا عليه البيئة الأكثر تطورا وغنى بالمكتبات التي لم تسمع بها من قبل إنه CodeTyphon وهو بيئة تطويرية للغة الأوبجكت باسكال عابر للمنصات ، يعمل على أكثر من عشرين منصة وعلى كل المعماريات   أنت لست محتاجا لتحميله مرتين ، البرنامج نفسه يثبت على اي نظام وعلى أي توزيعة والبرامج المكتوبة به تصرف إلي اي منصة تشاء حتى لو كان أندرويد الذي أعجبني في هذه المنصة التطويرية أنهم يدعمون gtk3 بعد أن تخلى عنها فريق lazarus بالإضافة إلى المكتبات الكثيرة في كل المجالات البرنامج حر يصدر تحت رخصة GPL مطورو object pascal ينبغي عليهم ان يجربوا هذه البيئة فهم بعد ذلك لن يستغنوا عنها أبدا الموقع الرسمي
  4. بسم الله الرحمن الرحيم   نكمل ما بدأناه بعون الله تعالى   المتغيرات المتغيرات هي عبارة حاويات للبيانات. فمثلاً في الطريقة الرياضية عندما نقول أن س = 5 فهذا يعني أن س هي متغير وهي في هذه اللحظة تحمل القيمة 5. كذلك يمكن إدخالها في عبارات رياضية، حيث أن قيمة س مضروبة في 2 ينتج عنها 10:   س = 5 س * 2 ينتج عنها 10   تتميز لغة باسكال بأنها تلتزم بنوع المتغيرStrong Typed language، فحسب البيانات التي سوف نضعها لابد من تحديد نوع المتغير. وهذا المتغير سوف يحمل نوع واحد فقط من البيانات طوال تشغيل البرنامج، فمثلاً إذا قمنا بتعريف متغير من النوع الصحيح، فإنه يمكننا فقط إسناد ارقام صحيحة له، ولايمكننا إسناد عدد كسري مثلاً. كذلك يجب التعريف عن المتغير قبل إستخدامه كما في المثال التالي: program FirstVar;{$mode objfpc}{$H+}uses {$IFDEF UNIX}{$IFDEF UseCThreads} cthreads, {$ENDIF}{$ENDIF} Classes { you can add units after this };var x: Integer;begin x:= 5; Writeln(x * 2); Writeln('Press enter key to close'); Readln;end.   فعند تنفيذه نحصل على القيمة 10. في المثال أعلاه قمنا بكتابة الكلمة المحجوزة Var والتي تفيد بأن الأسطر القادمة عبارة عن تعريف للمتغيرات. وعبارة:   x: Integer;  تفيد شيئين: أولهما أن إسم المتغير الذي سوف نستخدمه هو x وأن نوعه Integer وهو نوع العدد الصحيح الذي يقبل فقط أرقام صحيحة لاتحتوي على كسور ويمكن أن تكون موجبة أو سالبة.   وأنا أنبه إلى أمرين الأول وهو أن الجملة في لغة الباسكال لا بد أن تنتهي بفاصلة منقوطة ";" ونسيانها يعني أن الجملة لم تنته وسواء في ذلك الإعلان عن المتغيرات كما العبارة السابقة أو الإسناد كما في العبارة التالية   الثاني أن الإعلان عن المتغيرات يقع قبل بداية البرنامج اي قبل العبارة begin   أما عبارة   x:= 5;  فهي تعني وضع القيمة 5 في المتغير الصحيح x   يمكن أن نعلن عن متغير ونسنده إلى قيمة افتراضية مثل أن نكتب بعد var   x:integer=50;  يمكن إضافة متغير آخر للبرنامج نسميه y مثلاً كما في المثال التالي:   var x, y: Integer;begin x:= 5; y:= 10; Writeln(x * y); Writeln('Press enter key to close'); Readln;end.    نجد أن مخرجات البرنامج السابق هي:   50Press enter key to close      في المثال التالي نقوم بإختبار نوع جديد من المتغيرات، وهو متغير يحتوي على حرف character   var c: Char;begin c:= 'M'; Writeln('My first letter is: ', c); Writeln('Press enter key to close'); Readln;end.      أما المثال التالي فهو لنوع الأعداد الحقيقية التي يمكن أن تحتوي على كسور: var x: Single;begin x:= 1.8; Writeln('My Car engine capacity is ', x, ' litters'); Writeln('Press enter key to close'); Readln;end.  لنتمكن من كتابة برامج أكثر تفاعلاً لابد من ذكر طريقة إدخال قيمة المتغيرات من المستخدم بدلاً من كتابتها في البرنامج. والطريقة البسيطة هي إستخدام عبارة Readln التي تُمكّن المستخدم من إدخال مدخلات حسب نوع المتغيرات كما في المثال التالي: var x: Integer;begin Write('Please input any number:'); Readln(x); Writeln('You have entered: ', x); Writeln('Press enter key to close'); Readln;end.   في هذه الحالة أصبح تخصيص القيمة للمتغير x هو عن طريق لوحة المفاتيح.   البرنامج التالي يقوم بحساب جدول الضرب لرقم يقوم بإدخاله المستخدم: program MultTable;{$mode objfpc}{$H+}uses {$IFDEF UNIX}{$IFDEF UseCThreads} cthreads, {$ENDIF}{$ENDIF} Classes { you can add units after this };var x: Integer;begin Write('Please input any number:'); Readln(x); Writeln(x, ' * 1 = ', x * 1); Writeln(x, ' * 2 = ', x * 2); Writeln(x, ' * 3 = ', x * 3); Writeln(x, ' * 4 = ', x * 4); Writeln(x, ' * 5 = ', x * 5); Writeln(x, ' * 6 = ', x * 6); Writeln(x, ' * 7 = ', x * 7); Writeln(x, ' * 8 = ', x * 8); Writeln(x, ' * 9 = ', x * 9); Writeln(x, ' * 10 = ', x * 10); Writeln(x, ' * 11 = ', x * 11); Writeln(x, ' * 12 = ', x * 12); Writeln('Press enter key to close'); Readln;end.  الملاحظة المهمة في المثال السابق أن أي عبارة تتم كتابتها بين علامتي تنصيص أحادية تكتب كما هي مثلاً:   ' * 1 = '  أما مايُكتب بدون تنصيص فإن قيمته هي التي تظهر. يمكن تجربة العبارتين التاليتين حتى يكون الفرق أوضح بن استخدام علامة التنصيص وعدم إستخدامها: Writeln('5 * 3'); Writeln(5 * 3);   فالعبارة تُكتب كما هي:   5 * 3   أما ناتج العبارة الثانية فيكون حاصل العملية الحسابية:   15   في المثال التالي سوف نقوم بإجراء عملية حسابية ونضع الناتج في متغير ثالث ثم نظهر قيمة هذا المتغير: var x, y: Integer; Res: Single;begin Write('Input a number: '); Readln(x); Write('Input another number: '); Readln(y); Res:= x / y; Writeln(x, ' / ', y, ' = ', Res); Writeln('Press enter key to close'); Readln;end.   فبما أن العملية الحسابية هي قسمة وربما ينتج عنها عدد كسري (حقيقي) لذلك يرفض مترجم الباسكال وضع النتيجة في متغير صحيح، لذلك لابد أن يكون هذا المتغير Res عدد حقيقي. ونوع المتغير Single يُستخدم لتعريف متغيرات كسرية ذات دقة عشرية أُحادية.     الأنواع الفرعية   توجد أنواع كثيرة للمتغيرات، فمثلاً الأعداد الصحيحة توجد منها Byte, SmallInt, Integer, LongInt, Word. وتختلف عن بعضها في مدى الأرقام وهي أصغر وأكبر عدد يمكن إسناده لها. كذلك تختلف في إحتاجها لعدد خانات الذاكرة (البايت). يمكن معرفة مدى هذه الأنواع وعدد خانات الذاكرة التي تحتاجها بإستخدام الدوال: Low, High, SizeOf. كما في المثال التالي: program Types;{$mode objfpc}{$H+}uses {$IFDEF UNIX}{$IFDEF UseCThreads} cthreads, {$ENDIF}{$ENDIF} Classes;begin Writeln('Byte: Size = ', SizeOf(Byte), ', Minimum value = ', Low(Byte), ', Maximum value = ', High(Byte)); Writeln('Integer: Size = ', SizeOf(Integer), ', Minimum value = ', Low(Integer), ', Maximum value = ', High(Integer)); Write('Press enter key to close'); Readln;end.      ================================================= الدورة منقولة من كتابي الأستاذ الفاضل معتز عبد العظيم وما تراه باللون الأخضر فمن زياداتي
  5. ضع طلبك هنا لفتح فرع جديد ل lazarus

    بسم الله الرحمن الرحيم بعد التطور السريع الذي حصل للفري باسكال ولازاريس وبعد الوعي الكبير لحركة المصادر المفتوحة واتجاه أناس كثيرين إليها صار من الضروري فتح فرع خاص لهذه اللغة أعني الأوبجكت باسكال   لذلك انا أطلب من الإخوة أن يضعوا طلبهم هنا لنرفعه إلى الإدارة من أجل فتح فرع خاص ب lazarus   والحقيقة لو أنصفنا وتكلمنا بأسلوب العلم لقلنا لغة object pascal بدل الدالفي لأنها مجرد بيئة تطويرية ، مثلها مثل لازاريس وإنما ذهبت بورلاند إلى تسميتها بلغة الدالفي وهو ظلم وعدوان على اللغة ، ولا يصح أبدا تسمية بئة تطوير باسم اللغة لأن ذلك يوقع في اللبس كما حصل الآن   نرجو التفاعل من الإخوة
  6. تعلم C#.Net

    نسالكم الدعاء   كورس سى شارب http://omarsalem.staff.scuegypt.edu.eg/?page_id=68  
  7. Synapse  مجموعة من مكتبات اﻷتصال بالشبكة  تعمل مع دلفي ولازاروس تحتوي علي وحدة smtpsend لارسال البريد اﻷلكتروني من برنامجك مباشرة   حمل المكتبة من هنا   http://synapse.ararat.cz/doku.php/download إذا كان بريدك اﻷلكتروني يحتاج  SSL  عليك تثبيت libssl-dev  في أوبنتو وما يكافئها في اﻷنظمة اﻷخري مكتبة Synapse لا تثبت في الـ IDE  مثل باقي المكونات وانما تضاف إلي المشروع اللذي تعمل عليه   من قائمة  Project >>> Project Options  >>> Paths ثم أضف الوحدتين  smtpsend,ssl_openssl  لقسم uses   ثم كود اﻷرسال           Uses   smtpsend,ssl_openssl; // Add these two units to the uses section....procedure TForm1.Button1Click(Sender: TObject);var  smtp:TSMTPSend;  msg_lines:TStringList;begin  smtp:=TSMTPSend.Create;  msg_lines:=TStringList.Create;  //  Formatting the message body  msg_lines.Insert(0, 'From: XXXXXX ');  msg_lines.Insert(1, 'To: XXXXXXX ' );  msg_lines.Insert(2,' Test SMTPSEND from Synapse ');  try    smtp.UserName:='[email protected]*****.com';    smtp.Password:='your_password';    smtp.TargetHost:='smtp.*****.com';    smtp.TargetPort:='465';   // if not using ssl  port=25    smtp.AutoTLS:=True;           smtp.FullSSL:=True;    if smtp.Login then    begin      smtp.MailFrom('[email protected]*****.com',Length('[email protected]*****.com'));      smtp.MailTo('receiver_email');      smtp.MailData(msg_lines);      if smtp.Logout then         ShowMessage('Message Sent and logged out');    end;  finally    msg_lines.Free;    smtp.Free;  end;end;     
  8. بسم الله الرحمن الرحيم ملفات الوصول العشوائي Random access files   كما سبق ذكره فإن النوع الثاني من الملفات من حيث الوصول هي ملفات الوصول العشوائي أو كما تسمى أحياناً بملفات الوصول المباشر. وهي تتميز بطول معروف للسجل ويمكن الكتابة والقراءة من الملف في آن واحد، كذلك يمكن الوصول مباشرة إلى أي سجل بغض النظر عن موقع القراءة أو الكتابة الحالي. توجد طريقتين للتعامل مع الملفات ذات الوصول العشوائي في لغة باسكال: الطريقة الأولى هي إستخدام الملفات ذات النوع typed files، أما الطريقة الثانية فهي إستخدام الملفات الغير محددة النوع untyped files.   الملفات ذات النوع typed file   في هذه الطريقة يكون الملف المراد قراءته أو كتابته مرتبط بنوع معين، والنوع المعين يمثله سجل، فمثلاً يمكن أن يكون ملف من النوع الصحيح Byte، في هذه الحال نقول أن السجل هو عبارة عن عدد صحيح Byte وفي هذه الحالة يكون طول السجل1 بايت.   المثال التالي يوضح طريقة كتابة ملف لأعداد صحيحة:   برنامج تسجيل درجات الطلاب   var F: file of Byte; Mark: Byte;begin AssignFile(F, 'marks.dat'); Rewrite(F); // Create file Writeln('Please input students marks, write 0 to exit'); repeat Write('Input a mark: '); Readln(Mark); if Mark <> 0 then // Don't write 0 value Write(F, Mark); until Mark = 0; CloseFile(F); Write('Press enter key to close..'); Readln;end.     نلاحظ في البرنامج أننا قمنا بتعريف نوع الملف بهذه الطريقة:       F: file of Byte;      وهي تعني أن الملف هو من نوع Byte أو أن سجلاته عبارة هي قيم للنوع Byte والذي يحتل في الذاكرة وفي القرص 1 بايت، ويمكنه تخزين القيم من 0 إلى 255.   كذلك قمنا بإنشاء الملف وتجهيزه للكتابة بإستخدام الأمر:     Rewrite(F); // Create file      وقد قمنا بإستخدام الإجراء Write للكتابة في الملف:     Write(F, Mark);      حيث أن Writeln لاتصلح لهذا النوع من الملفات لأنها تقوم بإضافة علامة نهاية السطر CR/LF كما سبق ذكره، أما Write فهي تكتب السجل كما هو بدون أي زيادات، لذلك نجد أننا في المثال السابق يمكننا معرفة حجم الملف، فإذا قمنا بإدخال 3 درجات فإن عدد السجلات يكون 3 وبما أن طول السجل هو 1 بايت فإن حجم الملف يكون 3 بايت. يمكن تغيير النوع إلى Integer الذي يحتل 4 خانات، ورؤية حجم الملف الناتج.   في المثال التالي نقوم بقراءة محتويات الملف السابق، فلاننسى إرجاع نوع الملف في البرنامج السابق إلى النوع Byte، لأن القراءة والكتابة لابد أن تكون لملف من نفس النوع.   برنامج قراءة ملف الدرجات program ReadMarks;{$mode objfpc}{$H+}uses {$IFDEF UNIX}{$IFDEF UseCThreads} cthreads, {$ENDIF}{$ENDIF} Classes, SysUtils { you can add units after this };var F: file of Byte; Mark: Byte;begin AssignFile(F, 'marks.dat'); if FileExists('marks.dat') then begin Reset(F); // Open file Writeln('Please input students marks, write 0 to exit'); while not Eof(F) do begin Read(F, Mark); Writeln('Mark: ', Mark); end; CloseFile(F); end else Writeln('File (marks.dat) not found'); Write('Press enter key to close..'); Readln;end.  نلاحظ أن البرنامج السابق قام بإظهار الدرجات الموجودة في الملف. وأظن أن البرنامج واضح ولايحتاج لشرح.   في البرنامج التالي نقوم بفتح الملف السابق ونضيف إليه درجات جديدة بدون حذف الدرجات السابقة:     برنامج إضافة درجات الطلاب program AppendMarks;{$mode objfpc}{$H+}uses {$IFDEF UNIX}{$IFDEF UseCThreads} cthreads, {$ENDIF}{$ENDIF} Classes, SysUtils { you can add units after this };var F: file of Byte; Mark: Byte;begin AssignFile(F, 'marks.dat'); if FileExists('marks.dat') then begin FileMode:= 2; // Open file for read/write Reset(F); // open file Seek(F, FileSize(F)); // Go to after last record Writeln('Please input students marks, write 0 to exit'); repeat Write('Input a mark: '); Readln(Mark); if Mark <> 0 then // Don't write 0 value Write(F, Mark); until Mark = 0; CloseFile(F); end else Writeln('File marks.dat not found'); Write('Press enter key to close..'); Readln;end.  بعد تنفيذ البرنامج السابق نقوم بتشغيل برنامج قراءة ملف الدرجات وذلك لرؤية أن قيم السجلات السابقة والجديدة موجودة معاً في نفس الملف. نلاحظ في هذا البرنامج أننا إستخدمنا الإجراء Reset للكتابة بدلاً من Rewrite. وفي هذا النوع من الملفات يمكن إستخدام كليهما للكتابة، والفرق الرئيسي بينهما يكمن في أن Rewrite تقوم بإنشاء الملف إذا لم يكن موجود وحذف محتوياته إذا كان موجود، أما Reset فهي تفترض وجود الملف، فإذا لم يكون موجود حدث خطأ. لكن عبارة Reset تقوم بفتح الملف حسب قيمة FileMode : فإذا كانت قيمتها 0 فإن الملف يفتح للقراءة فقط، وإذا كانت قيمته 1 يفتح للكتابة فقط، وإذا كانت قيمته 2 -وهي القيمة الإفتراضية- فإنه يفتح للقراءة والكتابة معاً:   FileMode:= 2; // Open file for read/write Reset(F); // open file  كذلك فإن الدالة Reset تقوم بوضع مؤشر القراءة والكتابة في أول سجل، لذلك إذا باشرنا الكتابة فإن البرنامج السابق يقوم بالكتابة فوق محتويات السجلات السابقة، لذلك وجب تحريك هذا المؤشر للسجل الأخير، وذلك بإستخدام الإجراء Seek الذي يقوم بتحريك الموشر، وبهذه الطريقة تمت تسمية هذا النوع من الملفات بالملفات العشوائية أو ملفات الوصول المباشر، حيث أن الإجراء Seek يسمح لنا بالتنقل لأي سجل مباشرة إذا علمنا رقمه، شريطة أن يكون هذا الرقم موجود، فسوف يحدث خطأ مثلاً إذا قمنا بمحاولة توجيه المؤشر إلى السجل رقم 100 في حين أن الملف يحتوي على عدد سجلات أقل من 100. استخدمنا الدالة FileSize والتي تقوم بإرجاع عدد السجلات:   Seek(F, FileSize(F)); // Go to after last record  نلاحظ أن المثال السابق يصلح فقط في حالة وجود ملف الدرجات، أما إذا لم يكن موجود وجب إستخدام البرنامج الأول لكتابة الدرجات. يمكننا المزج بين الطريقتين، بحيث أن البرنامج يقوم بفحص وجود الملف، فإذا كان موجود يقوم بفتحه للإضافة عن طريق Reset وإذا لم يكن موجود يقوم بإنشائه بإستخدام Rewrite:     برنامج إنشاء وإضافة درجات الطلاب   program ReadWriteMarks;{$mode objfpc}{$H+}uses {$IFDEF UNIX}{$IFDEF UseCThreads} cthreads, {$ENDIF}{$ENDIF} Classes, SysUtils { you can add units after this };var F: file of Byte; Mark: Byte;begin AssignFile(F, 'marks.dat'); if FileExists('marks.dat') then begin FileMode:= 2; // Open file for read/write Reset(F); // open file Writeln('File already exist, opened for append'); // Display file records while not Eof(F) do begin Read(F, Mark); Writeln('Mark: ', Mark); end end else // File not found, create it begin Rewrite(F); Writeln('File does not exist, created'); end; Writeln('Please input students marks, write 0 to exit'); Writeln('File pointer position at record # ', FilePos(f)); repeat Write('Input a mark: '); Readln(Mark); if Mark <> 0 then // Don't write 0 value Write(F, Mark); until Mark = 0; CloseFile(F); Write('Press enter key to close..'); Readln;end.    بعد تشغيل البرنامج نجد أن القيم السابقة تم عرضها في البداية قبل الشروع في إضافة درجات جديدة. نلاحظ أننا في هذه الحالة لم نستخدم الإجراء Seek وذلك لأننا قمنا بقراءة كل محتويات الملف، ومن المعروف أن القراءة تقوم بتحريك مؤشر الملف إلى الأمام، لذلك بعد الفراغ من قراءة كافة سجلاته يكون المؤشر في الخانة الأخيرة في الملف، لذلك يمكن الإضافة مباشرة. استخدمنا الدالة FilePos التي تقوم بإرجاع الموقع الحالي لمؤشر الملفات.     في المثال التالي سوف نستخدم سجل Record لتسجيل بيانات سيارة، نلاحظ أننا نقوم بكتابة وقراءة السجل كوحدة واحدة:   برنامج سجل السيارات   program CarRecords;{$mode objfpc}{$H+}uses {$IFDEF UNIX}{$IFDEF UseCThreads} cthreads, {$ENDIF}{$ENDIF} Classes, SysUtils { you can add units after this };type TCar = record ModelName: string[20]; Engine: Single; ModelYear: Integer; end;var F: file of TCar; Car: TCar;begin AssignFile(F, 'cars.dat'); if FileExists('cars.dat') then begin FileMode:= 2; // Open file for read/write Reset(F); // open file Writeln('File already exist, opened for append'); // Display file records while not Eof(F) do begin Read(F, Car); Writeln; Writeln('Car # ', FilePos(F), ' --------------------------'); Writeln('Model : ', Car.ModelName); Writeln('Year : ', Car.ModelYear); Writeln('Engine: ', Car.Engine); end end else // File not found, create it begin Rewrite(F); Writeln('File does not exist, created'); end; Writeln('Please input car informaion, ', 'write x in model name to exit'); Writeln('File pointer position at record # ', FilePos(f)); repeat Writeln('--------------------------'); Write('Input car Model Name : '); Readln(car.ModelName); if Car.ModelName <> 'x' then begin Write('Input car Model Year : '); Readln(car.ModelYear); Write('Input car Engine size: '); Readln(car.Engine); Write(F, Car); end; until Car.ModelName = 'x'; CloseFile(F); Write('Press enter key to close..'); Readln;end.  في البرنامج السابق إستخدمنا سجل لمعلومات السيارة، والحقل الأول في السجل ModelName هو من النوع المقطعي، إلا أننا في هذه الحالة قمنا بتحديد طول المقطع بالعدد 20 وهو يمثل 20 حرف:   ModelName: string[20];    وبهذه الطريقة يكون طول المقطع معروف ومحدد ويأخذ مساحة معروفة من القرص، أما طريقة إستخدام النوع string مطلقاً والذي يسمى AnsiString فهي طريقة لها تبعاتها في طريقة تخزينها في الذاكرة، وسوف نتكلم عنها في كتاب لاحق إن شاء الله.   نسخ الملفات Files copy  الملفات بكافة أنواعها سواءً كانت ملفات نصية أو ثنائية، صور ، برامج، أو غيرها فإنها تشترك في أن الوحدة الأساسية فيها هي البايت Byte، حيث أن أي ملف هو عبارة عن مجموعة من البايتات، تختلف في محتوياتها، لكن البايت يحتوي على أرقام من القيمة صفر إلى القيمة 255، لذلك فإذا قرأنا أي ملف فنجد أن رموزه لاتخرج عن هذه اﻹحتمالات (0 - 255). عملية نسخ الملف هي عملية بسيطة، فنحن نقوم بنسخ الملف حرفاً حرفاً بإستخدام متغير يحتل بايت واحد من الذاكرة مثل البايت Byte أو الرمز Char. في هذه الحالة لايهم نوع الملف، لأن النسخ بهذه الطريقة يكون الملف المنسوخ صورة طبق الأصل من الملف الأصلي:     برنامج نسخ الملفات عن طريق البايت   program FilesCopy;{$mode objfpc}{$H+}uses {$IFDEF UNIX}{$IFDEF UseCThreads} cthreads, {$ENDIF}{$ENDIF} Classes, SysUtils { you can add units after this };var SourceName, DestName: string; SourceF, DestF: file of Byte; Block: Byte;begin Writeln('Files copy'); Write('Input source file name: '); Readln(SourceName); Write('Input destination file name: '); Readln(DestName); if FileExists(SourceName) then begin AssignFile(SourceF, SourceName); AssignFile(DestF, DestName); FileMode:= 0; // open for read only Reset(SourceF); // open source file Rewrite(DestF); // Create destination file // Start copy Writeln('Copying..'); while not Eof(SourceF) do begin Read(SourceF, Block); // Read Byte from source file Write(DestF, Block); // Write this byte into new // destination file end; CloseFile(SourceF); CloseFile(DestF); end else // Source File not found Writeln('Source File does not exist'); Write('Copy file is finished, press enter key to close..'); Readln;end.  عند تشغيل هذا البرنامج يجب كتابة إسم الملف المراد النسخ منه والملف الجديد كاملاً مثلا في نظام لينكس نكتب:   Input source file name: /home/motaz/quran/mishari/32.mp3 Input destination file name: /home/motaz/Alsajda.mp3   وفي نظام وندوز:   Input source file name: c:\photos\mypphoto.jpg Input destination file name: c:\temp\copy.jpg   أما إذا كان البرنامج FileCopy موجود في نفس الدليل للملف المصدر والنسخة، فيمكن كتابة إسمي الملف بدون كتابة إسم الدليل مثلاً:   Input source file name: test.pas Input destination file name: testcopy.pas     نلاحظ أن برنامج نسخ الملفات يأخذ وقت طويل عند نسخ الملفات الكبيرة مقارنة بنسخها بواسطة نظام التشغيل نفسه، وذلك يعني أن نظام التشغيل يستخدم طريقة مختلفة لنسخ الملفات. فهذه الطريقة بطيئة جداً بسبب قراءة حرف واحد في الدورة الواحدة ثم نسخة في الملف الجديد، فلو كان حجم الملف مليون بايت فإن الحلقة تدور مليون مرة، تتم فيها القراءة مليون مرة والكتابة مليون مرة. وكانت هذه الطريقة للشرح فقط، أما الطريقة المثلى لنسخ الملفات فهي عن طريق استخدام الملفات غير محددة النوع untyped files.     الملفات غير محددة النوع untyped files   وهي ملفات ذات وصول عشوائي، إلا أنها تختلف عن الملفات محددة النوع في أنها لاترتبط بنوع محدد، كذلك فإن القراءة والكتابة غير مرتبطة بعدد سجلات معين، حيث أن للمبرمج كامل الحرية في تحديد عدد السجلات التي يرغب في كتابتها أو قراءتها في كل مرة.     برنامج نسخ الملفات بإستخدام الملفات غير محددة النوع   program FilesCopy2;{$mode objfpc}{$H+}uses {$IFDEF UNIX}{$IFDEF UseCThreads} cthreads, {$ENDIF}{$ENDIF} Classes, SysUtils { you can add units after this };var SourceName, DestName: string; SourceF, DestF: file; Block: array [0 .. 1023] of Byte; NumRead: Integer;begin Writeln('Files copy'); Write('Input source file name: '); Readln(SourceName); Write('Input destination file name: '); Readln(DestName); if FileExists(SourceName) then begin AssignFile(SourceF, SourceName); AssignFile(DestF, DestName); FileMode:= 0; // open for read only Reset(SourceF, 1); // open source file Rewrite(DestF, 1); // Create destination file // Start copy Writeln('Copying..'); while not Eof(SourceF) do begin // Read Byte from source file BlockRead(SourceF, Block, SizeOf(Block), NumRead); // Write this byte into new destination file BlockWrite(DestF, Block, NumRead); end; CloseFile(SourceF); CloseFile(DestF); end else // Source File not found Writeln('Source File does not exist'); Write('Copy file is finished, press enter key to close..'); Readln;end.    في المثال السابق نجد أن هناك أشياء جديدة وهي:   طريقة تعريف الملفات، وهي بتعريفها أن المتغير مجرد ملف:   SourceF, DestF: file;   المتغير الذي يستخدم في نسخ البيانات بين الملفين:   Block: array [0 .. 1023] of Byte;     نجد أنه في هذه الحالة عبارة مصفوفة من نوع البايت تحتوي على كيلو بايت، ويمكن تغييرها إلى أي رقم يريده المبرمج.   طريقة فتح الملف إختلفت قليلاً:   Reset(SourceF, 1); // open source file Rewrite(DestF, 1); // Create destination file   فقد زاد مُدخل جديد وهو طول السجل، وفي حالة نسخ ملفات هذه يجب أن يكون دائماً يحمل القيمة واحد وهو يعني أن طول السجل واحد بايت. والسبب يكمن في أن الرقم واحد يقبل القسمة على جميع قيم حجم الملفات، مثلاً يمكن أن يكون حجم الملف 125 بايت، أو 23490 بايت وهكذا.   طريقة القراءة:   BlockRead(SourceF, Block, SizeOf(Block), NumRead);   يستخدم الإجراء BlockRead مع الملفات غير محددة النوع، حيث يعتبر أن القيمة المراد قراءتها هي عبارة عن كومة أو رزمة غير معلومة المحتويات. والمدخلات لهذا الإجراء هي:   SourceF: وهو متغير الملف المراد القراءة منه.   Block : وهو المتغير أو المصفوفة التي يراد وضع محتويات القراءة الحالية فيها.   SizeOf(Block): وهو عدد السجلات المراد قراءتها في هذه اللحظة، ونلاحظ أننا استخدمنا الدالة SizeOf التي ترجع حجم المتغير من حيث عدد البايتات، وفي هذه الحالة هو الرقم 1024.   NumRead: عندما نقول أننا نريد قراءة 1024 بايت ربما ينجح الإجراء بقراءتها جميعاً في حالة أن تكون هناك بيانات متوفر في الملف، أما إذا كانت محتويات الملف أقل من هذه القيمة أو أن مؤشر القراءة وصل قرب نهاية الملف، ففي هذه الحالة لايستطيع قراءة 1024 بايت، وتكون القيمة التي قرأها أقل من ذلك وتخزن القيمة في المتغير NumRead. فمثلاً إذا كان حجم المف 1034 بايت، فيقوم الإجراء بقراءة 1024 بايت في المرة الأولى، أما في المرة الثانية فيقوم بقراءة 10 بايت فقط ويرجع هذه القيمة في المتغير NumRead حتى يتسنى إستخدامها مع الإجراء BlockWrite.   طريقة الكتابة:   BlockWrite(DestF, Block, NumRead);     وأظن أنها واضحة، والمتغير الأخيرة NumRead في هذه المرة عدد البايتات المراد كتابتها في الملف المنسوخ، وهي تعني عدد البياتات من بداية المصفوفة Block. وعند تشغيل هذا اﻹجراء فإن المتغير NumRead يحمل قيمة عدد البايتات التي تمت قراءتها عن طريق BlockRead   وعند تشغيل البرنامج سوف نلاحظ السرعة الكبيرة في نسخ الملفات، فمثلاً إذا كان طول الملف مليون بايت، فيلزم حوالي أقل من ألف دورة فقط للقراءة ثم الكتابة في الملف الجديد.     في المثال التالي، يقوم البرنامج بإظهار محتويات الملف بالطريقة المستخدمة في التخزين في الذاكرة أو الملف، فكما سبق ذكره فإن الملف هو عبارة عن سلسلة من الحروف أو البايتات.     برنامج عرض محتويات ملف بالبايت   program ReadContents;{$mode objfpc}{$H+}uses {$IFDEF UNIX}{$IFDEF UseCThreads} cthreads, {$ENDIF}{$ENDIF} Classes, SysUtils { you can add units after this };var FileName: string; F: file; Block: array [0 .. 1023] of Byte; i, NumRead: Integer;begin Write('Input source file name: '); Readln(FileName); if FileExists(FileName) then begin AssignFile(F, FileName); FileMode:= 0; // open for read only Reset(F, 1); while not Eof(F) do begin BlockRead(F, Block, SizeOf(Block), NumRead); // display contents in screen for i:= 0 to NumRead - 1 do Writeln(Block[i], ':', Chr(Block[i])); end; CloseFile(F); end else // File does not exist Writeln('Source File does not exist'); Write('press enter key to close..'); Readln;end.    بعد تنفيذ البرنامج يمكن للمستخدم كتابة إسم ملف نصي حتى نقوم بعرض محتوياته. نلاحظ أن بعد كل سطر نجد علامة الـ Line Feed LF وقيمتها بالبايت 10 في نظام لينكس، أما في نظام وندوز فنجد علامتي Carriage Return/Line Feed CRLF وقيمتهما على التوالي 13 و 10، وهي الفاصل الموجود بين السطور في الملف النصي. يمكن كذلك إستخدام البرنامج في فتح ملفات من نوع آخر لمعرفة طريقة تكوينها. إستخدمنا في البرنامج الدالة Chr التي تقوم بتحويل البايت إلى حرف، مثلاً نجد أن البايت الذي قيمته 97 يمثل الحرف a وهكذا.   ================================================== من كتاب الأستاذ معتز عبد العظيم جزاه الله خيرا  
  9. دورة في لغة Object Pascal و Lazarus

    بسم الله الرحمن الرحيم قال النبي صلى الله عليه وسلم "خير الناس أنفعهم للناس" وإني قد عزمت على أكتب دروسا عن لغة الأبجكت باسكال مستفيدا بشكل كبير من الأستاذ معتز عبد العظيم من كتابيه الرائعين  ابدأ مع الأوبجكت باسكال و الخطوة الثانية مع الأوبجكت باسكال   الدورة ستكون منقولة من الكتابين وإنما أزيد أنا وأنقص ما أراه صالحا وستكون زياداتي باللون الأخضر على طريقة الشناقطة في الاكحلال والاخضرار   وقبل أن أبدأ أود أن أشكر الأستاذ عبد العظيم على أن اعطاني الكتابين مفتوحي المصدر كي يسهل النقل منهما   مقدمة   لغة أوبجكت باسكال   أول ظهور للغة باسكال تدعم البرمجة الكائنية الموجهة (Object Oriented Programming) كان في عام 1983 في شركة أبل للكمبيوتر. بعد ذلك تلتها تيربو باسكال 5.5 الشهيرة التابعة لسلسة تيربو باسكال التي كانت تنتجتها شركة بورلاند، وقد قام المبرمج أندرس هجلسبيرغ بإضافة البرمجة الكائنية لخط تيربو باسكال في عام 1989. لغة الباسكال الكائنية هي لغة تدعم البرمجة الهيكلية (Structured Programming) كما وتدعم البرمجة الكائنية(Object Oriented Programming). لغة الباسكال هي لغة متعددة الأغراض تصلح لكافة أنواع التطبيقات والإحتياجات، فبدايةً من تعلُم البرمجة لسهولتها ووضوحها، مروراً بالألعاب ، والبرامج الحسابية، والبرامج التعليمية، وتطبيقات الإنترنت، وبرامج الإتصالات ، ولغات البرمجة، فمثلاً بيئة تطوير دلفي مطورة بالدلفي نفسها، كذلك فري باسكال ولازاراس تم تطويرهما بلغة الباسكال، وإنتهاءً بنظم التشغيل مثل اﻹصدارات اﻷولى من نظام تشغيل ماكنتوش كان يستخدم فيها لغة باسكال الكائنية و كذلك نظامي التشغيل StreamOS وToro OS المستخدم فيه مترجم Free Pascal.   بعد النجاح التي حققته أداة التطوير تيربو باسكال التي كانت تُستخدم لإنتاج برامج تعمل في نظام الدوز، قامت شركة بورلانت بإنتاج أداة التطوير دلفي في عام 1995 لتستهدف نظام التشغيل وندوز 16 بت ثم وندوز 32 بت في إصدارة دلفي 2 ليعمل مع وندوز 95. وقد لاقت دلفي نجاح كبير حيث أنها كانت تنتج برامج أسرع بأضعاف المرات التي كانت تنتجها نظيرتها الفيجوال بيسك، وكان البرنامج الذي ينتج عن الدلفي لايحتاج لمكتبات إضافية أو مايعرف بالـ Run-time libraries حين إنزال البرامج في أجهزة أخرى لاتحتوي على دلفي.       دلفي Delphi   أداة التطوير دلفي التي أنتجتها شركة بورلاند كما سبق ذكره هي عبارة عن أداة تطوير سريعة للبرامج (Rapid Application Development Tool) ، أما اللغة المستخدمة في هذه الأداة فهي لغة باسكال الكائنية. حدث تطوير كبير للغة باسكال الكائنية من قِبل فريق دلفي حتى أصبحت لغة منافسة لمثيلاتها. وأصبحت لغة ذات إمكانات عالية ومكتبات غنيّة. المشكلة الرئيسية الموجودة في الدلفي هي أنها مرتبطة بنظام التشغيل وندوز، ولم يحدث تطوير لمترجمها ليعمل على أنظمة أخرى بشكل جدي.   بعد المنافسة بين المصادر المفتوحة والمصادر المغلقة، تأثرت شركة بورلاند كثيراً بهذه المنافسة، خصوصاً القسم المتخصص في إنتاج أدوات البرمجة الذي تم فصله في شركة تسمى CodeGear . بعد ذلك تم بيع هذه الشركة المتخصصة في أدوات البرمجة لشركة Embarcadero في عام 2008. أنتجت شركة بورلاند في عام 2006 نسخ مجانية في أدوات تطوير دلفي وسي بلدر تسمى تيربو إكسبلورر (Turbo Explorer). طوال هذه الفترة كان الكود المصدري للغة وأدوات التطوير مغلقاً وخاصاً بشركة بورلاند ثم Embarcadero. بلغ عدد المبرمجين الذين يستخدمون الدلفي أكثر من مليون ونصف مبرمج حسب إحصائية الشركة في عام 2008. وتم تصميم برامج كثيرة بإستخدامها، نذكر منها Skype, Morfik, Age of wonder وغيرها من البرامج المهمة.   والخطأ الكبير الذي وقعت فيه شركة بورلاند هو تسميتها للغة الأوبجكت باسكال بلغة الدالفي والحق أن الدالفي ليس إلا أداة تطويرية ولو كان سائغا أن نسمي أدوات التطوير بأسماء اللغات لسمينا لغة eclipse ولغة qt ولغة lazarus ولغة ...   ولكن ذلك خطأ باتفاق المبرمجين فكيف جاز لبورلاند أن تسمي الدالفي بلغة الدالفي وتمحو اسم الأوبجكت باسكال حتى تناسى الناس هذا الاسم وصاروا يتحدثون بلغة الدالفي     فري باسكال Free Pascal   بعد توقف شركة بورلاند عن إنتاج خط تيربو باسكال الذي كان يستخدم نظام الدوز إلى عام 1993، قام فريق فري باسكال بإنتاج نسخة شبيهة بتيربو باسكال ليكون بديل حر مفتوح المصدر. لكن هذه المرة مع إضافة مهمة وهي إستهداف منصات جديدة مثل: لينكس، ماكنتوش، آرم، واﻵي فون، وغيرها بالإضافة إلى الوندوز 32 بت والوندوز 64 بت. فريق فري باسكال كانت إحدى أهدافه هي التوافقية مع لغة باسكال الكائنية المستخدمة في الدلفي. النسخة اﻷولى من مترجم فري باسكال صدرت في يوليو عام 2000، وآخر نسخة رسمية متوفرة اﻵن في عام 2012 هي نسخة رقم 2.6     لازاراس Lazarus   بعد نجاح مترجم فري باسكال وتفوقه على مترجم تيربو باسكال، وإنتاج نسخة تعمل في عدد من المنصات التشغيلية، كانت الحلقة الناقصة هي أداة التطوير المتكاملة. لازاراس هي أداة التطوير المستخدمة مع فري باسكال، أو هي أداة التطوير التي تستخدم فري باسكال كمترجم. وهي عبارة عن مكتبة ضخمة للكائنات class library، وبهذه الطريقة نكود قد حولنا أداة باسكال إلى أداة معتمدة على التطوير بإستخدام المكونات أو الكائنات component driven development مماثلة للدلفي بالإضافة لكونها محرر للكود ومصمم للبرنامج. فهي بذلك تحقق كونها أداة تطوير سريعة RAD Rapid Application Development. بدأ مشروع لازاراس عام 1999 وتم إصدار النسخة رقم 1 منه في أواخر أغسطس من العام 2012، لكن تمت كتابة عدد كبير من البرامج بواسطة النسخ السابقة للنسخة رقم 1 كما تمت كتابة عدد من الكتب حوله.   ميزات لغة باسكال   تتميز لغة باسكال الهدفية بسهولة تعلمها، وإمكاناتها العالية، وسرعة مترجماتها والبرامج التي تنتج عنها. لذلك فهي تعطي المبرمج فرصة إنتاج برامج ذات كفاءة وإعتمادية عاليتين في وقت وجيز، بإستخدام بيئة تطوير متكاملة وواضحة دون الدخول في تعقيدات اللغات وأدوات التطوير الصعبة. وهذا يحقق الإنتاجية العالية.
  10. بسم الله الرحمن الرحيم الملفات files   الملفات هي من أهم العناصر في نظام التشغيل والبرامج عموماً، فإن بعض إجزاء نظام التشغيل نفسها هي عبارة عن ملفات. والمعلومات والبيانات هي عبارة عن ملفات، مثل الصور والكتب والبرامج والنصوص البسيطة هي عبارة عن ملفات. ويجب على نظام التشغيل توفير إمكانية لإنشاء الملفات، ولقراءتها وكتابتها وتحريرها وحذفها.   تنقسم الملفات إلى عدة أنواع بناءً على عدة أوجه نظر. فيمكن تقسيم الملفات إلى ملفات تنفيذية وملفات بيانات، حيث أن الملفات التنفيذية هي التي تمثل البرامج وأجزائه التنفيذية مثل الملف الثنائي الذي يحتوي على كود يفهمه نظام التشغيل ومثال لها الملفات التنفيذية التي تصدر عن مترجم الفري باسكال أو الـ gcc والتي يمكن نقلها في عدد من الأجهزة التي تحتوي على نفس نظام التشغيل ثم تشغيلها بالنقر عليها أو بكتابة إسمها في شاشة الطرفية console. وكمثال لها برنامج اﻵلة الحاسبة، محرر النصوص، برامج اﻷلعاب، إلخ. أما النوع الثاني فهي ملفات البيانات التي لاتحتوى على كود ولاتمتلك إمكانية التشغيل، إنما تحتوي على بيانات بسيطة أو معقدة يمكن قراءتها مثل النصوص والملفات المصدرية للغات البرمجة مثل first.lpr ، أو الصور وملفات الصوت التي هي عبارة عن بيانات يمكن عرضها بإستخدام برامج معينة مثل برامج تحرير الصور وبرامج تعدد الوسائط multimedia. وكمثال لهذه الملفات ملفات الصوت .mp3 وملفات الكتب .pdf   يمكننا كذلك تقسيم الملفات من حيث نوع البيانات إلى قسمين:   ملفات نصية بسيطة يمكن إنشائها وقراءتها عن طريق أدوات بسيطة في نظام التشغيل مثل cat التي تعرض محتويات ملف نصي في نظام لينكس، و type التي تطبع محتويات ملف نصي في وندوز، و vi التي تقوم بتحرير وإنشاء الملفات النصية في نظام لينكس. ملفات بيانات ثنائية وهي يمكن أن تحتوى على رموز غير مقروءة وهذه الملفات لاتصلح لأن يقوم المستخدم بتحريرها أو قراءتها مباشرة، بل يجب عليه إستخدام برامج محددة لهذه العمليات. مثل ملفات الصور إذا حاول المستخدم قراءتها بإستخدام cat مثلاً فإن يحصل على رموز لاتُفهم، لذلك يجب فتحها بإستخدام برامج عرض أو تحرير مثل المتصفح أو برنامج Gimp. كذلك يمكن أن يكون مثال لهذه الأنواع ملفات قواعد البيانات البسيطة مثل paradox, dBase فهي عبارة عن ملفات ثنائية تُخزن فيها سجلات تحتوى على معلومات منظمة بطريقة معينة.     النوع الآخر من التقسيم للملفات هو طريقة الوصول والكتابة، حيث يوجد نوعين من الملفات:   ملفات ذات وصول تسلسلي sequential access files: ومثال لها الملفات النصية، وتتميز بأن طول السجل أو السطر فيها غير ثابت، لذلك لامكن معرفة موقع سطر معين في الملف. ويجب فتح الملف للقراءة فقط أو الكتابة فقط، ولا يمكن الجمع بين الوضعين (الكتابة والقراءة) ولايمكن تعديلها بسهولة إلا بقراءتها كاملة في مخزن مؤقت ثم تعديل أسطر معينة فيها ثم مسح الملف وكتابته من جديد. كذلك فإن القراءة والكتابة تتم بتسلسل وهو من بداية الملف إلى نهايته، حيث لايمكن الرجوع سطر إلى الوراء. ملفات ذات وصول عشوائي random access files: وهي ملفات ذات طول سجل ثابت، حين أن السجل يمثل أصغر وحدة يتعامل معها البرنامج في القراءة، الكتابة والتعديل. ويمكن الجمع بين الكتابة والقراءة في نفس اللحظة، مثلاً يمكن قراءة السجل الخامس، ثم نسخ محتوياته في السجل الأخير. ويمكن الوصول مباشرة إلى أي سجل دون التقيد بمكان القراءة أو الكتابة الحالي. فمثلاً إلى كان طول السجل هو 5 حروف أو بايت، فإن السجل الخامس يبدأ في الموقع رقم 50 في هذا الملف.   الملفات النصية text files   الملفات النصية كما سبق ذكره هي ملفات بسيطة يمكن قراءتها بسهولة. ومن ناحية الوصول هي ملفات تسلسلية sequential files حيث يجب القراءة فقط في إتجاه واحد وهو من البداية للنهاية ويجب الكتابة فيها بنفس الطريقة. لعمل برنامج بسيط يقوم بقراءة محتويات ملف، علينا أولاً إنشاء ملفات نصية أو البحث عنها ثم وضعها في الدليل أو المجلد الذي يوجد فيه البرنامج ثم تنفيذ البرنامج التالي:     برنامج قراءة ملف نصي   program ReadFile;{$mode objfpc}{$H+}uses {$IFDEF UNIX}{$IFDEF UseCThreads} cthreads, {$ENDIF}{$ENDIF} Classes, sysUtils { you can add units after this };var FileName: string; F: TextFile; Line: string;begin Write('Input a text file name: '); Readln(FileName); if FileExists(FileName) then begin // Link file variable (F) with physical file (FileName) AssignFile(F, FileName); Reset(F); // Put file mode for read, file should exist // while file has more lines that does not read yet do the loop while not Eof(F) do begin Readln(F, Line); // Read a line from text file Writeln(Line); // Display this line in user screen end; CloseFile(F); // Release F and FileName connection end else // else if FileExists.. Writeln('File does not exist'); Write('Press enter key to close..'); Readln;end.    بعد تنفيذ البرنامج السابق نقوم بإدخال إسم ملف موجود في نفس مكان البرنامج أو بكتابة الإسم كاملاً مثل:   /etc/resolv.conf  أو   /proc/meminfo/proc/cpuinfo  بإستخدام أسماء الملفين الأخيرين، فإن هذا البرنامج قادر على قراءة الذاكرة الكلية للحاسوب والذاكرة المستخدمة والذاكرة المتاحة، كذلك يمكنه قراءة نوع المعالج المستخدم في جهاز الحاسوب وسرعته.   نلاحظ أننا استخدمنا دوال وإجراءات وأنواع جديدة في هذه البرنامج وهي:   1.     F: TextFile;      وهي تعريف المتغير F بأن نوعه TextFile وهو النوع الذي يتعامل مع الملفات النصية. وفي البرنامج سوف نستخدم هذا المتغيير للتعبير عن الملف الفعلي.   2.     if FileExists(FileName) then      وهي دالة موجودة في المكتبة SysUtils وهي تختبر وجود هذا الإسم كملف، فإذا كان موجود تحقق الشرط وإن لم يكن موجود فإن عبارة else هي التي سوف تُنفّذ.   3.     AssignFile(F, FileName);      بعد التأكد من أن الملف موجود يقوم إجراء AssignFile بربط إسم الملف الفعلي بالمتغير F، والذي عن طريقه يمكننا التعامل مع الملف من داخل باسكال.   4.     Reset(F); // Put file mode for read, file should exist      وهي العبارة التي تقوم بفتح الملف النصي للقراءة فقط، وهي تخبر نظام التشغيل أن هذا الملف محجوز للقراءة، فإذا حاول برنامج آخر فتح الملف للكتابة أو حذفه فإن نظام التشغيل يمنعه برسالة مفادها أن الملف مفتوح بواسطة تطبيق آخر أو أن السماحية غير متوفرة access denied   5.     Readln(F, Line); // Read a line from text file      وهو إجراء القراءة من الملف، حيث أن هذا اﻹجراء يقوم بقراءة سطر واحد فقط من الملف المفتوح F ووضع هذا السطر في المتغير Line.   6.     while not Eof(F) do      كما ذكرنا في اﻹجراء Readln فإنه يقوم بقراءة سطر واحد فقط، وبالنسبة للملف النصي فإننا لايمكننا معرفة كم سطر يحتوي هذا الملف قبل الإنتهاء من قراءته، لذلك إستخدمنا هذه الدالة eof والتي تعني نهاية الملEnd Of File. إستخدمناها مع الحلقة while وذلك للإستمرار في القراءة حتى الوصول إلى نهاية الملف وتحقيق شرط end of file.   7.     CloseFile(F); // Release F and FileName connection      بعد الفراغ من قراءة الملف، يجب إغلاقه وذلك لتحريره من جهة نظام التشغيل حتى يمكن لبرامج أخرى التعامل معه بحرية، ولابد من تنفيذ هذا الإجراء فقط بعد فتح الملف بنجاح بواسطة reset مثلاً. فإذا فشل فتح الملف أصلاً بواسطة reset فلايجب إغلاقه بواسطة CloseFile.     في المثال التالي سوف نقوم بإنشاء ملف نصي جديد والكتابة فيه:     برنامج إنشاء وكتابة ملف نصي var FileName: string; F: TextFile; Line: string; ReadyToCreate: Boolean; Ans: Char; i: Integer;begin Write('Input a new file name: '); Readln(FileName); // Check if file exists, warn user if it is already exist if FileExists(FileName) then begin Write('File already exist, did you want to overwrite it? (y/n)'); Readln(Ans); if upcase(Ans) = 'Y' then ReadyToCreate:= True else ReadyToCreate:= False; end else // File does not exist ReadyToCreate:= True; if ReadyToCreate then begin // Link file variable (F) with physical file (FileName) AssignFile(F, FileName); Rewrite(F); // Create new file for writing Writeln('Please input file contents line by line, ' , 'when you finish write % then press enter'); i:= 1; repeat Write('Line # ', i, ':'); Inc(i); Readln(Line); if Line <> '%' then Writeln(F, Line); // Write line into text file until Line = '%'; CloseFile(F); // Release F and FileName connection, flush buffer end else // file already exist and user does not want to overwrite it Writeln('Doing nothing'); Write('Press enter key to close..'); Readln;end.  في البرنامج السابق استخدمنا عدة أشياء وهي:   1.     ReadyToCreate: Boolean;      النوع boolean يمكن لمتغيراته أن تحمل إحدى قيمتين فقط: True/False . وهذه القيم يمكن استخدامها مع عبارة if condition كما في المثال، كذلك يمكن إستخدامها مع حلقة while وحلقة repeat. حيث أن الشرط في النهاية يتحول إلى إحدى هتين القيمتين، فكما في أمثلة سابقة إستخدمنا هذه العبارة:       if Marks[i] > Max then      فهي إما أن تكون النتيجة فيتحول الشرط إلى True أو تكون خاطئة فيتحول الشرط إلى False. فعندما تتحول إلى True يتم تنفيذ الشرط:   if True then  وإذا كانت قيمتها النهائية False لاتم تنفيذ إجراء الشرط وإنما يتم تنفيذ إجراء else إن وجد.     2. if upcase(Ans) = 'Y' then  هذه العبارة يتم تنفيذها في حالة وجود الملف، فيقوم البرنامج بتنبيه المستخدم بوجود الملف، وسؤاله إذا كان يرغب في حذف محتوياته والكتابة عليه من جديد (overwrite). فإذا قام بإدخال الحرف y صغيرة أو Y كبيرة فإن الشرط يتم تنفيذه في الحالتين، حيث أن الدالة upCase تقوم بتحويل الحرف إلى حرف كبير لمقارنته مع الحرف الكبير 'Y'. أما إذا ادخل المستخدم حرفاً كبيراً Y فإن الدالة upCase لاتقوم بأي تغيير وترجع الحرف كما هو Y.   3.     Rewrite(F); // Create new file for writing      الإجراء Rewrite يقوم بإنشاء ملف جديد أو حذف محتويات الملف إذا كان موجود. كذلك فهو يفتح الملف للكتابة فقط في حالة الملف النصي.   4.     Writeln(F, Line); // Write line into text file      الإجراء Writeln(F يقوم بكتابة المقطع Line في الملف ثم إضافة علامة نهاية السطر وهي CR/LF. وهي عبارة عن رموز الواحد منها يمثل بايت وقيمتها هي كالآتي :     CR: Carriage Return = 13LF: Line Feed = 10  وهذه الرموز من اﻷحرف الغير مرئية، حيث لاتتم كتابتها في الشاشة، إنما يظهر فقط مفعولها، وهي اﻹنتقال إلى سطر جديد.   5.     Inc(i);      يقوم الإجراء Inc بإضافة واحد إلى قيمة المتغير الصحيح، في هذه الحالة i وهو يعادل هذه العبارة:   i:= i + 1;    6.     CloseFile(F); // Release F and FileName connection, flush buffer      كما ذكرنا سابقاً فإن الإجراء CloseFile يقوم بإغلاق الملف وإيقاف عملية الكتابة أو القراءة من الملف، وتحريره من الحجز بواسطة نظام التشغيل. إلا أن له وظيفة إضافية في حالة الكتابة. فكما نعلم أن الكتابة على القرص الصلب هي عملية بطيئة نسبياً مقارنة بالكتابة في الذاكرة، مثل إعطاء قيم للمتغيرات، أو الكتابة في مصفوفة. لذلك من غير المنطقي كتابة كل سطر على حده في القرص الصلب أو أي وسيط تخزين آخر، لذلك يقوم البرنامج بتخزين عدد معين من السطور في الذاكرة بعملية تسمى الـ Buffering ، فكلما إستخدمنا عبارة Write أو Writeln لكتابة سطر فإن البرنامج يقوم تلقائياً بكتابته في الذاكرة إلى أن يمتليء هذا الوعاء (Buffer) في الذاكرة فيقوم البرنامج تلقائياً بالكتابة الفعلية على القرص الصلب ثم حذف المحتويات من الذاكرة (Buffer)، وهذه العلمية تسمى Flushing وبهذه الطريقة نضمن السرعة في كتابة الملف، بإعتبار أن التكلفة الزمنية مثلاً لكتابة سطر واحد ربما تساوي تقريباً تكلفة كتابة 10 أسطر في القرص الصلب دفعة واحدة. وتكمن خطورة هذه الطريقة في إنقطاع الطاقة عن الحاسوب قبل الكتابة الفعلية، فيجد المستخدم أن الأسطر الأخيرة التي قام بكتابتها قد ضاعت. ويمكن إجبار البرنامج بالقيام بالكتابة الفعلية على القرص بإستخدام الإجراء Flush، كذلك فإن عملية الـ Flushing تحدث إيضاًعند إغلاق الملف بإستخدام CloseFile.           الإضافة إلى ملف نصي   سوف نقوم في هذا المثال بفتح ملف نصي يحتوي على بيانات ثم إضافة أسطر عليه بدون حذف الأسطر القديمة، ويتم ذلك بإستخدام الإجراء AppendFile     برنامج الإضافة إلى ملف نصي: var FileName: string; F: TextFile; Line: string; i: Integer;begin Write('Input an existed file name: '); Readln(FileName); if FileExists(FileName) then begin // Link file variable (F) with physical file (FileName) AssignFile(F, FileName); Append(F); // Open file for appending Writeln('Please input file contents line by line', 'when you finish write % then press enter'); i:= 1; repeat Write('Line # ', i, ' append :'); Inc(i); Readln(Line); if Line <> '%' then Writeln(F, Line); // Write line into text file until Line = '%'; CloseFile(F); // Release F and FileName connection, flush buffer end else Writeln('File does not exist'); Write('Press enter key to close..'); Readln;end.  بعد تنفيذ البرنامج يمكننا كتابة إسم ملف نصي موجود وإضافة بضعة أسطر عليه، بعد ذلك يمكننا أن نستعرض الملف عن طريق الأمر cat في لينكس، أو عن طريق تصفح الدليل الذي يوجد فيه البرنامج والضعط عليه بالماوس لفتحه.     ================================================= الدورة منقولة من كتاب الأستاذ الفاضل معتز عبد العظيم
  11. بسم الله الرحمن الرحيم السجلات Records   كما لاحظنا أن المصفوفات تحتوي على مجموعة متغيرات من نوع واحد، فإن السجلات تجمع بين مجموعة من أنواع مختلفة تسمى حقول Fields، ولكنها تمثل كيان واحد. مثلاً إذا افترضنا أننا نريد تسجيل معلومات سيارة، فنجد أن هذه المعلومات هي:   نوع السيارة: متغير مقطعي سعة المحرك: حدد حقيقي (كسري) سنة التصنيع: متغير صحيح فلايمكن التعبير عن هذه الأنواع المختلفة كوحدة واحدة إلا بإستخدام السجل كما في المثال التالي:   program Cars;{$mode objfpc}{$H+}uses {$IFDEF UNIX}{$IFDEF UseCThreads} cthreads, {$ENDIF}{$ENDIF} Classes { you can add units after this };type TCar = record ModelName: string; Engine: Single; ModelYear: Integer; end;var Car: TCar;begin Write('Input car Model Name: '); Readln(Car.ModelName); Write('Input car Engine size: '); Readln(Car.Engine); Write('Input car Model year: '); Readln(Car.ModelYear); Writeln; Writeln('Car information: '); Writeln('Model Name : ', Car.ModelName); Writeln('Engine size : ', Car.Engine); Writeln('Model Year : ', Car.ModelYear); Write('Press enter key to close..'); Readln;end.    في المثال السابق نجد أننا قمنا بتعريف نوع جديد بإستخدام الكلمة المفتاحية type :   type TCar = record ModelName: string; Engine: Single; ModelYear: Integer; end;      وسمينا هذا النوع الجديد TCar والحرف T هو من كلمة Type حتى نفرق بينه وبين المتغيرات. وهذا النوع الجديد الذي يمثل سجل Record يحتوي على ثلاث أنواع كما يظهر في المثال.   وعندما نريد استخدام هذا النوع الجديد لابد من تعريف متغير يمثل هذا النوع، حيث لايمكننا استخدام النوع TCar مباشرةً كما لايمكننا إستخدام النوع Integer مباشرة إلا بعد تعريف متغير مثلاً I أو Num. لذلك قمنا بتعريف المتغير Car من النوع TCar في بند المتغيرات:   var Car: TCar;    وعندما نريد إدخال قيم للمتغيرات أو طباعتها نستخدم هذه الطريقة للوصول لمتغير ما في سجل:   Car.ModelName    في درس الملفات ذات الوصول العشوائي إن شاء الله سوف نستفيد فائدة مباشرة من السجلات التي تمثل ركن أساسي في قواعد البيانات.   ================================================= الدورة منقولة من كتاب الأستاذ الفاضل معتز عبد العظيم
  12. تحريك صورة على الاطار

    السلام عليكم ورحمه الله وبركاته اتمنى المساعده السريعه من اى حد قد يكون قام بعمل هذه الفكره وهى ان يكون لدينا اطار JPanel باقوم بالرسم عليها واريد ان اضع صوره على هذه الـ JPanel   ولكن هذه الصوره تكون متحركه (Object) ممكن احركه وامسحه فى وقت اتمنى المساعده فى اقرب وقت التسليم غدا والبروجكت كله متوقف على هذه الجزئيه     وشكرا
  13. بسم الله الرحمن الرحيم المصفوفات arrays   المصفوفة هي عبارة عن صف أو مجموعة من متغيرات ذات نوع واحد، مثلاً إذا قلنا أن لدينا مصفوفة من الأعداد الصحيحة تحتوي على 10 عناصر فإن تعريفها يكون كالتالي       Numbers: array [1 .. 10] of Integer;      ويمكننا وضع قيمة في المتغير الأول في المصفوفة كالتالي:       Numbers[1]:= 30;      ويمكننا وضع قيمة في المتغير الثاني في المصفوفة كالتالي:       Numbers[2]:= 315;      في المثال التالي نقوم بتخزين درجات 10 طلاب ثم عرضها:   var Marks: array [1 .. 10] of Integer; i: Integer;begin for i:= 1 to 10 do begin Write('Input student number ', i, ' mark: '); Readln(Marks[i]); end; for i:= 1 to 10 do begin Write('Student number ', i, ' mark is : ', Marks[i]); if Marks[i] >= 40 then Writeln(' Pass') else Writeln(' Fail'); end; Writeln('Press enter key to close'); Readln;end.    نجد أننا إستخدمنا حلقة for لإدخال وطباعة الدرجات. كذلك قمنا بمقارنة نتيجة كل طالب داخل الحلقة لنعرف الناجح وغير الناجح.     يمكن تعديل البرنامج السابق لنعرف أكبر وأصغر درجة في الدرجات كالتالي:     var Marks: array [1 .. 10] of Integer; i: Integer; Max, Min: Integer;begin for i:= 1 to 10 do begin Write('Input student number ', i, ' mark: '); Readln(Marks[i]); end; Max:= Marks[1]; Min:= Marks[1]; for i:= 1 to 10 do begin // Get if current Mark is maximum mark or not if Marks[i] > Max then Max:= Marks[i]; // Check if current value is minimum mark or not if Marks[i] < Min then Min:= Marks[i]; Write('Student number ', i, ' mark is : ', Marks[i]); if Marks[i] >= 40 then Writeln(' Pass') else Writeln(' Fail'); end; Writeln('Max mark is: ', Max); Writeln('Min mark is: ', Min); Writeln('Press enter key to close'); Readln;end.    نلاحظ أننا إفترضنا أن الرقم الأول هو أكبر درجة لذلك قمنا بوضعه في المتغير Max كذلك إعتبرنا أنه أصغر درجة فوضعناه في المتغير Min إلى أن يثبت العكس في كلا الحالتين.   Max:= Marks[1]; Min:= Marks[1];    وفي داخل الحلقة عند طباعة الأرقام العشرة، قمنا بمقارنة كل رقم مع القيم max و min فإذا وجدنا رقم أكبر من max قمنا بإستبدال قيمة max بقيمة الدرجة الحالية ، ونفعل نفس الشيء مع القيمة min.     نلاحظ في المثال السابق أننا إستخدمنا تعليق مثل:   // Get if current Mark is maximum mark or not  وقد بدأنا السطر بالعلامة // وهي تعني أن باقي السطر عبارة عن تعليق لاتتم ترجمته، إنما يستفيد منه المبرمج كشرح حتى يصبح البرنامج مقروء له ولمن يريد الإطلاع على البرنامج. هذه الطريقة تصلح للتعليق القصير، أما إذا كان التعليق أكثر من سطر يمكس إستخدام الأقواس المعكوفة {} أو الأقواس والنجمة (* *)   مثلاً:   for i:= 1 to 10 do begin { Get if current Mark is maximum mark or not check if Mark is greater than Max then put it in Max } if Marks[i] > Max then Max:= Marks[i]; (* Check if current value is minimum mark or not if Min is less than Mark then put Mark value in Min *) if Marks[i] < Min then Min:= Marks[i]; Write('Student number ', i, ' mark is : ', Marks[i]); if Marks[i] >= 40 then Writeln(' Pass') else Writeln(' Fail'); end;    كذلك يمكن الإستفادة من هذه الخاصية بتعطيل جزء من الكود مؤقتاً كالتالي:   Writeln('Max mark is: ', Max); // Writeln('Min mark is: ', Min); Writeln('Press enter key to close'); Readln;    في هذا المثال قمنا بتعطيل إجراء طباعة أصغر درجة.     ================================================= الدورة منقولة من كتاب الأستاذ الفاضل معتز عبد العظيم وما تراه باللون الأخضر فمن زياداتي
  14. بسم الله الرحمن الرحيم الدرس الرابع الحلقات loops   الحلقات هي من المواضيع المهمة والعملية في البرمجة، فهي تعني الإستمرار في تنفيذ جزء معين من العبارات بوجود شرط معين. وعندما ينتهي أو ينتفي هذا الشرط تتوقف الحلقة عن الدوران.     حلقة for   يمكن تكرار عبارة معينة بعدد معين بإستخدام for كما في المثال التالي: والكتابة العامة لها هي     for < variable-name > := < initial_value > to [down to] < final_value > do S;  مثالها   var i: Integer; Count: Integer;begin Write('How many times? '); Readln(Count); for i:= 1 to Count do Writeln('Hello there'); Write('Press enter key to close'); Readln;end.    نستخدم في حلقات for متغير صحيح يسمى متغير الحلقة، وهو في هذا المثال المتغير i، وقيمته تبدأ في الدورة الأولى بالقيمة الإبتدائية التي حددها المبرمج، في هذه الحالة هو الرقم 1 ثم يزيد هذا المتغير في كل دورة حتى يتنهي في الدورة الأخيرة بالقيمة الأخيرة، وهي التي يحددها المستخدم بإدخالة لقيمة Count   يمكن إظهار قيمة متغير الحلقة كما في التعديل التالي للمثال السابق: var i: Integer; Count: Integer; begin Write('How many times? '); Readln(Count); for i:= 1 to Count do begin Writeln('Cycle number: ', i); Writeln('Hello there'); end; Write('Press enter key to close'); Readln; end.  نلاحظ هذه المرة أننا قمنا تنفيذ عبارتين، لذلك إحتجنا لأن نوحدهما في شكل عبارة واحدة بإستخدام begin end.     جدول الضرب بإستخدام for loop   لو قارنا بين برنامج جدول الضرب السابق والتالي الذي سوف نستخدم فيه عبارة for سوف نجد أن الأخير ليس فيه تكرار كالأول:   program MultTableWithForLoop;{$mode objfpc}{$H+}uses {$IFDEF UNIX}{$IFDEF UseCThreads} cthreads, {$ENDIF}{$ENDIF} Classes { you can add units after this };{$IFDEF WINDOWS}{$R first.rc}{$ENDIF}var x, i: Integer;begin Write('Please input any number: '); Readln(x); for i:= 1 to 12 do Writeln(x, ' * ', i, ' = ', x * i); Writeln('Press enter key to close'); Readln;end.    نجد أننا بدلاً عن كتابة إجراء إظهار حاصل الضرب 12 مرة فقد تمت كتابته مرة واحدة فقط وتولت حلقة for تكرار هذا اﻹجراء 12 مرة.   يمكن جعل الحلقة تدور بالعكس، من القيمة الكبرى إلى القيمة الصغرى وذلك بإستخدام downto وذلك بتغيير سطر واحد في المثال السابق لجدول الضرب:       for i:= 12 downto 1 do        برنامج المضروب Factorial   المضروب هو مجموع حاصل ضرب الرقم مع الرقم الذي يسبقه إلى الرقم واحد:   مضروب 3 يساوي 3 * 2 * 1 وتنتج عنه القيمة: 6 var Fac, Num, i: Integer;begin Write('Please input any number: '); Readln(Num); Fac:= 1; for i:= Num downto 1 do Fac:= Fac * i; Writeln('Factorial of ', Num ,' is ', Fac); Writeln('Press enter key to close'); Readln;end.   حلقة Repeat Until   بخلاف حلقة for loop التي تتميز بأنها تدور بعدد مين فإن Repeat loop تدور إلى أن يتحقق شرط معين، فمادام هذا الشرط غير مُحقق فهي تعيد الدوران، فإذا تحقق الشرط فسوف يخرج مؤشر التنفيذ من هذه الحلقة ويتم تنفيذ مابعدها. لذلك نجد أن هذه الحلقة غير محددة بعدد معين من الدورات، فعددها يعتمد على أن الشرط تحقق بعد كم من الدورات. var Num : Integer;begin repeat Write('Please input a number: '); Readln(Num); until Num <= 0; Writeln('Finished, please press enter key to close'); Readln;end.   في البرنامج السابق يقوم البرنامج بالدخول للحلقة أولاً ثم سؤال المستخدم أن يدخل عدداً، ثم يقوم في نهاية الحلقة بفحص قيمة هذا العدد فإذا ساوي الصفر أو عدد أقل منه فإن الشرط يكون قد تحقق وتتنتهي الحلقة، أما إذا أدخلنا فيها أرقام أكبر من الصفر فإن الحلقة تستمر في الدوران.     برنامج المطعم بإستخدام Repeat Until   var Selection: Char; Price: Integer; Total: Integer;begin Total:= 0; repeat Writeln('Welcome to Pascal Restaurant. Please select your order'); Writeln('1 - Chicken (10 Geneh)'); Writeln('2 - Fish (7 Geneh)'); Writeln('3 - Meat (8 Geneh)'); Writeln('4 – Salad (2 Geneh)'); Writeln('5 - Orange Juice (1 Geneh)'); Writeln('6 - Milk (1 Geneh)'); Writeln('X - nothing'); Writeln; Write('Please enter your selection: '); Readln(Selection); case Selection of '1': begin Writeln('You have ordered Chicken, ', 'this will take 15 minutes'); Price:= 10; end; '2': begin Writeln('You have ordered Fish, ', ' this will take 12 minutes'); Price:= 7; end; '3': begin Writeln('You have ordered meat, ', ' this will take 18 minutes'); Price:= 8; end; '4': begin Writeln('You have ordered Salad, ' ' this will take 5 minutes'); Price:= 2; end; '5': begin Writeln('You have ordered Orange juice, ', 'this will take 2 minutes'); Price:= 1; end; '6': begin Writeln('You have ordered Milk, ', 'this will take 1 minute'); Price:= 1; end; else begin Writeln('Wrong entry'); Price:= 0; end; end; Total:= Total + Price; until (Selection = 'x') or (Selection = 'X'); Writeln('Total price = ', Total); Write('Press enter key to close'); Readln;end.     في البرنامج السابق هناك عدة أشياء جديدة وهي:   إضافة begin end مع case وذلك لأن تنفيذ الشرط لابد أن يكون عبارة واحدة، وكما سبق ذكره فإن begin end تقوم بتحويل عدة عبارات إلى عبارة واحدة. الفريق العربي للبرمجةارة   Writeln('You have ordered..   تمت إضافة عبارة جديدة معها وهي price:= 2 وهي لمعرفة قيمة الطلب وإضافته لاحقاً لمعرفة الحساب الكلي. تم إستخدام المتغير selection من النوع الحرفي char وهو يتميز بإمكانيته في إستقبال أي رمز من لوحة المفاتيح، فمثلاً يمكن أن يستقبل رقم (خانة واحدة فقط) أو حرف. وقد إستخدمنا الحرف x للدلالة على نهاية الطلبات. قمنا بوضع صفر في المتغير Total والذي سوف نقوم بتجميع قيمة الطلبات فيه ثم نعرضه في النهاية. وقد إستخدمنا هذه العبارة للتجميع:     Total:= Total + Price;       وضعنا خيارين لإدخال الحرف x فإذا قام المستخدم بإدخال x كبيرة X أو صغيرة x فإن الحلقة تتوقف. علماً بأن قيمة الحرف x تختلف عن قيمته بالصيغة الكبيرة X.   حلقة while do   والكتابة العامة لها هي while (condition) do S;  تتشابه حلقة while مع حلقة repeat بإرتباط الإستمرار في الدوران مع شرط معين، إلا أن while تختلف إختلافين: يتم فحص الشرط أولاً ثم الدخول إلى الحلقة حلقة repeat يتم تنفيذها مرة واحدة على الأقل، وبعد الدورة الأولى يتم فحص الشرط، أما while فهي تمنع البرنامج من دخول الحلقة إذا كان الشرط غير صحيح من البداية. إذا كانت الحلقة تحتوي على أكثر من عبارة فلابد من إستخدام begin end. أما حلقة repeat فإنها لاتحتاج، لأن الحلقة حدودها تبدأ من كلمة repeat وتنتهي بـ until.   مثال: var Num: Integer;begin Write('Input a number: '); Readln(Num); while Num > 0 do begin Write('From inside loop: Input a number : '); Readln(Num); end; Write('Press enter key to close'); Readln;end.   يمكننا إعادة كتابة برنامج المضروب بإستخدام while do       برنامج المضروب بإستخدام حلقة while do var Fac, Num, i: Integer;begin Write('Please input any number: '); Readln(Num); Fac:= 1; i:= Num; while i > 1 do begin Fac:= Fac * i; i:= i - 1; end; Writeln('Factorial of ', Num ,' is ', Fac); Writeln('Press enter key to close'); Readln;end.   بما أن حلقة while ليس لديها متغير حلقة مثل for loop فقد قمنا بإستخدام المتغير i ليكون متغير الحلقة. لذلك قمنا بإنقاص قيمة المتغير i حتى يصلى إلى واحد وهو شرط عدم الدخول مرة أخرى في الحلقة.   الحلقات من نوع while او من نوع repeat يجب الحذر فيها لأمر واحد وهو أن تجعل لها غاية تنتهي إليها إذا لم تكن تريد البقاء في الحقلة ومعنى ذلك أن تجعل الحقات تنتهي إلى ذلك الشرط الذي وضعته للحقلة مثل while i > 10 do   فلا بد أن تزود i ب 1 أو أكثر في كل مرة تدور بها الحلقة وإلا بقيت تدور ما دام البرنامج مشتغلا وذلك يعد عند المبرمجين خطأ منطقيا   والصواب أنه سيكون خطأ منطقيا إذا لم ترد أنت البقاء في الحلقة إلى ما لا نهاية وإنما قلت ذلك لأنه في بعض البرامج يحتاج أن تبقى في حلقة لا منتهية إلى غاية نهاية البرنامج   مثال ذلك برنامج bash أو الطرفية فهو برنامج مؤسس من حلقة لا متناهية وهي كل مرة تدور فيها تنتظر من المستخدم أن يدخل أمرا لتنفذه   ‫يستخدم الأمر  ‪  break‬والأمر  ‪  continue‬مع حلقات  ‪  for‬وآافة حلقات التكرار‬ ‫الأخرى مثل ‪  while , repeat‬وآما يلي ‪:‬‬ ‫‪ .1‬الأمر  ‪  break‬ويستخدم للسيطره على تدفق تكرار العبارات وهي تؤدي الى أنهاء‬ ‫أو توقف التكرار ‪ ,‬مثال‬ ‫‪For i: = 1 to 10 do‬‬‫‪begin‬‬‫;( ‪Readln( x‬‬‫‪If x < 0 then‬‬‫‪Break‬‬‫‪Else‬‬‫;( ( ‪Writeln( sqrt( x‬‬‫;‪End‬‬  ‫في هذه الحاله يتوقف التنفيذ عند ورود عدد سالب لعدم أمكانية أيجاد الجذر التربيعي‬ ‫للعدد السالب ‪.‬‬ ‫‪ .2‬الأمر  ‪  continue‬ويستخدم أيضا مع حلقات التكراروهو يعني أستمر مع حلقة‬ ‫تكرار جديده أي أهمل تنفيذ الأوامر التي بعد الأمر  ‪  continue‬عند تحقق شرط‬ ‫معين حيث سيعيد المؤشر الى الأمر ) ‪ ,  for‬مثال‬   ‫‪For i: = 1 to 10 do‬‬‫‪Begin‬‬‫;(‪Readln(x‬‬‫‪If x < 0 then‬‬‫‪Continue‬‬‫‪Else‬‬‫;((‪Writeln( sqrt(x‬‬‫;‪End‬‬  ‫في هذه الحاله عند ورود عدد سالب فأن الأمر  ‪  continue‬سيمنع متابعة تنفيذ‬ ‫العبارات الأخرى في حلقة التكرار والمتمثله بأمر الطباعه في هذا المثال ويعيد المؤشر‬ ‫الى الأمر  ‪  for‬ليبدأ بتكرار جديد ‪.‬‬     ================================================= الدورة منقولة من كتاب الأستاذ الفاضل معتز عبد العظيم وما تراه باللون الأخضر فمن زياداتي
  15. الدرس الثالث في لغة Object pascal :الشروط

    بسم الله الرحمن الرحيم أواصل ما عزمت عليه وإن لم أر إقبالا على الدورة لأني مقتنع أنه سيأتي يوم ينتفع بها أحد ويكفيني ذلك ، فأنا نفسي قد انتفعت من دورات كتبت منذ عشر سنين وأدعو الله لأولئك الذين كتبوها أن يغفر لهم وذلك ما أرجوه أنا من قارئ منتفع من هذه الدورة   الدرس الثالث الشروط   من أهم مايميز برامج الحاسوب أو أي جهاز إلكتروني آخر، هو إمكانية تنفيذ إجراء معين عند حدوث شرط معين. مثلاً نجد أن في بعض السيارات يتم تأمين الأبواب عند بلوغها سرعة معينة وهي غير مؤمنة. ففي هذه الحالة الشرط مركب هو وصول سرعة معينة في وجود أبواب غير مؤمنة، أما التفرع أو الإجراء فهو عملية تأمين الأبواب. أما في حالة عدم توفر الشرط وهو (بلوغ سرعة معينة مع وجود حالة اﻷبواب غير مؤمنة) فإن الإجراء (تأمين اﻷبواب) لا يتم تنفيذه.   معظم السيارات والمصانع والغسالات الآلية وماشابهها من اﻷجهزة تعمل بمعالج صغير أو مايسمى micro controller وهي دائرة مدمجة(IC) يمكن برمجتها بواسطة الأسمبلي أو لغة سي. كذلك فإن بعض أنواع هذه المعالجات التي تعمل في مثل هذه اﻷنظمة المدمجة embedded systems مثل المعالج آرم ARM يمكن برمجتها بواسطة فري باسكال، وهي توجد في الموبايلات وبعض أجهزة كمبيوترات الإنترنت أو الألعاب وبعض الأجهزة الأخرى.     عبارة الشرط If condition   عبارة if الشرطية في لغة باسكال هي عبارة سهلة وواضحة والكتابة العامة لها هي كالتالي if <condition> then    begin       toDo;       toDO;   end    else    begin       toDo;       toDo;    end;ويمكن أن نستغني عن begin و end إذا كان جواب الشرط جملة واحدة هكذا if <condition> then toDOelse toDo;ومعنى هذا : إن كان هذا الشرط متحققا فافعل كذا وإلا فافعل كذا   وينبغي التنبه لأمر مهم وهو أن جملة الشرط وجوابها تعتبر جملة واحدة فلذلك لا تكون الفاصلة المنقوطة إلا في آخر الجملة اي بعد toDo الثانية   يا أخي ما هذا ألم تضع الفاصلة المنقوطة بعد toDo الأولى والثانية والثالثة والرابعة في العبارة الأولى ؟   في العبارة الأولى كان جواب الشرط هو begin toDo; toDO; endوهو مجموعة من الأوامر ينبغي أن نحدد نهاية كل أمر وهذه الأوامر محزمة في جملة begin و end فجواب الشرط هو هذه الجملة وهي كما ترى لم نختمها بالفاصلة المنقوطة اي لم نضع بعد end فاصلة منقوطة وإنما وضعناها بعد ختام الجملة الشرطية الكبيرة    إذا لم تفهم هذا فتجاوزه وستدركه مع مر الايام     . في المثال التالي سوف نستقبل من المستخدم درجة الحرارة ثم نحكم هل نقوم بتشغيل جهاز التكيف أم لا:   برنامج مكيف الهواء:   var Temp: Single;begin Write('Please enter Temperature of this room :'); Readln(Temp); if Temp > 28 then Writeln('Please turn on air-condition') else Writeln('Please turn off air-condition'); Write('Press enter key to close'); Readln;end.  نجد أن العبارات الجديدة هي: if then else وهي تعني: إذا كانت درجة الحرارة أكبر من 28 قم بكتابة السطر الأول (Please turn on air-condition) وإذا لم يتحقق الشرط (رقم أصغر أو يساوي 28) في هذه الحالة قم بكتابة السطر الثاني (Please turn off air-condition).     يمكن كتابة شروط متتالية كما في المثال التالي:     var Temp: Single;begin Write('Please enter Temperature of this room :'); Readln(Temp); if Temp > 28 then Writeln('Please turn on air-condition') else if Temp < 25 then Writeln('Please turn off air-condition') else Writeln('Do nothing');    قم بتنفيذ البرنامج أعلاه عدة مرات مُدخِلاً قيم تتراوح بين 20 و 30 وشاهد النتائج.   يمكن تعقيد البرنامج السابق ليصبح أكثر واقعية كما في المثال أدناه:   var Temp: Single; ACIsOn: Byte;begin Write('Please enter Temperature of this room : '); Readln(Temp); Write('Is air condition on? if it is (On) write 1, if it is (Off) write 0 : '); Readln(ACIsOn); if (ACIsOn = 1) and (Temp > 28) then Writeln('Do no thing, we still need cooling') else if (ACIsOn = 1) and (Temp < 25) then Writeln('Please turn off air-condition') else if (ACIsOn = 0) and (Temp < 25) then Writeln('Do nothing, it is still cold') else if (ACIsOn = 0) and (Temp > 28) then Writeln('Please turn on air-condition') else Writeln('Please enter valid values'); Write('Press enter key to close'); Readln;end.     نجد في المثال السابق وجود عبارة and وهي تعني إذا تحقق الشرطين الأول والثاني قم بتفيذ العبارة التالية.   وهذا هو تفسير البرنامج السابق:   إذا كان المكيف يعمل ودرجة الحرارة أكبر من 28 قم بكتابة: Do no thing, we still need cooling، أما إذا لم ينطبق هذا الشرط (else) فقم بالذهاب إلى الإجراء التالي: إذا كان المكيف يعمل ودرجة الحرارة أقل من 25 قم بكتابة: Please turn off air-condition. أما إذا لم ينطبق الشرط فقم بالإجراء التالي: إذا كان المكيف مغلق ودرجة الحرارة أقل من 25 قم بكتابة: Do nothing, it is still cold. أما إذا لم ينطبق الشرط فقم بالإجراء التالي: إذا كان المكيف مغلق ودرجة الحرارة أكبر من 28 قم بكتابة: Please turn on air-condition. - أما إذا لم ينطبق هذا الشرط فهوي يعني أن المستخدم قام بإدخال قيمة غير الـ 0 أو 1 في المتغير ACIsOn، وفي هذه الحالة نقوم بتنبيهه بإدخال قيم صحيحة: Please enter valid values. إذا إفترضنا أن جهاز الحاسوب أو أي جهاز آخر يمكن تشغيل الباسكال به موصل بالمكيف وأن هناك إجراء لفتح المكيف وآخر لغلقه في هذه الحال يمكننا إستبدال إجراء Writeln بإجراءات حقيقية تقوم بتنفيذ الفتح والإغلاق. في هذه الحالة يجب زيادة الشروط لتصبح أكثر تعقيداً تحسباً للمدة الزمنية التي عمل بها المكيف، كذلك يمكن الأخذ في الإعتبار أن الوقت هو في الصباح أم المساء.     برنامج الأوزان   في المثال التالي يقوم المستخدم بإدخال طوله بالأمتار ووزنه بالكيلوجرام. يقوم البرنامج بحساب الوزن المثالي بناءً على طول المستخدم. ويقارن الوزن المثالي بالوزن الحالي للمستخدم، ويطبع النتائج حسباً لفرق الوزن:   program Weight;{$mode objfpc}{$H+}uses {$IFDEF UNIX}{$IFDEF UseCThreads} cthreads, {$ENDIF}{$ENDIF} Classes, SysUtils { you can add units after this };var Height: Double; Weight: Double; IdealWeight: Double;begin Write('What is your height in meters (e.g. 1.8 meter) : '); Readln(Height); Write('What is your weight in kilos : '); Readln(Weight); if Height >= 1.4 then IdealWeight:= (Height - 1) * 100 else IdealWeight:= Height * 20; if (Height < 0.4) or (Height > 2.5) or (Weight < 3) or (Weight > 200) then begin Writeln('Invalid values'); Writeln('Please enter proper values'); end else if IdealWeight = Weight then Writeln('Your wight is suitable') else if IdealWeight > Weight then Writeln('You are under weight, you need more ', Format('%.2f', [IdealWeight - Weight]), ' Kilos') else Writeln('You are over weight, you need to lose ', Format('%.2f', [Weight - IdealWeight]), ' Kilos'); Write('Press enter key to close'); Readln;end.    في المثال السابق نجد عدة أشياء جديدة:   النوع Double: وهو مشابه للنوع Single فكلاهما عدد حقيقي، أو مايسمى بالرقم ذو الفاصلة العائمة (floating point number). والنوع Double هو رقم حقيقي ذو دقة مضاعفة، وهو يحتل مساحة ضعف النوع single حيث أن الأخير يحتل مساحة 4 بايت من الذاكرة أما الـ Double فهو يحتاج إلى 8 بايت من الذاكرة لتخزينه.   الشي الثاني هو إستخدامنا للكلمة Or، وهي بخلاف And ومن معناها تفيد تحقيق أحد الشروط. مثلاً إذا تحقق الشرط الأول (Height < 0.4) فإن البرنامج يقوم بتنفيذ إجراء الشرط، ولو لم يتحقق سوف يتم إختبار الشرط الثاني، فإذ تحقق تم تنفيذ إجراء الشرط، وإذا لم يتحقق الشرط الثاني تم إختبار الشرط الثالث وهكذا..   الشيء الثالث هو إستخدامنا لعبارتي begin و end بعد عبارة if وذلك لأن إجراء الشرط لابد أن يكون عبارة واحدة، وفي هذه الحالة إحتجنا لأن نقوم بتنفيذ عبارتين وهما: Writeln('Invalid values'); Writeln('Please enter proper values');   لذلك إستخدمنا begin end لتحويل العبارتين إلى كتلة واحدة أو عبارة واحدة تصلح لأن تكون إجراء الشرط:   if (Height < 0.4) or (Height > 2.5) or (Weight < 3) or (Weight > 200) then begin Writeln('Invalid values'); Writeln('Please enter proper values'); end    الشيء الرابع هو إستخدام الدالة Format. ولا يمكن إستخدام هذه الدالة إلا بعد إضافة الوحدة SysUtils في عبارة Uses، والوحدة SysUtils هي عبارة عن مكتبة تحتوي على الإجراء Format، وسوف نقوم بتفصيل الوحدات أو المكتبات والإجراءأت في فصل البرمجة الهيكلية إن شاء الله. هذه الدالة تقوم بإظهار المتغيرات بشكل معين، مثلاً في المثال السابق تقوم بإظهار العدد الحقيقي في شكل رقم يحتوي على فاصلة عشرية ذات خانتين كما يظهر في التنفيذ. مثلاً   What is your height in meters (e.g. 1.8 meter) : 1.8 What is your weight in kilos : 60.2 You are under weight, you need more 19.80 Kilos   ملحوظة: حساب الوزن المثالي في البرنامج السابق ربما تكون غير دقيقة. ولمزيد من الدقة يمكن البحث عن الموضوع في الإنترنت. والمقصود بهذا البرنامج كيفية وضع حلول برمجية لمثل هذه الأمثلة. فلابد للمبرمج أن يعرف كيف يضع حل لمسألة معينة، لأن المعرفة بالبرمجة وأدواتها لاتكفي لأن يصبح المبرمج قادر على تحليل وتصميم برامج يعتمد عليها، لذلك لابد من الدخول في تفاصيل الموضوع الذي يتم تحليله قبل وضع البرنامج المناسب.     عبارة الشرط Case .. of   والعبارة العامة هي Case <variable> of <valeur1> : {code..} <valeur2> : {code..} ...End; //End Case ينبغي أن يكون variable معرفا في قسم الإعلان عن المتغيرات وينبغي أن يكون إما integer او char ولا يقبل أي قيمة أخرى وينبغي أن يكون valeur1...من نفس نوع variable وبالمثال يتضح المقال مثلاً نريد إستقبال طلب للزبون في مطعم، والوجبات مرقمة في قائمة رئيسية، ونريد من الزبون إختيار رقم الطلب كما في المثال التالي:     برنامج المطعم   var Meal: Byte;begin Writeln('Welcome to Pascal Restaurant. Please select your order'); Writeln('1 - Chicken (10 Geneh)'); Writeln('2 - Fish (7 Geneh)'); Writeln('3 - Meat (8 Geneh)'); Writeln('4 – Salad (2 Geneh)'); Writeln('5 - Orange Juice (1 Geneh)'); Writeln('6 - Milk (1 Geneh)'); Writeln; Write('Please enter your selection: '); Readln(Meal); case Meal of 1: Writeln('You have ordered Chicken, ', 'this will take 15 minutes'); 2: Writeln('You have ordered Fish, this will take 12 minutes'); 3: Writeln('You have ordered meat, this will take 18 minutes'); 4: Writeln('You have ordered Salad, this will take 5 minutes'); 5: Writeln('You have ordered Orange juice, ', 'this will take 2 minutes'); 6: Writeln('You have ordered Milk, this will take 1 minute'); else Writeln('Wrong entry'); end; Write('Press enter key to close'); Readln;end. تنبيه مهم قم بكتابة البرنامج من جديد ولا تعتمد على النسخ واللصق ولا تقل كما يقول الكسالى هذا سهل هذا واضح فبالكتابة تظهر أخطاؤك ومن أخطائك تتعلم   إذا أردنا عمل نفس البرنامج بإستخدام عبارة If فإن البرنامج سوف يكون أكثر تعقيداً ويحتوي على تكرار.       برنامج المطعم بإستخدام عبارة if   var Meal: Byte;begin Writeln('Welcome to Pascal restaurant, please select your meal'); Writeln('1 - Chicken (10 Geneh)'); Writeln('2 - Fish (7 Geneh)'); Writeln('3 - Meat (8 Geneh)'); Writeln('4 - Salad (2 Geneh)'); Writeln('5 - Orange Juice (1 Geneh)'); Writeln('6 - Milk (1 Geneh)'); Writeln; Write('Please enter your selection: '); Readln(Meal); if Meal = 1 then Writeln('You have ordered Chicken, this will take 15 minutes') else if Meal = 2 then Writeln('You have ordered Fish, this will take 12 minutes') else if Meal = 3 then Writeln('You have ordered meat, this will take 18 minutes') else if Meal = 4 then Writeln('You have ordered Salad, this will take 5 minutes') else if Meal = 5 then Writeln('You have ordered Orange juice, ', 'this will take 2 minutes') else if Meal = 6 then Writeln('You have ordered Milk, this will take 1 minute') else Writeln('Wrong entry'); Write('Press enter key to close'); Readln;end.      يمكن كذلك إستخدام مدى للأرقام بعبارة case. في المثال التالي يقوم البرنامج بتقييم درجة الطالب:               برنامج درجة الطالب   var Mark: Integer;begin Write('Please enter student mark: '); Readln(Mark); Writeln; case Mark of 0 .. 39 : Writeln('Student grade is: F'); 40 .. 49: Writeln('Student grade is: E'); 50 .. 59: Writeln('Student grade is: D'); 60 .. 69: Writeln('Student grade is: C'); 70 .. 84: Writeln('Student grade is: B'); 85 .. 100: Writeln('Student grade is: A'); else Writeln('Wrong mark'); end; Write('Press enter key to close'); Readln;end.    نلاحظ في البرنامج السابق أننا إستخدما مدى مثل 85 .. 100 أي أن الشرط هو أن تكون الدرجة بين هاتين القيمتين. عبارة case لاتعمل إلا مع المتغيرات المعدودة مثل الأعداد الصحيحة أو الحروف، لكنها لاتعمل مع بعض الأنواع الأخرى مثل الأعداد الحقيقية والمقاطع.     برنامج لوحة المفاتيح   في البرنامج التالي نقوم بإستخدام نوع المتغيرات الحرفية char وذلك لإستقبال حرف من لوحة المفاتيح ومعرفة موقعه:   var Key: Char;begin Write('Please enter any English letter: '); Readln(Key); Writeln; case Key of 'q', 'w', 'e', 'r', 't', 'y', 'u', 'i', 'o', 'p': Writeln('This is in the second row in keyboard'); 'a', 's', 'd', 'f', 'g', 'h', 'j', 'k', 'l': Writeln('This is in the third row in keyboard'); 'z', 'x', 'c', 'v', 'b', 'n', 'm': Writeln('This is in the fourth row in keyboard'); else Writeln('Unknown character'); end; Write('Press enter key to close'); Readln;end.     نلاحظ في المثال السابق أنا لم نستخدم المدى لكن إستخدمنا تعدد الخيارات، مثلاً إذا إخترنا العبارة الأخيرة:   'z', 'x', 'c', 'v', 'b', 'n', 'm':  فهي تعني إذا كانت قيمة key هي z أو x أو c أو v أو b أو n أو m قم بتنفيذ إجراء الشرط.   يمكن كذلك المزج بين صيغة المدى وتعدد الخيارات مثل:   'a' .. 'd', 'x', 'y', 'z':  وهي تعني إختبار الحرف إذا كان في المدى من الحرف a إلى الحرف d أو كان هو الحرف x أو y إو z قم بتنفيذ الشرط.     ================================================= الدورة منقولة من كتاب الأستاذ الفاضل معتز عبد العظيم وما تراه باللون الأخضر فمن زياداتي
  16. الدرس الأول في لغة Object Pascal

    بسم الله الرحمن الرحيم   نبتدأ إن شاء الله وبعون الله هذه الدورة التي نسأل الله أن يوفقنا لإتمامها   الدرس الأول   سوف نستخدم في هذه الدورة إن شاء الله بيئة لازاراس وفري باسكال كما سبق ذكره، ويمكن الحصول عليه من هذا الموقع: lazarus.freepascal.org أو يمكن الحصول عليه من داخل نظام لينكس عن طريق برامج إضافة التطبيقات، حيث نجده في قسم أدوات التطوير، أو عن طريق إستخدام     yum install lazarus   في فيدورا أو مايشابهها من توزيعات لينكس، أو بإستخدام   apt-get install lazarus  في توزيعة Ubuntu أو مايشابهها.   وأما مستعملو ويندوز فيمكنهم التحميل من الموقع نفسه وتثبيته كما يثبت أي برنامج بضغطتين   واللازاراس هو عبارة عن برنامج حر ومفتوح المصدر كما ذكرنا، ويوجد في أكثر من منصة نظام تشغيل. الكود والبرامج المكتوبة به يمكن نقلها لإعادة ترجمتها وربطها (Compilation and linking) في أي منصة يريدها المبرمج، إلا أن البرنامج الناتج (الملف الثنائي executables) لايمكن نقله، فهو مربتط فقط بالمنصة التي قام المبرمج بترجمة وربط برنامجه فيها حيث أن اللازاراس وفري باسكال ينتج عنه ملفات ثنائية تنفيذية تعمل مباشرة على نواة نظام التشغيل ومكتباتها ولاتحتاج لوسيط مثل برامج الجافا والدوت نت، لذلك فهو يتفوق على هذه اللغات بالسرعة في التنفيذ وعدم إحتياج مكتبات إضافية في الأجهزة التي سوف يتم تثبيت برامج لازاراس بها.   إستخدام البيئة النصية   الفصول الأولى من هذا الكتاب تستخدم إمكانات الإدخال والإخراج البسيطة والأساسية التي تسمى بالطرفية console أو البيئة النصية Text mode، وذلك لبساطتها وتوفرها في كل أنظمة التشغيل وسهولة فهمها. ربما يمل الطالب منها ويتمنى أن يقوم بعمل برامج تستخدم الشاشة الرسومية بما تحتويه من أزرار ونوافذ وقوائم ومربعات نصية وغيرها، إلا أننا أحببنا أن لاينشغل الطالب بشيء ويركز على المفاهيم الأساسية التي سوف يستخدمها في البرامج النصية البسيطة وسوف يستخدمها في البرامج الرسومية المعقدة إن شاء الله. بهذه الطريقة يكون الفهم سهلاً وسريعاً لأساسيات الباسكال والبرمجة. وفي الفصول المتقدمة سوف نستخدم إن شاء الله البيئة الرسومية ذات الواجهة المحببة للمستخدم العادي.     برنامجك الأول   بعد تثبيت اللازاراس وتشغيله، نقوم بإنشاء برنامج جديد باستخدام الأمر التالي من القائمة الرئيسية:   Project/New Project/Program   لنحصل على الكود التالي في الـ Source Editor:     program Project1;{$mode objfpc}{$H+}uses {$IFDEF UNIX}{$IFDEF UseCThreads} cthreads, {$ENDIF}{$ENDIF} Classes { you can add units after this };{$IFDEF WINDOWS}{$R project1.rc}{$ENDIF}beginend.     بعد ذلك نحفظ البرنامج عن طريق File/Save من القائمة الرئيسية، في مجلد معروف بالنسبة لنا، ثم نسميه مثلاً first.lpi   بين عبارتي begin end. نقوم بكتابة الأوامر التالية:       Writeln('This is Free Pascal and Lazarus'); Writeln('Press enter key to close'); Readln;          ليصبح البرنامج الكامل كالآتي:   program first;{$mode objfpc}{$H+}uses {$IFDEF UNIX}{$IFDEF UseCThreads} cthreads, {$ENDIF}{$ENDIF} Classes { you can add units after this };{$IFDEF WINDOWS}{$R first.rc}{$ENDIF}begin Writeln('This is Free Pascal and Lazarus'); Writeln('Press enter key to close'); Readln;end.  عبارة Writeln تقوم بكتابة نص في الشاشة. وعبارة Readln تقوم بتعليق البرنامج حتى يقوم المستخدم بقراءة الأسطر السابقة وإنتظار المستخدم حتى يقوم بالضغط على مفتاح إدخال. بعد ذلك يتنهي البرنامج ويتم إغلاقه.   بعد ذلك نقوم بتنفيذ البرنامج عن طريق المفتاح F9 أو بالضغط على الزر: لنحصل على المخرجات التالية:   This is Free Pascal and Lazarus Press enter key to close   بعد تشغيل البرنامج والضغط على مفتاح الإدخال، ينتهي البرنامج ونرجع إلى الحالة الأولى، وهي حالة كتابة الكود. إذا كنا نستخدم نظام لينكس نجد على القرص ملف بإسم first، وإذا كنا نستخدم وندوز نجد ملف بإسم first.exe وهي الملفات الثنائية التنفيذية التي يمكن توزيعها في أي أجهزة أخرى لاتحتوي بالضرورة على لازاراس أو فري باسكال. هذه البرامج تكون عبارة عن برامج تطبيقية طبيعية بالنسبة لنظام التشغيل (Native Applications).   ملاحظة   إذا لم تظهر مخرجات البرنامج كالسابق (الشاشة السوداء) نقم بتعطيل الـ Debugger كالآتي: نختار Environment/Options/Debugger من القائمة الرئيسية في لازاراس. ثم في مربع Debugger type and path نختار (None)   ================================================= الدورة منقولة من كتابي الأستاذ الفاضل معتز عبد العظيم وما تراه باللون الأخضر فمن زياداتي
  17. سؤال في المكون Tprocess في O-pascal

    بسم الله الرحمن الرحيم يوفر lazarus مكونا عابرا للقارات عفوا للمنصات يسمى Tprocess يقوم هذا المكون بتشغيل برامج خارجية بعض البرامج الخارجية لها مخرجات على التارمينال مثل برنامج ls ويكي لازاريس يوفر مثالا كاملا للتعامل مع البرامج التي لها مخرجات وهذا هو الكود   program procoutlarge;{ Copyright (c) 2004-2011 by Marc Weustink and contributors This example is created in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.}// This is a // WORKING// demo program that shows// how to launch an external program// and read from its output. uses Classes, Process, SysUtils; const READ_BYTES = 2048; var OurCommand: String; OutputLines: TStringList; MemStream: TMemoryStream; OurProcess: TProcess; NumBytes: LongInt; BytesRead: LongInt; begin // A temp Memorystream is used to buffer the output MemStream := TMemoryStream.Create; BytesRead := 0; OurProcess := TProcess.Create(nil); // Recursive dir is a good example. OurCommand:='invalid command, please fix the IFDEFS.'; {$IFDEF Windows} //Can't use dir directly, it's built in //so we just use the shell: OurCommand:='cmd.exe /c "dir /s c:\windows\"'; {$ENDIF Windows} {$IFDEF Unix} //Needs to be tested on Linux/Unix: OurCommand := 'ls --recursive --all -l /'; {$ENDIF Unix} writeln('-- Going to run: ' + OurCommand); OurProcess.CommandLine := OurCommand; // We cannot use poWaitOnExit here since we don't // know the size of the output. On Linux the size of the // output pipe is 2 kB; if the output data is more, we // need to read the data. This isn't possible since we are // waiting. So we get a deadlock here if we use poWaitOnExit. OurProcess.Options := [poUsePipes]; WriteLn('-- External program run started'); OurProcess.Execute; while OurProcess.Running do begin // make sure we have room MemStream.SetSize(BytesRead + READ_BYTES); // try reading it NumBytes := OurProcess.Output.Read((MemStream.Memory + BytesRead)^, READ_BYTES); if NumBytes > 0 then begin Inc(BytesRead, NumBytes); Write('.') //Output progress to screen. end else begin // no data, wait 100 ms Sleep(100); end; end; // read last part repeat // make sure we have room MemStream.SetSize(BytesRead + READ_BYTES); // try reading it NumBytes := OurProcess.Output.Read((MemStream.Memory + BytesRead)^, READ_BYTES); if NumBytes > 0 then begin Inc(BytesRead, NumBytes); Write('.'); end; until NumBytes <= 0; if BytesRead > 0 then WriteLn; MemStream.SetSize(BytesRead); WriteLn('-- External program run complete'); OutputLines := TStringList.Create; OutputLines.LoadFromStream(MemStream); WriteLn('-- External program output line count = ', OutputLines.Count, ' --'); for NumBytes := 0 to OutputLines.Count - 1 do begin WriteLn(OutputLines[NumBytes]); end; WriteLn('-- Program end'); OutputLines.Free; OurProcess.Free; MemStream.Free;end.المشكلة أنه عند تشغيل برنامج مثل wget لا نجد أي مخرجات على التارمينال فهل من خبير أو عارف بحل هذه المشكلة ؟