Skip to content

translate part 1, 2.11- logical operators to AR #14

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
May 24, 2020
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
The answer is `2`, that's the first truthy value.
الإجابة هي `2` لأنها أول قيمة truthy.

```js run
alert( null || 2 || undefined );
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
importance: 5
الأهمية: 5

---

# What's the result of OR?
# ما نتيجة OR?

What is the code below going to output?
ما خرج الأمر التالي ؟

```js
alert( null || 2 || undefined );
12 changes: 6 additions & 6 deletions 1-js/02-first-steps/11-logical-operators/2-alert-or/solution.md
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
The answer: first `1`, then `2`.
الإجابة: أولًا `1` ثم `2`.

```js run
alert( alert(1) || 2 || alert(3) );
```

The call to `alert` does not return a value. Or, in other words, it returns `undefined`.
استدعائ `alert` لا يرجع أي قيمة أو بمعنى آخر يرجع `undefined`.

1. The first OR `||` evaluates its left operand `alert(1)`. That shows the first message with `1`.
2. The `alert` returns `undefined`, so OR goes on to the second operand searching for a truthy value.
3. The second operand `2` is truthy, so the execution is halted, `2` is returned and then shown by the outer alert.
1. أول OR `||` تنفذ العملية على يسارها `alert(1)`. وهذا يعرض أول رسالة `1`.
2. إن `alert` ترجع `undefined` لذلك تنتقل OR للعملية الثانية بحثًا عن قيمة truthy.
3. القيمة الثانية `2` هي truthy لذلك يتوقف التنفيذ وترجع `2` ويتم عرضها.

There will be no `3`, because the evaluation does not reach `alert(3)`.
لن يتم عرض `3` لأن التنفيذ لم يصل إلى `alert(3)`.
6 changes: 3 additions & 3 deletions 1-js/02-first-steps/11-logical-operators/2-alert-or/task.md
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
importance: 3
الأهمية: 3

---

# What's the result of OR'ed alerts?
# نتيجة التنبيهات التي بينها OR?

What will the code below output?
ما خرج الكود التالي ؟

```js
alert( alert(1) || 2 || alert(3) );
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
The answer: `null`, because it's the first falsy value from the list.
الإجابة: `null` لأنها أول قيمة falsy في القائمة.

```js run
alert( 1 && null && 2 );
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
importance: 5
الأهمية: 5

---

# What is the result of AND?
# نتيحة AND?

What is this code going to show?
ما خرج الكود التالي ؟

```js
alert( 1 && null && 2 );
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
The answer: `1`, and then `undefined`.
الإجابة: `1` ثم `undefined`.

```js run
alert( alert(1) && alert(2) );
```

The call to `alert` returns `undefined` (it just shows a message, so there's no meaningful return).
استدعاء `alert` يرجع `undefined` (إنها تعرض رسالة لذلك لا يوجد معنى لإرجاع قيمة).

Because of that, `&&` evaluates the left operand (outputs `1`), and immediately stops, because `undefined` is a falsy value. And `&&` looks for a falsy value and returns it, so it's done.
وبسبب هذا تقوم `&&` بتنفيذ العملية على اليسار (تعرض `1`) وتتوقف لأن `undefined` تعتبر قيمة falsy. And `&&` تبحث عن قيمة falsy وترجعها.

5 changes: 3 additions & 2 deletions 1-js/02-first-steps/11-logical-operators/4-alert-and/task.md
Original file line number Diff line number Diff line change
@@ -2,9 +2,10 @@ importance: 3

---

# What is the result of AND'ed alerts?
# نتيجة التنبيهات التي بينها AND?

ما خرج الكود التالي ؟

What will this code show?

```js
alert( alert(1) && alert(2) );
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
The answer: `3`.
الإجابة: `3`.

```js run
alert( null || 2 && 3 || 4 );
```

The precedence of AND `&&` is higher than `||`, so it executes first.
أولوية AND `&&` أعلى من `||` لذلك تنفذ أولًا.

The result of `2 && 3 = 3`, so the expression becomes:
نتيجة `2 && 3 = 3` لذلك يصبح التعبير كالتالي:

```
null || 3 || 4
```

Now the result is the first truthy value: `3`.
النتيجة الآن هي أول قيمة truthy: `3`.

Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
importance: 5
الأهمية: 5

---

# The result of OR AND OR
# نتيجة OR AND OR

What will the result be?
ما ناتج تنفيذ الأمر التالي ؟

```js
alert( null || 2 && 3 || 4 );
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
importance: 3
الأهمية: 3

---

# Check the range between
# فحص المدى بين

Write an "if" condition to check that `age` is between `14` and `90` inclusively.
اكتب تعبير "if" يفحص أن العمر `age` بين `14` و `90`.

"Inclusively" means that `age` can reach the edges `14` or `90`.
يمكن للعمر `age` أن يكون `14` أو `90`.
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
The first variant:
الطريقة الأولى:

```js
if (!(age >= 14 && age <= 90))
```

The second variant:
الطريقة الثانية:

```js
if (age < 14 || age > 90)
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
importance: 3
الأهمية: 3

---

# Check the range outside
# فحص المدى بالخارج

Write an `if` condition to check that `age` is NOT between 14 and 90 inclusively.
اكتب تعبير `if` يفحص أن العمر `age` ليس بين.

Create two variants: the first one using NOT `!`, the second one -- without it.
قم بالحل بطريقتين مختلفتين: الأولى باستخدام NOT `!` والثانية بدونها.
Original file line number Diff line number Diff line change
@@ -1,19 +1,19 @@
The answer: the first and the third will execute.
الإجابة: سيتم تنفيذ الأول والثالث

Details:
التفاصيل:

```js run
// Runs.
// The result of -1 || 0 = -1, truthy
// ينفذ
// نتيجة -1 || 0 = -1 هي truthy
if (-1 || 0) alert( 'first' );

// Doesn't run
// لا ينفذ
// -1 && 0 = 0, falsy
if (-1 && 0) alert( 'second' );

// Executes
// Operator && has a higher precedence than ||
// so -1 && 1 executes first, giving us the chain:
// ينفذ
// المعامل && له أولوية أعلى من ||
// لذلك يتم تنفيذ -1 && 1 أولا وينتج التالي:
// null || -1 && 1 -> null || 1 -> 1
if (null || -1 && 1) alert( 'third' );
```
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
importance: 5
الأهمية: 5

---

# A question about "if"
# سؤال عن "if"

Which of these `alert`s are going to execute?
أي من هذه التنبيهات `alert` سيتم تنفيذه ؟

What will the results of the expressions be inside `if(...)`?
ماذا ستكون نتيجة التعبيرات داخل `if(...)`?

```js
if (-1 || 0) alert( 'first' );
Original file line number Diff line number Diff line change
@@ -22,4 +22,4 @@ if (userName == 'Admin') {
}
```

Note the vertical indents inside the `if` blocks. They are technically not required, but make the code more readable.
لاحظ المسافات داخل `if`. غير مطلوبة فعليًا ولكنها تجعل الكود مقروء أكثر.
22 changes: 11 additions & 11 deletions 1-js/02-first-steps/11-logical-operators/9-check-login/task.md
Original file line number Diff line number Diff line change
@@ -1,25 +1,25 @@
importance: 3
الأهمية: 3

---

# Check the login
# فحص تسجيل الدخول

Write the code which asks for a login with `prompt`.
أكتب كود يكلب تسجيل الدخول باستخدام `prompt`.

If the visitor enters `"Admin"`, then `prompt` for a password, if the input is an empty line or `key:Esc` -- show "Canceled", if it's another string -- then show "I don't know you".
إذا كتب المستخدم كلمة `"Admin"` اطلب منه `prompt` كلمة المرور فإذا كتب سطر فارغ أو استخدم `key:Esc` -- أظهر رسالة "Canceled" وإذا كان نص آخر أظهر له "I don't know you".

The password is checked as follows:
يتم فحص كلمة المرور كالتالي:

- If it equals "TheMaster", then show "Welcome!",
- Another string -- show "Wrong password",
- For an empty string or cancelled input, show "Canceled"
- إذا كانت تساوي "TheMaster" يتم عرض "Welcome!",
- نص آخر يتم عرض "Wrong password",
- نص فارغ أو إلغاء العملية يتم عرض "Canceled"

The schema:
الصيغة العامة:

![](ifelse_task.svg)

Please use nested `if` blocks. Mind the overall readability of the code.
استخدم تعبيرات `if` متداخلة. انتبه أن يكون الكود مقروء.

Hint: passing an empty input to a prompt returns an empty string `''`. Pressing `key:ESC` during a prompt returns `null`.
ملحوظة: تمرير نص فارغ إلى prompt يرجع نص فارغ `''`. تمرير `key:ESC` يرجع `null`.

[demo]
168 changes: 84 additions & 84 deletions 1-js/02-first-steps/11-logical-operators/article.md
Original file line number Diff line number Diff line change
@@ -1,24 +1,24 @@
# Logical operators
# المعاملات المنطقية

There are three logical operators in JavaScript: `||` (OR), `&&` (AND), `!` (NOT).
يوجد ثلاثة معاملات منطقية في الجافاسكربت: `||` (OR), `&&` (AND), `!` (NOT).

Although they are called "logical", they can be applied to values of any type, not only boolean. Their result can also be of any type.
بالرغم من أن اسمهم معاملات منطقية إلا أنه يمكنك تطبيقهم على أي نوع من البيانات وليس فقط البيانات المنطقية. كما أنه يمكنهم إنتاج أي قيمة.

Let's see the details.
لنرى ذلك بالتفصيل.

## || (OR)

The "OR" operator is represented with two vertical line symbols:
معامل "OR" رمزه هو خطين أفقيين:

```js
result = a || b;
```

In classical programming, the logical OR is meant to manipulate boolean values only. If any of its arguments are `true`, it returns `true`, otherwise it returns `false`.
إذا كان أي من القيم الممررة له `true`يكون الناتج `true` وغير ذلك يرجع `false`.

In JavaScript, the operator is a little bit trickier and more powerful. But first, let's see what happens with boolean values.
في الجافاسكربت فهو مخادع أكثر وأقوى. ولكن دعنا أولًا نرى ماذا يحدث مع القيم المنطقية.

There are four possible logical combinations:
هناك أربع إحتمالات:

```js run
alert( true || true ); // true
@@ -27,83 +27,83 @@ alert( true || false ); // true
alert( false || false ); // false
```

As we can see, the result is always `true` except for the case when both operands are `false`.
يمكننا أن نرى أن النتيجة دائما `true` ما عدا في حالة عندما تكون كلتا القيمتين `false`.

If an operand is not a boolean, it's converted to a boolean for the evaluation.
إذا كانت القيم غير منطقية يتم تحويلها إلى قيم منطقية.

For instance, the number `1` is treated as `true`, the number `0` as `false`:
مثلًا الرقم `1` يعامل مثل `true`, الرقم `0` مثل `false`:

```js run
if (1 || 0) { // works just like if( true || false )
if (1 || 0) { // تعمل مثل ( true || false )
alert( 'truthy!' );
}
```

Most of the time, OR `||` is used in an `if` statement to test if *any* of the given conditions is `true`.
في معظم الأوقات يتم استخدام OR `||` مع `if` لإختبار إذا كان *أي* من الشروط المكتوبة تحقق `true`.

For example:
على سبيل المثال:

```js run
let hour = 9;

*!*
if (hour < 10 || hour > 18) {
*/!*
alert( 'The office is closed.' );
alert( 'المكتب مغلق.' );
}
```

We can pass more conditions:
يمكن تمرير شروط أكثر:

```js run
let hour = 12;
let isWeekend = true;

if (hour < 10 || hour > 18 || isWeekend) {
alert( 'The office is closed.' ); // it is the weekend
alert( 'المكتب مغلق.' ); // إنها عطلة
}
```

## OR "||" finds the first truthy value
## OR "||" إيجاد أول قيمة truthy

The logic described above is somewhat classical. Now, let's bring in the "extra" features of JavaScript.
ما تم وصفه بالأعلى هو الأمر التقليدي. الآن دعنا نرى ما أضافته الجافاسكربت.

The extended algorithm works as follows.
الخوارزمية المضافة تعمل كالتالي.

Given multiple OR'ed values:
يعطى العديد من القيم بينهم OR:

```js
result = value1 || value2 || value3;
```

The OR `||` operator does the following:
المعامل OR `||` يفعل الآتي:

- Evaluates operands from left to right.
- For each operand, converts it to boolean. If the result is `true`, stops and returns the original value of that operand.
- If all operands have been evaluated (i.e. all were `false`), returns the last operand.
- تنفيذ العمليات من اليسار لليمين.
- تحويل كل عملية إلى قيمة منطقية وإذا كان الناتج `true` يتوقف وينتج القيمة الأصلية لهذه العملية.
- إذا تم تنفيذ كل العمليات (مثلًا كلهم `false`) يرجع آخر عملية.

A value is returned in its original form, without the conversion.
يتم إرجاع القيمة بصيغتها الأصلية دون تحويل.

In other words, a chain of OR `"||"` returns the first truthy value or the last one if no truthy value is found.
بصيغة أخرى فإن مجموعة OR `"||"` ترجع أول قيمة truthy value أو آخر قيمة إذا لم تجد أي قيمة truthy.

For instance:
مثلًا:

```js run
alert( 1 || 0 ); // 1 (1 is truthy)

alert( null || 1 ); // 1 (1 is the first truthy value)
alert( null || 0 || 1 ); // 1 (the first truthy value)
alert( null || 1 ); // 1 (1 هو أول قيمة truthy)
alert( null || 0 || 1 ); // 1 (أول قيمة truthy)

alert( undefined || null || 0 ); // 0 (all falsy, returns the last value)
alert( undefined || null || 0 ); // 0 (الكل falsy, ترجع آخر قيمة)
```

This leads to some interesting usage compared to a "pure, classical, boolean-only OR".
هذا يوصل إلى بعض الاستخدامات الشيقة مقارنةً بالاستخدام التقليدي.

1. **Getting the first truthy value from a list of variables or expressions.**
1. **الحصول على أول قيمة truthy من مبين مجموعة متغيرات أو تعبيرات.**

For instance, we have `firstName`, `lastName` and `nickName` variables, all optional.
مثلًا لدينا `firstName`, `lastName` و `nickName` متغيرات كلها اختيارية.

Let's use OR `||` to choose the one that has the data and show it (or `anonymous` if nothing set):
هيا نستخدم OR `||` لاختيار الذي لديه قيمة ونعرضه (أو نعرض `anonymous` إذا لم يحدد أي أحد):

```js run
let firstName = "";
@@ -115,36 +115,36 @@ This leads to some interesting usage compared to a "pure, classical, boolean-onl
*/!*
```

If all variables were falsy, `Anonymous` would show up.
إذا كانت كل المتغيرات falsy, `Anonymous` سيتم عرض.

2. **Short-circuit evaluation.**

Another feature of OR `||` operator is the so-called "short-circuit" evaluation.
ميزة أخرى للمعامل OR `||` تسمى "short-circuit" evaluation.

It means that `||` processes its arguments until the first truthy value is reached, and then the value is returned immediately, without even touching the other argument.
ويعني أن `||` ينفذ العمليات الممررة له حتى أول قيمة truthy وبعد ذلك يتم إرجاع القيمة مباشرة بدون لمس باقي العمليات.

That importance of this feature becomes obvious if an operand isn't just a value, but an expression with a side effect, such as a variable assignment or a function call.
أهمية هذه الميزة تصبح ملحوظة إذا كانت القيمة الممررة عبارة عن عملية لها آثار جانبية مثل تخصيص قيمة متغير أو استدعاء دالة

In the example below, the first message is printed, while the second is not:
في هذا المثال سيتم طباعة الرسالة الأولى ولن يتم طباعة الثانية:

```js run no-beautify
*!*true*/!* || alert("printed");
*!*false*/!* || alert("not printed");
*!*false*/!* || alert("printed");
*!*true*/!* || alert("not printed");
```

In the first line, the OR `||` operator stops the evaluation immediately upon seeing `true`, so the `alert` isn't run.
في السطر الثاني يتوقف المعامل OR `||` مباشرة عند الوصول إلى `true` لذلك فإن `alert` لا ينفذ.

Sometimes, people use this feature to execute commands only if the condition on the left part is truthy.
أحيانًا يستخدم الناس هذه الخاصية لتنفيذ أوامر فقط إذا كان الجزء الأيسر truthy.

## && (AND)

The AND operator is represented with two ampersands `&&`:
المعامل AND يكتب بعلامتين عطف `&&`:

```js
result = a && b;
```

In classical programming, AND returns `true` if both operands are truthy and `false` otherwise:
في البرمجة التقليدية فإن المعامل AND ينتج `true` إذا كان كلتا القيمتان truthy وغير ذلك يرجع `false`:

```js run
alert( true && true ); // true
@@ -153,7 +153,7 @@ alert( true && false ); // false
alert( false && false ); // false
```

An example with `if`:
مثال باستخدام `if`:

```js run
let hour = 12;
@@ -164,126 +164,126 @@ if (hour == 12 && minute == 30) {
}
```

Just as with OR, any value is allowed as an operand of AND:
يمكن استخدام أي قيمة مع AND:

```js run
if (1 && 0) { // evaluated as true && false
alert( "won't work, because the result is falsy" );
if (1 && 0) { // تنفذ مثل true && false
alert( "لن يعمل لأن النتيجة falsy" );
}
```


## AND "&&" finds the first falsy value
## AND "&&" إيجاد أول قيمة falsy

Given multiple AND'ed values:
يعطى العديد من القيم بينهم AND:

```js
result = value1 && value2 && value3;
```

The AND `&&` operator does the following:
المعامل AND `&&` يفعل الآتي:

- Evaluates operands from left to right.
- For each operand, converts it to a boolean. If the result is `false`, stops and returns the original value of that operand.
- If all operands have been evaluated (i.e. all were truthy), returns the last operand.
- تنفيذ العمليات من اليسار إلى اليمين.
- كل عملية تحول إلى قيمة منطقية. إذا كانت النتيجة `false` يتوقف ويرجع القيمة الأصلية لهذه العملية.
- إذا تم تنفيذ كل العمليات (يعنى أن كلهم were truthy) يرجع آخر قيمة

In other words, AND returns the first falsy value or the last value if none were found.
بكلمات أخرى فإن AND ترجع أول قيمة falsy أو آخر قيمة.

The rules above are similar to OR. The difference is that AND returns the first *falsy* value while OR returns the first *truthy* one.
هذا مشابه ل OR. الاختلاف هو أن AND ترجع أول قيمة *falsy* بينما OR ترجع أول قيمة *truthy*.

Examples:

```js run
// if the first operand is truthy,
// AND returns the second operand:
// إذا كانت أول قيمة truthy,
// AND ترجع ثاني قيمة:
alert( 1 && 0 ); // 0
alert( 1 && 5 ); // 5
// if the first operand is falsy,
// AND returns it. The second operand is ignored
// إذا كانت أول قيمة falsy,
// AND ترجعها وتتجاهل القيمة الثانية
alert( null && 5 ); // null
alert( 0 && "no matter what" ); // 0
```

We can also pass several values in a row. See how the first falsy one is returned:
يمكننا أيضًا تمرير العديد من القيم وسيتم إرجاع أول قيمة falsy:

```js run
alert( 1 && 2 && null && 3 ); // null
```

When all values are truthy, the last value is returned:
إذا كانت كل القيم truthy يتم إرجاع آخر قيمة:

```js run
alert( 1 && 2 && 3 ); // 3, the last one
alert( 1 && 2 && 3 ); // 3, آخر قيمة
```

````smart header="Precedence of AND `&&` is higher than OR `||`"
The precedence of AND `&&` operator is higher than OR `||`.
````smart header="أولوية المعامل AND `&&` أعلى من OR `||`"
أولوية المعامل AND `&&` أعلى من OR `||`.

So the code `a && b || c && d` is essentially the same as if the `&&` expressions were in parentheses: `(a && b) || (c && d)`.
لذلك فإن `a && b || c && d` كأنك وضعت `&&` بين أقواس: `(a && b) || (c && d)`.
````

````warn header="Don't replace `if` with || or &&"
Sometimes, people use the AND `&&` operator as a "shorter to write `if`".
````warn header="لا تستبدل `if` ب || أو &&"
بعض الناس يستخدمون AND `&&` كإختصار ل `if`.

For instance:
مثلًا:

```js run
let x = 1;
(x > 0) && alert( 'Greater than zero!' );
```

The action in the right part of `&&` would execute only if the evaluation reaches it. That is, only if `(x > 0)` is true.
سيتم تنفيذ الجزء الأيمن من `&&` إذا كان `(x > 0)` يساوي true.

So we basically have an analogue for:
لذلك فهو يطابق:

```js run
let x = 1;
if (x > 0) alert( 'Greater than zero!' );
```

Although, the variant with `&&` appears shorter, `if` is more obvious and tends to be a little bit more readable. So we recommend using every construct for its purpose: use `if` if we want if and use `&&` if we want AND.
بالرغم من أن `&&` يبدو مختصرًا إلا أن `if` أفذل ومقروءة أكثر. لذلك ننصح باستخدام كل تعبير في مكانه: نستخدم `if` إذا أردنا if ونستخدم `&&` إذا أردنا AND.
````


## ! (NOT)

The boolean NOT operator is represented with an exclamation sign `!`.
المعامل NOT يتم تمثيله بعلامة تعجب `!`.

The syntax is pretty simple:
طريقة الكتابة بسيطة:

```js
result = !value;
```

The operator accepts a single argument and does the following:
يقبل قيمة واحدة ويفعل الآتي:

1. Converts the operand to boolean type: `true/false`.
2. Returns the inverse value.
1. تحويل القيمة إلى قيمة منطقية: `true/false`.
2. يرجع القيمة العكسية.

For instance:
مثلًا:

```js run
alert( !true ); // false
alert( !0 ); // true
```

A double NOT `!!` is sometimes used for converting a value to boolean type:
أحيانًا يتم استخدام علامتين NOT `!!` للتحويل إلى قيمة منطقية:

```js run
alert( !!"non-empty string" ); // true
alert( !!null ); // false
```

That is, the first NOT converts the value to boolean and returns the inverse, and the second NOT inverses it again. In the end, we have a plain value-to-boolean conversion.
أول NOT تحول إلى قيمة منطقية وترجع القيمة العكسية والثانية تعكسها مجددًا وفي النهاية نحصل على تحويل القيمة إلى قيمة منطقية.

There's a little more verbose way to do the same thing -- a built-in `Boolean` function:
وهناك طرق أخرى لعمل نفس الشئ -- مثل دالة `Boolean` المدمجة في اللغة:

```js run
alert( Boolean("non-empty string") ); // true
alert( Boolean(null) ); // false
```

The precedence of NOT `!` is the highest of all logical operators, so it always executes first, before `&&` or `||`.
أولوية NOT `!` هي الأعلى في كل المعاملات المنطقية لذلك تنفذ أولًا دائمًا قبل `&&` أو `||`.