Лекция · 4.3

Кірістірілген және каскадты шарттар

Өткен сабақта бір ғана шартты тексеруді үйрендік: «егер a > 0 болса — мынау, болмаса — анау». Бірақ өмірде шешімдер көбіне бір қадаммен бітпейді: «егер сыртта суық болса — күрте киесің, ал егер сонымен қатар жаңбыр да жауып тұрса — оның үстінен қолшатыр да аласың». Дәл осындай «шарт ішіндегі шартты» бағдарламада қалай жазатынымызды, сонымен қатар екіден көп нұсқадан таңдау керек болғанда не істейтінімізді осы сабақта үйренеміз. Бұл тақырып ҰБТ-да жиі кездеседі: координаталық жазықтықтың ширегін анықтау, бірнеше санатқа бөлу, көп нұсқалы есептер — барлығы дәл осы тақырыпқа негізделген.

Кірістірілген тармақталу

Ойланып көр: киім таңдағанда сен алдымен ауа райына қарайсың — суық па, жылы ма? Егер суық болса, бұл жерде шешім бітпейді — тағы бір сұрақ туады: жаңбыр жауып тұр ма? Жаңбыр болса — күрте үстіне қолшатыр да аласың, болмаса — тек күрте жеткілікті.

Мұнда не байқадың? Бірінші шарттың («суық па?») «иә» жауабының ішінде тағы бір шарт («жаңбыр бар ма?») жасырылған. Жауабы — қарапайым: if блогының ішіне тағы бір if жазуға болады. Сыртқы шарт ақиқат болғанда ғана, оның ішінде орналасқан екінші шарт тексеріледі. Осындай, басқа тармақтың ішінде орналасқан тармақты кірістірілген тармақталу дейміз.

Шарт 1 Шарт 1 → иә Шарт 2 (ішкі if)
Анықтама
Кірістірілген тармақталу — басқа тармақталу бұтақтарының (if немесе else) ішінде орналасқан тармақ. Бір if операторының ішінде тағы бір if операторы жазылады. Шегініс өлшемі әр деңгейде артады (8 бос орын, 2 деңгей).

Анықтаманы бөлшектеп көрейік: «Басқа тармақтың ішінде орналасқан» — ішкі if сыртқы if-тің (немесе else-тің) блогының бір бөлігі болып саналады, ол сыртқы шарт орындалғанда ғана іске қосылады. «Бір if операторының ішінде тағы бір if» — деңгейлердің саны шектелмеген, бірақ көбінесе 2 деңгеймен шектеледі, өйткені одан көп болса, кодты оқу қиындайды. «Шегініс әр деңгейде артады» — бірінші деңгей 4 бос орын шегінісімен жазылса, екінші деңгей (ішкі if) тағы 4 бос орын қосып, жалпы 8 бос орын шегінісімен жазылады.

Неге дәл осылай ұйымдастырылған? Себебі кейбір шешімдер бір ғана сұрақпен шешілмейді — алдымен бір жалпы сұраққа жауап табу керек, содан кейін сол жауапқа байланысты тағы нақтыланған сұрақ қою керек. Мысалы: «егер ученик 5 сынса оқыса (1-шарт), және сонымен қатар үй жұмысын да тапсырса (2-шарт), оған «үздік» белгісі қойылады». Бұл — екі деңгейлі кірістірілген тармақталудың типтік мысалы.

📦 Шарт 1 🎁 Шарт 2

Кірістірілген тармақталуды бір-бірінің ішінде тұрған қорапшаларға (матрёшкаға) ұқсатуға болады. Сыртқы қорапты ашсаң — оның ішінде тағы кішірек қорап тұр. Дәл осылай, сыртқы шартты «ашқанда», оның ішінен тағы бір шарт шығады.

⚠️
Жиі кеткен қате: көп оқушылар екі деңгейлі кірістіруде шегіністі дұрыс есептей алмайды — ішкі if-ті сыртқы if-пен бірдей деңгейде жазып қояды. Нәтижесінде Python ішкі шартты бөлек, тәуелсіз шарт деп қабылдайды, бағдарлама дұрыс жұмыс істемейді. Есте сақта: әр ішкі деңгей сыртқыдан тағы 4 бос орынға артық шегінумен жазылады.
Кірістірілген тармақталуды есепте қолдану

Мұғалім тақтада қалай шешер еді, дәл солай қадаммен жүрейік.

Деңгей: орта
Не белгілі: (x, y) нүктесінің координаттары.
Не табу керек: Нүкте координаталық жазықтықтың қай ширегінде орналасқанын анықтайтын программа.
Неге дәл осы әдісті қолданамыз: ширекті анықтау үшін екі белгі керек — x оң ба, теріс пе, және y оң ба, теріс пе. Бұл екі тәуелсіз шарт, бірақ олар бірге тексерілуі керек, сондықтан кірістірілген тармақталу қолданылады: алдымен x бойынша бөлеміз, содан кейін әр бөліктің ішінде y бойынша нақтылаймыз.
1
Координаттарды енгіземіз.
x = int(input())
y = int(input())
2
Сыртқы шартты құрамыз (x таңбасы бойынша) — бұл бізді екі үлкен топқа бөледі: x оң немесе x теріс/нөл.
if x > 0:
    ...
else:
    ...
3
Әр топтың ішінде y таңбасы бойынша нақтылаймыз. x > 0 болғанда: y > 0 болса — Бірінші ширек, болмаса — Төртінші ширек. x ≤ 0 болғанда: y > 0 болса — Екінші ширек, болмаса — Үшінші ширек.
if x > 0:
    if y > 0:
        print("Birinshi toksan")
    else:
        print("Tortinshi toksan")
else:
    if y > 0:
        print("Ekinshi toksan")
    else:
        print("Ushinshi toksan")
Тексеру: x=1, y=1 — x>0 ақиқат, y>0 ақиқат → "Birinshi toksan". x=2, y=-2 — x>0 ақиқат, y>0 жалған → "Tortinshi toksan". Жауабы: x=1,y=1 → "Birinshi toksan"; x=2,y=-2 → "Tortinshi toksan". Қорытынды идея: екі белгі бойынша (x пен y таңбасы) төрт нұсқаны ажырату керек болғанда, алдымен бір белгі бойынша екіге бөліп, содан кейін әр бөліктің ішінде екінші белгі бойынша тағы екіге бөлу — кірістірілген тармақталудың классикалық қолданысы.
I ширек II ширек III ширек IV ширек
Каскадты тармақталу (if-elif-else)

Енді басқа жағдайды қарастырайық: оқушының бағасын анықтау керек делік — «5» болса «Үздік», «4» болса «Жақсы», «3» болса «Қанағаттанарлық», қалғаны «Қанағаттанарлықсыз». Мұнда екі емес, төрт түрлі нұсқа бар. Бұл есепті кірістірілген if арқылы шешуге болады, бірақ әр жаңа нұсқа қосылған сайын кірістіру тереңдей береді, шегініс саны өсе береді, кодты оқу қиындай түседі.

Python мұндай жағдай үшін ыңғайлырақ тәсіл ұсынады — бірнеше шартты бір деңгейде, тізбектей тексеретін құрылым. Осындай, екіден көп нұсқадан таңдау үшін қолданылатын, шарттарды жоғарыдан төмен қарай тізбектей тексеретін тармақталуды каскадты тармақталу дейміз.

if number == 5: elif number == 4: elif number == 3: ✓ тоқтады else: (тексерілмейді)
Анықтама
Каскадты тармақталу (if-elif-else) — екіден көп нұсқадан таңдау қажет болғанда қолданылады. Шарттар жоғарыдан төмен қарай тізбектей тексеріледі; біреуі орындалған сәтте сәйкес блок іске қосылады және қалған шарттар тексерілмейді.

Анықтаманы бөлшектеп көрейік: «Екіден көп нұсқа» — каскадты тармақталу дәл осы жағдайда тиімді: екі ғана нұсқа болса, қарапайым if-else жеткілікті. «Жоғарыдан төмен қарай тізбектей тексеріледі» — Python алдымен бірінші шартты тексереді, ол жалған болса — екіншісін, ол да жалған болса — үшіншісін, осылай жалғасады. «Біреуі орындалған сәтте... қалғаны тексерілмейді» — бұл өте маңызды қасиет: бір шарт ақиқат болып, сәйкес блок орындалғаннан кейін, Python қалған шарттарды мүлдем тексермейді, тіпті олар да ақиқат болатын болса да.

Неге дәл осылай жұмыс істейді? Себебі есеп логикасы бойынша, бір нәрсе тек бір санатқа жатуы керек. Сондықтан бірінші сәйкес келген шарт табылғаннан кейін, қалғанын тексерудің қажеті жоқ — бұл, сонымен қатар, бағдарламаны жылдамырақ та етеді. Мысалы: number = 1 болғанда, Python алдымен «number == 1» дегенді тексереді — ол ақиқат, сондықтан «Bir» деп шығарады да, «number == 2» шартын мүлдем тексермейді.

Каскадты тармақталуды эскалатор баспалдақтарына ұқсатуға болады: жоғарыдан төмен қарай түсе бересің, әр баспалдақта «осында тоқтаймын ба?» деп тексересің. Қажетті жерге жеткенде тоқтайсың да, қалған баспалдақтарға назар аудармайсың.

⚠️
Жиі кеткен қате: кейбір оқушылар elif орнына бірнеше тәуелсіз if жазады. Бұл — қате емес, бірақ тиімсіз әрі қауіпті: Python әр if-ті бөлек тексереді, тіпті алдыңғысы ақиқат болса да, келесі if-ті де тексере береді. Бұл кейде күтпеген нәтижеге әкелуі мүмкін.
if-elif-else синтаксисі
Анықтама
Python синтаксисі:
if <шарт 1>:
    <нұсқау 1>
elif <шарт 2>:
    <нұсқау 2>
else:
    <нұсқау 3>
elif бірнеше рет қайталануы мүмкін, ал else блогы міндетті емес.

Бөлшектеп қарайық: «elif» — «else if» дегеннің қысқарған түрі, «алдыңғы шарт жалған болса, мынаны тексер» дегенді білдіреді. «elif бірнеше рет қайталануы мүмкін» — нұсқа саны қанша болса, сонша elif жазуға болады, шектеу жоқ. «else блогы міндетті емес» — егер барлық elif шарттары жалған болғанда ешқандай арнайы әрекет керек болмаса, else-ті жазбауға болады.

Неге elif деңгейі бір ғана? Себебі бұл — каскадты тармақталудың басты артықшылығы: барлық шарттар if-тің бір деңгейінде тұрады, кірістіру жасалмайды, сондықтан код жазылым ретімен оқуға оңай. Мысалы:

number = int(input())
if number == 1:
    print("Bir")
elif number == 2:
    print("Eki")
else:
    print("Baska san")

Мұнда үш нұсқа бар: 1, 2 және «басқа сан». Барлығы бір деңгейде, кірістірусіз жазылған. Бұл — кезекте тұрған сияқты: алдымен біріншіге сұрақ қойылады, «иә» десе — сол адаммен жұмыс жасалады, «жоқ» десе — кезектегі келесіге өтеді. Бір адам «иә» дегеннен кейін, қалған кезекке қарамайсың.

⚠️
Жиі кеткен қате: кейбір оқушылар elif мен else-ті шатастырып, екеуінде де шарт жазуға тырысады (else number == 5: деп жазып қояды). Бұл — синтаксистік қате. else-тің өзінің шарты болмайды — ол «барлық алдыңғы шарттар жалған болғанда» дегенді ғана білдіреді. Шарт қажет болса, ол міндетті түрде elif болуы керек.
❌ Қате
else number == 5:
    print("Bes")
✅ Дұрыс
elif number == 5:
    print("Bes")
Каскадты тармақталуды есепте қолдану

Мұғалім тақтада қалай шешер еді, дәл солай қадаммен жүрейік.

Деңгей: оңай
Не белгілі: Пернетақтадан енгізілген number саны.
Не табу керек: Сан 1 немесе 2 болса, оны сөзбен атау, басқа жағдайда "Baska san" деп хабарлау.
Неге дәл осы әдісті қолданамыз: мұнда үш нұсқа бар: «1», «2» немесе «басқа сан». Үш нұсқа — екіден көп болғандықтан, каскадты тармақталу (if-elif-else) ең қолайлы тәсіл.
1
Санды енгіземіз.
number = int(input())
2
Бірінші шартты тексереміз. Егер number дәл 1-ге тең болса, «Bir» шығады да, қалған тексерулер өткізіп жіберіледі.
if number == 1:
    print("Bir")
3
Екінші нұсқаны elif арқылы тексереміз — бұл тек бірінші шарт жалған болғанда тексеріледі.
elif number == 2:
    print("Eki")
4
Қалған барлық жағдайды else арқылы жабамыз — number 1-ге де, 2-ге де тең болмағанда орындалады.
else:
    print("Baska san")
Тексеру: number=1 — бірінші шарт ақиқат → «Bir», қалғаны тексерілмейді. number=2 — бірінші шарт жалған, екінші (elif) ақиқат → «Eki». number=100 — екі шарт та жалған → else іске қосылып, «Baska san» шығады. Жауабы: number=1 → "Bir"; number=2 → "Eki"; number=100 → "Baska san". Қорытынды идея: үш және одан көп нұсқа болғанда, оларды бірінен соң бірі elif арқылы тізбектей тексеру — кодты қысқа әрі түсінікті етеді, кірістірудің қажеті жоқ.
Қайсысын қашан қолдану керек?

Енді бір сұрақ туады: ширек анықтау есебінде неге кірістірілген if қолдандық, ал баға анықтау есебінде неге elif қолдандық? Екеуі де «бірнеше нұсқадан таңдау» емес пе?

Мәселе мынада — бұл екі есептің құрылымы мүлдем әртүрлі. Ширек есебінде екі тәуелсіз белгі бар (x таңбасы және y таңбасы), олардың комбинациясы нәтижені анықтайды. Ал баға есебінде бір ғана белгі бар (number мәні), оның әртүрлі нақты мәндерін кезекпен тексереміз. Дәл осы айырмашылық — қашан кірістіру, қашан каскад қолдану керектігін анықтайтын негізгі белгі.

if...elif...else құрылымы кірістірілген if-else-ден оқылуы оңай болғандықтан артық: кірістіруде шегініс саны артып, кодты түсіну қиындайды, ал elif барлық шартты бір деңгейде тексереді.

Бөлшектеп қарайық, қашан қайсысын қолдану керек: Кірістірілген if — екі немесе одан да көп тәуелсіз белгінің комбинациясын тексеру керек болғанда қолданылады (мыс. x пен y таңбасы бірге қарастырылады). Каскадты if-elif-else — бір ғана белгінің әртүрлі нақты мәндерін немесе диапазондарын кезекпен тексеру керек болғанда қолданылады (мыс. бір ғана number айнымалысының 1, 2 немесе басқа мәндері).

Неге elif жалпы алғанда оқуға оңайырақ деп саналады? Себебі кірістіруде әр жаңа деңгей қосымша шегініс қосады — 2 деңгей 8 бос орын, 3 деңгей 12 бос орын талап етеді. Бұл кодты экранда оңға қарай «жылжытып» жібереді, оны оқу қиындайды. Ал elif барлық нұсқаны бір тік сызықта, бір деңгейде ұстайды.

🧩 Кірістіру
Тәуелсіз белгілердің комбинациясы үшін (мыс. x пен y таңбасы).
🚪 Каскад (elif)
Бір белгінің бірнеше мәні үшін (мыс. number = 1, 2, 3...).

Кірістіру — бір үлкен жолдың ішінен тармақталатын кішкене сыңарлар сияқты (алдымен үлкен жолды таңда, содан кейін сол жолдың ішіндегі кіші жолды таңда). Ал каскад — бір үлкен жолда қатар тұрған бірнеше есік сияқты, әр есікке кезекпен барасың, біреуі ашылса — кіресің де, қалғанына бармайсың.

⚠️
Жиі кеткен қате: кейбір оқушылар әрдайым тек кірістірілген if қолданып, elif-ті мүлдем қолданбайды, тіпті бір ғана белгінің бірнеше мәнін тексеру керек жағдайда да. Нәтижесінде код керексіз тереңдеп, оқуы қиындайды. Есте сақта: бір белгінің бірнеше мәні болса — elif қолдан, тәуелсіз белгілердің комбинациясы болса — кірістір.
Кірістіру — «бірнеше тәуелсіз белгінің комбинациясы үшін», каскад (elif) — «бір белгінің бірнеше мәні үшін». Дұрыс тәсілді есептің құрылымына қарай таңда.
📝 ҰБТ-мен байланысы

Бұл тақырып ҰБТ-да жиі үш түрлі формада кездеседі: (1) екі немесе үш белгінің комбинациясы бойынша нәтиже анықтау (мыс. координаталық ширек); (2) бір айнымалының бірнеше мәні бойынша санатқа бөлу (мыс. баға, дәреже); (3) кірістірілген немесе каскадты кодтың нәтижесін «қолмен» орындап шығу (трассировка).

Есте сақтау керек негізгі ережелер: кірістіру — тәуелсіз белгілердің комбинациясы үшін; elif — бір белгінің бірнеше мәні үшін; ішкі if әрқашан сыртқыдан 4 бос орынға артық шегінеді; каскадта бірінші ақиқат шарт табылғаннан кейін, қалғаны тексерілмейді.

Ең жиі кеткен қателер:
!
екі деңгейлі кірістіруде шегіністі дұрыс есептей алмау
!
elif орнына бөлек, тәуелсіз if жазып, артық тексерулерге жол беру
!
else-ке шарт жазуға тырысу (else-тің меншікті шарты болмайды)
!
каскадты тармақталуда бірінші сәйкес келген шарттан кейін қалғандарының тексерілмейтінін ұмытып, дұрыс емес нәтиже күту
Сабақ қорытындысы
  • Кірістірілген тармақталу — бір шарттың ішіне тағы бір шарт орналастыру; тәуелсіз белгілердің комбинациясын тексеру керек болғанда қолданылады, әр деңгей шегіністі 4 бос орынға арттырады.
  • Каскадты тармақталу (if-elif-else) — бір белгінің бірнеше нақты мәнін бір деңгейде, тізбектей тексереді, біреуі табылған соң қалғаны тексерілмейді.
  • elif бірнеше рет қайталануы мүмкін, else блогы міндетті емес.
  • Екі тәсілдің де өз орны бар: есептің құрылымына қарай дұрысын таңдау маңызды.
Кірістірілген if
«Шарт ішіндегі шарт, тереңдеп бару» — тәуелсіз белгілердің комбинациясы үшін
Каскадты if-elif-else
«Бір қатарда тұрған бірнеше есік, кезекпен тексеру» — бір белгінің мәндері үшін