Boolean Logic

មាតិកា

  1. តម្លៃពីរ ការសម្រេចចិត្តមិនចេះចប់
  2. AND, OR និង NOT
  3. Truth Table
  4. XOR៖ មួយតែមួយគត់
  5. លំដាប់អទិភាព និងវង់ក្រចក
  6. ច្បាប់ De Morgan
  7. Short-Circuit Evaluation
  8. ដោះស្រាយការពិនិត្យសិទ្ធិដែលច្របូកច្របល់
  9. រូបមន្ត៖ logic.js សម្រាប់ mathlab
  10. សាកល្បងដោយខ្លួនឯង

1. តម្លៃពីរ ការសម្រេចចិត្តមិនចេះចប់

Boolean មានតម្លៃអាចទៅរួចត្រឹមតែពីរ៖ true និង false។ ស្តាប់ទៅដូចជាតូចពេកមិនសំខាន់ ប៉ុន្តែគ្រប់ if គ្រប់ while គ្រប់ filter និងគ្រប់ការពិនិត្យសិទ្ធិក្នុងកូដរបស់អ្នក សុទ្ធតែសម្រេចចុងក្រោយជា boolean មួយ។

Boolean logic គឺជាគណិតវិទ្យានៃការផ្សំ boolean។ George Boole បានសរសេរវាចុះក្នុងសតវត្សទី 1800 យូរមុនមានកុំព្យូទ័រ ហើយវាប្រែជាអ្វីដែលបន្ទះឈីបកុំព្យូទ័រធ្វើយ៉ាងពិតប្រាកដ៖ ឈីបគឺជាកុងតាក់តូចៗរាប់ពាន់លានដែលផ្សំ 1 និង 0។

នៅក្នុង ជំពូកទី 3 អ្នកបានផ្សំ bit ដោយ &, |, ^ និង ~។ Operator ទាំងនោះធ្វើការលើគ្រប់ bit នៃលេខក្នុងពេលតែមួយ។ ជំពូកនេះគឺអំពីគំនិតដូចគ្នា ដែលអនុវត្តលើតម្លៃ true/false តែមួយៗ ជាមួយ &&, || និង !។ ពួកវាជាញាតិនឹងគ្នា។ ពេលអ្នកស្គាល់មួយសំណុំ អ្នកក៏ស្គាល់សំណុំមួយទៀតដែរ។

ប្រសិនបើអ្នកចង់រំលឹក syntax ជាមុនសិន សូមមើល Operator និងលក្ខខណ្ឌ។

2. AND, OR និង NOT

មានប្រតិបត្តិការមូលដ្ឋានបី៖

ប្រតិបត្តិការJavaScriptអត្ថន័យ
ANDa && btrue តែនៅពេលដែល ទាំងពីរ ជា true
ORa || btrue នៅពេលដែល យ៉ាងហោចណាស់មួយ ជា true
NOT!aប្តូរ true ទៅ false និងប្តូរត្រឡប់វិញ

និយាយជាពាក្យធម្មតា៖ "អាចកែបាន" ប្រសិនបើអ្នកជាអ្នកនិពន្ធ ហើយ ប្រកាសមិនត្រូវបានចាក់សោ។ "អាចមើលឃើញ" ប្រសិនបើអ្នកជា admin ឬ ជាម្ចាស់។ "Not" គ្រាន់តែប្តូរចម្លើយទៅផ្ទុយ។

const isAuthor = true;
const isLocked = false;

console.log(isAuthor && !isLocked); // true
console.log(isAuthor && isLocked);  // false
console.log(isAuthor || isLocked);  // true
console.log(!isAuthor);             // false

សូមអាន isAuthor && !isLocked ឮៗថា "ជាអ្នកនិពន្ធ ហើយមិនត្រូវបានចាក់សោ"។ ប្រសិនបើលក្ខខណ្ឌមួយពិបាកអានឮៗ វាប្រហែលជាស្មុគស្មាញពេក។

3. Truth Table

ដោយមានតម្លៃត្រឹមតែពីរសម្រាប់ input នីមួយៗ អ្នកអាចរាយ គ្រប់ ករណីដែលអាចកើតមាន។ បញ្ជីនោះហៅថា truth table។ វាជាវិធីដែលគួរឲ្យទុកចិត្តបំផុតក្នុងការពិនិត្យថាលក្ខខណ្ឌមួយធ្វើអ្វីពិតប្រាកដ ព្រោះវាមិនទុកករណីណាមួយចោលឡើយ។

នេះគឺ AND សម្រាប់ input ពីរ គឺ a និង b៖

aba && b
FFF
FTF
TFF
TTT

ហើយ OR៖

aba || b
FFF
FTT
TFT
TTT

សូមកត់សម្គាល់ចំនួនជួរ៖ input ពីរផ្តល់ 2 × 2 = 4 ជួរ។ Input បីផ្តល់ 2 × 2 × 2 = 8 ជួរ។ ជាទូទៅ input n ផ្តល់ 2ⁿ ជួរ។ (នេះគឺជាការកើនទ្វេដងដូចគ្នាដែលអ្នកបានជួបនៅជំពូកទី 2៖ input បន្ថែមមួយគឺ bit បន្ថែមមួយ។) Input ដប់នឹងផ្តល់ 1,024 ជួរ ដែលកុំព្យូទ័រពិនិត្យបានក្នុងមួយភ្លែត ប៉ុន្តែមនុស្សនឹងអស់កម្លាំង។ ហេតុនេះហើយបានជាយើងឲ្យកូដបង្កើតតារាងទាំងនោះ ដូចក្នុងរូបមន្តនៅពេលក្រោយ។

4. XOR៖ មួយតែមួយគត់

មានប្រតិបត្តិការទីបួនដែលមនុស្សច្រើនភ្លេច៖ XOR ដែលជាអក្សរកាត់នៃ "exclusive or"។ វាជា true នៅពេលដែល input ទាំងពីរ ខុសគ្នា មានន័យថាមានតែមួយប៉ុណ្ណោះជា true។

aba XOR b
FFF
FTT
TFT
TTF

ប្រៀបធៀបជាមួយ OR៖ ភាពខុសគ្នាតែមួយគត់គឺជួរចុងក្រោយ។ OR និយាយថា "មួយ ឬទាំងពីរ"; XOR និយាយថា "មួយ ប៉ុន្តែមិនមែនទាំងពីរ"។

JavaScript មិនមាន operator ^^ ទេ។ សម្រាប់ boolean !== ធ្វើការងារនេះបាន ព្រោះ "តម្លៃទាំងពីរខុសគ្នា" គឺជា XOR យ៉ាងពិតប្រាកដ៖

const a = true;
const b = false;

console.log(a !== b); // true  (XOR)
console.log(a ^ b);   // 1     (bitwise XOR ក៏ដំណើរការដែរ ប៉ុន្តែផ្តល់ជាលេខ)

ស្ថានភាព XOR ក្នុងជីវិតប្រចាំថ្ងៃ៖ "បង់ប្រាក់ដោយសាច់ប្រាក់ ឬ កាត ប៉ុន្តែមិនមែនទាំងពីរ" "ប៊ូតុងបិទបើកប្តូរស្ថានភាពរាល់ពេលចុច" (isOn = isOn !== clicked) ឬ "ប្រអប់ពាក្យសម្ងាត់ពីរ មានតែមួយទទេ"។

5. លំដាប់អទិភាព និងវង់ក្រចក

នៅពេល expression មួយលាយ operator ច្រើន JavaScript ត្រូវការលំដាប់មួយ ដូចជា * ធ្វើមុន + ក្នុងនព្វន្ត។ សម្រាប់ boolean លំដាប់គឺ៖

  1. ! មុនគេ
  2. បន្ទាប់មក &&
  3. បន្ទាប់មក ||

ដូច្នេះ a || b && c មានន័យថា a || (b && c) មិនមែន (a || b) && c ទេ។

const a = true, b = false, c = false;

console.log(a || b && c);   // true   -> a || (b && c)
console.log((a || b) && c); // false

Input ដូចគ្នា ចម្លើយខុសគ្នា។ កុំពឹងលើការទន្ទេញលំដាប់អទិភាព។ ប្រើវង់ក្រចកគ្រប់ពេលដែលអ្នកលាយ && និង || ទោះបីមិនចាំបាច់ទាំងស្រុងក៏ដោយ។ អ្នកអានមិនគួរត្រូវដំណើរការច្បាប់អទិភាពក្នុងក្បាលរបស់ខ្លួនឡើយ។

6. ច្បាប់ De Morgan

Augustus De Morgan បានកត់សម្គាល់ថា នៅពេលអ្នកដាក់ ! នៅមុខវង់ក្រចក អ្នកអាចរុញ ! ចូលខាងក្នុងបាន ដរាបណាអ្នកប្តូរ AND ទៅ OR និងប្តូរ OR ទៅ AND៖

!(a && b)   is the same as   !a || !b
!(a || b)   is the same as   !a && !b

និយាយជាពាក្យ៖ "មិនមែន (A និង B)" មានន័យថា "មិនមែន A ឬមិនមែន B"។ "មិនមែន (A ឬ B)" មានន័យថា "មិនមែន A ហើយមិនមែន B"។

ប្រយោគពិតមួយបង្ហាញថាហេតុអ្វីវាសមហេតុផល។ យកច្បាប់ "អ្នកអាចចូលបាន ប្រសិនបើមិនមែន (អាយុក្រោម 18 ឬគ្មានសំបុត្រ)"។ អ្នកណាចូលបាន? មានតែអ្នកដែលមិនមែនអាយុក្រោម 18 ហើយ មានសំបុត្រប៉ុណ្ណោះ។ OR បានប្តូរទៅជា AND។

អ្នកអាចបញ្ជាក់ច្បាប់នេះដោយ truth table៖

ab!(a && b)!a || !b
FFTT
FTTT
TFTT
TTFF

ជួរឈរពីរចុងក្រោយត្រូវគ្នាគ្រប់ជួរ ដូច្នេះ expression ទាំងពីរ សមមូល។ នេះគឺជាវិធីដែលអ្នកបញ្ជាក់ថាការសរសេរឡើងវិញមានសុវត្ថិភាព ដោយមិនចាំបាច់ប្រើភស្តុតាងស្មុគស្មាញ៖ ប្រសិនបើគ្រប់ជួរនៃតារាងត្រូវគ្នា នោះលក្ខខណ្ឌទាំងពីរគឺដូចគ្នា។

ច្បាប់ De Morgan មានសារៈសំខាន់បំផុតនៅពេលវាអនុញ្ញាតឲ្យអ្នកដក ! ដែលធ្វើឲ្យកូដពិបាកអាន៖

const age = 20;
const hasTicket = true;

// ពិបាកអាន
const blocked1 = !(age >= 18 && hasTicket);

// ដូចគ្នា ដោយអនុវត្ត De Morgan។ ចំណាំថា !(age >= 18) គឺ age < 18។
const blocked2 = age < 18 || !hasTicket;

console.log(blocked1, blocked2); // false false

ការអនុវត្តច្បាប់នេះលើការប្រៀបធៀបក៏ប្តូរ comparison operator ដែរ៖

ដើមសមមូល
!(x > 5)x <= 5
!(x >= 5)x < 5
!(x === 5)x !== 5

Bug ដ៏ញឹកញាប់គឺប្តូរ > ទៅ < ហើយភ្លេចករណីស្មើ។ ផ្ទុយនៃ "ធំជាង" គឺ "តូចជាង ឬស្មើ" មិនមែន "តូចជាង" ទេ។ Truth table (ឬការសាកល្បងនៅតម្លៃព្រំដែន) ចាប់បានកំហុសនេះ។

7. Short-Circuit Evaluation

&& និង || មិនតែងតែគណនាទាំងសងខាងទេ។ JavaScript អានពីឆ្វេងទៅស្តាំ ហើយ ឈប់ភ្លាមៗពេលចម្លើយច្បាស់លាស់៖

  • ក្នុង a && b ប្រសិនបើ a ជា false ចម្លើយគឺ false រួចហើយ ដូច្នេះ b មិនត្រូវបានមើលឡើយ។
  • ក្នុង a || b ប្រសិនបើ a ជា true ចម្លើយគឺ true រួចហើយ ដូច្នេះ b មិនត្រូវបានមើលឡើយ។

អ្នកអាចបង្ហាញវាដោយ function ដែលប្រកាសខ្លួនឯង៖

let calls = 0;
const check = () => {
  calls++;
  return true;
};

false && check(); // check មិនដែលដំណើរការ
true || check();  // check មិនដែលដំណើរការ
console.log(calls); // 0

នេះលើសពីល្បិចធ្វើឲ្យលឿន។ វាជាឧបករណ៍សុវត្ថិភាព។ ដាក់ការសាកល្បងដែលថោក ឬមានសុវត្ថិភាពមុន ហើយការសាកល្បងដែលគ្រោះថ្នាក់ទីពីរ៖

const user = { name: "Dara", profile: null };

// សុវត្ថិភាព៖ ប្រសិនបើ profile ជា null ផ្នែកខាងស្តាំត្រូវបានរំលង
console.log(user.profile && user.profile.city); // null

// បើគ្មានការការពារនេះ វានឹង throw TypeError៖
// user.profile.city

// ផ្លូវកាត់ទំនើបសម្រាប់គំនិតដូចគ្នា
console.log(user.profile?.city); // undefined

JavaScript មានចំណុចចម្លែកមួយទៀត។ && និង || មិនត្រឡប់ true ឬ false ទេ។ ពួកវាត្រឡប់ operand មួយក្នុងចំណោមពីរ៖

console.log(0 || "default");  // "default"
console.log("Dara" || "x");   // "Dara"
console.log(true && "ready"); // "ready"
console.log(null && 1);       // null

នោះហើយជាមូលហេតុដែល name || "Anonymous" ដំណើរការជាតម្លៃលំនាំដើម។ គ្រាន់តែចាំថា || ចាត់ទុក 0 និង "" ជា "បាត់" ដែលអាចខុសសម្រាប់បរិមាណសូន្យ។ ប្រើ ?? នៅទីនោះ ដូចបានគ្របដណ្តប់ក្នុង Operator និងលក្ខខណ្ឌ។

ជាចុងក្រោយ ដាក់ការពិនិត្យដែលថោកបំផុតមុន។ ប្រសិនបើលក្ខខណ្ឌមួយជាការសាកល្បង variable រហ័ស ហើយមួយទៀតសួរ database សូមសរសេរលក្ខខណ្ឌរហ័សនៅខាងឆ្វេង នោះការហៅ database នឹងត្រូវរំលងរាល់ពេលដែលការសាកល្បងរហ័សសម្រេចចម្លើយរួចហើយ។

8. ដោះស្រាយការពិនិត្យសិទ្ធិដែលច្របូកច្របល់

នេះគឺជាបញ្ហាដែលជំពូកនេះកំពុងសាងសង់ឆ្ពោះទៅរក។ ច្បាប់សម្រាប់កែប្រកាសប្លុកគឺ៖

  1. Admin អាចកែបានជានិច្ច។
  2. គ្មាននរណាផ្សេងអាចកែប្រកាសដែលចាក់សោបានទេ។
  3. អ្នកនិពន្ធអាចកែប្រកាសរបស់ខ្លួនបាន។
  4. Editor អាចកែប្រកាសរបស់អ្នកណាក៏បាន លើកលែងតែវាត្រូវបាន archive។

អ្នកអភិវឌ្ឍន៍ម្នាក់ដែលនឿយហត់បានសរសេរកូដនេះ៖

function canEditOld(user, post) {
  if (
    !(user.role !== "admin") ||
    (!post.locked &&
      (post.authorId === user.id || (user.role === "editor" && !post.archived)))
  ) {
    return true;
  }
  return false;
}

វាដំណើរការ ប៉ុន្តែគ្មាននរណាអាចយល់បានទេ។ តោះសម្អាតវាជាបួនជំហាន។

ជំហានទី 1៖ ដកអវិជ្ជមានទ្វេដង។ !(user.role !== "admin") គឺ "មិនមែន (មិនស្មើ)" ហើយ NOT ពីរលុបគ្នាចោល។ វាគឺគ្រាន់តែ user.role === "admin"។

ជំហានទី 2៖ ត្រឡប់ boolean ដោយផ្ទាល់។ if (condition) return true; return false; ដូចគ្នានឹង return condition;។

ជំហានទី 3៖ បំបែកជា early return។ Early return ចេញពី function ភ្លាមៗពេលដឹងចម្លើយ ដូចជា short circuit ប៉ុន្តែសម្រាប់ជំហានទាំងមូល។ ច្បាប់នីមួយៗក្លាយជាមួយបន្ទាត់រាបស្មើ តាមលំដាប់ដែលអ្នកនឹងពន្យល់ច្បាប់ទាំងនោះដល់មិត្តរួមការងារ៖

function canEdit(user, post) {
  if (user.role === "admin") return true;   // ច្បាប់ទី 1
  if (post.locked) return false;            // ច្បាប់ទី 2
  if (post.authorId === user.id) return true; // ច្បាប់ទី 3
  return user.role === "editor" && !post.archived; // ច្បាប់ទី 4
}

ជំហានទី 4៖ បញ្ជាក់ថាវាមិនបានប្តូរ។ កុំទុកចិត្តការកែសម្រួលកូដដោយភ្នែកឡើយ។ ដំណើរការកំណែទាំងពីរលើគ្រប់ការផ្សំនៃ input ដែលសំខាន់ (role, locked, archived, ជាអ្នកនិពន្ធឬអត់) ហើយប្រៀបធៀប៖

let same = true;
let cases = 0;

for (const role of ["admin", "editor", "viewer"]) {
  for (const locked of [true, false]) {
    for (const archived of [true, false]) {
      for (const authorId of [1, 2]) {
        const user = { id: 1, role };
        const post = { authorId, locked, archived };
        cases++;
        if (canEditOld(user, post) !== canEdit(user, post)) same = false;
      }
    }
  }
}

console.log(same, cases); // true 24

បី role គុណពីរ គុណពីរ គុណពីរ ស្មើ 24 ករណី ហើយទាំងអស់ត្រូវគ្នា។ នេះគឺជាគំនិតដូច truth table ហើយជាបេះដូងនៃការ refactor ដោយសុវត្ថិភាព៖ ប្រសិនបើ input ទាំងអស់អាចរាប់បាន សូមពិនិត្យវាទាំងអស់។

Early return ធ្វើឲ្យការដាក់ជាន់ៗរាបស្មើ។ ប្រៀបធៀប "ប្រសិនបើ admin នោះ ... បើមិនដូច្នោះ ប្រសិនបើ ... បើមិនដូច្នោះ ..." ជាមួយបញ្ជីច្បាប់សាមញ្ញៗដែលអានពីលើចុះក្រោម។ ទីពីរអានងាយជាង និងកែងាយជាង នៅពេលច្បាប់ទីប្រាំមកដល់។

9. រូបមន្ត៖ logic.js សម្រាប់ mathlab

ឥឡូវនេះបន្ថែម module logic ទៅក្នុង mathlab។ បង្កើត src/logic.js៖

// ការផ្សំ true/false ទាំងអស់សម្រាប់ input n។
export function boolCombos(n) {
  const rows = [];
  for (let i = 0; i < 2 ** n; i++) {
    const row = [];
    for (let bit = n - 1; bit >= 0; bit--) {
      row.push(((i >> bit) & 1) === 1);
    }
    rows.push(row);
  }
  return rows;
}

// fn ទទួល boolean n; ត្រឡប់ [{ inputs: [...], result }, ...]
export function truthTable(fn) {
  return boolCombos(fn.length).map((inputs) => ({
    inputs,
    result: fn(...inputs),
  }));
}

// បោះពុម្ពតារាងទៅ console។
export function printTable(fn) {
  for (const { inputs, result } of truthTable(fn)) {
    const cells = inputs.map((v) => (v ? "T" : "F")).join(" ");
    console.log(`${cells} | ${result ? "T" : "F"}`);
  }
}

// តើ function ពីរផ្តល់លទ្ធផលដូចគ្នាសម្រាប់គ្រប់ការផ្សំឬទេ?
export function areEquivalent(f, g) {
  if (f.length !== g.length) return false;
  return boolCombos(f.length).every((row) => f(...row) === g(...row));
}

// ច្បាប់ De Morgan ពិនិត្យដោយ brute force។
export const deMorganAnd = areEquivalent(
  (a, b) => !(a && b),
  (a, b) => !a || !b,
);
export const deMorganOr = areEquivalent(
  (a, b) => !(a || b),
  (a, b) => !a && !b,
);

// ច្បាប់សិទ្ធិដែលបានសម្អាតពីផ្នែកទី 8។
export function canEdit(user, post) {
  if (user.role === "admin") return true;
  if (post.locked) return false;
  if (post.authorId === user.id) return true;
  return user.role === "editor" && !post.archived;
}

ចំណុចខ្លះដែលគួរកត់សម្គាល់។ fn.length គឺជាចំនួន parameter ដែល function ប្រកាស ដូច្នេះ truthTable ដឹងថាត្រូវសាកល្បង input ប៉ុន្មានដោយមិនចាំបាច់ប្រាប់។ i >> bit ផ្លាស់ទី bit របស់ i ទៅស្តាំ (ពីជំពូកទី 3) ហើយ & 1 ជ្រើស bit ទាបបំផុត ដែលជាវិធីដែលរាប់ពី 0 ដល់ 2ⁿ - 1 ក្លាយជាគ្រប់ការផ្សំនៃ true និង false។ ...inputs ពន្លាត array ទៅជា argument ដាច់ដោយឡែក។

Re-export វាពី src/index.js៖

export * from "./logic.js";

បន្ទាប់មកសាកល្បងក្នុង demo.js៖

import {
  printTable,
  areEquivalent,
  deMorganAnd,
  canEdit,
} from "./src/logic.js";

printTable((a, b) => a && b);
console.log(deMorganAnd);
console.log(areEquivalent((a, b) => a || b, (a, b) => !(!a && !b)));
console.log(
  canEdit({ id: 7, role: "editor" }, { authorId: 7, locked: true, archived: false }),
);
console.log(
  canEdit({ id: 1, role: "admin" }, { authorId: 7, locked: true, archived: false }),
);

ដំណើរការវា៖

node demo.js
F F | F
F T | F
T F | F
T T | T
true
true
false
true

true សម្រាប់ deMorganAnd គឺជាកម្មវិធីបញ្ជាក់ច្បាប់ De Morgan ឲ្យអ្នក។ true បន្ទាប់បង្ហាញថា a || b ស្មើ !(!a && !b) ដែលជាច្បាប់ De Morgan ទីពីរប្រើបញ្ច្រាស។ ពីរបន្ទាត់ចុងក្រោយបង្ហាញថា ប្រកាសដែលចាក់សោរារាំងសូម្បីតែអ្នកនិពន្ធរបស់វា ប៉ុន្តែមិនរារាំង admin ទេ។

10. សាកល្បងដោយខ្លួនឯង

  1. អានតារាង។ ហៅ printTable((a, b, c) => a && (b || c)) ហើយរាប់លទ្ធផល T។ បន្ទាប់មកប្តូរ function ទៅ (a && b) || c ហើយប្រៀបធៀប។ មួយណាជា true ញឹកញាប់ជាង?
  2. XOR ពីមូលដ្ឋាន។ សរសេរ xor(a, b) ដោយប្រើតែ &&, || និង ! (ជំនួយ៖ "មួយ ឬមួយទៀត ប៉ុន្តែមិនមែនទាំងពីរ")។ ប្រើ areEquivalent បញ្ជាក់ថាវាស្មើ (a, b) => a !== b។
  3. កែការបដិសេធ។ សរសេរ !(items.length > 0 && !isLoading) ឡើងវិញដោយគ្មាន ! នៅខាងមុខ ដោយអនុវត្តច្បាប់ De Morgan។ ពិនិត្យចម្លើយរបស់អ្នកដោយ areEquivalent ដោយបំប្លែងការប្រៀបធៀបទៅជា input boolean ធម្មតា។
  4. បន្ថែមច្បាប់។ ពង្រីក canEdit ដើម្បីឲ្យប្រកាសដែលសម្គាល់ draft: true អាចកែបានដោយអ្នកនិពន្ធរបស់វា ឬ admin ប៉ុណ្ណោះ សូម្បីតែ editor ក៏មិនបាន។ តើច្បាប់ថ្មីគួរដាក់នៅកន្លែងណាក្នុងបញ្ជី early return ហើយហេតុអ្វី?
  5. ភស្តុតាង short-circuit។ សរសេរ function loud(label, value) ដែលបោះពុម្ព label ហើយត្រឡប់ value។ គណនា loud("A", false) && loud("B", true) និង loud("A", true) || loud("B", false)។ តើ label ណាបោះពុម្ព?
  6. រក bug។ មិត្តរួមក្រុមម្នាក់បានសរសេរ !(age >= 18) ឡើងវិញជា age < 17។ តើអាយុណាខ្លះដែលទាំងពីរមិនត្រូវគ្នា? ប្រើ loop ពី 0 ដល់ 30 ដើម្បីរក។

Boolean logic ធ្វើការលើចម្លើយបាទ/ចាសតែមួយៗ។ បន្ទាប់យើងនឹងមើលបណ្តុំនៃវត្ថុជំនួសវិញ៖ សំណុំ និងប្រតិបត្តិការសំណុំ បង្ហាញពីរបៀបដែល AND, OR និង NOT ក្លាយជា intersection, union និង difference នៅពេល "តម្លៃ" គឺជាក្រុមទាំងមូលនៃអ្នកប្រើ ឬ tag។

ទិញកាហ្វេជូនខ្ញុំ

ចូលចិត្តមេរៀននេះមែនទេ? សូមពិចារណាទិញកាហ្វេជូនខ្ញុំមួយកែវ ដើម្បីគាំទ្រការបង្កើតមាតិកាឥតគិតថ្លៃបន្ថែមទៀត!