Лекция · 5.1

Есептерді компьютерде шешу

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

Мәселе деген не?

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

Дәл осындай сезім — бар білімің мен алдыңдағы тапсырманы шешу қажеттілігінің арасында алшақтық пайда болуы — информатикада да кездеседі. Сұрақ: бұл алшақтықты қалай дұрыс түсініп, оны шешуге қалай дайындалу керек?

Алдымен, мұндай жағдайды дәл атап алу керек. Білім мен тапсырманы шешу қажеттілігі арасындағы сәйкессіздіктен туындайтын қиындықты мәселелік жағдаят дейміз. Ал осы мәселелік жағдаятты дәл, ғылыми тілмен сипаттап жазғанда, оны мәселе дейміз.

Бар білім Шешу қажеттілігі алшақтық мәселелік жағдаят
Анықтама
Мәселе — мәселелік жағдаятты ғылыми түрде бейнелеу формасы. Мәселелік жағдаят — білім мен тапсырманы шешу қажеттілігі арасындағы сәйкессіздіктен туындайтын қиындық.

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

Неге бұл екеуін ажырату маңызды? Себебі мәселелік жағдаят — әлі «шикі», анық емес сезім, ал мәселе — соны нақтыланған, шешуге дайын түрге келтірілген сипаттама. Тек мәселе ретінде дұрыс қалыптастырылған қиындықты ғана компьютерде бағдарламалап шешуге болады. Мысалы: «маған бағдарлама керек, бірақ оны қалай жазу керектігін білмеймін» — бұл мәселелік жағдаят. Ал «берілген ax+b=0 теңдеуінің барлық мүмкін жағдайын ескере отырып шешетін бағдарлама керек» — бұл нақты тұжырымдалған мәселе.

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

⚠️
Жиі кеткен қате: көп оқушылар «есеп» (бұған дейін шешкен, дайын алгоритмі бар тапсырма) пен «мәселе» (әлі шешу жолы белгісіз, жаңа қиындық) ұғымдарын шатастырады. Есеп — мәселе дұрыс қалыптастырылып, формальданғаннан кейінгі нәтиже; ал мәселенің өзі — әлі шешу жолы анық емес бастапқы жағдай.
Есепті шешудің 5 кезеңі

Енді мәселе анық қалыптастырылды делік. Сұрақ туады: одан кейін не істейміз? Бірден кодты жазуға кірісе салуға бола ма?

Көп бастаушы бағдарламашылар дәл осы қатені жасайды — олар ойланбай-ақ бірден кодты теруге кіріседі, нәтижесінде орта жолда адасып қалады немесе қате логика жазып алады.

Дұрысы — жоспарлы түрде жүру. Информатикада есепті компьютерде шешу әрқашан белгілі бір кезеңдер тізбегінен өтеді, әр кезең алдыңғысының нәтижесіне сүйенеді. Бұл тізбекті білу — кез келген, тіпті ең күрделі есепті де реттілікпен шешуге көмектеседі.

Анықтама
Есепті компьютерде шешу 5 кезеңнен тұрады: 1) Мәселенің қойылуы (мақсат, бастапқы деректер, нәтиже формасын анықтау), 2) Формальдау (математикалық модель құру), 3) Алгоритмді құру (блок-сызба, кесте немесе сөздік түрінде), 4) Программалау (таңдалған тілде жазу), 5) Тестілеу және реттеу (қателерді тексеру және түзету).
1Мәселенің қойылуы
2Формальдау
3Алгоритмді құру
4Программалау
5Тестілеу және реттеу

Бес кезеңді бөлек қарастырайық: «1) Мәселенің қойылуы» — бұл кезеңде сен нақты не істеу керек екенін (мақсат), сенде қандай деректер бар екенін (бастапқы деректер) және нәтиже қандай түрде болу керек екенін (нәтиже формасы) анықтайсың. «2) Формальдау» — мәселені математикалық тілге аударасың: формулалар, шарттар, теңдеулер жазасың. «3) Алгоритмді құру» — формальданған модель негізінде нақты қадамдар тізбегін жасайсың — блок-сызба, кесте немесе сөздік түрінде көрсетуге болады. «4) Программалау» — дайын алгоритмді нақты бағдарламалау тілінде (мыс. Python) кодқа аударасың. «5) Тестілеу және реттеу» — дайын бағдарламаны әртүрлі деректермен тексеріп, қателерді тауып, түзетесің.

Неге дәл осы ретпен? Себебі әр кезең келесісінің негізі болады: мәселе анық қойылмаса, формальдау қате болады; формальдау қате болса, алгоритм қате құрылады; алгоритм қате болса, бағдарлама дұрыс жұмыс істемейді. Сондықтан кезеңдерді алып тастау немесе ретін бұзу — соңында үлкен қателерге әкеледі.

Мысалы: ax+b=0 теңдеуін шешетін бағдарлама жазу керек делік. 1-кезеңде — a мен b белгілі, x табу керек екенін анықтаймыз. 2-кезеңде — математикалық жағынан үш түрлі жағдай болатынын формальдаймыз (a≠0; a=0,b≠0; a=0,b=0). 3-кезеңде — осы үш жағдайды тексеретін алгоритм құрамыз. 4-кезеңде — оны Python кодына аударамыз. 5-кезеңде — әртүрлі a, b мәндерімен тексереміз.

Бес кезең — үй салуға ұқсас: алдымен не үшін, қанша бөлмелі үй керек екенін анықтайсың (мәселенің қойылуы), содан кейін сызба-жоба жасайсың (формальдау), құрылыс жоспарын құрасың (алгоритм), іс жүзінде құрылыс жұмысын бастайсың (программалау), ал соңында үйдің барлық бөлігі дұрыс тұрғанын тексересің (тестілеу және реттеу).

⚠️
Жиі кеткен қате: көп бастаушылар 1, 2, 3-кезеңдерді өткізіп жіберіп, бірден 4-кезеңге (программалау) асығады. Нәтижесінде код жазу барысында «бұл жағдайды қалай өңдеу керек еді?» деген сұрақтар туындайды, бағдарлама бірнеше рет қайта жазылады. Есте сақта: мәселені алдын ала формальдап, алгоритмін ойластырып алу — соңында уақытты үнемдейді, тіпті қарапайым көрінетін есепте де.
Тестілеу және реттеу

Бағдарламаны жазып бітірдік делік. Сұрақ: бағдарлама дұрыс жұмыс істейтінін қайдан білеміз? Тек бір рет іске қосып, нәтиже дұрыс болса, бағдарлама түгел дұрыс деп есептей аламыз ба?

Көбіне — жоқ. Бағдарлама бір деректермен дұрыс жұмыс істеуі мүмкін, бірақ басқа (мыс. шеткі немесе ерекше) деректермен қате беруі мүмкін. Сондықтан бағдарламаны бірнеше әртүрлі жағдаймен тексеру керек.

Дәл осы тексеру процесін тестілеу дейміз. Ал тестілеу барысында қате табылса, оны түзету процесін реттеу (дебаггинг) дейміз.

prog тест 1 тест 2 тест 3 қате!
Анықтама
Тестілеу — программаның немесе бөлігінің дұрыс жұмыс істеуін тексеру процесі (нәтижелерді күтілгенмен салыстыру). Реттеу (дебаггинг) — табылған қателерді жою процесі. Қателер алгоритмдік, грамматикалық немесе техникалық болуы мүмкін.

Бөлшектеп қарайық: «Тестілеу» — бағдарламаны әртүрлі деректермен іске қосып, нәтиженің күтілгенге сәйкес келетінін тексеру. «Реттеу (дебаггинг)» — тестілеу барысында табылған қатені нақты қай жерде, неліктен пайда болғанын анықтап, оны түзету. «Алгоритмдік қате» — есептің логикасы дұрыс құрылмаған (мыс. формула қате таңдалған, жағдай ескерілмей қалған). «Грамматикалық қате» — бағдарламалау тілінің синтаксис ережесі бұзылған (мыс. қос нүкте қойылмаған, шегініс қате). «Техникалық қате» — бағдарламаны орындау кезінде пайда болатын қате (мыс. нөлге бөлу, файл табылмауы).

Неге дәл осы үш түрге бөлінген? Себебі әр қате түрінің табу және түзету тәсілі әртүрлі: грамматикалық қатені Python өзі көрсетеді (SyntaxError), техникалық қате бағдарлама жұмыс істеп тұрғанда пайда болады (мыс. ZeroDivisionError), ал алгоритмдік қате — ең қиыны, себебі бағдарлама «бұзылмайды», тек қате нәтиже береді, сондықтан оны тек мұқият тестілеу арқылы ғана анықтауға болады.

Мысалы: ax+b=0 теңдеуін шешетін бағдарламада, егер a=0 жағдайын ескермей кетсек, бұл — алгоритмдік қате: бағдарлама жұмыс істейді, бірақ кейбір жағдайда қате немесе мүлдем нәтиже бермейді.

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

⚠️
Жиі кеткен қате: көп оқушылар бағдарламаны тек бір рет, «қарапайым» деректермен тексеріп, «жұмыс істейді» деп есептейді. Шеткі жағдайларды (мыс. нөл, теріс сан, бос мән) тексермей қалдырса, бағдарлама сол жағдайда дұрыс емес нәтиже беруі немесе мүлдем тоқтап қалуы мүмкін. Әрқашан әртүрлі, соның ішінде шеткі деректермен де тексеру керек.
Толық есеп: сызықтық теңдеу

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

Деңгей: қиын
Не белгілі: ax+b=0 сызықтық теңдеуі, a және b — кез келген сан.
Не табу керек: Теңдеудің барлық мүмкін жағдайын ескеретін шешу программасы.
1
Мәселенің қойылуы. Мақсат — x-тің мәнін табу. Бастапқы деректер — a мен b коэффициенттері (кез келген сан болуы мүмкін, тіпті нөл де). Нәтиже формасы — не x-тің сандық мәні, не «түбірі жоқ» хабарламасы, не «кез келген сан түбір болады» хабарламасы.
2
Формальдау. Математикалық тұрғыдан үш жағдай мүмкін екенін анықтаймыз. a≠0 болса, теңдеуді x туралы шешеміз: ax = -b, демек x = -b/a (бір ғана түбір). a=0 болса, теңдеу b=0 түріне айналады: егер b≠0 болса, теңдеу орындалмайды (түбір жоқ); ал b=0 болса, теңдеу кез келген x үшін орындалады (кез келген сан түбір болады).
3
Алгоритмді құру. Үш жағдайды кезекпен тексеретін тармақталған алгоритм құрамыз: алдымен a≠0 па, тексереміз; жалған болса, b≠0 па, тексереміз; ол да жалған болса, үшінші жағдай (a=0, b=0) орындалады.
4
Программалау. Назар аудар: «a != 0» шарты жалған болғанда, бұл автоматты түрде a=0 екенін білдіреді, сондықтан elif-те тек b-ні тексеру жеткілікті — a-ны қайта тексерудің қажеті жоқ.
print("Tendeydin koeffisientin engiz")
a = int(input())
b = int(input())
if a != 0:
    print("x=", -b/a)
elif b != 0:
    print("Tubiri jok")
else:
    print("Kez kelgen san")
5
Тестілеу және реттеу. Үш түрлі жағдайды тексереміз. a=5, b=7 (a≠0 жағдайы): x = -7/5 = -1.4. a=0, b=7 (a=0, b≠0 жағдайы): «Tubiri jok». a=0, b=0 (a=0, b=0 жағдайы): «Kez kelgen san». Үш жағдай да дұрыс өңделді, демек бағдарлама барлық мүмкіндікті қамтыды.
Жауабы: a=5,b=7 → x=-1.4; a=0,b=7 → "Tubiri jok"; a=0,b=0 → "Kez kelgen san". Қорытынды идея: бұл есептің кілті — кодты жазудан бұрын формальдау кезеңінде барлық мүмкін математикалық жағдайды (үш жағдайды) тауып алу. Егер формальдау кезеңінде a=0 жағдайын ескермей кетсек, бағдарлама b≠0 болғанда нөлге бөлу қатесін (ZeroDivisionError) берер еді — бұл дәл 5 кезеңнің неліктен маңызды екенін көрсетеді.
a ≠ 0 ? иә x = -b/a (a=5,b=7→-1.4) жоқ b ≠ 0 ? иә "Tubiri jok" (a=0,b=7) жоқ "Kez kelgen san"
📝 ҰБТ-мен байланысы

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

Есте сақтау керек негізгі ережелер: мәселе — шешу жолы әлі белгісіз қиындық, есеп — формальданған, шешуге дайын тапсырма; 5 кезең: қою → формальдау → алгоритм → программалау → тестілеу; параметрлі теңдеулерде a коэффициентінің нөл болу-болмауы әрқашан бөлек жағдай ретінде қаралуы керек.

Ең жиі кеткен қателер:
!
5 кезеңнің ретін шатастыру немесе бір кезеңді басқасымен алмастыру (мыс. формальдауды алгоритм құрумен шатастыру)
!
формальдау кезеңінде барлық мүмкін жағдайды (мыс. a=0 жағдайын) ескермей кету
!
тестілеуде тек «оңай» жағдайды тексеріп, шеткі жағдайларды (нөл, теріс сан) елемеу
Сабақ қорытындысы
  • Мәселелік жағдаят — біздің білім мен тапсырманы шешу қажеттілігі арасындағы алшақтық, ал мәселе — сол алшақтықты ғылыми тілмен дәл сипаттау.
  • Мәселе дұрыс қойылған соң, оны компьютерде шешу 5 кезеңнен өтеді: мәселенің қойылуы, формальдау, алгоритмді құру, программалау, тестілеу және реттеу.
  • Әр кезең келесісінің іргетасы болады, сондықтан ретін бұзуға немесе кезеңді өткізіп жіберуге болмайды.
  • Бағдарлама дайын болғаннан кейін де жұмыс бітпейді — оны әртүрлі деректермен тестілеп, табылған қателерді (алгоритмдік, грамматикалық немесе техникалық) реттеу қажет.
Мәселе
«Нақты қойылған сұрақ» — шешу жолы әлі белгісіз қиындықтың ғылыми сипаты
5 кезең
Қою → формальдау → алгоритм → программалау → тестілеу/реттеу
Тестілеу/реттеу
«Нәтиженің шынымен дұрыс екенін дәлелдеу» — алгоритмдік, грамматикалық, техникалық қателерді табу