Күрделі шарттар
Концертке кіру үшін екі шарт орындалуы керек делік: жасың 18-ден асуы керек ЖӘНЕ қолыңда билет болуы керек. Тек біреуі жеткіліксіз — екеуі де бірге орындалуы тиіс. Дәл осы сұраққа жауап беретін тақырыппен танысамыз — күрделі (құрамды) шарттар: and, or, not логикалық операторлары арқылы бірнеше шартты бір тұтас шартқа біріктіру. Бұл тақырып ҰБТ-да аса жиі кездеседі: жас санатын анықтау, координаталық ширекті and арқылы табу, бірнеше санның арасында белгілі бір қасиет бар-жоғын тексеру — барлығы дәл осы тақырыпқа негізделген.
Өткен сабақта координаталық ширекті анықтау үшін кірістірілген if қолдандық: алдымен x таңбасын тексеріп, содан кейін оның ішінде y таңбасын тексердік. Бұл дұрыс жұмыс істеді, бірақ ойлап көрсек — біз шын мәнінде нені тексеріп жатырмыз? «x оң ЖӘНЕ y оң» деген бір тұтас ойды!
Сұрақ туады: екі шартты («x > 0» және «y > 0») кірістірудің орнына, бір жолда, бір тұтас шарт ретінде жазуға бола ма? Жауабы — иә, болады. Python-да бірнеше қарапайым шартты логикалық операторлар (and, or, not) арқылы біріктіріп, бір тұтас шарт жасауға болады. Осындай, бірнеше қарапайым шарттан құралған шартты күрделі (құрамды) шарт дейміз.
Күрделі (құрамды) шарт — логикалық амалдар (
and, or, not) көмегімен бір тұтас шартқа біріктірілген бірнеше қарапайым шарт. Қарапайым шарт екі мән арасындағы салыстырудан тұрады (мыс. x >= 5).
Анықтаманы бөлшектеп көрейік: «Логикалық амалдар (and, or, not)» — бұл операторлар шарттарды бір-бірімен «жалғайтын» арнайы сөздер, олар математикадағы +, -, × сияқты, бірақ сандар емес, рас/жалған мәндермен жұмыс істейді. «Бір тұтас шартқа біріктірілген» — нәтижесінде бірнеше шарт болса да, Python оларды бір ғана шарт ретінде қарастырады, нәтиже жалғыз True немесе False болады. «Қарапайым шарт» — бұл бұған дейін көрген, бір ғана салыстырудан тұратын шарт (мыс. x > 0), ол күрделі шарттың «кірпіші» болып табылады.
Неге дәл осылай жасалған? Себебі көптеген нақты есептерде шешім бір ғана белгіге емес, бірнеше белгінің бірлесіп орындалуына немесе кем дегенде біреуінің орындалуына байланысты болады. Мысалы: x > 0 and y > 0 — бұл бір тұтас шарт, ол тек x та, y да оң болғанда ғана True болады. Ал x > 0 or y > 0 — бұл шарт x пен y-дың кем дегенде біреуі оң болса жеткілікті, True болады.
Бұл — екі құлпы бар сейфке ұқсайды: сейфті ашу үшін екі кілт ТЕ керек (and логикасы). Ал кейде керісінше — үйге кіру үшін алдыңғы есік НЕМЕСЕ артқы есік ашық болса жеткілікті (or логикасы), екеуі бірге ашық болуы шарт емес.
or операторы олай емес — екі шарт та ақиқат болса да, нәтиже сонда да True болады. Бұл — логикадағы or мен күнделікті тілдегі «немесе» арасындағы маңызды айырмашылық.Логикалық операторлардың нақты қалай жұмыс істейтінін көру үшін, барлық мүмкін жағдайды бір кестеге жинап көрейік. Бұл — математикадағы көбейту кестесі сияқты, бірақ сандар емес, рас/жалғанмен жұмыс істейді. x пен y — екі бөлек шарттың нәтижесі (0 — жалған, 1 — рас); ал «x and y», «x or y», «not x» бағандары — сол екі шартты әртүрлі оператормен біріктіргендегі нәтиже.
| x | y | x and y | x or y | not x |
|---|---|---|---|---|
| 0 | 0 | 0 | 0 | 1 |
| 0 | 1 | 0 | 1 | 1 |
| 1 | 0 | 0 | 1 | 0 |
| 1 | 1 | 1 | 1 | 0 |
and — логикалық көбейту (конъюнкция, «және»), or — логикалық қосу (дизъюнкция, «немесе»), not — логикалық теріске шығару (инверсия, «емес»).
Кестені қарапайым сөзбен қайталайық: and (және) — нәтиже тек екеуі де рас болғанда ғана рас болады. or (немесе) — нәтиже екеуінің кем дегенде біреуі рас болса жеткілікті рас болады. not (емес) — берілген мәнді керісінше айналдырады: рас болса — жалғанға, жалған болса — расқа.
Неге and «көбейту» деп аталады? Себебі 0 мен 1-ді көбейту ережесімен дәл сәйкес келеді: 1×1=1, ал қалғанының бәрі 0. Ал or «қосу» деп аталады, себебі логикалық тұрғыдан кем дегенде бір «бірдің» болуы жеткілікті болатын жағдайды білдіреді. Мысалы: x = (5 > 3) — бұл рас (1), y = (2 > 10) — бұл жалған (0). x and y — рас and жалған = жалған (0). x or y — рас or жалған = рас (1), себебі кем дегенде біреуі рас.
Екі шамды елестет: and — екі шам да жанғанда ғана бөлме жарық болады (екеуі тізбектей қосылған сияқты). or — кез келген біреуі жанса да бөлме жарық болады (екеуі параллель қосылған сияқты). not — шамды керісінше айналдыратын қосқыш, жанып тұрса өшіреді, өшіп тұрса жағады.
and мен or-дың нәтижесін шатастырады, әсіресе екеуі де жалған болатын жағдайды дұрыс есептей алмайды. Есте сақта: and — ең «талапшыл» (екеуі де керек), or — ең «жеңіл» (біреуі жетеді). Сондықтан бірдей екі шартта and нәтижесі әрқашан or нәтижесінен қатаңырақ (азырақ жағдайда True) болады.Математика сабағында «0 < a < 10» деген жазуды көрген боларсың — бұл «a нөлден үлкен, ЖӘНЕ a онға кіші» дегенді білдіреді. Сұрақ: Python-да да дәл осылай қысқа жазуға бола ма, әлде міндетті түрде «0 < a and a < 10» деп ұзақ жазу керек пе? Қызығы — көптеген бағдарламалау тілдерінде мұндай қысқа жазу мүмкін емес. Бірақ Python — бұл жағынан ерекше тіл.
Python математикадағыдай жазуға рұқсат береді: 0 < a < b деп жазсаң, Python мұны автоматты түрде 0 < a and a < b деп түсінеді. Бұл — Python-ның ерекше, ыңғайлы мүмкіндігі, оны тізбектелген салыстыру дейміз.
Python тілінің ерекшелігі — салыстыру амалдарының қысқартылған жазылуы:
if 0 < a < b жазуы if a > 0 and a < b-мен бірдей нәтиже береді.
Бөлшектеп қарайық: «Қысқартылған жазылуы» — бір айнымалыны екі жақтан салыстыру бір жолда, екі рет жазбай-ақ көрсетіледі. «0 < a < b» — бұл жазу «a саны 0-ден де үлкен, b-дан да кіші» дегенді білдіреді, яғни a екі шектің арасында жатыр. «a > 0 and a < b» — бұл толық, ұзақ жазылу түрі, нәтижесі қысқа жазумен дәл бірдей.
Неге бұл мүмкін? Себебі Python ішінде осындай тізбектелген салыстыруды автоматты түрде екі бөлек салыстыруға бөліп, оларды and арқылы біріктіреді. Мысалы: 3 <= old < 6 деген жазу — old санының 3-тен кем еместігін ЖӘНЕ 6-дан кем екенін бір мезетте тексереді. Бұл, мысалы, жас санатын анықтауда («балабақша жасы») өте ыңғайлы қолданылады.
Бұл — екі қоршаудың арасында тұрған жануарды сипаттауға ұқсас: «жануар бірінші қоршаудан да әрі, екінші қоршаудан да бері тұр» дегенді бір сөйлеммен айтасың, екі бөлек сөйлемге бөлмейсің.
0 < a < b деген жазу мүлдем басқа (қате) нәтиже беруі мүмкін.Мұғалім тақтада қалай шешер еді, дәл солай қадаммен жүрейік.
old = int(input("Jasynyzdy engiziniz: "))
if 3 <= old < 6: print("Balabaksha")
elif 6 <= old < 10: print("Bastayysh mektep") elif 10 <= old < 15: print("Orta mektep") elif 15 <= old: print("Jogary mektep")
x = int(input()) y = int(input())
if x > 0 and y > 0: print("Birinshi toksan") elif x < 0 and y > 0: print("Ekinshi toksan") elif x < 0 and y < 0: print("Ushinshi toksan") else: print("Tortinshi toksan")
Үш санды енгізу керек делік — a, b, c. Бұған дейін біз әр санды бөлек жолмен сұрап едік: a = int(input()), содан кейін b = int(input()), содан кейін c = int(input()). Бұл жұмыс істейді, бірақ үш рет Enter басу керек.
Сұрақ: үш санды бір ғана жолда, бос орынмен бөліп, бір рет Enter басып енгізуге бола ма? Жауабы — иә, болады. Бұл үшін бұған дейін файлдан сан оқығанда көрген split() әдісін, енді input()-пен бірге қолданамыз. input().split() пернетақтадан енгізілген бір жолды бос орын бойынша бөлек бөліктерге бөледі, ал map(int, ...) сол бөліктердің әрқайсысын санға айналдырады.
Бір жолдан бірнеше мән оқу үшін
map() функциясы split()-пен бірге қолданылады: a, b, c = map(int, input().split()). Бұл әдіс пернетақтадан 3 санды бір рет бос орынмен бөліп енгізуге мүмкіндік береді.
Бөлшектеп қарайық: «input().split()» — input() пернетақтадан бір тұтас жолды оқиды (мыс. «4 10 -4»), ал split() оны бос орын бойынша бөлек бөліктерге бөліп, тізім қайтарады (["4", "10", "-4"]). «map(int, ...)» — тізімдегі әр элементті (олар әлі де жол түрінде) int() функциясы арқылы санға айналдырады. «a, b, c = ...» — нәтижесінде шыққан үш санды бірден үш айнымалыға бөліп тарату.
Неге дәл осылай жасалады? Себебі input() әрқашан тек бір тұтас жол қайтарады, ал бізге сол жолдың ішінен бөлек сандар керек. Мысалы: пайдаланушы «4 10 -4» деп енгізсе, input().split() нәтижесі — ["4", "10", "-4"]. map(int, ...) нәтижесі — әр элемент санға айналады. a, b, c = ... жолынан кейін a=4, b=10, c=-4 болады.
Бұл — бір қапшықты үш бөлек себетке бөліп төгуге ұқсас: алдымен қапшықтың ішіндегісін бос орындар бойынша бөлек бөліктерге бөлесің (split), содан кейін әр бөлікті дұрыс «формаға» (санға) келтіресің (map int), соңында әрбірін өз себетіне (a, b, c айнымалыларына) саласың.
a, b, c = map(int, input().split()) деп жазып, тек екі сан енгізеді. Бұл — ValueError қатесіне әкеледі, өйткені Python үш мән күтіп тұр, ал тек екеуі келді. Енгізілетін сандар саны мен айнымалылар саны әрқашан дәл сәйкес келуі керек.Мұғалім тақтада қалай шешер еді, дәл солай қадаммен жүрейік.
a, b, c = map(int, input().split())
if (a+b==0) or (a+c==0) or (b+c==0): print('ia') else: print('jog')
Бұл тақырып ҰБТ-да жиі үш түрлі формада кездеседі: (1) бірнеше шартты and/or арқылы біріктіріп, нәтижені анықтау; (2) тізбектелген салыстыруды (a < x < b) қолданып диапазонды тексеру; (3) бірнеше мәнді бір жолдан map() пен split() арқылы оқып, оларды күрделі шартпен өңдеу.
Есте сақтау керек негізгі ережелер: and — барлығы рас болғанда ғана рас; or — кем дегенде біреуі рас болса жеткілікті; not — мәнді керісінше айналдырады; 0 < a < b жазуы a > 0 and a < b-мен бірдей; map(int, input().split()) — бір жолдан бірнеше санды оқу үшін қолданылады.
and мен or-дың логикасын шатастыруor операторымен шатастыруmap(int, input().split()) қолданғанда айнымалылар саны мен енгізілген сандар санын сәйкестендірмеу- Күрделі шарт — бірнеше қарапайым шартты логикалық операторлар (
and,or,not) арқылы бір тұтас шартқа біріктіру. and— барлық шарт рас болғанда ғана рас,or— кем дегенде біреуі рас болса жеткілікті,not— мәнді теріске айналдырады.- Тізбектелген салыстыру (
0 < a < b) — екі шартты бір жолда қысқа жазуға мүмкіндік береді (тек Python-да). - Бірнеше мәнді бір рет енгізу үшін
map()пенsplit()бірге қолданылады:a, b, c = map(int, input().split()).