الفصل الأول

الأسس

هدف هذا الكتاب هو أن يعلمك كيف تفكر كعالم حاسبات , و طريقة التفكير هذة تجمع بعضا من أفضل خصائص  منهجيات التفكير في علوم  عديدة اخرى .منهجية التفكير كعالم حاسبات مشابهة في عدد من النواحي لمنهجيات التفكير المستخدمة في الرياضيات و الهندسة , و أيضا في العلوم الطبيعية . علماء الحاسب , مثلهم مثل علماء الرياضيات ,يستعملون لغة ( لغات , إذا أردنا الدقة ) محددة ذات قواعد صارمة للتعبير عن الأفكار بدقة عالية . و مثل المهندسين , يصمم علماء الحاسبات بنى معينة , و يقيمون الخيارات المحتملة بين عدد من البدائل التي يستطيعون اختيارها . و مثل علماء الطبيعيات , يقوم علماء الحاسبات بمراقبة تصرفات نظم معقدة , و وضع نظريات عنها , و من ثم يختبرون توقعاتهم في التجارب التي يجرونها على تلك النظم المعقدة .

أهم ميزة يمكن أن يتمتع بها ( أو ينميها ) عالم حاسبات هي القدرة على حل المشاكل. كلمة المشاكل هنا لا تشير إلى المنغصات اليومية , كالزوجة و الأولاد مثلا . حتى أفضل علماء الحاسبات لا يستطيعون التعامل مع هذا النوع من المشاكل . المشاكل هنا هي مشاكل قابلة للحل , و ستقابل الكثير منها لاحقا في هذا الكتاب . القدرة على حل المشاكل تعني القدرة على التعبير عن المشكلة أولا بطريقة واضحة , و من ثم التفكير الخلاق من أجل التوصل إلى حل ممكن , و من ثم التعبير عن ذلك الحل بطريقة واضحة و دقيقة . في الحقيقة , تعلم البرمجة هو طريقة ممتازة لتطوير مهارات حل المشاكل.

ستتعلم في هذا الكتاب كيف تبرمج , و هي مهارة مفيدة جدا . و لكنك بالإضافة إلى ذلك ستتعلم كيف تستخدم البرمجة كوسيلة للوصول إلى غاية محددة , و ستتضح لك هذة الغاية أكثر لاحقا في هذا الكتاب ...

لغة برمجة اسمها بايثون

لغة البرمجة التي ستتعلمها اسمها بايثون . بايثون هي لغة برمجة عالية المستوى. هناك لغات برمجة عالية المستوى اخرى , ربما تكون قد سمعت بها من قبل , مثل سي , سي++ , بيرل , و جافا . 

كما قد تكون استنتجت , بما انه هناك لغات برمجة عالية المستوى , فلا بد من وجود لغات برمجة منخفضة المستوى, و في الحقيقة توجد هكذا لغات , و تسمى أحيانا بــ"لغات الآلة" , أو "لغات التجميع" .إذاأردنا الدقّة, لا يمكن لأجهزة الحاسب تنفيذ برنامج إلا كان مكتوبا بواحدة من اللغات المنخفضة المستوى . و هكذا لا بد من بعض المعالجة الإضافية للبرامج المكتوبة باللغات العالية المستوى لكي تعمل على الحاسب. تحتاج المعالجة الإضافية هذة  إلى بعض الوقت الإضافي, و هذة إحدى مساؤى اللغات عالية المستوى . 

لكن, من جهة اخرى, فإن مزايا اللغات عالية المستوى عديدة جدا. أولا : البرمجة بلغة عالية المستوى أسهل بكثير من البرمجة بلغة منخفضة المستوى : البرامج المكتوبة باللغات عالية المستوى قصيرة, أقصر بكثير من تلك المكتوبة بلغات منخفضة المستوى, و قرائتها أسهل, كما أن كتابتها تستغرق و قتا أقل بكثير. ثانيا : لغات البرمجة عالية المستوى قابلة للنقل (portable), بمعنى أنها تعمل على عدد من نظم الحاسب المختلفة دون أي تعديل, أو مع القليل من التعديل. البرامج التي تكتب باستخدام لغات منخفضة المستوى تعمل حصرا على نوع واحد من الحاسبات , و لا بد من إعادة كتابتها كلية لتعمل على أي نوع آخر.

الغالبية العظمى من البرامج تكتب باستخدام لغات برمجة عالية المستوى , بسبب المزايا العديدة التي تتمتع بها هذة اللغات. لا تستعمل اللغات منخفضة المستوى إلا لكتابة بضع تطبيقات خاصة.

هنالك نوعان من البرامج لمعالجة لغات البرمجة عالية المستوى و تحويلها إلى لغات برمجة منخفضة المستوى. المفسرات (interpreters) و المترجمات (compilers) . المفسر يقرأ برنامجا مكتوبا بلغة عالية المستوى , و من ثم ينفذه , بمعنى أنه يقوم بفعل ما يقولة ذلك البرنامج. يقوم المفسر بمعالجة البرنامج المذكور قليلا فقليل. يقرأ بعض سطور البرنامج ثم يجري بعض الحسابات, ثم يقرأ المزيد من السطور و يجري المزيد من الحسابات, و هكذا ..

المترجم يقرأ البرنامج  و يقوم بترجمته كاملا قبل أن يبدأ تنفيذه . في هذة الحالة , يسمى البرنامج المكتوب باللغة عالية المستوى النص المصدر, و يسمى البرنامج بعد أن تمت ترجمته النص النتيجة, أو أيضا "البرنامج القابل للتنفيذ" (executable) , لأنه بعد أن تتم ترجمة برنامج إلى اللغة منخفضة المستوى المستعملة ذلك الحاسب , يمكنك تنفيذة مباشرة كلما أردت ذلك , دونما حاجة إلى المزيد من الترجمة . 

تعتبر بايثون لغة مفسرة , لأن برامجها يتم تنفيذها بواسطة مفسر. هنالك طريقتان لإستخدام المفسر, إما من على سطر الأوامر (Command Line), أو بإستخدام ملف دفعي (Script) . إذا كنت تريد إستخدام سطر الأوامر , فالطريقة بسيطة : إكتب البرنامج , إضغط مفتاح الإدخال (ُEnter), و سيعرض المفسر النتيجة . 

$ python

Python 1.5.2 (#1, Feb 1 2000, 16:32:16)

Copyright 1991-1995 Stichting Mathematish Centrum, Amsterdam

>>> print 1 + 1

2

أول سطر من المثال السابق هو الأمر المستخدم لإستدعاء مفسر بايثون . السطران التاليان هما رسائل من المفسر . السطر الثالث يبدأ بــ (<<&ltWink , و هو المحث الذي يستخدمه المفسر ليدل على جاهزيته لتلقي الأوامر . كتبنا 1+1 print , و ضغطنا مفتاح الإدخال (Enter) , و كان جواب المفسر : 2 . 

أو يمكنك فعل ذلك بطريقة مختلفة , إكتب برنامجا و احفظه في ملف , ثم استخدم المفسر لتنفيذ محتويات الملف . يسمى هذا الملف ملفا دفعيا (Script) . على سبيل المثال , استخدمنا محررا نصيا لإنشاء ملف سميناه add.py فيه المحتويات التالية : 

print 1 + 1

جرت العادة أن الملفات التي تحوي على برامج بايثون يتم سميتها باسماء تنتهي باللاحقة .py  . 

لتنفيذ البرنامج , عليك أن تخبر المفسر بإسم الملف المطلوب :

$ python firstProgram.py

2

هذا طبعا في لينوكس . في البيئات الاخرى , كويندوز أو الماكنتوش , قد تختلف طريقة استدعاء المفسر . و أيضا , أغلبية البرامج التي ستراها ستكون أكثر إثارة للإهتمام من هذا .

غالبية الأمثلة في هذا الكتاب يتم تنفيذها من على سطر الأوامر . العمل من على سطر الأوامر مثالي لتطوير البرامج و اختبارها . لأنك قادر على كتابة البرنامج و من ثم اختباره مباشرة . بمجرد أن يصبح عندك برنامج يعمل , قم بتخزينه في ملف لتتمكن من تنفيذه أو تعديله في المستقبل .

ما البرنامج؟

البرنامج هو عبارة عن سلسلة مرتّبة من التعليمات (instructions) التي توضّح للحاسب كيفيّة القيام بإجراء حسابي معيّن. يمكن أن يكون هذا الأجراء ذا طبيعة رياضيّاتية, مثلا حل مجموعة من المعادلات, أو إيجاد جذور كثير حدود, لكنّه أيضا قد يكون ذا طبيعة رمزيّة (symbolic), مثلا البحث في نص معيّن عن سلسلة نصيّة ما و تبديل كل تكرار لها بسلسلة اخرى, أو ترجمة برنامج بلغة برمجة عالية المستوى إلى لغة الآلة (هل توقعت هذا؟).

قد تختلف التفاصيل من لغة برمجة إلى اخرى, لكن هنالك عدّة تعليمات أساسيّة تظهر في لغات البرمجة كافّة :

تعليمات إدخال:للحصول على بيانات من مصدر ما, قد يكون ملفّا, أو من لوحة المفاتيح, أو من أداة إدخال اخرى.
تعليمات إخراج:لعرض بيانات على الشاسة, أو إرسالها إلى ملف إو إلى أداة أخراج اخرى.تعليمات رياضيّاتيّة:
للقيام بالعمليات الحسابيّة الأساسيّة مثل الجمع او الضرب.تعليمات للتنفيذ الشرطي:تقوم هذة التعليمات بالتحقق من شرط معيّن, و من ثم بتنفيذ سلسلة محدّدة مسبقا من التعليمات المرتبطة بحصول ذلك الشرط.
تعليمات تكراريّة:تقوم هذة التعليمات بتنفيذ تعليمات اخرى عددا من المرّات, غالبا مع بعض التغييرات.

صدق أو لا تصدق, هذا كل ما في الأمر! كل البرامج التي استعملتها مسبقا, مهما كانت درجة تعقيدها و أيّا كانت وظيفتها, هي عبارة عن تسلسل من التعليمات التي تنتظم في واحدة من الفئات السابقة. يمكننا طبقا لهذا أن نصف البرمجة كما يلي : البرمجة هي عمليّة تجزئة المهام المعقّدة و الكبيرة إلى مهام جزئية أصغر, و من ثمّ تجزئة المهام الجزئيّة بدورها إلة مهام حزئيّة أصغر, و هكذا حتّى تصبح في أيدينا مهام جزئيي صغيرة بسيطة يمكننا أن نعبّر عنها باستخدام تعليمات من الأنواع الأساسيّة الخمس.

قد يبدو هذا غامضا بعض الشيء, لكننا سنعود إلى هذا الموضوع عندما نتحدث عن الخوارزميّات.

What is debugging?

Programming is a complex process, and because it is done by human beings, it often leads to errors. For whimsical reasons, programming errors are called bugs and the process of tracking them down and correcting them is called debugging.

Three kinds of errors can occur in a program: syntax errors, runtime errors, and semantic errors. It is useful to distinguish between them in order to track them down more quickly.

الأخطاء النحويّة

لا تستطيع بايثون أن تنفّذ برنامجا إلا إذا كان ذلك البرنامج صحيحا من الناحية النحويّة. إذا كان هناك خطأ نحوي في البرنامج فإن التنفيذ سيفشل و ستظهر رسالة خطأ. النحو هو بنية البرنامج و هو القواعد التي تنظم هذة البنية. على سبيل المثال, في اللغة الإنجليزيّة, لا بد أن تبدأ الجملة بحرف كبير مطبعيّا, أو ما نسميه Capital Letter, و لا بد أن تنتهي الجملة بنقطة. و لهذا فإن الجملتين التاليتين غير صحيحتين نحويّا :

this sentence contains a syntax error.

This one does , too


For most readers, a few syntax errors are not a significant problem, which is why we can read the poetry of e. e. cummings without spewing error messages. Python is not so forgiving. If there is a single syntax error anywhere in your program, Python will print an error message and quit, and you will not be able to run your program. During the first few weeks of your programming career, you will probably spend a lot of time tracking down syntax errors. As you gain experience, though, you will make fewer errors and find them faster.

Runtime errors

The second type of error is a runtime error, so called because the error does not appear until you run the program. These errors are also called exceptions because they usually indicate that something exceptional (and bad) has happened.

Runtime errors are rare in the simple programs you will see in the first few chapters, so it might be a while before you encounter one.

Semantic errors

The third type of error is the semantic error. If there is a semantic error in your program, it will run successfully, in the sense that the computer will not generate any error messages, but it will not do the right thing. It will do something else. Specifically, it will do what you told it to do.

The problem is that the program you wrote is not the program you wanted to write. The meaning of the program (its semantics) is wrong. Identifying semantic errors can be tricky because it requires you to work backward by looking at the output of the program and trying to figure out what it is doing.

Experimental debugging

One of the most important skills you will acquire is debugging. Although it can be frustrating, debugging is one of the most intellectually rich, challenging, and interesting parts of programming.

In some ways, debugging is like detective work. You are confronted with clues, and you have to infer the processes and events that led to the results you see.

Debugging is also like an experimental science. Once you have an idea what is going wrong, you modify your program and try again. If your hypothesis was correct, then you can predict the result of the modification, and you take a step closer to a working program. If your hypothesis was wrong, you have to come up with a new one. As Sherlock Holmes pointed out, When you have eliminated the impossible, whatever remains, however improbable, must be the truth. (A. Conan Doyle, The Sign of Four)

For some people, programming and debugging are the same thing. That is, programming is the process of gradually debugging a program until it does what you want. The idea is that you should start with a program that does something and make small modifications, debugging them as you go, so that you always have a working program.

For example, Linux is an operating system that contains thousands of lines of code, but it started out as a simple program Linus Torvalds used to explore the Intel 80386 chip. According to Larry Greenfield, One of Linus's earlier projects was a program that would switch between printing AAAA and BBBB. This later evolved to Linux. (The Linux Users' Guide Beta Version 1)

Later chapters will make more suggestions about debugging and other programming practices.

Formal and natural languages

Natural languages are the languages that people speak, such as English, Spanish, and French. They were not designed by people (although people try to impose some order on them); they evolved naturally.

Formal languages are languages that are designed by people for specific applications. For example, the notation that mathematicians use is a formal language that is particularly good at denoting relationships among numbers and symbols. Chemists use a formal language to represent the chemical structure of molecules. And most importantly:

Programming languages are formal languages that have been designed to express computations.

Formal languages tend to have strict rules about syntax. For example, 3+3=6 is a syntactically correct mathematical statement, but 3=+6$ is not. H2O is a syntactically correct chemical name, but 2Zz is not.

Syntax rules come in two flavors, pertaining to tokens and structure. Tokens are the basic elements of the language, such as words, numbers, and chemical elements. One of the problems with 3=+6$ is that $ is not a legal token in mathematics (at least as far as we know). Similarly, 2Zz is not legal because there is no element with the abbreviation Zz.

The second type of syntax rule pertains to the structure of a statement--- that is, the way the tokens are arranged. The statement 3=+6$ is structurally illegal because you can't place a plus sign immediately after an equal sign. Similarly, molecular formulas have to have subscripts after the element name, not before.

As an exercise, create what appears to be a well-structured English sentence with unrecognizable tokens in it. Then write another sentence with all valid tokens but with invalid structure.

When you read a sentence in English or a statement in a formal language, you have to figure out what the structure of the sentence is (although in a natural language you do this subconsciously). This process is called parsing.

For example, when you hear the sentence, The other shoe fell, you understand that the other shoe is the subject and fell is the verb. Once you have parsed a sentence, you can figure out what it means, or the semantics of the sentence. Assuming that you know what a shoe is and what it means to fall, you will understand the general implication of this sentence.

Although formal and natural languages have many features in common---tokens, structure, syntax, and semantics---there are many differences:

ambiguity: Natural languages are full of ambiguity, which people deal with by using contextual clues and other information. Formal languages are designed to be nearly or completely unambiguous, which means that any statement has exactly one meaning, regardless of context.redundancy:In order to make up for ambiguity and reduce misunderstandings, natural languages employ lots of redundancy. As a result, they are often verbose. Formal languages are less redundant and more concise.literalness:Natural languages are full of idiom and metaphor. If someone says, The other shoe fell, there is probably no shoe and nothing falling. Formal languages mean exactly what they say.

People who grow up speaking a natural language---everyone---often have a hard time adjusting to formal languages. In some ways, the difference between formal and natural language is like the difference between poetry and prose, but more so:

Poetry:Words are used for their sounds as well as for their meaning, and the whole poem together creates an effect or emotional response. Ambiguity is not only common but often deliberate.Prose:The literal meaning of words is more important, and the structure contributes more meaning. Prose is more amenable to analysis than poetry but still often ambiguous.Programs: The meaning of a computer program is unambiguous and literal, and can be understood entirely by analysis of the tokens and structure.

Here are some suggestions for reading programs (and other formal languages). First, remember that formal languages are much more dense than natural languages, so it takes longer to read them. Also, the structure is very important, so it is usually not a good idea to read from top to bottom, left to right. Instead, learn to parse the program in your head, identifying the tokens and interpreting the structure. Finally, the details matter. Little things like spelling errors and bad punctuation, which you can get away with in natural languages, can make a big difference in a formal language.

برنامجك الأول

Traditionally, the first program written in a new language is called Hello, World! because all it does is display the words, Hello, World! In Python, it looks like this:

This is an example of a print statement, which doesn't actually print anything on paper. It displays a value on the screen. In this case, the result is the words

The quotation marks in the program mark the beginning and end of the value; they don't appear in the result.

Some people judge the quality of a programming language by the simplicity of the Hello, World! program. By this standard, Python does about as well as possible.

شرح المفردات

problem solving:The process of formulating a problem, finding a solution, and expressing the solution.high-level language:A programming language like Python that is designed to be easy for humans to read and write.low-level language:A programming language that is designed to be easy for a computer to execute; also called machine language or assembly language.portability:A property of a program that can run on more than one kind of computer. interpret:To execute a program in a high-level language by translating it one line at a time.compile:To translate a program written in a high-level language into a low-level language all at once, in preparation for later execution.source code:A program in a high-level language before being compiled.object code:The output of the compiler after it translates the program.executable:Another name for object code that is ready to be executed.shell-mode:


script-mode:


Python shell:


script:A program stored in a file (usually one that will be interpreted).program:A set of instructions that specifies a computation.algorithm:A general process for solving a category of problems.bug:An error in a program.debugging:The process of finding and removing any of the three kinds of programming errors.syntax:The structure of a program.syntax error:An error in a program that makes it impossible to parse (and therefore impossible to interpret).runtime error:An error that does not occur until the program has started to execute but that prevents the program from continuing.exception:Another name for a runtime error.semantic error:An error in a program that makes it do something other than what the programmer intended.semantics:The meaning of a program.natural language:Any one of the languages that people speak that evolved naturally.formal language:Any one of the languages that people have designed for specific purposes, such as representing mathematical ideas or computer programs; all programming languages are formal languages.token:One of the basic elements of the syntactic structure of a program, analogous to a word in a natural language.parse:To examine a program and analyze the syntactic structure.print statement:An instruction that causes the Python interpreter to display a value on the screen.

Exercises