Основы и методология программирования, 1 модуль ПМИ ФКН ВШЭ Михаил Густокашин, 2016 [email protected] 2 Оглавление 1 2 Ввод-вывод, простые типы данных 7 1.1 Êàê èçó÷àòü ïðîãðàììèðîâàíèå . . . . . . . . . . . . . . . . . . . . . . . . 1.2 ßçûê Python . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1.3 Îðãàíèçàöèÿ êóðñà, âûñòàâëåíèå îöåíîê è òðåáîâàíèÿ . . . . . . . . . . . 1.4 Ïðîãðàììíîå îáåñïå÷åíèå . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1.5 Òèïû äàííûõ è ôóíêöèÿ âûâîäà . . . . . . . . . . . . . . . . . . . . . . . 1.6 Ïåðåìåííûå . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1.7 Àðèôìåòè÷åñêèå âûðàæåíèÿ . . . . . . . . . . . . . . . . . . . . . . . . . . 1.8 Îïåðàöèè íàä ñòðîêàìè . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1.9 ×òåíèå äàííûõ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1.10 Ïðèìåðû ðåøåíèÿ çàäà÷ . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1.11 Êàê ïåðåìåííûå óñòðîåíû âíóòðè . . . . . . . . . . . . . . . . . . . . . . . 1.12 Êàê ðåøàòü çàäà÷è . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7 7 8 9 9 10 11 12 12 13 14 15 Логический тип данных, условный оператор, цикл while, вещественные числа 17 2.1 2.2 2.3 2.4 2.5 2.6 2.7 2.8 2.9 3 Ëîãè÷åñêèé òèï äàííûõ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Ëîãè÷åñêèå îïåðàöèè . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Âûâîä è ïðåîáðàçîâàíèå ëîãè÷åñêèõ âûðàæåíèé . . . . . . . . . . . . . . Óñëîâíûé îïåðàòîð . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Âëîæåííûé óñëîâíûé îïåðàòîð . . . . . . . . . . . . . . . . . . . . . . . . Êîíñòðóêöèÿ èíà÷å-åñëè . . . . . . . . . . . . . . . . . . . . . . . . . . . Öèêë while . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Èíñòðóêöèè óïðàâëåíèÿ öèêëîì . . . . . . . . . . . . . . . . . . . . . . . . Îñíîâû ðàáîòû ñ âåùåñòâåííûìè ÷èñëàìè . . . . . . . . . . . . . . . . . . 17 18 19 19 20 20 21 22 23 Вещественные числа и строки 25 3.1 3.2 3.3 3.4 3.5 3.6 3.7 3.8 25 25 26 27 28 29 30 30 Âåùåñòâåííûå ÷èñëà â ïàìÿòè êîìïüþòåðà . . . . . . . . . . . . . . . . . . Çàïèñü, ââîä è âûâîä âåùåñòâåííûõ ÷èñåë . . . . . . . . . . . . . . . . . . Ïðîáëåìû âåùåñòâåííûõ ÷èñåë . . . . . . . . . . . . . . . . . . . . . . . . Îêðóãëåíèå âåùåñòâåííûõ ÷èñåë . . . . . . . . . . . . . . . . . . . . . . . . Ïîëåçíûå ôóíêöèè áèáëèîòåêè math . . . . . . . . . . . . . . . . . . . . . Ñðåçû ñòðîê . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Ìåòîäû nd è rnd . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Ìåòîäû replace è count . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3 4 ОГЛАВЛЕНИЕ 4 Функции и рекурсия 33 5 Кортежи, цикл for, списки 41 6 Сортировка, лямбда-функции, именованные параметры 49 7 Множества, словари, полезные методы для строк 59 8 Элементы функционального программирования 67 4.1 4.2 4.3 4.4 4.5 4.6 4.7 4.8 5.1 5.2 5.3 5.4 5.5 5.6 5.7 5.8 5.9 6.1 6.2 6.3 6.4 6.5 6.6 6.7 6.8 6.9 7.1 7.2 7.3 7.4 7.5 7.6 7.7 7.8 8.1 8.2 8.3 8.4 8.5 Ñîçäàíèå ïðîñòîé ôóíêöèè . . . . . . . . . . . . . . . . . . . . . . . . . . . Âûçîâû ôóíêöèé èç ôóíêöèè . . . . . . . . . . . . . . . . . . . . . . . . . Íåñêîëüêî return â ôóíêöèè . . . . . . . . . . . . . . . . . . . . . . . . . . Ëîêàëüíûå è ãëîáàëüíûå ïåðåìåííûå . . . . . . . . . . . . . . . . . . . . . Âîçâðàò íåñêîëüêèõ çíà÷åíèé ôóíêöèåé . . . . . . . . . . . . . . . . . . . Âîçâðàò ëîãè÷åñêèõ çíà÷åíèé . . . . . . . . . . . . . . . . . . . . . . . . . Ìåõàíèçì çàïóñêà ôóíêöèé . . . . . . . . . . . . . . . . . . . . . . . . . . Ðåêóðñèÿ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Êîðòåæè . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Ðàáîòà ñ êîðòåæàìè . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Ôóíêöèÿ range . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Öèêë for . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Ñïèñêè . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Èçìåíåíèå ñïèñêîâ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Ìåòîäû split è join, ôóíêöèÿ map . . . . . . . . . . . . . . . . . . . . . . . Äðóãèå ïîëåçíûå ìåòîäû äëÿ ðàáîòû ñî ñïèñêàìè . . . . . . . . . . . . . Ïî÷åìó ñîçäàíèå íîâîãî ëó÷øå óäàëåíèÿ . . . . . . . . . . . . . . . . . . . Ñîðòèðîâêà ñïèñêîâ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Ñðàâíåíèå êîðòåæåé è ñïèñêîâ . . . . . . . . . . . . . . . . . . . . . . . . . Ïàðàìåòð key â ôóíêöèè sort . . . . . . . . . . . . . . . . . . . . . . . . . ¾Ñòðóêòóðû¿ â Ïèòîíå . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Ëÿìáäà-ôóíêöèè . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Èìåíîâàííûå ïàðàìåòðû è íåîïðåäåëåííîå ÷èñëî ïàðàìåòðîâ . . . . . . . ×òåíèå äî êîíöà ââîäà . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Ñîðòèðîâêà ïîäñ÷åòîì . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Ñâÿçü çàäà÷ ïîèñêà è ñîðòèðîâêè . . . . . . . . . . . . . . . . . . . . . . . Ìíîæåñòâà è õåø-ôóíêöèè . . . . . . . . . . . . . . . . . . . . . . . . . . . Ñîçäàíèå ìíîæåñòâ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Ðàáîòà ñ ýëåìåíòàìè ìíîæåñòâ . . . . . . . . . . . . . . . . . . . . . . . . . Ãðóïïîâûå îïåðàöèè íàä ìíîæåñòâàìè . . . . . . . . . . . . . . . . . . . . Ñëîâàðè . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Êîãäà íóæíî èñïîëüçîâàòü ñëîâàðè . . . . . . . . . . . . . . . . . . . . . . Ïîëåçíûå ìåòîäû ñòðîê . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Ïðèìåð ðåøåíèÿ ñëîæíîé çàäà÷è íà ñëîâàðè . . . . . . . . . . . . . . . . Ïàðàäèãìû ïðîãðàììèðîâàíèÿ . . . . . . . . . . . . . . . . . . . . . . . . . Ôóíêöèîíàëüíîå ïðîãðàììèðîâàíèå . . . . . . . . . . . . . . . . . . . . . . Èòåðàòîðû è ãåíåðàòîðû . . . . . . . . . . . . . . . . . . . . . . . . . . . . Âñòðîåííûå ôóíêöèè äëÿ ðàáîòû ñ ïîñëåäîâàòåëüíîñòÿìè . . . . . . . . . Ãåíåðàöèÿ êîìáèíàòîðíûõ îáúåêòîâ itertools . . . . . . . . . . . . . . . . . 33 34 35 35 37 37 38 38 41 41 42 43 44 44 46 46 47 49 50 51 52 53 54 55 56 57 59 60 61 62 62 64 64 65 67 68 69 70 71 ОГЛАВЛЕНИЕ 8.6 9 partial, reduce, accumulate . . . . . . . . . . . . . . . . . . . . . . . . . . . . Объектно-ориентированное программирование 9.1 9.2 9.3 9.4 9.5 9.6 9.7 9.8 9.9 Îáúåêòíî-îðèåíòèðîâàííîå ïðîãðàììèðîâàíèå . . . . . . . . . . . . . . . Èíêàïñóëÿöèÿ è êîíñòðóêòîðû . . . . . . . . . . . . . . . . . . . . . . . . . Îïðåäåëåíèå ìåòîäîâ è ñòàíäàðòíûå ôóíêöèè . . . . . . . . . . . . . . . . Ïåðåîïðåäåëåíèå îïåðàòîðîâ . . . . . . . . . . . . . . . . . . . . . . . . . . Ïðîâåðêà êëàññà îáúåêòà . . . . . . . . . . . . . . . . . . . . . . . . . . . . Îáðàáîòêà îøèáîê . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Íàñëåäîâàíèå è ïîëèìîðôèçì . . . . . . . . . . . . . . . . . . . . . . . . . Ïåðåîïðåäåëåíèå ìåòîäîâ . . . . . . . . . . . . . . . . . . . . . . . . . . . . Ïðîåêòèðîâàíèå ñòðóêòóðû êëàññîâ . . . . . . . . . . . . . . . . . . . . . . 5 71 73 73 74 75 75 76 78 79 81 82 6 ОГЛАВЛЕНИЕ Лекция 1 Ввод-вывод, простые типы данных 1.1 Как изучать программирование Ïî íàøåìó óáåæäåíèþ åäèíñòâåííûé ñïîñîá íàó÷èòüñÿ ïðîãðàììèðîâàòü ýòî ìíîãî ïðîãðàììèðîâàòü. Âîçìîæíî, âû ñëûøàëè ìíåíèå, ÷òî íàó÷èòü ïðîãðàììèðîâàíèþ íåâîçìîæíî è åäèíñòâåííûé ñïîñîá ýòî ñàìîîáðàçîâàíèå. Òàê ãîâîðÿò ëþäè, êîòîðûå íå óìåþò ó÷èòü ïðîãðàììèðîâàíèþ. Ìû óìååì ó÷èòü ïðîãðàììèðîâàíèþ. Íàø êóðñ áóäåò ñîäåðæàòü â ñåáå áîëüøîå ÷èñëî íåñëîæíûõ ïðàêòè÷åñêèõ çàäà÷, ÷òîáû ¾íàáèòü ðóêó¿.  ëåêöèîííûõ ìàòåðèàëàõ òàêæå áóäóò ñîäåðæàòüñÿ ìàòåðèàëû äëÿ áîëåå ãëóáîêîãî ïîíèìàíèÿ ïðîèñõîäÿùèõ ïðîöåññîâ. Ñäà÷à çàäà÷ çàéìåò äîñòàòî÷íî áîëüøîå âðåìÿ è íåêîòîðûå èç íèõ äåéñòâèòåëüíî ñëîæíûå, íî ÷åðåç ýòîò êóðñ ïðîøëî óæå áîëüøîå êîëè÷åñòâî ëþäåé è åäèíñòâåííàÿ ïðè÷èíà, ïî êîòîðîé ìàòåìàòè÷åñêè îäàðåííûå ëþäè íå ñìîãëè ïðîéòè åãî ýòî èõ ëåíü. Ìû áóäåì ïîìîãàòü âàì áîðîòüñÿ ñ ëåíüþ. 1.2 Язык Python ßçûê Python (ïî-ðóññêè ìîæíî ïðîèçíîñèòü êàê Ïàéòîí èëè Ïèòîí) ïîÿâèëñÿ â 1991 ãîäó è áûë ðàçðàáîòàí Ãâèäà âàí Ðîññóìîì. ßçûê íàçâàí â ÷åñòü øîó ¾Ëåòàþùèé öèðê Ìîíòè Ïàéòîíà¿. Îäíà èç ãëàâíûõ öåëåé ðàçðàáîò÷èêîâ ñäåëàòü ÿçûê çàáàâíûì äëÿ èñïîëüçîâàíèÿ. Ñåé÷àñ Ïèòîí ðåãóëÿðíî âõîäèò â äåñÿòêó íàèáîëåå ïîïóëÿðíûõ ÿçûêîâ è õîðîøî ïîäõîäèò äëÿ ðåøåíèÿ øèðîêîãî êëàññà çàäà÷: îáó÷åíèå ïðîãðàììèðîâàíèþ, ñêðèïòû äëÿ îáðàáîòêè äàííûõ, ìàøèííîå îáó÷åíèå, ñåðâåðíàÿ âåá-ðàçðàáîòêà è ìíîãîå äðóãîå. Áîëüøèíñòâó èç âàñ ÿçûê Ïèòîí ïîòðåáóåòñÿ äëÿ íàïèñàíèÿ ïðîåêòîâ è â ðÿäå ïðåäìåòîâ òðåòüåãî êóðñà, à òàêæå â ïîâñåäíåâíîì áûòó äëÿ àâòîìàòèçàöèè çàäà÷ îáðàáîòêè äàííûõ. Ìû áóäåì èçó÷àòü ÿçûê Ïèòîí òðåòüåé âåðñèè. 7 8 ЛЕКЦИЯ 1. 1.3 ВВОД-ВЫВОД, ПРОСТЫЕ ТИПЫ ДАННЫХ Организация курса, выставление оценок и требования Ïðîäîëæèòåëüíîñòü êóðñà 1 ìîäóëü. Îöåíêè âûñòàâëÿþòñÿ çà âûïîëíåíèå äîìàøíèõ çàäàíèé è ýêçàìåí. Íà êàæäîì ñåìèíàðñêîì çàíÿòèè âàì áóäåò ïðåäëîæåíî íîâîå çàäàíèå, êîòîðîå îöåíèâàåòñÿ ìàêñèìóì â 10 áàëëîâ (ìîæíî ïîëó÷èòü +2 äîïîëíèòåëüíûõ áàëëà ðåøàÿ çàäà÷è ¾ñî çâåçäî÷êîé¿). Ðàç â äâå íåäåëè áóäåò ïðîâîäèòñÿ î÷íàÿ çàùèòà äîìàøíèõ çàäàíèé â âèäå êîíòðîëüíîé ðàáîòû ïî ðåøåíèþ ïðàêòè÷åñêèõ çàäà÷, ïðè ýòîì çàäà÷è áóäóò ïîõîæè íà çàäà÷è èç ÄÇ. Ïëîõîå íàïèñàíèå êîíòðîëüíîé ðàáîòû ñíèæàåò îöåíêó çà âåñü áëîê äîìàøíèõ çàäàíèé. Íà ðåøåíèå çàäà÷ ÄÇ îòâîäèòñÿ îäíà íåäåëÿ (168 ÷àñîâ) ñ ìîìåíòà íà÷àëà ñåìèíàðà ïî ñîîòâåòñòâóþùåé òåìå.  òå÷åíèå åùå îäíîé íåäåëè ìîæíî äîñäàòü çàäàíèÿ ñ êîýôôèöèåíòîì 0.5. Çàòåì çàäàíèÿ íå îöåíèâàþòñÿ. Óâàæèòåëüíîé ïðè÷èíîé äëÿ íåâûïîëíåíèÿ ÄÇ ÿâëÿåòñÿ äëèòåëüíàÿ íåâîçìîæíîñòü ïðîãðàììèðîâàòü, íàïðèìåð, êîìà. Òàêèå âîïðîñû ðåøàþòñÿ èíäèâèäóàëüíî ñ ïðåïîäàâàòåëåì ñåìèíàðñêèõ çàíÿòèé. Âñå çàäà÷è ÄÇ, êîíòðîëüíûõ ðàáîò è ýêçàìåíà ïðîâåðÿþòñÿ àâòîìàòè÷åñêè è âðó÷íóþ. Ïðîâåðêà ñîñòîèò èç íåñêîëüêèõ ýòàïîâ. Âî-ïåðâûõ, çàäà÷à ïðîâåðÿåòñÿ íà çàðàíåå ïîäãîòîâëåííîì íàáîðå òåñòîâ, íà êîòîðûõ âàøà ïðîãðàììà äîëæíà âûäàâàòü ïðàâèëüíûé îòâåò. Âî-âòîðûõ, êîä ïðîâåðÿåòñÿ íà ñîîòâåòñòâèå ñòàíäàðòàì îôîðìëåíèÿ PEP8 è äðóãèì òðåáîâàíèÿì ïðåäúÿâëåìûõ ïðåïîäàâàòåëÿìè. Â-òðåòüèõ, ïðîãðàììà ïðîõîäèò code review, ãäå âàø ïðåïîäàâàòåëü èëè àññèñòåíò ìîæåò äàòü âàì ðåêîìåíäàöèè ïî èñïðàâëåíèþ ïëîõèõ, íî íå ôîðìàëèçóåìûõ ÿâíî âåùåé. Â-÷åòâåðòûõ, îñóùåñòâëÿåòñÿ ïðîâåðêà íà ñïèñûâàíèå. Çàäà÷à ñ÷èòàåòñÿ ñäàííîé, òîëüêî åñëè îíà ïðîøëà âñå ÷åòûðå ýòàïà ïðîâåðêè. ×àñòè÷íûõ îöåíîê çà çàäà÷ó íå ïðåäóñìòîðåíî.  ñîîòâåòñòâèå ñî âíóòðåííèìè íîðìàòèâíûìè äîêóìåíòàìè â îòíîøåíèå ñòóäåíòîâ, óëè÷åííûõ â ñïèñûâàíèè èëè äâîéíîé ñäà÷å (ñîâìåñòíîå âûïîëíåíèå ðàáîòû) áóäóò ïðèìåíåíû ñëåäóþùèå ñàíêöèè: 1. ïðåäóïðåæäåíèå è îáíóëåíèå áàëëà çà âñþ ðàáîòó (äàæå åñëè ñïèñàíà îäíà çàäà÷à), â ñëó÷àå ñïèñûâàíèÿ íà êîíòðîëüíîé ðàáîòå îáíóëåíèå îöåíîê çà âåñü áëîê äîìàøíèõ ðàáîò 2. âûãîâîð 3. îò÷èñëåíèå Íàëè÷èå âûãîâîðà íå òîëüêî ñòàâèò ñòóäåíòà â ðèñêîâàííóþ ñèòóàöèþ áûòü îò÷èñëåííûì çà ëþáîå íàðóøåíèå (íàïðèìåð, çà êóðåíèå âîçëå êîðïóñà), íî è ìåøàåò ïîëó÷åíèþ ïîâûøåííûõ ñòèïåíäèé, ïåðåâîäó íà äðóãóþ ñïåöèàëüíîñòü è ìíîãîå äðóãîå.  ñëó÷àå ïîäëîãà (âûïîëíåíèÿ íåíóæíîé äëÿ ñåáÿ ðàáîòû çà äðóãîãî ÷åëîâåêà), íàïðèìåð, ðåøåíèÿ êîíòðîëüíîé ðàáîòû ÷åëîâåêó, ó êîòîðîãî îíà ïðîèñõîäèò â äðóãîå âðåìÿ, ïðèìåíÿþòñÿ ñëåäóþùèé ñàíêöèè (íîìåð ýòî êîëè÷åñòâî âûÿâëåííûõ íàðóøåíèé): 1. îò÷èñëåíèå Îáðàòèòå âíèìàíèå, ÷òî óêàçàííûå ñàíêöèè ïðèìåíÿþòñÿ ê îáîèì ëþäÿì: êàê ê ñïèñàâøèì, òàê è ê äàâøèì ñïèñàòü. 1.4. ПРОГРАММНОЕ ОБЕСПЕЧЕНИЕ 9 Ïðè ýòîì ìû êðàéíå ïîëîæèòåëüíî îòíîñèìñÿ ê êîíñòðóêòèâíîìó îáùåíèþ è âçàèìîïîìîùè ìåæäó ñòóäåíòàìè, âåäü êîíñóëüòàöèþ îò ïðåïîäàâàòåëÿ èëè àññèñòåíòà íå âñåãäà ìîæíî ïîëó÷èòü ñòîëü æå áûñòðî è èñ÷åðïûâàþùå. Ïðè îêàçàíèè ïîìîùè îòñòàþùèì òîâàðèùàì ñîáëþäàéòå ñëåäóþùèå ïðàâèëà: 1. íå ïîêàçûâàòü/ïåðåñûëàòü êîä ñâîèõ ðåøåíèé 2. íå ïèñàòü êîä çà äðóãîãî ÷åëîâåêà 3. óáåäèòüñÿ, ÷òî îòñòàþùèé ðàçîáðàëñÿ â òåìå è ñïîñîáåí ðåøàòü ïîäîáíûå çàäà÷è ñàìîñòîÿòåëüíî 1.4 Программное обеспечение Ìû áóäåì èñïîëüçîâàòü íà íàøåì êóðñå èíòåðïðåòàòîð ÿçûêà Ïèòîí ïîä íàçâàíèå CPython. Îí óñòàíîâëåí ïî óìîë÷àíèþ â ñîâðåìåííûõ îïåðàöèîííûõ ñèñòåìàõ ñåìåéñòâà Linux, äëÿ îñòàëüíûõ îïåðàöèîííûõ ñèñòåì íåîáõîäèìî ñêà÷àòü åãî ñ îôèöèàëüíîãî ñàéòà (ñìîòðè ññûëêè íà âèêè-ñòðàíèöå êóðñà). Ïîñëå óñòàíîâêè íàì ïîòðåáóåòñÿ IDE (Integrated Development Environment). Ðåêîìåíäîâàíû ê èñïîëüçîâàíèþ Wing IDE 101 è JetBrains PyCharm. Åñëè âàì ãîâîðÿò, ÷òî ëó÷øå ïîëüçîâàòüñÿ vim è ãîëûì èíòåðïðåòàòîðîì âû ìîæåòå ïîâåðèòü (íà ñâîé ñòðàõ è ðèñê). Óêàçàííîå ÏÎ äîëæíî áûòü óñòàíîâëåíî íà âàøèõ íîóòáóêàõ äëÿ âûïîëíåíèÿ ÄÇ, à òàêæå îíî óñòàíîâëåíî âî âñåõ êîìïüþòåðíûõ êëàññàõ. 1.5 Типы данных и функция вывода Ïðîãðàììû íà ÿçûêå Ïèòîí ïðåäñòàâëÿþò ñîáîé îáû÷íûå òåêñòîâûå ôàéëû, â êîòîðûõ çàïèñàíà ïîñëåäîâàòåëüíîñòü êîìàíä. Êîä ëåãêî ÷èòàåòñÿ è èíòóèòèâíî ïîíÿòåí. Íàïðèìåð, ïðîãðàììû âûâîäÿùàÿ Hello, world! çàïèñûâàåòñÿ âñåãî â îäíó ñòðîêó: print ( ' H e l l o , world ! ' )  ýòîé ïðîãðàììå âûçûâàåòñÿ ôóíêöèÿ ïå÷àòè print, êîòîðîé â êà÷åñòâå ïàðàìåòðà ïåðåäàåòñÿ ñòðîêà, ñîäåðæàùàÿ â ñåáå ôðàçó Hello, world!. Åñëè ìû õîòèì çàäàòü êàêóþòî ñòðîêó, òî äîëæíû îáðàìëÿòü å¼ îäèíàðíûìè (') èëè äâîéíûìè() êàâû÷êàìè, èíà÷å îíà áóäåò èíòåðïðåòèðîâàòüñÿ êàê êîä íà ÿçûêå Ïèòîí. Êðîìå ñòðîê â ñåãîäíÿøíåì çàíÿòèè ìû ðàññìîòðèì öåëî÷èñëåííûé òèï äàííûõ. Íàïðèìåð, ìîæíî ïîñ÷èòàòü ðåçóëüòàò âû÷èñëåíèÿ àðèôìåòè÷åñêîãî âûðàæåíèÿ 2 + 3 è âûâåñòè åãî ñ ïîìîùüþ òàêîé îäíîñòðî÷íîé ïðîãðàììû íà ÿçûêå Ïèòîí: print ( 2 + 3 ) Òàêàÿ ïðîãðàììà âûâåäåò ðåçóëüòàò âû÷èñëåíèÿ âûðàæåíèÿ, êîòîðûé áóäåò ðàâåí 5. Åñëè áû ÷èñëà 2 è 3 áûëè çàêëþ÷åíû â êàâû÷êè, òî îíè èíòåðïðåòèðîâàëèñü áû êàê ñòðîêè, à îïåðàöèÿ + ïðîâîäèëà áû êîíêàòåíàöèþ (ñêëåèâàíèå) ñòðîê. Íàïðèìåð, òàêîé êîä: print ( ' 2 ' + ' 3 ' ) 10 ЛЕКЦИЯ 1. ВВОД-ВЫВОД, ПРОСТЫЕ ТИПЫ ДАННЫХ âûâåäåò 23 ñòðîêó, ñîñòîÿùóþ èç ñêëååííûõ ñèìâîëîâ '2' è '3'. Ôóíêöèÿ print ìîæåò ïðèíèìàòü è íåñêîëüêî ïàðàìåòðîâ, òîãäà îíè áóäóò âûâîäèòüñÿ ÷åðåç ïðîáåë, ïðè÷åì ïàðàìåòðû ìîãóò èìåòü ðàçëè÷íûå òèïû. Åñëè ìû õîòèì ïîëó÷èòü âûâîä âèäà 2 + 3 = 5, òî ìîæåì âîñïîëüçîâàòüñÿ ñëåäóþùåé ïðîãðàììîé: print ( ' 2 + 3 = ' , 2 + 3 ) Îáðàòèòå âíèìàíèå, ÷òî â ñòðîêå '2 + 3 =' íåò ïðîáåëà ïîñëå çíàêà =. Ïðîáåë ïîÿâëÿåòñÿ àâòîìàòè÷åñêè ìåæäó ïàðàìåòðàìè ôóíêöèè print. ×òî æå äåëàòü, åñëè õî÷åòñÿ âûâåñòè ñòðîêó âèäà 2+3=5 (áåç ïðîáåëîâ)? Äëÿ ýòîãî ïîíàäîáèòñÿ èìåíîâàííûé ïàðàìåòð sep (separator, ðàçäåëèòåëü) äëÿ ôóíêöèè print. Òà ñòðîêà, êîòîðàÿ ïåðåäàåòñÿ â êà÷åñòâå ïàðàìåòðà sep áóäåò ïîäñòàâëÿòüñÿ âìåñòî ïðîáåëà â êà÷åñòâå ðàçäåëèòåëÿ.  ýòîé çàäà÷å ìû áóäåì èñïîëüçîâàòü ïóñòóþ ñòðîêó â êà÷åñòâå ðàçäåëèòåëÿ. Ïóñòàÿ ñòðîêà çàäàåòñÿ äâóìÿ ïîäðÿä èäóùèìè êàâû÷êàìè. print ( '2+3= ' , 2 + 3 , s e p= ' ' )  êà÷åñòâå ïàðàìåòðà sep ìîæíî èñïîëüçîâàòü ëþáóþ ñòðîêó, â òîì ÷èñëå ñîñòîÿùóþ èç íåñêîëüêèõ ñèìâîëîâ. Åñëè íàì íóæíî ñäåëàòü íåñêîëüêî ðàçíûõ ðàçäåëèòåëåé äëÿ ðàçíûõ ÷àñòåé ñòðîê, òî íå îñòàåòñÿ äðóãîãî âûáîðà, êðîìå êàê èñïîëüçîâàòü íåñêîëüêî ïîäðÿä èäóùèõ ôóíêöèé print. Íàïðèìåð, åñëè ìû õîòèì âûâåñòè ñòðîêó âèäà 1 + 2 + 3 + 4 = 10, òî ìîæåì ïîïðîáîâàòü âîñïîëüçîâàòüñÿ ñëåäóþùèì êîäîì: print ( 1 , 2 , 3 , 4 , s e p = ' + ' ) print ( ' = ' , 1 + 2 + 3 + 4 , s e p = ' ' ) Îäíàêî, âûâîä òàêîãî êîäà íàñ îãîð÷èò. Îí áóäåò âûãëÿäåòü êàê: 1 + 2 + 3 + 4 = 10 Ýòî ñâÿçàíî ñ òåì, ÷òî ïîñëå êàæäîé ôóíêöèè print ïî óìîë÷àíèþ îñóùåñòâëÿåòñÿ ïåðåâîä ñòðîêè. Äëÿ èçìåíåíèÿ òîãî, ÷òî áóäåò ïå÷àòàòüñÿ ïîñëå âûâîäà âñåãî, ÷òî åñòü â ôóíêöèè print ìîæíî èñïîëüçîâàòü èìåíîâàííûé ïàðàìåòð end. Íàïðèìåð, â íàøåì ñëó÷àå ïîñëå ïåðâîãî print ìû íå õîòåëè áû ïå÷àòàòü íè÷åãî. Ïðàâèëüíûé êîä âûãëÿäèò ñëåäóþùèì îáðàçîì: print ( 1 , 2 , 3 , 4 , s e p= ' + ' , end= ' ' ) print ( ' = ' , 1 + 2 + 3 + 4 , s e p= ' ' )  êà÷åñòâå end òàêæå ìîæíî èñïîëüçîâàòü àáñîëþòíî ëþáóþ ñòðîêó. 1.6 Переменные  íåêîòîðûõ çàäà÷àõ âû÷èñëåíèÿ óäîáíî ïðîâîäèòü èñïîëüçóÿ âñïîìîãàòåëüíûå ïåðåìåííûå. Íàïðèìåð, â øêîëüíûõ ôîðìóëàõ ïî ôèçèêè áûëî óäîáíî âû÷èñëÿòü íå ãèãàíòñêîå âûðàæåíèå öåëèêîì, à çàïîìèíàÿ ðåçóëüòàòû âû÷èñëåíèÿ âî âñïîìîãàòåëüíûå ïåðåìåííûå. Äëÿ ïðèìåðà ðåøèì çàäà÷ó âû÷èñëåíèÿ ïðîéäåííîãî ðàññòîÿíèÿ ïî èçâåñòíîìó âðåìåíè è ñêîðîñòè: 1.7. АРИФМЕТИЧЕСКИЕ ВЫРАЖЕНИЯ 11 s p e e d = 108 time = 12 d i s t = s p e e d * time print ( d i s t )  ýòîé ïðîãðàììå ìû ñîçäàåì òðè ïåðåìåííûå: speed äëÿ ñêîðîñòè, time äëÿ âðåìåíè è dist äëÿ âû÷èñëåííîãî ðàññòîÿíèÿ. Ïðè èñïîëüçîâàíèè ïåðåìåíûõ â àðèôìåòè÷åñêîì âûðàæåíèè ïðîñòî èñïîëüçóåòñÿ çíà÷åíèå, êîòîðîå ëåæèò â ïåðåìåííîé. Äëÿ ïðèñâàèâàíèÿ çíà÷åíèÿ ïåðåìåííîé èñïîëüçóåòñÿ çíàê =. Èìÿ ïåðåìåííîé äîëæíî áûòü çàïèñàíî ñëåâà îò çíàêà ïðèñâàèâàíèÿ, à àðèôìåòè÷åñêîå âûðàæåíèå (â êîòîðîì ìîãóò áûòü èñïîëüçîâàíû ÷èñëà è äðóãèå óæå çàäàííûå ïåðåìåííûå) ñïðàâà. Èìÿ ïåðåìåííîé äîëæíî íà÷èíàòüñÿ ñ ìàëåíüêîé ëàòèíñêîé áóêâû, äîëæíî áûòü îñìûñëåííûì (àíëèéñêèå ñëîâà èëè îáùåóïîòðåáèìûå ñîêðàùåíèÿ) è íå äîëæíî ïðåâûøàòü ïî äëèíå 10-15 ñèìâîëîâ. Åñëè ëîãè÷íîå èìÿ ïåðåìåííîé ñîñòîèò èç íåñêîëüêèõ ñëîâ, òî íóæíî çàïèñûâàòü åãî ñ ïîìîùüþ camelTyping (êàæäîå íîâîå ñëîâî êðîìå ïåðâîãî äîëæíî áûòü çàïèñàíî ñ áîëüøîé áóêâû). Ïîäáðîáíåå î òîì, êàê îñóùåñòâëÿåòñÿ ïðèñâàèâàíèå áóäåò îïèñàíî íèæå. 1.7 Арифметические выражения Ìû óæå èñïîëüçîâàëè àðèôìåòè÷åñêèå âûðàæåíèÿ â íàøèõ ïðîãðàììàõ, â ÷àñòíîñòè îïåðàöèè + è *. Òàêæå ñóùåñòâóåò ðÿä äðóãèõ àðèôìåòè÷åñêèõ îïåðàöèé, êîòîðûå ïðèâåäåíû â òàáëèöå: Îáîçíà÷åíèå Îïåðàöèÿ Îïåðàíä 1 Îïåðàíä 2 Ðåçóëüòàò + Ñëîæåíèå 11 6 17 Âû÷èòàíèå 11 6 5 * Óìíîæåíèå 11 6 66 // Öåëî÷èñëåííîå äåëåíèå 11 6 1 % Îñòàòîê îò äåëåíèÿ 11 6 5 ** Âîçâåäåíèå â ñòåïåíü 2 3 8 Âñå îïåðàöèè èíôèêñíûå (çàïèñûâàþòñÿ ìåæäó îïåðàíäàìè), ò.å., íàïðèìåð, äëÿ âîçâåäåíèÿ 2 â ñòåïåíü 3 íóæíî ïèñàòü 2**3. Îñîáî îñòàíîâèìñÿ íà îïåðàöèÿõ âû÷èñëåíèÿ öåëîé ÷àñòè è îñòàòêà îò äåëåíèÿ îò ÷èñëà. Ïóñòü çàäàíû äâà ÷èñëà 𝐴 è 𝐵 , ïðè÷åì 𝐵 > 0. Îáîçíà÷èì çà 𝐶 öåëóþ ÷àñòü îò äåëåíèÿ 𝐴 íà 𝐵 , 𝐶 = 𝐴//𝐵 , à çà 𝐷 îñòàòîê îò äåëåíèÿ 𝐴 íà 𝐵 , 𝐷 = 𝐴%𝐵 . Òîãäà äîëæíû âûïîëíÿòüñÿ ñëåäóþùèå óòâåðæäåíèÿ: 𝐴=𝐵×𝐶 +𝐷 0≤𝐷<𝐵 Ýòè óòâåðæäåíèÿ íåîáõîäèìû äëÿ ïîíèìàíèÿ ïðîöåññà âçÿòèÿ îñòàòêà îò äåëåíèÿ îòðèöàòåëüíîãî ÷èñëà íà ïîëîæèòåëüíîå. Íåòðóäíî óáåäèòüñÿ, ÷òî åñëè -5 ðàçäåëèòü íà 2, òî öåëàÿ ÷àñòü äîëæíà áûòü ðàâíà -3, à îñòàòîê ðàâåí 1.  íåêîòîðûõ äðóãèõ ÿçûêàõ ïðîãðàììèðîâàíèÿ îñòàòêè â òàêîé ñèòóàöèè ìîãóò áûòü îòðèöàòåëüíûìè, ÷òî íåïðàâèëüíî ïî ìàòåìàòè÷åñêèì îïðåäåëåíèÿì. 12 ЛЕКЦИЯ 1. ВВОД-ВЫВОД, ПРОСТЫЕ ТИПЫ ДАННЫХ Â ñëó÷àå, åñëè 𝐵 < 0 âûïîëíÿþòñÿ ñëåäóþùèå óòâåðæäåíèÿ: 𝐴=𝐵×𝐶 +𝐷 𝐵<𝐷≤0 Íàïðèìåð, ïðè äåëåíèè 11 íà -5 ìû ïîëó÷èì öåëóþ ÷àñòü ðàâíóþ -3, à îñòàòîê áóäåò ðàâåí -4. Åñëè æå ðàçäåëèòü -11 íà -5, òî öåëàÿ ÷àñòü áóäåò ðàâíà 2, à îñòàòîê áóäåò ðàâåí -1. Îáðàòèòå âíèìàíèå, ÷òî öåëûå ÷èñëà â Ïèòîíå íå èìåþò îãðàíè÷åíèé íà äëèíó (êðîìå îáúåìà äîñòóïíîé ïàìÿòè). 1.8 Операции над строками Ñòðîêè òàêæå ìîæíî ñîõðàíÿòü â ïåðåìåííûå è èñïîëüçîâàòü â íåêîòîðîì îãðàíè÷åííîì êîëè÷åñòâå âûðàæåíèé.  ÷àñòíîñòè, ìîæíî ñêëåèâàòü äâå ñòðîêè ñ ïîìîùüþ îïåðàöèè +: goodByePhrase = ' Hasta l a v i s t a ' p e r s o n = ' baby ' print ( goodByePhrase + ' , ' p e r s o n + ' ! ' ) Òàêæå ìîæíî óìíîæèòü ñòðîêó íà öåëîå íåîòðèöàòåëüíîå ÷èñëî, â ðåçóëüòàòå ïîëó÷èòñÿ èñõîäíàÿ ñòðîêà ïîâòîðåííàÿ çàäàííîå ÷èñëî ðàç: word = ' Bye ' p h r a s e = word * 3 + ' ! ' print ( p h r a s e ) Âûâîä ýòîé ïðîãðàììû áóäåò ByeByeBye! Ñêëàäûâàòü ÷èñëî ñî ñòðîêîé (è íàîáîðîò) íåëüçÿ. Íî ìîæíî âîñïîëüçîâàòüñÿ ôóíêöèåé str, êîòîðàÿ ïî ÷èñëó ãåíåðèðóåò ñòðîêó. Str ýòî ñîêðàùåíèå îò ñëîâà string, êîòîðîå ìîæíî ïåðåâåñòè íà ðóññêèé êàê ¾ñòðîêà, êîòîðàÿ ïðåäñòàâëÿåò ñîáîé ïîñëåäîâàòåëüíîñòü ñèìâîëîâ¿. Íàïðèìåð, çàäà÷ó ïðî âûâîä 2 + 3 = 5 ìîæíî ðåøèòü è òàêèì ñïîñîáîì: answer = ' 2 + 3 = ' + s t r ( 2 + 3 ) print ( answer ) 1.9 Чтение данных Ïðîãðàììû, êîòîðûå óìåþò òîëüêî ïèñàòü, íî íå óìåþò ÷èòàòü, ðåäêî ïðåäñòàâëÿþò èíòåðåñ äëÿ ïîëüçîâàòåëåé. Óçíàâàòü ÷òî-òî èç âíåøíåãî ìèðà íàøè ïðîãðàììû áóäóò ñ ïîìîùüþ ôóíêöèè input(). Ýòà ôóíêöèÿ ñ÷èòûâàåò ñòðîêó èç êîíñîëè, ÷òîáû çàêîí÷èòü ââîä ñòðîêè íóæíî íàæàòü Enter. Ïîä ñòðîêîé â äàííîì ñëó÷àå ïîíèìàåòñÿ àíãëèéñêîå ñëîâî line, ÷òî îçíà÷àåò ¾ñòðîêà, îêàí÷èâàþùàÿñÿ ïåðåâîäîì ñòðîêè¿. Íàïðèìåð, åñëè â òàêóþ ïðîãðàììó: name = input ( ) print ( ' I l o v e ' , name ) 1.10. ПРИМЕРЫ РЕШЕНИЯ ЗАДАЧ 13 ââåñòè ñëîâî Python, òî îíà íàïå÷àòàåò I love Python. Âî ìíîãèõ çàäà÷àõ íàì òðåáóåòñÿ ðàáîòàòü ñî ââåäåííûìè ÷èñëàìè, à ÷èòàòü ìû óìååì òîëüêî ñòðîêè. ×òîáû ïðåîáðàçîâàòü ñòðîêó, ñîñòîÿùóþ èç öèôð (è, âîçìîæíî, çíàêà − ïåðåä íèìè) â öåëîå ÷èñëî ìîæíî âîñïîëüçîâàòüñÿ ôóíêöèåé int (ñîêðàùåíèå îò àíãëèéñêîãî integer, ¾öåëîå ÷èñëî¿). Íàïðèìåð, ðåøåíèå çàäà÷è î ñëîæåíèè äâóõ ÷èñåë áóäåò âûãëÿäåòü òàê: a = i n t ( input ( ) ) b = i n t ( input ( ) ) print ( a + b ) Ôóíêöèÿ int ìîæåò áûòü ïðèìåíåíà íå òîëüêî ê ðåçóëüòàòó, âîçâðàùàåìîìó ôóíêöèåé input, íî è ê ïðîèçâîëüíîé ñòðîêå.  ñòðîêàõ ìîãóò áûòü íå òîëüêî áóêâû, öèôðû è ïðî÷èå çíàêè ïðåïèíàíèÿ, íî è, íàïðèìåð, ñèìâîëû òàáóëÿöèè è ïåðåâîäà ñòðîêè. ×òîáû èñïîëüçîâàòü ýòè ñèìâîëû â êîíñòàíòíîé ñòðîêå â êîäå ïðîãðàììû íåîáõîäèìî çàïèñûâàòü èõ êàê \t è \n ñîîòâåòñòâåííî. Èñïîëüçîâàíèå áýêñëåøà ïåðåä ñèìâîëîì íàçûâàåòñÿ ýêðàíèðîâàíèå. Òàêæå ñóùåñòâóþò è äðóãèå ñèìâîëû, êîòîðûå òðåáóþò áýêñëåøà ïåðåä ñîáîé. Íàïðèìåð, ýòî êàâû÷êè \' è \ (èñïîëüçîâàíèå áýêñëåøà ïðîñòî íåîáõîäèìî, åñëè â ñòðîêå èñïîëüçóþòñÿ îáà òèïà êàâû÷åê), à òàêæå, ñîáñòâåííî, ñèìâîë áýêñëåøà, êîòîðûé íàäî çàïèñûâàòü êàê \\.  ñëó÷àå ñ÷èòûâàíèÿ ñ ïîìîùüþ input ñèìâîëû â êîíñîëè ýêðàíèðîâàòü íå íóæíî. 1.10 Примеры решения задач Ðàññìîòðìè íåñêîëüêî çàäà÷, ðåøàåìûõ ñ ïîìîùüþ àðèôìåòè÷åñêèõ îïåðàöèé, êîòîðûå ïîêàçûâàþò íåêîòîðûå èäåè. Ïóñòü åñòü äâà òîâàðà, ïåðâûé èç íèõ ñòîèò 𝐴 ðóáëåé 𝐵 êîïååê, à âòîðîé 𝐶 ðóáëåé 𝐷 êîïååê. Ñêîëüêî ðóáëåé è êîïååê ñòîÿò ýòè òîâàðû âìåñòå.  çàäà÷àõ ãäå åñòü íåñêîëüêî ðàçìåðíîñòåé âåëè÷èí (íàïðèìåð, ðóáëè è êîïåéêè, êèëîìåòðû è ìåòðû, ÷àñû è ìèíóòû) ñëåäóåò ïåðåâîäèòü âñå â íàèìåíüøóþ åäèíèöó èçìåðåíè, îñóùåñòâëÿòü íåîáõîäèìûå äåéñòâèÿ, à çàòåì ïåðåâîäèòü îáðàòíî ê íóæíûì åäèíèöàì.  íàøåé çàäà÷å íàèìåíüøåé åäèíèöåé ÿâëÿþòñÿ êîïåéêè, ïîýòîìó âñå öåíû ñëåäóåò ïåðåâåñòè â íèõ, çàòåì ñëîæèòü èõ, à çàòåì ïåðåâåñòè ðåçóëüòàò îáðàòíî â ðóáëè è êîïåéêè. Êîä ðåøåíèÿ áóäåò âûãëÿäåòü òàê: a = i n t ( input ( ) ) b = i n t ( input ( ) ) c = i n t ( input ( ) ) d = i n t ( input ( ) ) c o s t 1 = a * 100 + b c o s t 2 = c * 100 + d totalCost = cost1 + cost2 print ( t o t a l C o s t // 1 0 0 , t o t a l C o s t % 1 0 0 ) Äëÿ îïðåäåëåíèÿ êîëè÷åñòâà ðóáëåé íóæíî ðàçäåëèòü öåíó â êîïåéêàõ íà 100 íàöåëî, à äëÿ îïðåäåëåíèÿ îñòàâøåãîñÿ ÷èñëà êîïååê ïîñ÷èòàòü îñòàòîê îò äåëåíèÿ íà 100. 14 ЛЕКЦИЯ 1. ВВОД-ВЫВОД, ПРОСТЫЕ ТИПЫ ДАННЫХ Ñëåäóþùàÿ çàäà÷à: Âàñÿ èãðàåò â Super Mario Bros. î÷åíü õîðîøî è ïîëó÷èë 𝑁 äîïîëíèòåëüíûõ æèçíåé. Èçâåñòíî, ÷òî ïåðåìåííàÿ, â êîòîðîé õðàíèòñÿ êîëè÷åñòâî æèçíåé ìîæåò ïðèíèìàòü çíà÷åíèÿ îò 0 äî 255.  ñëó÷àå, åñëè áûëî 255 æèçíåé è èãðîê ïîëó÷èë äîïîëíèòåëüíóþ æèçíü, ñ÷åò÷èê îáíóëÿåòñÿ. Ñêîëüêî æèçíåé íà ñ÷åò÷èêå?  ýòîé çàäà÷å äîñòàòî÷íî ïîñ÷èòàòü îñòàòîê îò äåëåíèÿ ââåäåííîãî ÷èñëà íà 256. Òàêèå äåéñòâèÿ ÷àñòî òðåáóþòñÿ, íàïðèìåð, ïðè ðàáîòå ñî âðåìåíåì (ïðè ïåðåõîäå ÷åðåç ñóòêè ñ÷åò÷èê âðåìåíè îáíóëÿåòñÿ). Ðåøåíèå çàäà÷è âûãëÿäèò òàê: n = i n t ( input ( ) ) print ( n % 2 5 6 ) Ñëåäóþùàÿ çàäà÷à: ââîäèòñÿ ÷èñëî 𝑁 , íåîáõîäèìî îòðåçàòü îò íåãî 𝐾 ïîñëåäíèõ öèôð. Íàïðèìåð, ïðè 𝑁 = 123456 è 𝐾 = 3 îòâåò äîëæåí áûòü 123. Äëÿ ðåøåíèÿ ýòîé çàäà÷è íóæíî ïîíÿòü, ÷òî ïðîèñõîäèò ïðè öåëî÷èñëåííîì äåëåíèè íà 10 (îñíîâàíèå ñèñòåìû ñ÷èñëåíèÿ). Åñëè ìû ðàçäåëèì ÷èñëî íà 10, òî áóäåò îòáðîøåíà ïîñëåäíÿÿ öèôðà, íåçàâèñèìî îò òîãî, êàêîé îíà áûëà. Åñëè ðàçäåëèì ÷èñëî íà 100 áóäåò îòáðîøåíî äâå ïîñëåäíèå öèôðû. Èñõîäÿ èç ýòîãî ïîëó÷àåòñÿ ðåøåíèå çàäà÷è: íåîáõîäèìî ïðîñòî ðàçäåëèòü ÷èñëî 𝑁 íà 10𝐾 : n = i n t ( input ( ) ) k = i n t ( input ( ) ) print ( n // 10 ** k ) 1.11 Как переменные устроены внутри  ÿçûêå Ïèòîí âñå ïåðåìåííûå ÿâëÿþòñÿ ññûëêàìè íà îáúåêòû. Êàæäûé îáúåêò èìååò òèï (íàì èçâåñòíû int è str) è ñîäåðæèìîå, â íàøåì ñëó÷àå êîíêðåòíîå ÷èñëî èëè ïîñëåäîâàòåëüíîñòü ñèìâîëîâ. Ïåðåìåííûå (ññûëêè) â ÿçûêå Ïèòîí óäîáíî ïðåäñòàâëÿòü ñåáå êàê ÿðëû÷êè íà âåðåâî÷êå, êîòîðûå ïðèâÿçàíû ê êàêîìó-òî îáúåêòó. Âîîáùå ãîâîðÿ, ê îäíîìó îáúåêòó ìîæåò áûòü ïðèâÿçàíî ñêîëü óãîäíî ìíîãî ÿðëûêîâ. Ðàçëè÷íûå ïåðåìåííûå ñ îäèíàêîâûì çíà÷åíèåì ôàêòè÷åñêè ÿâëÿþòñÿ ÿðëû÷êàìè, ïðèâÿçàííûìè ê îäíîìó è òîìó æå îáúåêòó. Òèïû int è str â Ïèòîíå ÿâëÿþòñÿ íåèçìåíÿåìûìè. Ëþáîå ïðèñâàèâàíèå â Ïèòîíå íå ìîæåò èçìåíèòü íåèçìåíÿåìûé òèï, à ìîæåò òîëüêî èçìåíèòü ìåñòî, íà êîòîðîå óêàçûâàåò ññûëêà (è, ïðè íåîáõîäèìîñòè, ñêîíñòðóèðîâàòü íîâûé îáúåêò). Íàïðèìåð, êîìàíäà x = 2, ïðèâåäåò ñíà÷àëà ê ñîçäàíèþ îáúåêòà òèïà ¾öåëîå ÷èñëî¿ ñî çíà÷åíèåì 2 â ïàìÿòè, à çàòåì ê ñîçäàíèþ ïåðåìåííîé x, êîòîðàÿ áóäåò ÿâëÿòüñÿ ññûëêîé íà ýòîò îáúåêò. Åñëè ïîñëå ýòîãî íàïèñàòü y = 2, òî íîâûé îáúåêò ñî çíà÷åíèåì 2 ñîçäàâàòüñÿ íå áóäåò, à ñîçäàñòñÿ òîëüêî íîâàÿ ññûëêà ñ èìåíåì y ïîêàçûâàþùàÿ íà òîò æå ñàìûé îáúåêò, ÷òî è ññûëêà x. Åñëè òåïåðü íàïèñàòü ñòðîêó x = 3, òî ñ îáúåêòîì ñî çíà÷åíèåì 2 íè÷åãî íå ñëó÷èòñÿ, âåäü îí íå íåèçìåíÿåìûé. Ñîçäàñòñÿ íîâûé îáúåêò ñî çíà÷åíèåì 3, ññûëêà x îòâÿæåòñÿ îò îáúåêòà ñî çíà÷åíèåì 2 è ïðèâÿæåòñÿ ê íîâîìó îáúåêòó 3. Ïðè ýòîì ê îáúåêòó 2 îñòàíåòñÿ ïðèâÿçàíà ññûëêà y. Åñëè èçìåíèòü è çíà÷åíèå ïåðåìåííîé y, òî ó îáúåêòà 2 íå îñòàíåòñÿ ññûëîê íà íåãî. Ïîýòîìó îí ìîæåò áûòü áåçáîëåçíåííî óíè÷òîæåí ïðè ñáîðêå ìóñîðà, âåäü ïîëó÷èòü ê 1.12. КАК РЕШАТЬ ЗАДАЧИ 15 íåìó äîñòóï óæå íåâîçìîæíî íà íåãî íå ññûëàåòñÿ íè îäíà ïåðåìåííàÿ. Êîíñòàíòíûå çíà÷åíèÿ â ïðîãðàììå (íàïðèìåð, ÿâíî çàäàííûå ÷èñëà â èñõîäíîì êîäå ïðîãðàììû) òàêæå ÿâëÿþòñÿ ññûëêàìè íà îáúåêòû, ñîäåðæèìîå êîòîðûõ ñîâïàäàåò ñî çíà÷åíèåì ýòèõ êîíñòàíò. Îäíàêî ýòè ññûëêè íå ìîãóò áûòü èçìåíåíû è íå ìîãóò ó÷àñòâîâàòü â ïðèñâàèâàíèè ñ ëåâîé ñòîðîíû îò çíàêà =. 1.12 Как решать задачи Ó êàæäîé çàäà÷è â âàøåì äîìàøíåì çàäàíèè åñòü óñëîâèå, ôîðìàò âõîäíûõ è âûõîäíûõ äàííûõ è ïðèìåðû.  óñëîâèè ñîäåðæèòñÿ îïèñàíèå çàäà÷è, êîòîðóþ íóæíî ðåøèòü.  ôîðìàòå âõîäíûõ äàííûõ ñêàçàíî, êàêèå ÷èñëà ââîäÿòñÿ è â êàêîì ïîðÿäêå îíè äàíû, à òàêæå óêàçàíû îãðàíè÷åíèÿ íà ýòè ÷èñëà. Ãàðàíòèðóåòñÿ, ÷òî ÷èñåë áóäåò ñòîëüêî, ñêîëüêî íóæíî, è îíè áóäóò óäîâëåòâîðÿòü îãðàíè÷åíèÿì. Âàì íóæíî ðåøèòü çàäà÷ó òîëüêî äëÿ óêàçàííûõ îãðàíè÷åíèé. Êàê ïðîãðàììà áóäåò ðàáîòàòü äëÿ ÷èñåë, íå óäîâëåòâîðÿþùèõ îãðàíè÷åíèÿì àáñîëþòíî íåâàæíî, òàêèõ òåñòîâ íå áóäåò.  ôîðìàòå âûõîäíûõ äàííûõ óêàçûâàåòñÿ, ÷òî è â êàêîì ïîðÿäêå ïðîãðàììà äîëæíà âûâîäèòü íè÷åãî, êðîìå ýòîãî, â ðåøåíèè áûòü íå äîëæíî. Ïðèìåðû ê çàäà÷å íóæíû äëÿ ëó÷øåãî ïîíèìàíèÿ óñëîâèÿ è ïåðâîíà÷àëüíîé ñàìîïðîâåðêè. Åñòåñòâåííî, ïðîãðàììà äîëæíà ðàáîòàòü íå òîëüêî íà ïðèìåðàõ, íî è íà ëþáûõ äðóãèõ äîïóñòèìûõ âõîäíûõ äàííûõ. Åñëè ïðîãðàììà ðàáîòàåò ïðàâèëüíî, òî îíà ïîëó÷èò ñòàòóñ OK. Åñëè ïðîãðàììà ïîëó÷èëà äðóãîé ñòàòóñ âàì ñëåäóåò ïðèäóìàòü òåñòû, óäîâëåòâîðÿþùèå îãðàíè÷åíèÿì, è ïðîâåðèòü ðàáîòó ñâîåé ïðîãðàììû. Îáÿçàòåëüíî íàéä¼òñÿ îøèáêà. Íàøà òåñòèðóþùàÿ ñèñòåìà ðàáîòàåò ïðàâèëüíî. Íàøè òåñòû ïðàâèëüíûå. Ïðàâèëüíûå îòâåòû ê íàøèì òåñòàì ïðàâèëüíûå. Ýòî òî÷íî. Ìû ïðîâåðÿëè ìíîãî ðàç. È íå òîëüêî ìû. 16 ЛЕКЦИЯ 1. ВВОД-ВЫВОД, ПРОСТЫЕ ТИПЫ ДАННЫХ Лекция 2 Логический тип данных, условный оператор, цикл while, вещественные числа 2.1 Логический тип данных Êðîìå óæå èçâåñòíûõ íàì öåëî÷èñëåííûõ è ñòðîêîâûõ òèïîâ äàííûõ â Ïèòîíå ñóùåñòâóåò òàêæå ëîãè÷åñêèé òèï äàííûõ, êîòîðûé ìîæåò ïðèíèìàòü çíà÷åíèÿ ¾èñòèíà¿ (True) èëè ¾ëîæü¿ (False). Ïî àíàëîãèè ñ àðèôìåòè÷åñêèìè âûðàæåíèÿìè ñóùåñòâóþò ëîãè÷åñêèå âûðàæåíèÿ, êîòîðûå ìîãóò áûòü èñòèííûìè èëè ëîæíûìè. Ïðîñòîå ëîãè÷åñêîå âûðàæåíèå èìååò âèä <àðèôìåòè÷åñêîå âûðàæåíèå> <çíàê ñðàâíåíèÿ> <àðèôìåòè÷åñêîå âûðàæåíèå>. Íàïðèìåð, åñëè ó íàñ åñòü ïåðåìåííûå 𝑥 è 𝑦 ñ êàêèìè-òî çíà÷åíèÿìè, òî ëîãè÷åñêîå âûðàæåíèå 𝑥 + 𝑦 < 3 * 𝑦 â êà÷åñòâå ïåðâîãî àðèôìåòè÷åñêîãî âûðàæåíèÿ èìååò 𝑥 + 𝑦 , â êà÷åñòâå çíàêà ñðàâíåíèÿ < (ìåíüøå), à âòîðîå àðèôìåòè÷åñêîå âûðàæåíèå â í¼ì 3 * 𝑦 .  ëîãè÷åñêèõ âûðàæåíèÿõ äîïóñòèìû ñëåäóþùèå çíàêè ñðàâíåíèé: Çíàê ñðàâíåíèÿ Îïèñàíèå == ðàâíî != íå ðàâíî < ìåíüøå > áîëüøå <= ìåíüøå èëè ðàâíî >= áîëüøå èëè ðàâíî  Ïèòîíå äîïóñòèìû è ëîãè÷åñêèå âûðàæåíèÿ, ñîäåðæàùèå íåñêîëüêî çíàêîâ ñðàâíåíèÿ, íàïðèìåð 𝑥 < 𝑦 < 𝑧 . Ïðè ýòîì âñå ñðàâíåíèÿ îáëàäàþò îäèíàêîâûì ïðèîðèòåòîì, êîòîðûé ìåíüøå, ÷åì ó ëþáîé àðèôìåòè÷åñêîé îïåðàöèè. Ðåçóëüòàò âû÷èñëåíèÿ ëîãè÷åñêîãî âûðàæåíèÿ ìîæíî ñîõðàíÿòü â ïåðåìåííóþ, êîòîðàÿ áóäåò èìåòü òèï bool. Ïåðåìåííûå òàêîãî òèïà, êàê è ÷èñëà è ñòðîêè, ÿâëÿþòñÿ íåèçìåíÿåìûìè îáúåêòàìè. Îäíèì èç ïðèìåðîâ èñïîëüçîâàíèÿ ëîãè÷åñêîãî âûðàæåíèÿ ÿâëÿåòñÿ ïðîâåðêà íà äåëèìîñòü. Íàïðèìåð, ÷òîáû ïðîâåðèòü, ÿâëÿåòñÿ ëè ÷èñëî ÷åòíûì, íåîáõîäèìî ñðàâíèòü îñòàòîê îò äåëåíèÿ ýòîãî ÷èñëà íà äâà ñ íóë¼ì: i s E v e n = number % 2 == 0 17 18ЛЕКЦИЯ 2. ЛОГИЧЕСКИЙ ТИП ДАННЫХ, УСЛОВНЫЙ ОПЕРАТОР, ЦИКЛ WHILE, ВЕЩЕС Ñòðîêè òàêæå ìîãóò ñðàâíèâàòüñÿ ìåæäó ñîáîé. Ïðè ýòîì ñðàâíåíèå ïðîèñõîäèò â ëåêñèêîãðàôè÷åñêîì ïîðÿäêå (êàê óïîðÿäî÷åíû ñëîâà â ñëîâàðå). 2.2 Логические операции ×òîáû çàïèñàòü ñëîæíîå ëîãè÷åñêîå âûðàæåíèå, ÷àñòî áûâàåò íåîáõîäèìî âîñïîëüçîâàòüñÿ ëîãè÷åñêèìè ñâÿçêàìè ¾è¿, ¾èëè¿ è ¾íå¿.  Ïèòîíå îíè îáîçíà÷àþòñÿ êàê and, or è not ñîîòâåòñòâåííî. Îïåðàöèè and è or ÿâëÿåþòñÿ áèíàðíûìè, ò.å. äîëæíû áûòü çàïèñàíû ìåæäó îïåðàíäàìè, íàïðèìåð x < 3 or y > 2. Îïåðàöèÿ not óíàðíàÿ è äîëæíà áûòü çàïèñàíà ïåðåä åäèíñòâåííûì ñâîèì îïåðàíäîì. Âñå ëîãè÷åñêèå îïåðàöèè èìåþò ïðèîðèòåò íèæå, ÷åì îïåðàöèè ñðàâíåíèÿ (à çíà÷èò, è íèæå ÷åì àðèôìåòè÷åñêèå îïåðàöèè). Ñðåäè ëîãè÷åñêèõ îïåðàöèé íàèâûñøèé ïðèîðèòåò èìååò îïåðàöèÿ not, çàòåì èäåò and è íàèìåíüøèé ïðèîðèòåò èìååò îïåðàöèÿ or. Íà ïîðÿäîê âûïîëíåíèÿ îïåðàöèé ìîæíî âëèÿòü ñ ïîìîùüþ ñêîáîê, êàê è â àðèôìåòè÷åñêèõ âûðàæåíèÿõ. Äëÿ ïðèìåðà ïîñìîòðèì çàäà÷ó î ïåðåñå÷åíèè äâóõ äëèòåëüíûõ ñîáûòèé ïî âðåìåíè. Îáà ñîáûòèÿ õàðàêòåðèçóþòñÿ äâóìÿ ÷èñëàìè ãîäàìè íà÷àëà è êîíöà. Íåîáõîäèìî îïðåäåëèòü, ïåðåñåêàëèñü ëè ñîáûòèÿ âî âðåìåíè, ïðè ýòîì åñëè îäíî ñîáûòèå íà÷àëîñü â òîò ãîä, êîãäà çàêîí÷èëîñü äðóãîå îíè ñ÷èòàþòñÿ ïåðåñåêàþùèìèñÿ. Ïåðâàÿ èäåÿ çàêëþ÷àåòñÿ â òîì, ÷òîáû ðàññìîòðåòü âñå âîçìîæíûå âàðèàíòû ðàñïîëîæåíèÿ ñîáûòèé è âûäåëèòü ñëåäóþùèé êðèòåðèé ïåðåñå÷åíèÿ: åñëè íà÷àëî èëè êîíåö îäíîãî èç ñîáûòèé ëåæèò ìåæäó íà÷àëîì è êîíöîì äðóãîãî, òî îíè ïåðåñåêàþòñÿ.  âèäå ïðîãðàììû ýòî ìîæíî çàïèñàòü òàê: i s 1 s t a r t I n 2 = s t a r t 2 <= s t a r t 1 <= f i n i s h 2 i s 1 f i n i s I n 2 = s t a r t 2 <= f i n i s h 1 <= f i n i s h 2 i s 1 i n 2 = i s 1 s t a r t I n 2 or i s 1 f i n i s h I n 2 i s 2 s t a r t I n 1 = s t a r t 1 <= s t a r t 2 <= f i n i s h 1 i s 2 f i n i s I n 1 = s t a r t 1 <= f i n i s h 2 <= f i n i s h 1 i s 2 i n 1 = i s 2 s t a r t I n 1 or i s 2 f i n i s h I n 1 answer = i s 1 i n 2 or i s 2 i n 1 Åñëè íåìíîãî ïîäóìàòü, òî ìîæíî ïðèäóìàòü áîëåå êîðîòêèé êðèòåðèé äëÿ ïðîâåðêè òàêîãî ïåðåñå÷åíèÿ: íåîáõîäèìî, ÷òîáû íà÷àëî ïåðâîãî ñîáûòèÿ ïðîèñõîäèëî íå ïîçæå êîíöà âòîðîãî è íà÷àëî âòîðîãî ñîáûòèÿ ïðîèñõîäèëî ðàíüøå êîíöà âòîðîãî. answer = s t a r t 1 <= f i n i s h 2 and s t a r t 2 <= f i n i s h 1 Òàêîé ñïîñîá çíà÷èòåëüíî ïðîùå.  Ïèòîíå, êàê è âî ìíîãèõ äðóãèõ ÿçûêàõ ïðîãðàììèðîâàíèÿ, åñëè ðåçóëüòàò âû÷èñëåíèÿ âûðàæåíèÿ îäíîçíà÷íî ïîíÿòåí ïî óæå âû÷èñëåííîé ëåâîé ÷àñòè, òî ïðàâàÿ ÷àñòü âûðàæåíèÿ äàæå íå ñ÷èòàåòñÿ. Íàïðèìåð, âûðàæåíèå True or 5 // 0 == 42, íå áóäåò âûçûâàòü îøèáêè äåëåíèÿ íà íîëü, ò.ê. ïî ëåâîé ÷àñòè âûðàæåíèÿ (True) óæå ïîíÿòíî, ÷òî ðåçóëüòàò åãî âû÷èñëåíèÿ òàêæå áóäåò True è àðèôìåòè÷åñêîå âûðàæåíèå â ïðàâîé ÷àñòè äàæå íå áóäåò âû÷èñëÿòüñÿ. 2.3. 2.3 ВЫВОД И ПРЕОБРАЗОВАНИЕ ЛОГИЧЕСКИХ ВЫРАЖЕНИЙ 19 Вывод и преобразование логических выражений Åñëè íàïå÷àòü ðåçóëüòàò âû÷èñëåíèÿ ëîãè÷åñêîãî âûðàæåíèÿ ñ ïîìîùüþ ôóíêöèè print, òî áóäåò íàïå÷àòàíî ñëîâî True èëè False. Ïî àíàëîãèè ñ ôóíêöèÿìè int è str, ñóùåñòâóåò ôóíêöèÿ bool, êîòîðàÿ ìîæåò ïðèâîäèòü ÷èñëà èëè ñòðîêè ê ëîãè÷åñêîìó òèïó. Ïðè ïðåîáðàçîâàíèè ÷èñåë, âñå ÷èñëà, îòëè÷íûå îò 0 ïðåîáðàçóþòñÿ â True, à ÷èñëî 0 â False. Ôóíêöèÿ bool ïðèìåíåííàÿ ê ïóñòîé ñòðîêå äàåò ðåçóëüòàò False, à ïðè ïðèìåíåíèè ê àáñîëþòíî ëþáîé äðóãîé ñòðîêå äàåò ðåçóëüòàò True. Íàïðèìåð, bool("False") äàñò ðåçóëüòàò True, ïîñêîëüêó ñòðîêà False íå ïóñòàÿ. Åñëè ïðèìåíèòü ôóíêöèþ int ê ëîãè÷åñêîìó âûðàæåíèþ, òî True ïðåîáðàçóåòñÿ â 1, à False â 0. Ïðèìåíåíèå ôóíêöèè str ê ëîãè÷åñêîìó âûðàæåíèþ äàåò ñòðîêè "True"è "False". Íåêîòîðûå ïðèâåäåíèÿ òèïîâ ìîãóò âûïîëíÿòüñÿ àâòîìàòè÷åñêè: Òèï îïåðàíäà 1 Òèï îïåðàíäà 2 Îïåðàöèÿ Òèï ðåçóëüòàòà bool int Àðèôìåòè÷åñêàÿ int bool bool Àðèôìåòè÷åñêàÿ int bool int Ëîãè÷åñêàÿ bool int int Ëîãè÷åñêàÿ bool Íåêîòîðûå îïåðàöèè äîïóñòèìû è äëÿ ïåðåìåííûõ ëîãè÷åñêîãî òèïà è ñòðîê, íî èõ ïðèìåíåíèå ÿâëÿåòñÿ ýêçîòèêîé è èõ íå ñëåäóåò èñïîëüçîâàòü áåç ÿâíîãî ïðèâåäåíèÿ òèïîâ. 2.4 Условный оператор Íàèáîëåå ÷àñòîå ïðèìåíåíèå ëîãè÷åñêèå âûðàæåíèÿ íàõîäÿò â óñëîâíûõ îïåðàòîðàõ. Óñëîâíûé îïåðàòîð ïîçâîëÿåò âûïîëíÿòü äåéñòâèÿ â çàâèñèìîñòè îò òîãî, âûïîëíåíî óñëîâèå èëè íåò. Çàïèñûâàåòñÿ óñëîâíûé îïåðàòîð êàê if <ëîãè÷åñêîå âûðàæåíèå>:, äàëåå ñëåäóåò áëîê êîìàíä, êîòîðûé áóäåò âûïîëíåí òîëüêî åñëè ëîãè÷åñêîå âûðàæåíèå ïðèíÿëî çíà÷åíèå True. Áëîê êîìàíä, êîòîðûé áóäåò âûïîëíÿòüñÿ, âûäåëÿåòñÿ îòñòóïàìè â 4 ïðîáåëà (â IDE ìîæíî íàæèìàòü êëàâèøó tab). Ðàññìîòðèì, íàïðèìåð, çàäà÷ó î íàõîæäåíèè ìîäóëÿ ÷èñëà. Åñëè ÷èñëî îòðèöàòåëüíîå, òî íåîáõîäèìî çàìåíèòü åãî íà ìèíóñ ýòî ÷èñëî. Ðåøåíèå âûãëÿäèò òàê: x = i n t ( input ( ) ) if x < 0: x = −x print ( x )  ýòîé ïðîãðàììå ñ îòñòóïîì çàïèñàíà òîëüêî îäíà ñòðîêà, x = -x. Ïðè íåîáõîäèìîñòè âûïîëíèòü íåñêîëüêî êîìàíä âñå îíè äîëæíû áûòü çàïèñàíû ñ òåì æå îòñòóïîì. Êîìàíäà print çàïèñàíà áåç îòñòóïà, ïîýòîìó îíà áóäåò âûïîëíÿòüñÿ â ëþáîì ñëó÷àå, íåçàâèñèìî îò òîãî, áûëî ëè óñëîâèå â if'å èñòèííûì èëè íåò.  äîïîëíåíèå ê if ìîæíî èñïîëüçîâàòü îïåðàòîð else: (èíà÷å). Áëîê êîìàíä, êîòîðûé ñëåäóåò ïîñëå íåãî, áóäåò âûïîëíÿòüñÿ åñëè óñëîâèå áûëî ëîæíûì. Íàïðèìåð, òó æå çàäà÷ó î âûâîäå ìîäóëÿ ÷èñëà ìîæíî áûëî ðåøèòü, íå ìåíÿÿ çíà÷åíèÿ ïåðåìåííîé x: x = i n t ( input ( ) ) 20ЛЕКЦИЯ 2. ЛОГИЧЕСКИЙ ТИП ДАННЫХ, УСЛОВНЫЙ ОПЕРАТОР, ЦИКЛ WHILE, ВЕЩЕС if x > 0: print ( x ) else : print (− x ) Âñå êîìàíäû, êîòîðûå âûïîëíÿþòñÿ â áëîêå else, äîëæíû áûòü òàêæå çàïèñàíû ñ îòñòóïîì. Else äîëæåí ñëåäîâàòü ñðàçó çà áëîêîì êîìàíä if, áåç ïðîìåæóòî÷íûõ êîìàíä, âûïîëíÿåìûõ áåçóñëîâíî. Else áåç ñîîòâåòñòâóþùåãî if'à íå èìååò ñìûñëà. Åñëè ïîñëå if çàïèñàíî íå ëîãè÷åñêîå âûðàæåíèå, òî îíî áóäåò ïðèâåäåíî ê ëîãè÷åñêîìó, êàê åñëè áû îò íåãî áûëà âûçâàíà ôóíêöèÿ bool. Îäíàêî, çëîóïîòðåáëÿòü ýòèì íå ñëåäóåò, ò.ê. ýòî óõóäøàåò ÷èòàåìîñòü êîäà. Äëÿ ïîäñ÷åòà ìîäóëÿ ÷èñëà â Ïèòîíå ñóùåñòâóåò ôóíêöèÿ abs, êîòîðàÿ èçáàâëÿåò îò íåîáõîäèìîñòè êàæäûé ðàç ïèñàòü ïîäñ÷åò ìîäóëÿ âðó÷íóþ. 2.5 Вложенный условный оператор Âíóòðè áëîêà êîìàíä ìîãóò íàõîäèòüñÿ äðóãèå óñëîâíûå îïåðàòîðû. Ïîñìîòðèì ñðàçó íà ïðèìåðå. Ïî çàäàííîìó êîëè÷åñòâó ãëàç è íîã íóæíî íàó÷èòüñÿ îòëè÷àòü êîøêó, ïàóêà, ìîðñêîãî ãðåáåøêà è æó÷êà. Ó ìîðñêîãî ãðåáåøêà áûâàåò áîëåå ñîòíè ãëàç, à ó ïàóêîâ èõ âîñåìü. Òàêæå ó ïàóêîâ âîñåìü íîã, à ó ìîðñêîãî ãðåáåøêà èõ íåò ñîâñåì. Ó êîøêè ÷åòûðå íîãè, à ó æó÷êà øåñòü íîã, íî ãëàç ó îáîèõ ïî äâà. Ðåøåíèå: e y e s = i n t ( input ( ) ) l e g s = i n t ( input ( ) ) i f e y e s >= 8 : i f l e g s == 8 : print ( " s p i d e r " ) else : print ( " s c a l l o p " ) else : i f l e g s == 6 : print ( "bug" ) else : print ( " c a t " ) Åñëè âëîæåííûõ óñëîâíûõ îïåðàòîðîâ íåñêîëüêî, òî, ê êàêîìó èç íèõ îòíîñèòñÿ else, ìîæíî ïîíÿòü ïî îòñòóïó. Îòñòóï ó else äîëæåí áûòü òàêîé æå, êàê ó if, ê êîòîðîìó îí îòíîñèòñÿ. 2.6 Конструкция ”иначе-если” Â íåêîòîðûõ ñèòóàöèÿõ íåîáõîäèìî îñóùåñòâèòü âûáîð áîëüøå ÷åì èç äâóõ âàðèàíòîâ, êîòîðûå ìîãóò áûòü îáðàáîòàíû ñ ïîìîùüþ if-else. Ðàññìîòðèì ïðèìåð: íåîáõîäèìî âûâåñòè ñëîâîì íàçâàíèå ÷èñëà 1 èëè 2 èëè ñîîáùèòü, ÷òî ýòî äðóãîå ÷èñëî: number = i n t ( input ( ) ) i f number == 1 : print ( ' One ' ) 2.7. ЦИКЛ WHILE 21 e l i f number == 2 : print ( 'Two ' ) else : print ( ' Other ' ) Çäåñü èñïîëüçóåòñÿ ñïåöèàëüíàÿ êîíñòðóêöèÿ elif, îáîçíà÷àþùàÿ ¾èíà÷å, åñëè¿, ïîñëå êîòîðîé çàïèñûâàåòñÿ óñëîâèå. Òàêàÿ êîíñòðóêöèÿ ââåäåíà â ÿçûê Ïèòîí, ïîòîìó ÷òî çàïèñü if-else ïðèâåäåò ê óâåëè÷åíèþ îòñòóïà è óõóäøåíèþ ÷èòàåìîñòè. Êîíñòðóêöèé elif ìîæåò áûòü íåñêîëüêî, óñëîâèÿ ïðîâåðÿþòñÿ ïîñëåäîâàòåëüíî. Êàê òîëüêî óñëîâèå âûïîëíåíî çàïóñêàåòñÿ ñîîòâåòñòâóþùèé ýòîìó óñëîâèþ áëîê êîìàíä è äàëüíåéøàÿ ïðîâåðêà íå âûïîëíÿåòñÿ. Áëîê else ÿâëÿåòñÿ íåîáÿçàòåëüíûì, êàê è â îáû÷íîì if. 2.7 Цикл while While ïåðåâîäèòñÿ êàê ¾ïîêà¿ è ïîçâîëÿåò âûïîëíÿòü êîìàíäû, äî òåõ ïîð, ïîêà óñëîâèå âåðíî. Ïîñëå îêîí÷àíèÿ âûïîëíåíèÿ áëîêà êîìàíä, îòíîñÿùèõñÿ ê while, óïðàâëåíèå âîçâðàùàåòñÿ íà ñòðîêó ñ óñëîâèåì è, åñëè îíî âûïîëíåíî, òî âûïîëíåíèå áëîêà êîìàíä ïîâòîðÿåòñÿ, à åñëè íå âûïîëíåíî, òî ïðîäîëæàåòñÿ âûïîëíåíèå êîìàíä, çàïèñàííûõ ïîñëå while. Ñ ïîìîùüþ while î÷åíü ëåãêî îðãàíèçîâàòü âå÷íûé öèêë, ïîýòîìó íåîáõîäèìî ñëåäèòü çà òåì, ÷òîáû â áëîêå êîìàíä ïðîèñõîäèëè èçìåíåíèÿ, êîòîðûå ïðèâåäóò ê òîìó, ÷òî â êàêîé-òî ìîìåíò óñëîâèå ïåðåñòàíåò áûòü èñòèííûì. Ðàññìîòðèì íåñêîëüêî ïðèìåðîâ. Åñòü ÷èñëî 𝑁 . Íåîáõîäèìî âûâåñòè âñå ÷èñëà ïî âîçðàñòàíèþ îò 1 äî 𝑁 . Äëÿ ðåøåíèÿ ýòîé çàäà÷è íóæíî çàâåñòè ñ÷¼ò÷èê (ïåðåìåííóþ i), êîòîðûé áóäåò ðàâåí òåêóùåìó ÷èñëó. Âíà÷àëå ýòî åäèíèöà. Ïîêà çíà÷åíèå ñ÷åò÷èêà íå ïðåâûñèò 𝑁 , íåîáõîäèìî âûâîäèòü åãî òåêóùåå çíà÷åíèå è êàæäûé ðàç óâåëè÷èòü åãî íà åäèíèöó: n = i n t ( input ( ) ) i = 1 while i <= n : print ( i ) i = i + 1 Åùå îäíà ÷àñòî âñòðå÷àþùàÿñÿ çàäà÷à ïîèñê ìèíèìóìà (èëè ìàêñèìóìà) â ïîñëåäîâàòåëüíîñòè ÷èñåë. Ïóñòü çàäàíà ïîñëåäîâàòåëüíîñòü ÷èñåë, îêàí÷èâàþùàÿñÿ íóë¼ì. Íåîáõîäèìî íàéòè ìèíèìàëüíîå ÷èñëî â ýòîé ïîñëåäîâàòåëüíîñòè. Ýòà çàäà÷à ìîæåò áûòü ðåøåíà ÷åëîâåêîì: êàæäûé ðàç êîãäà åìó íàçûâàþò î÷åðåäíîå ÷èñëî, îí ñðàâíèâàåò åãî ñ òåêóùèì çàïîìíåííûì ìèíèìóìîì è, ïðè íåîáõîäèìîñòè, çàïîìèíàåò íîâîå ìèíèìàëüíîå ÷èñëî.  êà÷åñòâå ïåðâîãî çàïîìíåííîãî ÷èñëà íóæíî âçÿòü ïåðâûé ýëåìåíò ïîñëåäîâàòåëüíîñòè, êîòîðûé äîëæåí áûòü ñ÷èòàí îòäåëüíî äî öèêëà. now = i n t ( input ( ) ) nowMin = now while now != 0 : i f now < nowMin : nowMin = now now = i n t ( input ( ) ) 22ЛЕКЦИЯ 2. ЛОГИЧЕСКИЙ ТИП ДАННЫХ, УСЛОВНЫЙ ОПЕРАТОР, ЦИКЛ WHILE, ВЕЩЕС print ( nowMin ) Òàêæå ÷àñòî âîçíèêàåò çàäà÷à î ïîäñ÷åòå ñóììû ïîñëåäîâàòåëüíîñòè. Äëÿ ïîäñ÷åòà ñóììû ÷èñåë íåîáõîäèìî çàâåñòè ïåðåìåííóþ, êîòîðàÿ áóäåò õðàíèòü íàêîïëåííóþ íà äàííûé ìîìåíò ñóììó è, ïðè ÷òåíèè î÷åðåäíîãî ÷èñëà, ïðèáàâëÿòü åãî ê íàêîïëåííîé ñóììå: now = i n t ( input ( ) ) seqSum = 0 while now != 0 : seqSum = seqSum + now now = i n t ( input ( ) ) print ( seqSum ) 2.8 Инструкции управления циклом Äëÿ óïðàâëåíèÿ ïîâåäåíèåì öèêëà ìîæíî èñïîëüçîâàòü äâå èíñòðóêöèè, êîòîðûå ïîçâîëÿþò äîñðî÷íî ïðåðûâàòü âûïîëíåíèå öèêëà èëè íà÷èíàòü âûïîëíåíèå èíñòðóêöèé öèêëà ñíà÷àëà. Ïåðâàÿ êîìàíäà íàçûâàåòñÿ break. Ïîñëå å¼ âûïîëíåíèÿ ðàáîòà öèêëà ïðåêðàùàåòñÿ (êàê áóäòî íå áûëî âûïîëíåíî óñëîâèå öèêëà). Îñìûñëåííîå èñïîëüçîâàíèå êîíñòðóêöèè break âîçìîæíî, òîëüêî åñëè âûïîëíåíî êàêîå-òî óñëîâèå, òî åñòü break äîëæåí âûçûâàòüñÿ òîëüêî âíóòðè if (íàõîäÿùåãîñÿ âíóòðè öèêëà). Èñïîëüçîâàíèå break ïëîõîé òîí, ïî âîçìîæíîñòè, ñëåäóåò îáõîäèòüñÿ áåç íåãî. Ðàññìîòðèì ïðèìåð âå÷íîãî öèêëà, âûõîä èç êîòîðîãî îñóùåñòâëÿåòñÿ ñ ïîìîùüþ break. Äëÿ ýòîãî ðåøèì çàäà÷ó î âûâîäå âñåõ öåëûõ ÷èñåë îò 1 äî 100. Èñïîëüçîâàòü break òàêèì îáðàçîì íè â êîåì ñëó÷àå íå íóæíî, ýòî ïðîñòî ïðèìåð: i = 1 while True : print ( i ) i = i + 1 i f i > 100: break Êîìàíäà continue íà÷èíàåò èñïîëíåíèå òåëà öèêëà çàíîâî, íà÷èíàÿ ñ ïðîâåðêè óñëîâèÿ. ż íóæíî èñïîëüçîâàòü, åñëè íà÷èíàÿ ñ êàêîãî-òî ìåñòà â òåëå öèêëà è ïðè âûïîëíåíèè êàêèõ-òî óñëîâèé äàëüíåéøèå äåéñòâèÿ íåæåëàòåëüíû. Ïðèâåä¼ì ïðèìåð èñïîëüçîâàíèÿ continue (õîòÿ ïðè ðåøåíèè ýòîé çàäà÷è ìîæíî è íóæíî îáõîäèòüñÿ áåç íåãî): äàíà ïîñëåäîâàòåëüíîñòü ÷èñåë, îêàí÷èâàþùàÿñÿ íóë¼ì. Íåîáõîäèìî âûâåñòè âñå ïîëîæèòåëüíûå ÷èñëà èç ýòîé ïîñëåäîâàòåëüíîñòè. Ðåøåíèå: now = −1 while now != 0 : now = i n t ( input ( ) ) i f now <= 0 : continue ; print ( now ) 2.9. ОСНОВЫ РАБОТЫ С ВЕЩЕСТВЕННЫМИ ЧИСЛАМИ 23  ýòîì ðåøåíèè åñòü èíòåðåñíûé ìîìåíò: ïåðåä öèêëîì ïåðåìåííàÿ èíèöèàëèçèðóåòñÿ çàâåäîìî ïîäõîäÿùèì çíà÷åíèåì. Êîìàíäà âûâîäà áóäåò âûïîëíÿòüñÿ òîëüêî â òîì ñëó÷àå, åñëè íå âûïîëíèòñÿ óñëîâèå â if.  ÿçûêå Ïèòîí ê öèêëó while ìîæíî íàïèñàòü áëîê else. Êîìàíäû â ýòîì áëîêå áóäóò âûïîëíÿòüñÿ, åñëè öèêë çàâåðøèë ñâîþ ðàáîòó íîðìàëüíûì îáðàçîì (ò.å. óñëîâèå â êàêîé-òî ìîìåíò ïåðåñòàëî áûòü èñòèííûì) è íå áóäóò âûïîëíÿòüñÿ òîëüêî â ñëó÷àå, åñëè âûõîä èç öèêëà ïðîèçîøåë ñ ïîìîùüþ êîìàíäû break. 2.9 Основы работы с вещественными числами Êðîìå öåëûõ ÷èñåë â ÿçûêå Ïèòîí òàêæå èìåþòñÿ âåùåñòâåííûå ÷èñëà.  îòëè÷èå îò öåëûõ ÷èñåë îíè èìåþò îãðàíè÷åííóþ òî÷íîñòü è èñïîëüçîâàòü èõ íóæíî òîëüêî â ñèòóàöèÿõ, êîãäà öåëûå ÷èñëà èñïîëüçîâàòü ñîâåðøåííî íåâîçìîæíî. Äëÿ ïðåîáðàçîâàíèÿ ñòðîêè â âåùåñòâåííîå ÷èñëî èñïîëüçóåòñÿ ôóíêöèÿ oat. Âåùåñòâåííûå ÷èñëà ìîæíî èñïîëüçîâàòü â àðèôìåòè÷åñêèõ âûðàæåíèÿõ âìåñòå ñ öåëûìè ÷èñëàìè, ïðè ýòîì ðåçóëüòàò áóäåò âåùåñòâåííûì ÷èñëîì. Âñå àðèôìåòè÷åñêèå îïåðàöèè ñ öåëûìè ÷èñëàìè òàêæå ïðèìåíèìû è ê âåùåñòâåííûì ÷èñëàì ñ òåì æå ñìûñëîì. Êðîìå äåëåíèÿ â öåëûõ ÷èñëàõ, ñóùåñòâóåò òàêæå îáû÷íîå äåëåíèå, êîòîðîå îáîçíà÷àåòñÿ çíàêîì /. Ðåçóëüòàò òàêîãî äåëåíèÿ âñåãäà ÿâëÿåòñÿ âåùåñòâåííûì ÷èñëîì, äàæå åñëè îáà îïåðàíäà áûëè öåëûìè. Áîëåå ïîäðîáíî âåùåñòâåííûå ÷èñëà áóäóò èçó÷åíû â ñëåäóþùåé ëåêöèè. 24ЛЕКЦИЯ 2. ЛОГИЧЕСКИЙ ТИП ДАННЫХ, УСЛОВНЫЙ ОПЕРАТОР, ЦИКЛ WHILE, ВЕЩЕС Лекция 3 Вещественные числа и строки 3.1 Вещественные числа в памяти компьютера  îòëè÷èå îò öåëûõ ÷èñåë, âåùåñòâåííûå ÷èñëà â ÿçûêå Ïèòîí èìåþò îãðàíè÷åííóþ äëèíó. Ïîäóìàåì, êàê õðàíèòü äåñÿòè÷íóþ äðîáü â ïàìÿòè. Ïîñêîëüêó âåùåñòâåííûõ ÷èñåë áåñêîíå÷íî ìíîãî (äàæå áîëüøå, ÷åì íàòóðàëüíûõ), òî íàì ïðèäåòñÿ îãðàíè÷èòü òî÷íîñòü. Íàïðèìåð, ìû ìîæåì õðàíèòü òîëüêî íåñêîëüêî ïåðâûõ çíà÷àùèõ öèôð, íå õðàíÿ íåçíà÷àùèå íóëè. Áóäåì îòäåëüíî õðàíèòü öåëîå ÷èñëî ñ ïåðâûìè çíà÷àùàìè öèôðàìè è îòäåëüíî õðàíèòü ñòåïåíü ÷èñëà 10, íà êîòîðóþ íóæíî óìíîæèòü ýòî ÷èñëî. Íàïðèìåð, ÷èñëî 5.972 × 1024 (ýòî ìàññà Çåìëè â êèëîãðàììàõ) ìîæíî ñîõðàíèòü êàê 5972 (öèôðû ÷èñëà, ìàíòèññà) è 21 (íà êàêóþ ñòåïåíü 10 íóæíî óìíîæèòü ÷èñëî, ýêñïîíåíòà). Ñ ïîìîùüþ òàêîãî ïðåäñòàâëåíèÿ ìîæíî õðàíèòü âåùåñòâåííûå ÷èñëà ëþáîé ðàçìåðíîñòè. Ïðèìåðíî òàê è õðàíÿòñÿ ÷èñëà â ïàìÿòè êîìïüþòåðà, îäíàêî âìåñòî äåñÿòè÷íîé ñèñòåìû èñïîëüçóåòñÿ äâîè÷íûå. Íà áîëüøèíñòâå àïïàðàòíûõ ñèñòåì â ÿçûêå Ïèòîí äëÿ õðàíåíèÿ oat èñïîëüçóåòñÿ 64 áèòà, èç êîòîðûõ 1 áèò óõîäèò íà çíàê, 52 áèòà íà ìàíòèññó è 11 áèò íà ýêñïîíåíòó. 53 áèòà äàþò îêîëî 15-16 äåñÿòè÷íûõ çíàêîâ, êîòîðûå áóäóò õðàíèòñÿ òî÷íî. 11 áèò íà ýêñïîíåíòó òàêæå íàêëàäûâàåò îãðàíè÷åíèÿ íà ðàçìåðíîñòü õðàíèìûõ ÷èñåë (ïðèìåðíî îò 10−1000 äî 101000 ). Ëþáîå âåùåñòâåííîå ÷èñëî íà ÿçûêå Ïèòîí ïðåäñòàâèìî â âèäå äðîáè, ãäå â ÷èñëèòåëå õðàíèòñÿ öåëîå ÷èñëî, à â çíàìåíàòåëå íàõîäèòñÿ êàêàÿ ëèáî ñòåïåíü äâîéêè. Íàïðèìåð, 0.125 ïðåäñòàâèìî êàê 1/8, à 0.1 êàê 3602879701896397/36028797018963968. Íåñëîæíî çàìåòèòü, ÷òî ýòà äðîáü íå ðàâíî 0.1, ò.å. õðàíåíèå ÷èñëà 0.1 òî÷íî â òèïå oat íåâîçìîæíî, êàê è ìíîãèõ äðóãèõ ¾êðàñèâûõ¿ äåñÿòè÷íûõ äðîáåé. 3.2 Запись, ввод и вывод вещественных чисел Äëÿ çàïèñè êîíñòàíò èëè ïðè ââîäå-âûâîäå ìîæåò èñïîëüçîâàòüñÿ êàê ïðèâû÷íîå ïðåäñòàâëåíèå â âèäå äåñÿòè÷íî äðîáè, íàïðèìåð 123.456, òàê è ¾èíæåíåðíàÿ¿ çàïèñü ÷èñëà, ãäå ìàíòèññà çàïèñûâàåòñÿ â âèäå âåùåñòâåííîãî ÷èñëà ñ îäíîé öèôðîé äî òî÷êè è íåêîòîðûì êîëè÷åñòâîì öèôð ïîñëå òî÷êè, çàòåì ñëåäóåò áóêâà e (èëè E) è 25 26 ЛЕКЦИЯ 3. ВЕЩЕСТВЕННЫЕ ЧИСЛА И СТРОКИ ýêñïîíåíòà. ×èñëî 123.456 â èíæåíåðíîé çàïèñè áóäåò âûãëÿäåòü êàê 1.23456e2, ÷òî îçíà÷àåò, ÷òî 1.23456 íóæíî óìíîæèòü íà 102 . È ìàíòèññà è ýêñïîíåíòà ìîãóò áûòü îòðèöàòåëüíûìè è çàïèñûâàþòñÿ â äåñÿòè÷íîé ñèñòåìå. Òàêàÿ çàïèñü ÷èñåë ìîæåò ïðèìåíÿòüñÿ ïðè ñîçäàíèè âåùåñòâåííûõ êîíñòàíò, à òàêæå ïðè ââîäå è âûâîäå. Èíæåíåðíàÿ çàïèñü óäîáíà äëÿ õðàíåíèÿ î÷åíü áîëüøèõ èëè î÷åíü ìàëåíüêèõ ÷èñåë, ÷òîáû íå ñ÷èòàòü êîëè÷åñòâî íóëåé â íà÷àëå èëè êîíöå ÷èñëà. Åñëè õî÷åòñÿ âûâåñòè ÷èñëî íå â èíæåíåðíîé çàïèñè, à ñ ôèêñèðîâàííûì êîëè÷åñòâîì çíàêîâ ïîñëå òî÷êè, òî ñëåäóåò âîñïîëüçîâàòüñÿ ìåòîäîì format, êîòîðûé èìååò ìàññó âîçìîæíîñòåé. Íàì íóæåí òîëüêî âûâîä ôèêñèðîâàííîãî êîëè÷åñòâà çíàêîâ, ïîýòîìó âîñïîëüçóåìñÿ ãîòîâûì ðåöåïòîì äëÿ âûâîäà 25 çíàêîâ ïîñëå äåñÿòè÷íîé òî÷êè ó ÷èñëà 0.1: x = 0.1 print ( ' { 0 : . 2 5 f } ' . format ( x ) ) Âûâîä òàêîé ïðîãðàììû áóäåò âûãëÿäåòü êàê 0.1000000000000000055511151, ÷òî åùå ðàç ïîäòâåðæäàåò ìûñëü î òîì, ÷òî ÷èñëî 0.1 íåâîçìîæíî ñîõðàíèòü òî÷íî. 3.3 Проблемы вещественных чисел Ðàññìîòðèì ïðîñòîé ïðèìåð: 0 . 1 + 0 . 2 == 0 . 3 : print ( ' A l l r i g h t ' ) else : print ( 'WTF? ! ' ) if Åñëè çàïóñòèòü ýòó ïðîãðàììó, òî ìîæíî ëåãêî óáåäèòüñÿ â òîì, ÷òî 0.1 + 0.2 íå ðàâíî 0.3. Õîòÿ ìîæíî áûëî íàäåÿòñÿ, ÷òî íåñìîòðÿ íà íåòî÷íîå ïðåäñòàâëåíèå, îíî îêàæåòñÿ îäèíàêîâî íåòî÷íûì äëÿ âñåõ ÷èñåë. Ïîýòîìó ïðè èñïîëüçîâàíèè âåùåñòâåííûõ ÷èñåë íóæíî ñëåäîâàòü íåñêîëüêèì ïðîñòûì ïðàâèëàì: 1. Åñëè ìîæíî îáîéòèñü áåç èñïîëüçîâàíèÿ âåùåñòâåííûõ ÷èñåë íóæíî ýòî ñäåëàòü. Âåùåñòâåííûå ÷èñëà ïðîáëåìíûå, íåòî÷íûå è ìåäëåííûå. 2. Äâå âåùåñòâåííûõ ÷èñëà ðàâíû ìåæäó ñîáîé, åñëè îíè îòëè÷àþòñÿ íå áîëåå ÷åì íà 𝜖. ×èñëî 𝑋 ìåíüøå ÷èñëà 𝑌 , åñëè 𝑋 < 𝑌 − 𝜖.  öåëîì áóäåò ïîëåçíî ïðåäñòàâëÿòü ñåáå âåùåñòâåííîå ÷èñëî 𝑋 êàê îòðåçîê [𝑋 − 𝜖; 𝑋 + 𝜖]. Êàê æå îïðåäåëèòü âåëè÷èíó 𝜖? Äëÿ ýòîãî íóæíî ïîíÿòü, ÷òî ïîãðåøíîñòü íå ÿâëÿåòñÿ àáñîëþòíîé, ò.å. îäèíàêîâîé äëÿ âñåõ ÷èñåë, à ÿâëÿåòñÿ îòíîñèòåëüíîé. Óïðîùåííî, àïïàðàòíóþ ïîãðåøíîñòü õðàíåíèÿ ÷èñëà 𝑋 ìîæíî îöåíèòü êàê 𝑋 × 2−54 . ×àùå âñåãî â çàäà÷àõ âõîäíûå äàííûå èìåþò îïðåäåëåííóþ òî÷íîñòü. Ðàññìîòðèì íà ïðèìåðå: çàäàíû äâà ÷èñëà 𝑋 è 𝑌 ñ òî÷íîñòüþ 6 çíàêîâ ïîñëå òî÷êè (çíà÷èò 𝜖 = 5*10−7 ) è ïî ìîäóëþ íå ïðåâîñõîäÿùèå 109 . Îöåíèòü àáñîëþòíóþ ïîãðåøíîñòü âû÷èñëåíèÿ 𝑋 × 𝑌 . Ðàññìîòðèì õóäøèé ñëó÷àé, êîãäà 𝑋 è 𝑌 ðàâíû 109 è îòêëîíèëèñü íà ìàêñèìàëüíî âîçìîæíîå çíà÷åíèå 𝜖 â îäíó ñòîðîíó. Òîãäà ðåçóëüòàò âû÷èñëåíèÿ áóäåò âûãëÿäåòü òàê: 3.4. ОКРУГЛЕНИЕ ВЕЩЕСТВЕННЫХ ЧИСЕЛ 27 (𝑋 + 𝜖) × (𝑌 + 𝜖) = 𝑋𝑌 + (𝑋 + 𝑌 ) × 𝜖 + 𝜖2 Âåëè÷èíà 𝜖2 ïðåíåáðåæèìî ìàëà, 𝑋𝑌 ýòî ïðàâèëüíûé îòâåò, à (𝑋 + 𝑌 ) × 𝜖 èñêîìîå çíà÷åíèå àáñîëþòíîé ïîãðåøíîñòè. Ïîäñòàâèì ÷èñëà è ïîëó÷èì: 2 × 109 × 5 * 10−7 = 103 Àáñîëþòíàÿ ïîãðåøíîñòü âû÷èñëåíèÿ ñîñòàâèëà 1000 (îäíó òûñÿ÷ó). ×òî äîâîëüíî íåîæèäàííî è ãðóñòíî. Òàêèì îáðàçîì, ñòàíîâèòñÿ ïîíÿòíî, ÷òî íóæíî àêêóðàòíî âû÷èñëÿòü çíà÷åíèå ïîãðåøíîñòè äëÿ ñðàâåíèÿ âåùåñòâåííûõ ÷èñåë. Êîä äëÿ ñðàâíåíèÿ äâóõ ÷èñåë, çàäàííûõ ñ òî÷íîñòüþ 6 çíàêîâ ïîñëå òî÷êè, âûãëÿäèò òàê: x = f l o a t ( input ( ) ) y = f l o a t ( input ( ) ) e p s i l o n = 5 * 10 **− 7 i f abs ( x − y ) < 2 * e p s i l o n : print ( ' Equal ' ) else : print ( ' Not e a u a l ' )  ñëó÷àå, åñëè íàä ÷èñëàìè ñîâåðøàëèñü êàêèå-òî äåéñòâèÿ, òî çíà÷åíèÿ 𝜖 íóæíî âû÷èñëÿòü êàê â ïðèâåäåííîì âûøå ïðèìåðå.  ó÷åáíûõ çàäà÷àõ ýòî ìîæíî ñäåëàòü íå âíóòðè ïðîãðàììû, à îäèí ðàç ðóêàìè äëÿ õóäøåãî ñëó÷àÿ è ïðèìåíÿòü âû÷èñëåííîå çíà÷åíèå êàê êîíñòàíòó. 3.4 Округление вещественных чисел Ïðè èñïîëüçîâàíèè öåëûõ è âåùåñòâåííûõ ÷èñåë â îäíîì âûðàæåíèè âû÷èñëåíèÿ ïðîèçâîäÿòñÿ â âåùåñòâåííûõ ÷èñëàõ. Òåì íå ìåíåå, èíîãäà âîçíèêàåò íåîáõîäèìîñòü ïðåîáðàçîâàòü âåùåñòâåííîå ÷èñëî â öåëîå. Äëÿ ýòîãî ìîæíî èñïîëüçîâàòü íåñêîëüêî âèäîâ ôóíêöèé îêðóãëåíèÿ: ∙ int îêðóãëÿåò â ñòîðîíó íóëÿ (îòáðàñûâåò äðîáíóþ ÷àñòü) ∙ round îêðóãëÿåò äî áëèæàéøåãî öåëîãî, åñëè áëèæàéøèõ öåëûõ íåñêîëüêî (äðîáíàÿ ÷àñòü ðàâíî 0.5), òî ê ÷åòíîìó ∙ oor îêðóãëÿåò â ìåíüøóþ ñòîðîíó ∙ ceil îêðóãëÿåò â áîëüøóþ ñòîðîíó Ïðèìåðû äëÿ ðàçëè÷íûõ ÷èñåë: Ôóíêöèÿ 2.5 3.5 -2.5 int 2 3 -2 round 2 4 -2 oor 2 3 -3 ceil 3 4 -3 28 ЛЕКЦИЯ 3. ВЕЩЕСТВЕННЫЕ ЧИСЛА И СТРОКИ Ôóíêöèè oor è ceil íàõîäÿòñÿ â áèáëèîòåêå math. Åñòü äâà ñïîñîáà ïîëó÷èòü âîñïîëüçîâàòüñÿ èìè â ñâîåé ïðîãðàììå.  ïåðâîì ñïîñîáå èìïîðòèðóåòñÿ áèáëèîòåêà math, òîãäà ïåðåä êàæäûì âûçîâîì ôóíêöèè îòòóäà íóæíî ïèñàòü ñëîâî math., à çàòåì èìÿ ôóíêöèè: import math print ( math . f l o o r ( − 2 . 5 ) ) print ( math . c e i l ( − 2 . 5 ) ) Âî âòîðîì ñïîñîáå èç áèáëèîòåêè èìïîðòèðóþòñÿ íåêîòîðûå ôóíêöèè è äîñòóï ê íèì ìîæíî ïîëó÷èòü áåç íàïèñàíèÿ math.: from math import f l o o r , ceil print ( f l o o r ( − 2 . 5 ) ) print ( c e i l ( − 2 . 5 ) ) Âòîðîé ñïîñîá ïðåäïî÷òèòåëüíî ïðèìåíÿòü â ñëó÷àå, åñëè êàêèå-òî ôóíêöèè èñïîëüçóþòñÿ ÷àñòî è íåò êîíôëèêòà èìåí (ôóíêöèé ñ îäèíàêîâûìè èìåíàìè â íåñêîëüêèõ ïîäêëþ÷åííûõ áèáëèîòåêàõ).  áèáëèîòåêå math òàêæå åñòü ôóíêöèÿ îêðóãëåíèÿ trunc, êîòîðàÿ ðàáîòàåò àíàëîãè÷íî int. 3.5 Полезные функции библиотеки math Êðîìå ôóíêöèé îêðóãëåíèÿ â áèáëèîòåêå math íàõîäèòñÿ ìàññà ïîëåçíûõ ôóíêöèé, êîòîðûå ïðèâåäåíû íèæå: sqrt(x) Êâàäðàòíûé êîðåíü. pow(a, b) Âîçâåäåíèå â ñòåïåíü, âîçâðàùàåò 𝑎𝑏 . exp(x) Ýêñïîíåíòà, âîçâðàùàåò 𝑒𝑥 . log(x) Íàòóðàëüíûé ëîãàðèôì. log(x, b) Ëîãàðèôì x ïî îñíîâàíèþ b. log10(x) Äåñÿòè÷íûé ëîãàðèôì. e Îñíîâàíèå íàòóðàëüíûõ ëîãàðèôìîâ 𝑒 ≈ 2.71828. sin(x) Ñèíóñ óãëà, çàäàâàåìîãî â ðàäèàíàõ. cos(x) Êîñèíóñ óãëà, çàäàâàåìîãî â ðàäèàíàõ. tan(x) Òàíãåíñ óãëà, çàäàâàåìîãî â ðàäèàíàõ. asin(x) Àðêñèíóñ, âîçâðàùàåò çíà÷åíèå â ðàäèàíàõ. acos(x) Àðêêîñèíóñ, âîçâðàùàåò çíà÷åíèå â ðàäèàíàõ. atan(x) Àðêòàíãåíñ, âîçâðàùàåò çíà÷åíèå â ðàäèàíàõ. atan2(y, x) Ïîëÿðíûé óãîë (â ðàäèàíàõ) òî÷êè ñ êîîðäèíàòàìè (x, y). hypot(a, b) Äëèíà ãèïîòåíóçû ïðÿìîóãîëüíîãî òðåóãîëüíèêà ñ êàòåòàìè a è b. degrees(x) Ïðåîáðàçóåò óãîë, çàäàííûé â ðàäèàíàõ, â ãðàäóñû. radians(x) Ïðåîáðàçóåò óãîë, çàäàííûé â ãðàäóñàõ, â ðàäèàíû. pi Êîíñòàíòà 𝜋 . 3.6. 3.6 СРЕЗЫ СТРОК 29 Срезы строк Íàì èçâåñòíû ñïîñîáû ñ÷èòûâàòü, âûâîäèòü è çàäàâàòü êîíñòàíòíûå ñòðîêè, à òàêæå ñêëåèâàòü ñòðîêè ìåæäó ñîáîé è óìíîæàòü ñòðîêó íà ÷èñëî. ×òîáû îïðåäåëèòü äëèíó ñòðîêè s ìîæíî âîñïîëüçîâàòüñÿ ôóíêöèåé len(s) îíà âîçâðàùàåò öåëîå ÷èñëî, ðàâíîå äëèíå ñòðîêè. Ñðåç ýòî ñïîñîá èçâëå÷ü èç ñòðîêè îòäåëüíûå ñèìâîëû èëè ïîäñòðîêè. Ïðè ïðèìåíåíèè ñðåçà êîíñòðóèðóåòñÿ íîâàÿ ñòðîêà, ñòðîêà, ê êîòîðîé áûë ïðèìåí¼í ñðåç, îñòàåòñÿ áåç èçìåíåíèé. Ïðîñòåéøèé âèä ñðåçà ýòî îáðàùåíèå ê êîíêðåòíîìó ñèìâîëó ñòðîêè ïî íîìåðó. ×òîáû ïîëó÷èòü i-ûé ñèìâîë ñòðîêè íóæíî íàïèñàòü s[i].  ðåçóëüòàòå ýòîãî áóäåò ñêîíñòðóèðîâàíà ñòðîêà, ñîäåðæàùàÿ òîëüêî îäèí ñèìâîë òîò, êîòîðûé ñòîÿë íà ìåñòå i. Íóìåðàöèÿ ñèìâîë èäåò ñ íóëÿ, ïðè ïîïûòêå îáðàòèòüñÿ ê ñèìâîëó ñ íîìåðîì áîëüøå ëèáî ðàâíîì äëèíå ñòðîêè âîçíèêàåò îøèáêà.  ÿçûêå Ïèòîí ïðèñóòñòâóåò è íóìåðàöèÿ ñèìâîëîâ ñòðîêè îòðèöàòåëüíûìè ÷èñëàìè. Ïîñëåäíèé ñèìâîë ñòðîêè èìååò íîìåð −1, ïðåäïîñëåíäèé −2 è òàê äàëåå. Ïðè ïîïûòêå îáðàòèòüñÿ ê ñèìâîëó ñ íîìåðîì, ìåíüøèì ÷åì -len(s) âîçíèêàåò îøèáêà. Íóìåðàöèÿ ñèìâîëîâ â ñòðîêå String ïðåäñòàâëåíà â òàáëèöå: S t r i n g 0 1 2 3 4 5 -6 -5 -4 -3 -2 -1 Ïîëó÷èòü äîñòóï, íàïðèìåð, ê ñèìâîëó n, ìîæíî äâóìÿ ñïîñîáàìè s[4] è s[-2]. Òàêæå ñóùåñòâóþò ñðåçû ñ äâóìÿ ïàðàìåòðàìè: â ðåçóëüòàòå ïðèìåíåíèÿ ñðåçà s[a:b] áóäåò ñêîíñòðóèðîâàíà ïîäñòðîêà íà÷èíàÿ ñ ñèìâîëà íà ïîçèöèè 𝑎 è çàêàí÷èâàÿ ñèìâîëîì íà ïîçèöèè 𝑏 − 1 (ïðàâàÿ ãðàíèöà íå âêëþ÷àåòñÿ). Êàæäûé èç èíäåêñîâ ìîæåò áûòü êàê ïîëîæèòåëüíûì, òàê è îòðèöàòåëüíûì. Íàïðèìåð, ïðè s = "String s[1:5] áóäåò ðàâíî "trin ýòî ìîæíî áûëî áû çàïèñàòü è êàê s[1:-1]. Åñëè â êà÷åñòâå âòîðîãî ÷èñëà â ñðåçå âçÿòü ÷èñëî, áîëüøå ëèáî ðàâíîå äëèíå ñòðîêè, òî îøèáêè íå âîçíèêíåò è áóäóò âçÿòû âñå ñèìâîëû äî êîíöà ñòðîêè.  ñëó÷àå, åñëè íóæíî âçÿòü âñå ñèìâîëû ñòðîêè íà÷èíàÿ ñ ïîçèöèè a è äî êîíöà, òî âòîðîé ïàðàìåòð ìîæíî îïóñêàòü. Íàïðèìåð, s[2:] áóäåò ðàâíî "ring". Åñëè îïóñòèòü ïåðâûé ïàðàìåòð â ñðåçå, òî áóäåò âçÿòà ïîäñòðîêà ñ íà÷àëà, íàïðèìåð s[:2] áóäåò ðàâíî "St". Åñëè æå íàïèñàòü S[:] òî áóäåò âçÿòà âñÿ ñòðîêà îò íà÷àëà äî êîíöà. Åñëè ïåðâûé ïàðàìåòð íàõîäèòñÿ ïðàâåå âòîðîãî, òî áóäåò ñãåíåíðèðîâàíà ïóñòàÿ ñòðîêà. Òàêæå ñóùåñòâóåò ñðåç ñ òðåìÿ ïàðàìåòðàìè, ãäå òðåòèé ïàðàìåòð çàäàåò øàã, ñ êîòîðûì íóæíî áðàòü ñèìâîëû. Íàïðèìåð, ìîæíî âçÿòü âñå ñèìâîëû ñ íà÷àëà äî êîíöà ñ øàãîì 2, ýòî áóäåò âûãëÿäåòü êàê s[::2], â ðåçóëüòàòå ÷åãî ïîëó÷èòñÿ ñòðîêà "Srn". Åñòåñòâåíî, ïåðâûé è âòîðîé ïàðàìåòðû ìîæíî íå îïóñêàòü. Åñëè òðåòèé ïàðàìåòð íå óêàçàí, ò.å. â êâàäðàòíûõ ñêîáêàõ çàïèñàíî òîëüêî îäíî äâîåòî÷èå, òî øàã ñ÷èòàåòñÿ ðàâíûì 1. Øàã â ñðåçå ìîæåò áûòü è îòðèöàòåëüíûì, â òàêîì ñëó÷àå ïåðâûé ïàðàìåòð äîëæåí íàõîäèòñÿ ïðàâååå âòîðîãî. Íàïðèìåð, s[5:1:-2] äàñò ñòðîêó "gi- 5-ûé è 3-èé ñèìâîëû, à ñèìâîë ñ íîìåðîì 1 óæå íå âõîäèò. Ðàçâåðíóòóþ ñòðîêó ìîæíî ïîëó÷èòü ñðåçîì s[::1] âñå ñèìâîëû îò ¾íà÷àëà¿ äî ¾êîíöà¿ â îáðàòíîì ïîðÿäêå. Åñëè òðåòèé ïàðàìåòð îòðèöàòåëüíûé, òî íà÷àëîì ñðåçà ñ÷èòàåòñÿ ïîñëåäíèé ñèìâîë, à êîíöîì ïîçèöèÿ 30 ЛЕКЦИЯ 3. ВЕЩЕСТВЕННЫЕ ЧИСЛА И СТРОКИ ïåðåä íóëåâûì ñèìâîëîì. 3.7 Методы find и rfind Ìåòîäû ýòî ôóíêöèè, ïðèìåíÿåìûå ê îáúåêòàì. Ìåòîä âûçûâàåòñÿ ñ ïîìîùüþ çàïèñè ÈìÿÎáúåêòà.ÍàçâàíèåÌåòîäà(Ïàðàìåòðû). Ìåòîäû î÷åíü ïîõîæè íà ôóíêöèè, íî ïîçâîëÿþò ëó÷øèì îáðàçîì îðãàíèçîâûâàòü õðàíåíèå è îáðàáîòêó äàííûõ. Íàïðèìåð, âû íàïèñàëè ñâîþ ñòðóêòóðó äàííûõ è õîòåëè áû, ÷òîáû ôóíêöèÿ len âîçâðàùàëà äëèíó âàøåé ñòðóêòóðû. ×òîáû ýòî çàðàáîòàëî, âàì ïðèäåòñÿ ëåçòü â èñõîäíûé êîä èíòåðïðåòàòîðà Ïèòîíà è âíîñèòü èçìåíåíèÿ â ôóíêöèþ len. Åñëè áû len áûëî ìåòîäîì, òî âû ìîãëè áû îïèñàòü ýòîò ìåòîä ïðè ñîçäàíèè ñòðóêòóðû è íèêàêèõ èçìåíåíèé â êîäå èíòåðïðåòàòîðà èëè ñòàíäàðòíîé áèáëèîòåêè íå ïîòðåáîâàëîñü áû. Ïîýòîìó ìåòîäû ïðåäïî÷òèòåëüíåå äëÿ ñëîæíûõ ñòðóêòóð, íàïðèìåð, òàêèõ êàê ñòðîêè. Ó ñòðîê åñòü ìíîæåñòâî ðàçëè÷íûõ ìåòîäîâ.  ýòîì ðàçäåëå ìû ðàññìîòðèì ìåòîäû ïîèñêà ïîäñòðîêè â ñòðîêå. Ìåòîä nd âîçâðàùàåò èíäåêñ ïåðâîãî âõîæäåíèÿ ïîäñòðîêè â ñòðîêó, à åñëè îíà íå íàøëàñü −1. Íàïðèìåð, 'String'.nd('ing') âåðíåò 3 èíäåêñ, ñ êîòîðîãî íà÷èíàåòñÿ âõîæäåíèå ïîäñòðîêè ing. Ìåòîä rnd èùåò ñàìîå ïðàâîå âõîæäåíèå. Ñóùåñòâóþò ìîäèôèêàöèè ýòèõ ìåòîäîâ ñ äâóìÿ ïàðàìåòðàìè. s.nd(substring, from) áóäåò îñóùåñòâëÿòü ïîèñê â ïîäñòðîêå s[from:]. Íàïðèìåð, 'String'.nd('ing', 1) âåðíåò 3 (íóìåðàöèÿ ñèìâîëîâ îñòàåòñÿ êàê â èñõîäíîé ñòðîêå). Ïî àíàëîãèè ñî ñðåçàìè ïàðàìåòðû ìîãóò áûòü è îòðèöàòåëüíûìè. Òàêæå åñòü ìîäèôèêàöèè ñ òðåìÿ ïàðàìåòðàìè: îíè èùóò ïîäñòðîêó â ñðåçó s[a:b]. ×àñòî âîçíèêàåò çàäà÷à íàéòè è âûâåñòè âñå âõîæäåíèÿ ïîäñòðîêè â ñòðîêó, âêëþ÷àÿ íàêëàäûâàþùèåñÿ. Íàïðèìåð, äëÿ ñòðîêè 'ABABA' è ïîäñòðîêè 'ABA' îòâåò äîëæåí áûòü 0, 2. Åå ðåøåíèå âûãëÿäèò òàê: s t r i n g = input ( ) s u b s t r i n g = input ( ) pos = s t r i n g . f i n d ( s u b s t r i n g ) while pos != − 1: print ( pos ) pos = s t r i n g . f i n d ( s u b s t r i n g , pos + 1 ) 3.8 Методы replace и count Ìåòîä replace(old, new) ïîçâîëÿåò çàìåíèòü âñå âõîæäåíèÿ ïîäñòðîêè old íà ïîäñòðîêó new. Ïðè ýòîì êîíñòðóèðóåòñÿ íîâàÿ ñòðîêà, ãäå áûëè ïðîèçâåäåíû çàìåíû. Íóæíî îáðàòèòü âíèìàíèå, ÷òî ìåòîä replace çàìåíÿåò âõîæäåíèÿ ïîäñòðîê áåç ó÷åòà ïðåäûäóùèõ ñîâåðøåííûõ çàìåí. Åñëè ïðèìåíèòü ñëåäóþùóþ îïåðàöèþ 'AAAAAA'.replace('AA', 'A'), òî â ðåçóëüòàòå ïîëó÷èòñÿ ñòðîêà 'AAA', à íå 'A', êàê ìîæíî áûëî áû îæèäàòü. Ôàêòè÷åñêè, ìîæíî ñ÷èòàòü, ÷òî ìåòîä replace íàõîäèò î÷åðåäíîå âõîæäåíèå ïîäñòðîêè old, îñóùåñòâëÿåò çàìåíó è ïðîäîëæàåò ïîèñê ñ ïîçèöèè ïîñëå âñåõ çàìåííåííûõ ñèìâîëîâ (áåç íàëîæåíèÿ è ïîèñêà â ñâåæåçàìåíåííîé ÷àñòè). Ñóùåñòâóåò ìîäèôèêàöèÿ replace(old, new, count), êîòîðàÿ îñóùåñòâëÿåò íå áîëåå count çàìåí ñàìûõ ëåâûõ âõîæäåíèé ïîäñòðîêè old. 3.8. МЕТОДЫ REPLACE И COUNT 31 Òàêæå äëÿ ñòðîê ñóùåñòâóåò ìåòîä count, êîòîðûé ïîçâîëÿåò ïîäñ÷èòàòü êîëè÷åñòâî âõîæäåíèé ïîäñòðîêè. Ïî àíàëîãèè ñ ìåòîäîì nd îïðåäåëåíû ìåòîäû count ñ äâóìÿ è òðåìÿ ïàðàìåòðàìè. 32 ЛЕКЦИЯ 3. ВЕЩЕСТВЕННЫЕ ЧИСЛА И СТРОКИ Лекция 4 Функции и рекурсия 4.1 Создание простой функции Ôóíêöèè ÷àñòè ïðîãðàììû, êîòîðûå ìîæíî ïîâòîðíî âûçûâàòü ñ ðàçíûìè ïàðàìåòðàìè, ÷òîáû íå ïèñàòü ìíîãî ðàç îäíî è òî æå. Ôóíêöèè â ïðîãðàììèðîâàíèè íåìíîãî îòëè÷àþòñÿ îò ìàòåìàòè÷åñêèõ ôóíêöèé.  ìàòåìàòèêå ôóíêöèè ìîãóò òîëüêî ïîëó÷èòü ïàðàìåòðû è äàòü îòâåò, â ïðîãðàììèðîâàíèè æå ôóíêöèè óìåþò äåëàòü ÷òî-íèáóäü ïîëåçíîå, íàïðèìåð, íè÷åãî íå âîçâðàùàòü, íî ÷òî-òî ïå÷àòàòü. Ôóíêöèè ÷ðåçâû÷àéíî ïîëåçíû, åñëè îäíè è òå æå äåéñòâèÿ íóæíî âûïîëíÿòü íåñêîëüêî ðàç. Íî íåêîòîðûå ëîãè÷åñêèå áëîêè ðàáîòû ñ ïðîãðàììîé èíîãäà òîæå óäîáíî îôîðìëÿòü â âèäå ôóíêöèè. Ýòî ñâÿçàíî ñ òåì, ÷òî ÷åëîâåê ìîæåò îäíîâðåìåííî äåðæàòü â ãîëîâå îãðàíè÷åííîå êîëè÷åñòâî âåùåé. Êîãäà ïðîãðàììà ðàçðàñòàåòñÿ, îòñëåäèòü âñå óæå î÷åíü ñëîæíî.  ïðåäåëàõ îäíîé íåáîëüøîé ôóíêöèè çàïóòàòüñÿ ãîðàçäî ñëîæíåå èçâåñòíî, ÷òî îíà ïîëó÷àåò íà âõîä, ÷òî äîëæíà âûäàòü, à îá îñòàëüíîé ïðîãðàììå â ýòî âðåìÿ ìîæíî íå äóìàòü.  ïðîãðàììèðîâàíèè òàêæå ñ÷èòàåòñÿ õîðîøèì ñòèëåì ïèñàòü ôóíêöèè, óìåùàþùèåñÿ íà îäèí ýêðàí. Òîãäà ìîæíî îäíîâðåìåííî îêèíóòü âçãëÿäîì âñþ ôóíêöèþ è íå íóæíî êðóòèòü òåêñò òóäà-ñþäà. Ïîýòîìó, åñëè ïîëó÷èëîñü ÷òî-òî î÷åíü äëèííîå, òî íóæíî íàðåçàòü åãî íà êóñî÷êè òàê, ÷òîáû êàæäûé èç íèõ áûë ëîãè÷íûì (äåëàë êàêîå-òî îïðåäåëåííîå äåéñòâèå, êîòîðîå ìîæíî íàçâàòü) è íå ïðåâûøàë ïðè ýòîì 1015 ñòðîê. Ìû óæå èñïîëüçîâàëè ãîòîâûå ôóíêöèè, òàêèå êàê print, len è íåêîòîðûå äðóãèå. Ýòè ôóíêöèè îïèñàíû â ñòàíäàðòíîé áèáëèîòåêå èëè äðóãèõ ïîäêëþ÷àåìûõ áèáëèîòåêàõ. Ñåãîäíÿ ìû íàó÷èìñÿ ñîçäàâàòü ñâîè ôóíêöèè. Ðàññìîòðèì, êàê ñîçäàòü ñâîþ ôóíêöèþ, íà ïðèìåðå âû÷èñëåíèÿ ôàêòîðèàëà. Òåêñò ïðîãðàììû áåç ôóíêöèè âûãëÿäèò òàê: n = i n t ( input ( ) ) fact = 1 i = 2 while i <= n : f a c t *= i i += 1 print ( f a c t ) 33 34 ЛЕКЦИЯ 4. ФУНКЦИИ И РЕКУРСИЯ Âû÷èñëåíèå ôàêòîðèàëà ìîæíî âûíåñòè â ôóíêöèþ, òîãäà ýòà æå ïðîãðàììà áóäåò âûãëÿäåòü òàê: def f a c t o r i a l (num ) : fact = 1 i = 2 while i <= num : f a c t *= i i += 1 return f a c t n = i n t ( input ( ) ) print ( f a c t o r i a l ( n ) ) Îïèñàíèå ôóíêöèè äîëæíî èäòè â íà÷àëå ïðîãðàììû. Íà ñàìîì äåëå, îíî ìîæåò áûòü â ëþáîì ìåñòå, äî ïåðâîãî âûçîâà ôóíêöèè factorial. Îïðåäåëåíèå ôóíêöèè äîëæíî íà÷èíàòüñÿ ñî ñëîâà def (ñîêðàùåíèå îò dene, îïðåäåëèòü). Äàëüøå èäåò èìÿ ôóíêöèè, ïîñëå êîòîðîãî â ñêîáêàõ ÷åðåç çàïÿòóþ ïåðå÷èñëÿþòñÿ ïàðàìåòðû (ó íàøåé ôóíêöèè âñåãî îäèí ïàðàìåòð). Ïîñëå çàêðûòèÿ ñêîáêè äîëæíî ñòîÿòü äâîåòî÷èå. Êîìàíäû, âûïîëíÿåìûå â ôóíêöèè äîëæíû çàïèñûâàòüñÿ ñ îòñòóïîì, êàê â áëîêàõ êîìàíä if èëè while.  íàøåé ôóíêöèè num ýòî ïàðàìåòð, íà åãî ìåñòî ïîäñòàâëÿåòñÿ òî çíà÷åíèå, ñ êîòîðûì ôóíêöèÿ áûëà âûçâàíà. Äåéñòâèÿ âíóòðè ôóíêöèè òî÷íî òàêèå æå, êàê â îáû÷íîé ïðîãðàììå, êðîìå äîïîëíèòåëüíîé êîìàíäû return. Êîìàíäà return âîçâðàùàåò çíà÷åíèå ôóíêöèè (îíî äîëæíî áûòü çàïèñàíî ÷åðåç ïðîáåë ïîñëå ñëîâà return) è ïðåêðàùàåò å¼ ðàáîòó. Âîçâðàùåííîå çíà÷åíèå ïîäñòàâëÿåòñÿ íà òî ìåñòî, ãäå îñóùåñòâëÿëñÿ âûçîâ ôóíêöèè. Êîìàíäà return ìîæåò âñòðå÷àòüñÿ â ëþáîì ìåñòå ôóíêöèè. Ïîñëå òîãî êàê îíà âûïîëíèòñÿ, ðàáîòà ôóíêöèè áóäåò ïðåêðàùåíà. Çäåñü åñòü íåêîòîðàÿ àíàëîãèÿ ñ êîìàíäîé break, ïðèìåíÿåìîé äëÿ âûõîäà èç öèêëà. 4.2 Вызовы функций из функции Ôóíêöèþ ïîäñ÷åòà ôàêòîðèàëà ìîæíî èñïîëüçîâàòü äëÿ ïîäñ÷åòà áèíîìèàëüíûõ êîýôôèöèåíòîâ (÷èñëà ñî÷åòàíèé). Ôîðìóëà äëÿ ïîäñ÷åòà ÷èñëà ñî÷åòàíèé âûãëÿäèò 𝑛! . òàê: 𝑘!×(𝑛−𝑘)! Åñëè áû ìû íå ïîëüçîâàëèñü ôóíêöèÿìè, òî íàì ïîòðåáîâàëîñü áû òðè ðàçà çàïèñàòü ïî÷òè îäíî è òî æå. Ñ ïîìîùüþ ôóíêöèé âû÷èñëåíèå âûãëÿäèò íàìíîãî ïðîùå: print ( f a c t o r i a l ( n ) // ( f a c t o r i a l ( k ) * f a c t o r i a l ( n−k ) ) ) Ïîäñ÷åò áèíîìèàëüíûõ êîýôôèöèåíòîâ ìîæíî òàêæå îôîðìèòü â âèäå ôóíêöèè ñ äâóìÿ ïàðàìåòðàìè: def b i n o m i a l ( n , k ) : return f a c t o r i a l ( n ) // ( f a c t o r i a l ( k ) * f a c t o r i a l ( n − k ) ) 4.3. НЕСКОЛЬКО RETURN В ФУНКЦИИ 4.3 35 Несколько return в функции Êàê áûëî ñêàçàíî âûøå, âûïîëíåíèå ôóíêöèè ïðåðûâàåòñÿ ïî êîìàíäå return. Äëÿ ïðèìåðà ðàññìîòðèì ôóíêöèþ ïîèñêà ìàêñèìóìà èç äâóõ ÷èñåë, êîòîðûå ïåðåäàþòñÿ åé â êà÷åñòâå ïàðàìåòðîâ: def max2 ( a , b ) : if a > b: return a else : return b ż ìîæíî áûëî áû çàïèñàòü è ïî-äðóãîìó: def max2 ( a , b ) : if a > b: return a return b Åñëè óñëîâèå â if'å áûëî èñòèííûì, òî âûïîëíèòñÿ êîìàíäà return a è âûïîëíåíèå ôóíêöèè áóäåò ïðåêðàùåíî äî êîìàíäû return b âûïîëíåíèå ïðîñòî íå äîéäåò. Ñ ïîìîùüþ ôóíêöèè max2 ìîæíî ðåàëèçîâàòü ôóíêöèþ max3, âîçâðàùàþùóþ ìàêñèìóì èç òðåõ ÷èñåë: def max3 ( a , b , c ) : return max2 ( max2 ( a , b ) , c ) Ýòà ôóíêöèÿ äâàæäû âûçûâàåò max2: ñíà÷àëà äëÿ âûáîðà ìàêñèìóìà ñðåäè ÷èñåë a è b, à çàòåì äëÿ âûáîðà ìàêñèìóìà ìåæäó íàéäåííûì çíà÷åíèåì è îñòàâøèìñÿ ÷èñëîì c. Çäåñü íóæíî îáðàòèòü âíèìàíèå, ÷òî â êà÷åñòâå àðãóìåíòà ôóíêöèè ìîæåò ïåðåäàâàòüñÿ íå òîëüêî ïåðåìåííàÿ èëè êîíñòàíòíîå çíà÷åíèå, íî è ðåçóëüòàò âû÷èñëåíèÿ ëþáîãî àðèôìåòè÷åñêîãî âûðàæåíèÿ. Íàïðèìåð, ðåçóëüòàò, âîçâðàùåííîé äðóãîé ôóíêöèåé. Íàøè ôóíêöèè max2 è max3 áóäóò ðàáîòàòü íå òîëüêî äëÿ ÷èñåë, íî è äëÿ ëþáûõ ñðàâíèìûõ îáúåêòîâ, íàïðèìåð, äëÿ ñòðîê. 4.4 Локальные и глобальные переменные Âñå ïåðåìåííûå, êîòîðûìè ìû ïîëüçîâàëèñü äî ñåãîäíÿøíåãî äíÿ, áûëè ãëîáàëüíûìè. Ãëîáàëüíûå ïåðåìåííûå âèäíû âî âñåõ ôóíêöèÿõ ïðîãðàììû. Íàïðèìåð, òàêîé êîä: def f ( ) : print a a = 1 f () íàïå÷àòàåò 1 è âûïîëíèòñÿ áåç îøèáîê. Ïåðåìåííàÿ a ãëîáàëüíàÿ, ïîýòîìó ìû ìîæåì ñìîòðåòü íà å¼ çíà÷åíèå èç ëþáîé ôóíêöèè. Íà ìîìåíò âûçîâà ôóíêöèè f ïåðåìåííàÿ a óæå ñîçäàíà, õîòÿ îïèñàíèå ôóíêöèè è èäåò ðàíüøå ïðèñâàèâàíèÿ. 36 ЛЕКЦИЯ 4. ФУНКЦИИ И РЕКУРСИЯ Åñëè æå èíèöèàëèçèðîâàòü ïåðåìåííóþ âíóòðè ôóíêöèè, òî èñïîëüçîâàòü å¼ âíå ôóíêöèè íåâîçìîæíî. Íàïðèìåð, òàêîé êîä: def f ( ) : f () a = 1 print ( a ) çàâåðøèòñÿ ñ îøèáêîé "builtins.NameError: name 'a' is not dened"(ïåðåìåííàÿ a íå îïðåäåëåíà). Ïåðåìåííûå, çíà÷åíèÿ êîòîðûõ èçìåíÿþòñÿ âíóòðè ôóíêöèè ïî óìîë÷àíèþ ñ÷èòàþòñÿ ëîêàëüíûìè, ò.å. äîñòóïíûìè òîëüêî âíóòðè ôóíêöèè. Êàê òîëüêî ôóíêöèÿ çàêàí÷èâàåò ñâîþ ðàáîòó, òî ïåðåìåííàÿ óíè÷òîæàåòñÿ. Òàêèì îáðàçîì, åñëè â ôóíêöèè ïðîèñõîäèëî ïðèñâàèâàíèå êàêîé-òî ïåðåìåííîé, òî ýòà ïåðåìåííàÿ ñ÷èòàåòñÿ ëîêàëüíîé. Åñëè ïðèñâàèâàíèé íå ïðîèñõîäèëî, òî ïåðåìåííàÿ ñ÷èòàåòñÿ ãëîáàëüíîé. Ëîêàëüíûå ïåðåìåííûå ìîæíî íàçûâàòü òàêèìè æå èìåíàìè, êàê è ãëîáàëüíûå. Íàïðèìåð, âûâîä òàêîãî êîäà: def f ( ) : a = 1 print ( a , end= ' a = 0 f () ') print ( a ) Áóäåò "1 0". Ñíà÷àëà ïðîèçîéäåò âûçîâ ôóíêöèè f, â êîòîðîé áóäåò ñîçäàíà ëîêàëüíàÿ ïåðåìåííàÿ a ñî çíà÷åíèåì 1 (ïîëó÷èòü äîñòóï ê ãëîáàëüíîé ïåðåìåííîé a èç ôóíêöèè òåïåðü íåëüçÿ), çàòåì ôóíêöèÿ çàêîí÷èò ñâîþ ðàáîòó è áóäåò âûâåäåíà ãëîáàëüíàÿ ïåðåìåííàÿ a, ñî çíà÷åíèåì êîòîðîé íè÷åãî íå ñëó÷èëîñü. Ïåðåìåííàÿ ñ÷èòàåòñÿ ëîêàëüíîé äàæå â ñëó÷àå, åñëè å¼ ïðèñâàèâàíèå ïðîèñõîäèëî âíóòðè óñëîâíîãî îïåðàòîðà (äàæå åñëè îí íèêîãäà íå âûïîëíèòñÿ): def f ( ) : print ( a ) i f False : a = 1 f () a = 0 Ýòà ïðîãðàììà çàâåðøèòñÿ ñ îøèáêîé builtins.UnboundLocalError: local variable 'a' referenced before assignment (îáðàùåíèå ê ïåðåìåííîé äî èíèöèàëèçàöèè). Ëþáîå ïðèñâàèâàíèå çíà÷åíèÿ ïåðåìåííîé âíóòðè òåëà ôóíêöèè äåëàåò ïåðåìåííóþ ëîêàëüíîé. Ñ ïîìîùüþ ñïåöèàëüíîé êîìàíäû global ìîæíî ñäåëàòü òàê, ÷òî ôóíêöèÿ ñìîæåò èçìåíèòü çíà÷åíèå ãëîáàëüíîé ïåðåìåííîé. Äëÿ ýòîãî íóæíî çàïèñàòü â íà÷àëå ôóíêöèè ñëîâî global, à çàòåì ÷åðåç çàïÿòóþ ïåðå÷èñëèòü èìåíà ãëîáàëüíûõ ïåðåìåííûõ, êîòîðûå ôóíêöèÿ ñìîæåò ìåíÿòü. Íàïðèìåð, òàêîé êîä: def f ( ) : global a a = 1 print ( a , end= ' ') 4.5. ВОЗВРАТ НЕСКОЛЬКИХ ЗНАЧЕНИЙ ФУНКЦИЕЙ 37 a = 0 f () print ( a ) âûâåäåò "1 1 ò.ê. çíà÷åíèå ãëîáàëüíîé ïåðåìåííîé áóäåò èçìåíåíî âíóòðè ôóíêöèè. Âñå ïàðàìåòðû ôóíêöèè ÿâëÿþòñÿ ëîêàëüíûìè ïåðåìåííûìè ñî çíà÷åíèÿìè, êîòîðûå áûëè ïåðåäàíû â ôóíêöèþ. Ïàðàìåòðû òàêæå ìîæíî èçìåíÿòü è ýòî íèêàê íå ïîâëèÿåò íà çíà÷åíèÿ ïåðåìåííûõ â òîì ìåñòå, îòêóäà áûëà âûçâàíà ôóíêöèÿ (åñëè òèï îáúåêòîâ-ïàðàìåòðîâ áûë íåèçìåíÿåìûì).Èñïîëüçîâàíèå ãëîáàëüíûõ ïåðåìåííûõ êàê íà ÷òåíèå, òàê è íà çàïèñü âíóòðè ôóíêöèé î÷åíü ïëîõîé òîí. Ýòî ñâÿçàíî ñ òåì, ÷òî äðóãèå ëþäè ìîãóò çàõîòåòü èñïîëüçîâàòü íåêîòîðûå îòäåëüíûå ôóíêöèè èç âàøåãî êîäà, êîòîðûå íå áóäóò ðàáîòàòü âíå âàøåé ïðîãðàììû â ñëó÷àå èñïîëüçîâàíèÿ ãëîáàëüíûõ ïåðåìåííûõ. Ïîýòîìó èñïîëüçîâàíèå ãëîáàëüíûõ ïåðåìåííûõ âíóòðè ôóíêöèé â íàøåì êóðñå строго запрещено. Âñå íóæíîå äëÿ ðàáîòû ôóíêöèè äîëæíî ïåðåäàâàòüñÿ â êà÷åñòâå ïàðàìåòðîâ. 4.5 Возврат нескольких значений функцией Ðàññìîòðèì ñëó÷àé, êîãäà ôóíêöèÿ äîëæíà âåðíóòü íåñêîëüêî çíà÷åíèé íà ïðèìåðå ôóíêöèè, óïîðÿäî÷èâàþùåé äâà ÷èñëà. ×òîáû âåðíóòü íåñêîëüêî çíà÷åíèé, äîñòàòî÷íî çàïèñàòü èõ â return ÷åðåç çàïÿòóþ. Àíàëîãè÷íî, ÷åðåç çàïÿòóþ äîëæíû áûòü ïåðå÷èñëåíû ïåðåìåííûå, â êîòîðûå áóäóò ïîïàäàòü âû÷èñëåííûå çíà÷åíèÿ. def s o r t 2 ( a , b ) : if a < b: return a , b else : return b , a a = i n t ( input ( ) ) b = i n t ( input ( ) ) minimum , maximum = s o r t 2 ( a , b ) print ( minimum , maximum) Íà ñàìîì äåëå, ïðè ïåðå÷èñëåíèè çíà÷åíèé ÷åðåç çàïÿòóþ, ôîðìèðóþòñÿ îáúåêòû òèïà ¾êîðòåæ¿, èõ ïîäðîáíîå èçó÷åíèå áóäåò íà ñëåäóþùåé ëåêöèè. Èìåþùèõñÿ çíàíèé äîñòàòî÷íî äëÿ èñïîëüçîâàíèÿ ôóíêöèé, âîçâðàùàþùèõ íåñêîëüêî çíà÷åíèé. 4.6 Возврат логических значений Èíîãäà óäîáíî îôîðìëÿòü äàæå ïðîñòûå âåùè â âèäå ôóíêöèé, ÷òîáû ïîâûñèòü ÷èòàåìîñòü ïðîãðàììû. Íàïðèìåð, åñëè íóæíî ïðîâåðèòü ÷èñëî íà ÷åòíîñòü, òî ãîðàçäî ïîíÿòíåå áóäåò êàæäûé ðàç âûçûâàòü ôóíêöèþ isEven(n), à íå ïèñàòü êàæäûé ðàç n Òàêàÿ ôóíêöèÿ ìîæåò âûãëÿäåòü òàê: def i s E v e n ( n ) : return n % 2 == 0 38 ЛЕКЦИЯ 4. ФУНКЦИИ И РЕКУРСИЯ Ðåçóëüòàòîì ðàáîòû ýòîé ôóíêöèè áóäåò èñòèíà èëè ëîæü. Òåïåðü ôóíêöèþ î÷åíü óäîáíî ïðèìåíÿòü â if'àõ: i f isEven (n ) : print ( "EVEN" ) else : print ( "ODD" ) Åñëè åñòü ñëîæíîå ëîãè÷åñêîå âûðàæåíèå, òî ëó÷øå îôîðìèòü åãî â âèäå ôóíêöèè ñ ãîâîðÿùèì íàçâàíèåì òàê ïðîãðàììó áóäåò ëåã÷å ÷èòàòü, à âåðîÿòíîñòü îøèáîê â íåé ðåçêî ñíèçèòñÿ. 4.7 Механизм запуска функций Ðàáîòàÿ ñ ôóíêöèÿìè, íóæíî ðàçëè÷àòü äâå ñóùíîñòè: ïîñëåäîâàòåëüíîñòü êîìàíä, êîòîðûå âûïîëíÿþòñÿ â ôóíêöèè, è ëîêàëüíûå ïåðåìåííûå êîíêðåòíîãî ýêçåìïëÿðà ôóíêöèè. Êðîìå ýòîãî êàæäûé ýêçåìïëÿð ôóíêöèè ïîìíèò, êóäà îí äîëæåí âåðíóòüñÿ ïîñëå çàâåðøåíèÿ ðàáîòû. Ýòèì ñâîéñòâîì ïîìíèòü, ñ êàêîãî ìåñòà íóæíî ïðîäîëæèòü ðàáîòó ôóíêöèè ìû ïîëüçóåìñÿ ïðè ëþáîì çàïóñêå ôóíêöèè âûïîëíåíèå íà âðåìÿ óõîäèò â ôóíêöèþ, à ïîñëå âûïîëíåíèÿ âñåõ êîìàíä óïðàâëåíèå âîçâðàùàåòñÿ ðîâíî íà òî ìåñòî, ãäå áûë ïðîèçâåäåí âûçîâ ôóíêöèè. 4.8 Рекурсия Ìû óæå ïðîáîâàëè çàïóñêàòü ôóíêöèþ èç äðóãîé ôóíêöèè è âñå ðàáîòàëî. Íè÷òî íå ìåøàåò çàïóñòèòü èç ôóíêöèè ñàìó ñåáÿ òîãäà ïðîñòî ñîçäàñòñÿ íîâûé ýêçåìïëÿð ôóíêöèè, êîòîðûå áóäåò âûïîëíÿòü òå æå êîìàíäû. Òàêîé ïðîöåññ íàçûâàåòñÿ ðåêóðñèåé. Ïðåäñòàâèì ñåáå, ÷òî ó íàñ åñòü ìèëëèàðä ÷åëîâåê (ýòî áóäóùèå ýêçåìïëÿðû ôóíêöèè), ñèäÿùèõ â ðÿä, è ó êàæäîãî èç íèõ åñòü ëèñòî÷åê äëÿ çàïèñè (ýòî åãî ëîêàëüíàÿ ïàìÿòü). Íàì íóæíî ïðîèçíîñèòü ÷èñëà è íàïèñàòü èíñòðóêöèþ äëÿ ëþäåé òàê, ÷òîáû îíè â èòîãå ñêàçàëè âñå ÷èñëà èç ïîñëåäîâàòåëüíîñòè â îáðàòíîì ïîðÿäêå. Ïóñòü êàæäûé èç íèõ áóäåò çàïèñûâàòü íà ñâîåì ëèñòî÷êå òîëüêî îäíî ÷èñëî. Òîãäà èíñòðóêöèÿ äëÿ ÷åëîâåêà áóäåò âûãëÿäåòü òàê: 1. Çàïèøè íàçâàííîå ÷èñëî 2. Åñëè ÷èñëî íå ïîñëåäíåå ïîòåðåáè ñëåäóþùåãî çà òîáîé ÷åëîâåêà, ïðèøëà åãî î÷åðåäü ðàáîòàòü 3. Êîãäà ñëåäóþùèé çà òîáîé ÷åëîâåê ñêàçàë, ÷òî îí çàêîí÷èë íàçîâè çàïèñàííîå ÷èñëî 4. Ñêàæè òîìó, êòî òåáÿ òåðåáèë (ïðåäûäóùèé ÷åëîâåê), ÷òî òû çàêîí÷èë Ôîðìàëèçóåì çàäà÷ó. Ïóñòü çàäàåòñÿ ïîñëåäîâàòåëüíîñòü íàòóðàëüíûõ ÷èñåë, çàêàí÷èâàþùàÿñÿ íóëåì. Íåîáõîäèìî ðàçâåðíóòü åå ñ ïîìîùüþ ðåêóðñèè. 4.8. РЕКУРСИЯ 39 def r e c ( ) : n = i n t ( input ( ) ) i f n != 0 : rec () rec () print ( n ) Ýòà ôóíêöèÿ îñóùåñòâëÿåò äåéñòâèå (âûâîä ÷èñëà) íà ðåêóðñèâíîì ñïóñêå, ò.å. ïîñëå ðåêóðñèâíîãî âûçîâà. Ðàññìîòðèì çàäà÷ó, ãäå äåéñòâèÿ âûïîëíÿþòñÿ êàê íà ðåêóðñèâíîì ïîäú¼ìå, òàê è íà ðåêóðñèâíîì ñïóñêå. Ïóñòü äàíà ïîñëåäîâàòåëüíîñòü, êîòîðàÿ îêàí÷èâàåòñÿ íóë¼ì. Íåîáõîäèìî âûâåñòè âñå ÷¼òíûå ÷ëåíû ïîñëåäîâàòåëüíîñòè â ïðÿìîì ïîðÿäêå, à çàòåì âñå íå÷¼òíûå ÷ëåíû ïîñëåäîâàòåëüíîñòè â îáðàòíîì ïîðÿäêå. ż ðåøåíèå áóäåò âûãëÿäåòü òàê: def r e c ( ) : n = i n t ( input ( ) ) i f n != 0 : i f n % 2 == 0 : print ( n ) rec () rec () i f n % 2 != 0 : print ( n ) Êàæäûé ýêçåìïëÿð ôóíêöèè ñ÷èòûâàåò â ñâîþ ëîêàëüíóþ ïåðåìåííóþ n ÷èñëî, åñëè îíî ÷¼òíîå, òî ñðàçó âûâîäèò åãî è çàïóñêàåò ñëåäóþùèé ýêçåìïëÿð. Ïîñëå òîãî, êàê âñå ïîñëåäóþùèå ýêçåìïëÿðû ôóíêöèè îêîí÷èëè ðàáîòó (è âûâåëè íå÷¼òíûå ÷èñëà â îáðàòíîì ïîðÿäêå), ôóíêöèÿ âûâîäèò ÷èñëî, åñëè îíî áûëî íå÷åòíûì. Ðàññìîòðèì åùå îäèí ïðèìåð: ïîäñ÷èòàòü ôàêòîðèàë ÷èñëà, íå ïîëüçóÿñü öèêëàìè: def f a c t o r i a l ( n ) : i f n == 0 : return 1 return n * f a c t o r i a l ( n − 1 ) n = i n t ( input ( ) ) print ( f a c t o r i a l ( n ) ) Òåì, êòî çíàêîì ñ ìåòîäîì ìàòåìàòè÷åñêîé èíäóêöèè, áóäåò äîâîëüíî ïðîñòî îñîçíàòü ðåêóðñèþ. Êàê è â ìàòåìàòè÷åñêîé èíäóêöèè, â ðåêóðñèè äîëæíà áûòü áàçà (ìîìåíò, êîãäà ôóíêöèÿ íå âûçûâàåò äðóãóþ ðåêóðñèâíóþ ôóíêöèþ) è ïåðåõîä (ïðàâèëî, ïî êîòîðîìó ñ÷èòàåòñÿ ðåçóëüòàò ïî èçâåñòíîìó ðåçóëüòàòó äëÿ ìåíüøåãî ïàðàìåòðà). Íàøà ôóíêöèÿ ïîäñ÷åòà ôàêòîðèàëà äåëàåò òîëüêî ñâîþ ðàáîòó, íî ïîëüçóåòñÿ ðåçóëüòàòàìè ÷óæîãî òðóäà. Íàïðèìåð, åñëè ôóíêöèÿ ïîëó÷èëà íà âõîä ïàðàìåòð 4, òî äîëæíà âåðíóòü 4 óìíîæåííîå íà 3! (êîòîðûé áóäåò ïîñ÷èòàí äðóãèìè ôóíêöèÿìè).  ñëó÷àå ôàêòîðèàëà àíàëîãîì ¾áàçû èíäóêöèè¿ ìîæåò âûñòóïàòü 0! ïî îïðåäåëåíèþ îí ðàâåí åäèíèöå. Ýòè ïðèìåðû èëëþñòðèðóþò îáùóþ ñõåìó íàïèñàíèÿ ðåêóðñèâíûõ ôóíêöèé: ñíà÷àëà ïðîâåðÿåòñÿ óñëîâèå, êîãäà ôóíêöèÿ äîëæíà çàêîí÷èòüñÿ, à äàëüøå äåëàåòñÿ âñå 40 ЛЕКЦИЯ 4. ФУНКЦИИ И РЕКУРСИЯ îñòàëüíîå. Ïðè ýòîì ïàðàìåòð äîëæåí ñõîäèòüñÿ ê çíà÷åíèþ áàçû. Îáû÷íî ýòî îçíà÷àåò, ÷òî ïðè êàæäîì ñëåäóþùåì âûçîâå ðåêóðñèè ïàðàìåòð äîëæåí óìåíüøàòüñÿ. Лекция 5 Кортежи, цикл for, списки 5.1 Кортежи Ïî àíàëîãèè ñî ñòðîêàìè, êîòîðûå ìîãóò õðàíèòü â ñåáå îòäåëüíûå ñèìâîëû, â ÿçûêå Ïèòîí ñóùåñòâóþò òèï êîðòåæ, êîòîðûé ïîçâîëÿåò õðàíèòü â ñåáå ïðîèçâîëüíûå ýëåìåíòû. Êîðòåæ ìîæåò ñîñòîÿòü èç ýëåìåíòîâ ïðîèçâîëüíûõ òèïîâ è ÿâëÿåòñÿ íåèçìåíÿåìûì òèïîì, ò.å. íåëüçÿ ìåíÿòü îòäåëüíûå ýëåìåíòû êîðòåæà, êàê è ñèìâîëû ñòðîêè. Êîíñòàíòíûå êîðòåæè ìîæíî ñîçäàâàòü â ïðîãðàììå, çàïèñûâàÿ ýëåìåíòû ÷åðåç çàïÿòóþ è îêðóæàÿ ñêîáêàìè. Íàïðèìåð, testTuple = (1, 2, 3).  ñëó÷àå, åñëè êîðòåæ ÿâëÿåòñÿ åäèíñòâåííûì âûðàæåíèåì ñëåâà èëè ñïðàâà îò çíàêà ïðèñâàèâàíèÿ, òî ñêîáêè ìîãóò áûòü îïóùåíû. Âî âñåõ îñòàëüíûõ ñëó÷àÿõ ñêîáêè îïóñêàòü íå ñëåäóåò ýòî ìîæåò ïðèâåñòè ê îøèáêàì. Ìíîãèå ïðèåìû è ôóíêöèè äëÿ ðàáîòû ñî ñòðîêàìè òàêæå ïîäõîäÿò è äëÿ êîðòåæåé, íàïðèìåð, ìîæíî ñêëàäûâàòü äâà êîðòåæà: a = (1 , 2 , 3) b = (4 , 5 , 6) print ( a + b )  ðåçóëüòàòå ïðèìåíåíèÿ ýòîé îïåðàöèè áóäåò âûâåäåíî (1, 2, 3, 4, 5, 6).  ñëó÷àå ñëîæåíèÿ ñîçäàåòñÿ íîâûé êîðòåæ, êîòîðûé ñîäåðæèò â ñåáå ýëåìåíòû ñíà÷àëà èç ïåðâîãî, à çàòåì âòîðîãî êîðòåæà (òî÷íî òàêæå êàê è â ñëó÷àå ñî ñòðîêàìè). Òàêæå êîðòåæ ìîæíî óìíîæèòü íà ÷èñëî, ðåçóëüòàò ýòîé îïåðàöèè àíàëîãè÷åí óìíîæåíèþ ñòðîêè íà ÷èñëî. Êîðòåæ ìîæíî ïîëó÷èòü èç ñòðîêè, âûçâàâ ôóíêöèþ tuple îò ñòðîêè.  ðåçóëüòàòå êàæäàÿ áóêâà ñòàíåò ýëåìåíòîì êîðòåæà. Ê êîðòåæó ìîæíî ïðèìåíÿòü ôóíêöèþ str, êîòîðàÿ âåðíåò òåêñòîâîå ïðåäñòàâëåíèå êîðòåæà (ýëåìåíòû, ïåðå÷èñëåííûå ÷åðåç çàïÿòóþ ñ ïðîáåëîì è ðàçäåëåííûå ïðîáåëàìè). 5.2 Работа с кортежами Ê êîðòåæó ìîæíî ïðèìåíÿòü ôóíêöèþ len è îáðàùàòüñÿ ê ýëåìåíòàì ïî èíäåêñó (â òîì ÷èñëå ïî îòðèöàòåëüíîìó) òàêæå êàê è ê ñòðîêàì.  îäíîì êîðòåæå ìîãóò õðàíèòüñÿ ýëåìåíòû ðàçëè÷íûõ òèïîâ, íàïðèìåð, ñòðîêè, ÷èñëà è äðóãèå êîðòåæè âïåðåìåøêó. Íàïðèìåð, â êîðòåæå myTuple = (('a', 1, 3.14), 41 42 ЛЕКЦИЯ 5. КОРТЕЖИ, ЦИКЛ FOR, СПИСКИ 'abc', ((1), (2, ))), myTuple[0] áóäåò êîðòåæåì ('a', 1, 3.14), myTuple[1] ñòðîêîé 'abc', à myTuple[2] êîðòåæåì ñîñòîÿùèì èç ÷èñëà 1 è êîðòåæà èç îäíîãî ýëåìåíòà (2, ). ×èñëà, çàïèñàííûå â ñêîáêàõ, èíòåðïðåòèðóþòñÿ êàê ÷èñëà, â ñëó÷àå âîçíèêíîâåíèÿ íåîáõîäèìîñòè ñîçäàòü êîðòåæ èç îäíîãî ýëåìåíòà íåîáõîäèìî ïîñëå çíà÷åíèÿ ýëåìåíòà íàïèñàòü çàïÿòóþ. Åñëè âûâåñòè myTuple[2][1], òî íàïå÷àòàåòñÿ (2,), à åñëè âûâåñòè myTuple[2][1][0], òî áóäåò íàïå÷àòàíî ÷èñëî 2. Êîðòåæ, ñîäåðæàùèé â ñåáå îäèí ýëåìåíò íàçûâàåòñÿ ñèíãëòîíîì. Êàê è ê ñòðîêàì, ê êîðòåæàì ìîæíî ïðèìåíÿòü îïåðàöèþ ñðåçà ñ òåì æå ñìûñëîì ïàðàìåòðîâ. Åñëè â ñðåçå îäèí ïàðàìåòð, òî áóäåò âîçâðàùåíà ññûëêà íà ýëåìåíò ñ ñîîòâåòñòâóþùèì íîìåðîì. Íàïðèìåð, print((1, 2, 3)[2]) íàïå÷àòåò 3. Åñëè æå â ñðåçå áîëåå îäíîãî ïàðàìåòðà, òî áóäåò ñêîíñòðóèðîâàí êîðòåæ, äàæå åñëè îí áóäåò ñèíãëòîíîì. Íàïðèìåð, â ñëó÷àå âûçîâà print((1, 2, 3)[1:]) áóäåò íàïå÷àòíî (2, 3), à â ñëó÷àå âûçîâà print((1, 2, 3)[2:]) áóäåò íàïå÷àòàí ñèíãëòîí (3,). Êîðòåæè, îáû÷íî, ïðåäíàçíà÷àþòñÿ äëÿ õðàíåíèÿ ðàçíîòèïîâûõ çíà÷åíèé, äîñòóï ê êîòîðûì ìîæåò áûòü ïîëó÷åí â ðåçóëüòàòå îáðàùåíèÿ ïî èíäåêñó èëè ñ ïîìîùüþ îïåðàöèè ðàñïàêîâêè. Ðàñïàêîâêîé íàçûâàåòñÿ ïðîöåññ ïðèñâàèâàíèÿ, â êîòîðîì êîðòåæ, ñîñòàâëåííûé èç îòäåëüíûõ ïåðåìåííûõ íàõîäèòñÿ â ëåâîé ÷àñòè âûðàæåíèÿ.  òàêîì âûðàæåíèè ñïðàâà äîëæåí íàõîäèòñÿ êîðòåæ òîé æå äëèíû. Íàïðèìåð, â ðåçóëüòàòå âûïîëíåíèÿ òàêîãî êîäà: manDesc = ( " Ivan " , " Ivanov " , 2 8 ) name , surname , age = manDesc  ïåðåìåííîé name êàæåòñÿ Ivan, â surname Ivanov, à â ïåðåìåííîé age ÷èñëî 28. Íà àíãëèéñêîì ðàñïàêîâêà êîðòåæà íàçûâàåòñÿ tuple unpacking. Ïðîöåññ ñîçäàíèÿ êîðòåæà íàçûâàåòñÿ óïàêîâêîé êîðòåæà. Åñëè â îäíîì âûðàæåíèè ïðèñâàèâàíèÿ ïðîèñõîäèò è óïàêîâêà è ðàñïàêîâêà êîðòåæà, òî ñíà÷àëà âûïîëíÿåòñÿ óïàêîâêà, à çàòåì ðàñïàêîâêà êîðòåæà. Òàê, â ðåçóëüòàòå ðàáîòû ïðîãðàììû: a, b, c = 1, 2, 3 a, b, c = c , b, a print ( a , b , c ) áóäåò âûâåäåíî 3 2 1. Îáðàòèòå âíèìàíèå, ÷òî ôóíêöèè print ïåðåäàåòñÿ â êà÷åñòâå ïàðàìåòðà íå êîðòåæ, à òðè öåëûõ ÷èñëà. Ãëàâíîå ÷òî íóæíî ïîíÿòü, ÷òî çàïèñàòü âèäà (a, b, c) = (c, b, a) íå ýêâèâàëåíòíà öåïî÷êå ïðèñâàèâàíèé âèäà a = c; b = b; c = a. Òàêàÿ öåïî÷êà ïðèñâàèâàíèé ïðèâåëà áû ê òîìó, ÷òî â ïåðåìåííûõ a, b, c îêàçàëèñü áû çíà÷åíèÿ 3, 2, 3. 5.3 Функция range  ÿçûêå Ïèòîí åñòü ôóíêöèÿ range, êîòîðàÿ ïîçâîëÿåò ãåíåðèðîâàòü îáúåêòû òèïà iterable (ê ýëåìåíòàì êîòîðûõ ìîæíî ïîëó÷àòü ïîñëåäîâàòåëüíûé äîñòóï) ñîñòîÿùèå èç öåëûõ ÷èñåë. Äëÿ âûâîäà îáúåêòîâ òèïà iterable ìû áóäåì ïîëüçîâàòüñÿ ôóíêöèåé tuple, êîòîðàÿ ïîçâîëÿåò ñäåëàòü êîðòåæ, ñîñòîÿùèé èç âñåõ ýëåìåíòîâ iterable, çàïèñàííûõ ïîñëåäîâàòåëüíî. Íàïðèìåð, åñë çàïóñòèòü ïðîãðàììó 5.4. 43 ЦИКЛ FOR print ( tuple ( range ( 1 0 ) ) ) òî áóäåò íàïå÷àòàíî (0, 1, 2, 3, 4, 5, 6, 7, 8, 9). Ôóíêöèÿ range ñ îäíèì ïàðàìåòðîì n ãåíåðèðóåò iterable, ñîäåðæàùèé ïîñëåäîâàòåëüíûå ÷èñëà îò 0 äî n-1. Ñóùåñòâóåò âàðèàíò range ñ äâóìÿ ïàðàìåòðàìè, range(from, to) ñãåíåðèðóåò iterable ñî âñåìè ÷èñëàìè îò 𝑓 𝑟𝑜𝑚 äî 𝑡𝑜 − 1 âêëþ÷èòåëüíî. Òàêæå ñóùåñòâóåò range ñ òðåìÿ ïàðàìåòðàìè range(from, to, step), êîòîðûé ñãåíåðèðóåò iterable ñ ÷èñëàìè îò 𝑓 𝑟𝑜𝑚, íå ïðåâûøàþùèå 𝑡𝑜 ñ øàãîì èçìåíåíèÿ 𝑠𝑡𝑒𝑝. Åñëè øàã îòðèöàòåëåí, òî 𝑓 𝑟𝑜𝑚 äîëæåí áûòü áîëüøå 𝑡𝑜. Íàïðèìåð, range(10, 0, -2) ñãåíåðèðóåò ïîñëåäîâàòåëüíîñòü ÷èñåë 10, 8, 6, 4, 2. 0 íå áóäåò âõîäèòü â ýòó ïîñëåäîâàòåëüíîñòü. Âî ìíîãîì ïàðàìåòðû range íàïîìèíàþò çíà÷åíèÿ ïàðàìåòðîâ â ñðåçàõ ñòðîê. 5.4 Цикл for Öèêë for ïîçâîëÿåò ïîî÷åðåäíî ïåðåáðàòü ýëåìåíòû èç ÷åãî-íèáóäü èòåðèðóåìîãî (iterable èëè tuple). Íàïðèìåð, ìû ìîæåì ïåðåáðàòü íàçâàíèÿ öâåòîâ ÿáëîê òàêèì ñïîñîáîì: f o r c o l o r in ( ' r e d ' , ' g r e e n ' , print ( c o l o r , ' a p p l e ' ) ' yellow ' ) :  ðåçóëüòàòå âûïîëíåíèÿ ýòîé ïðîãðàììû áóäåò íàïå÷àòàíî: red apple green apple yellow apple Íà ìåñòî ïåðåìåííîé color áóäóò ïîî÷åðåäíî ïîäñòàâëÿòüñÿ çíà÷åíèÿ èç êîðòåæà.  îáùåì ñëó÷àå öèêë for âûãëÿäèò òàê for èìÿÏåðåìåííîé in íå÷òîÈòåðèðóåìîå: Âñå äåéñòâèÿ, êîòîðûå äîëæíû âûïîëíÿòüñÿ â for, äîëæíû âûäåëÿòüñÿ îòñòóïîì, êàê è â if èëè while. Ðàáîòà öèêë for ìîæåò áûòü ïðåðâàíà ñ ïîìîùüþ êîìàíäû break èëè ìîæåò áûòü îñóùåñòâëåí ïåðåõîä ê ñëåäóþùåé èòåðàöèè ñ ïîìîùüþ continue. Ýòè êîìàíäû èìåþò òîò æå ýôôåêò, ÷òî è ïðè ðàáîòå ñ öèêëîì while. ×àñòî for ñïîëüçóåòñÿ âìåñòå ñ ôóíêöèåé range. Íàïðèìåð, ñ ïîìîùüþ for ìîæíî íàïå÷àòàòü íå÷åòíûå ÷èñëà îò 1 äî 100: f o r i in range ( 1 , 1 0 0 , 2 ) : print ( i ) Âíóòðè for ìîæåò áûòü ðàñïîëîæåí è äðóãîé for. Âîò òàê âûãëÿäèò êîä äëÿ âûâîäà òàáëèû óìíîæåíèÿ âñåõ ÷èñåë îò 1 äî 10 (íå î÷åíü êðàñèâîé): f o r i in range ( 1 , 1 1 ) : f o r j in range ( 1 , 1 1 ) : print ( i * j , end= ' print ( ) ') Êàê âû ìîæåòå çàìåòèòü, ïðè èñïîëüçîâàíèè ôóíêöèè range â for ìû íå ïðåîáðàçîâûâàëè iterable â tuple. Ýòî ñâÿçàíî ñ òåì, ÷òî for êàê ðàç õî÷åò ïîëó÷àòü ïîñëåäîâàòåëüíûé äîñòóï, êîòîðûé óìååò äàâàòü iterable. Tuple óìååò íàìíîãî áîëüøå, íî çäåñü åãî èñïîëüçîâàíèå ïðèâåäåò ê íåíóæíûì çàòðàòàì âðåìåíè è ïàìÿòè. 44 5.5 ЛЕКЦИЯ 5. КОРТЕЖИ, ЦИКЛ FOR, СПИСКИ Списки Ñïèñîê â Ïèòîíå ÿâëÿåòñÿ àíàëîãîì ìàññèâîâ â äðóãèõ ÿçûêàõ ïðîãðàììèðîâàíèÿ. Ñïèñîê ýòî íàáîð ññûëîê íà îáúåêòû (òàêæå êàê è êîðòåæ), îäíàêî îí ÿâëÿåòñÿ èçìåíÿåìûì. Êîíàñòíàíòíûå ñïèñêè çàïèñûâàþòñÿ â êâàäðàòíûõ ñêîáêàõ, âñå îñòàëüíîå â íèõ àíàëîãè÷íî êîðòåæàì. Íàïðèìåð ìîæíî ñîçäàòü ñïèñîê ñ ÷èñëàìè îò 1 äî 5: myList = [1, 2, 3, 4, 5]. Ñïèñêè è êîðòåæè ëåãêî ïðåîáðàçóþòñÿ äðóã â äðóãà. Äëÿ ïðåîáðàçîâàíèÿ ñïèñêà â êîðòåæ íàäî èñïîëüçîâàòü óæå èçâåñòíóþ íàì ôóíêöèþ tuple, à äëÿ ïðåîáðàçîâàíèÿ êîðòåæà â ñòðîêó íóæíà ôóíêöèÿ list. Òàêæå ôóíêöèþ list ìîæíî ïðèìåíèòü ê ñòðîêå.  ðåçóëüòàòå ýòîãî ïîëó÷èòñÿ ñïèñîê, êàæäûì ýëåìåíòîì êîòîðîãî áóäåò áóêâà èç ñòðîêè. Òàê list('abc') áóäåò âûãëÿäåòü êàê ['a', 'b', 'c']. Ê ñïèñêàì òàêæå ïðèìåíèìà ôóíêöèÿ len è ñðåçû, êîòîðûå ðàáîòàþò òàêæå êàê â êîðòåæàõ. Ãëàâíûì îòëè÷èåì ñïèñêà îò êîðòåæà ÿâëÿåòñÿ èçìåíÿåìîñòü. Òî åñòü ìîæíî âçÿòü îïðåäåëåííûé ýëåìåíò ñïèñêà è èçìåíèòü åãî (îí ìîæåò áûòü â ëåâîé ÷àñòè îïåðàöèè ïðèñâàèâàíèÿ). Íàïðèìåð, â ðåçóëüòàòå âûïîëíåíèÿ òàêîãî êîäà: myList = [ 1 , 2 , 3 ] myList [ 1 ] = 4 print ( myList ) áóäåò íàïå÷àòàíî [1, 4, 3]. Èçìåíåíèå ñèìâîëà (èëè ýëåìåíòà â êîðòåæå) ìîæíî áûëî ðåàëèçîâàòü, ñäåëàâ äâà ñðåçà è êîíêàòåíàöèÿ ïåðâîé ÷àñòè ñòðîêè, íîâîãî ñèìâîëà è ¾õâîñòà¿ ñòðîêè. Ýòî î÷åíü ìåäëåííàÿ îïåðàöèÿ, âðåìÿ åå âûïîëíåíèÿ ïðîïîðöèîíàëüíî äëèíå ñòðîêè. Çàìåíà ýëåìåíòà â ñïèñêå îñóùåñòâëÿåòñÿ çà 𝑂(1), ò.å. íå çàâèñèò îò äëèíû ñïèñêà. 5.6 Изменение списков Ñïèñîê, êàê è äðóãèå òèïû â ÿçûêå Ïèòîí, ÿâëÿåòñÿ ññûëêîé íà ñïèñîê ññûëîê. Ïðè ýòîì ñïèñîê ÿâëÿåòñÿ èçìåíÿåìûì îáúåêòîì, ò.å. ñîäåðæèìîå ïî ýòîé ññûëêå ìîæåò ïîìåíÿòüñÿ. ðàññìàîòðèì òàêîé ïðèìåð: a = [1 , 2] b = a b[0] = 3 print ( a )  ðåçóëüòàòå âûïîëíåíèÿ ýòîé ïðîãðàììû áóäåò íàïå÷àòàíî [3, 2]. Ýòî ñâÿçàíî ñ òåì, ÷òî ïðèñâàèâàíèå â Ïèòîíå ýòî ïðîñòî ¾ïðèâÿçûâàíèå¿ íîâîãî ¾ÿðëû÷êà¿ îáúåêòó. Ïîñëå ïðèñâàèâàíèÿ b = a îáå ññûëêè íà÷èíàþò ïîêàçûâàòü íà îäèí è òîò æå îáúåêò è åñëè îí èçìåíåíåí ïî îäíîé ññûëêå, òî ïî âòîðîé ññûëêå îí òàæêå áóäåò äîñòóïåí â èçìåíåííîì ñîñòîÿíèè. Åñëè æå íàïèñàòü òàêîé êîä: a = [1 , 2] b = [1 , 2] 5.6. ИЗМЕНЕНИЕ СПИСКОВ 45 a[0] = 3 print ( b ) òî áóäåò âûâåäåíî [1, 2]. Íåñìîòðÿ íà òî, ÷òî îáúåêòû èìåþò îäèíàêîâîå çíà÷åíèå èç-çà èõ ìóòàáåëüíîñòè (èçìåíÿåìîñòè) äëÿ êàæäîãî çíà÷åíèÿ áóäåò ñîçäàí îòäåëüíûé îáúåêò è ññûëêè a è b áóäóò ïîêàçûâàòü íà ðàçíûå îáúåêòû. Èçìåíåíèå îäíîãî èç íèõ, åñòåòñòâåííî, íå ïðèâîäèò ê èçìåíåíèþ äðóãîãî.  ðåçóëüòàòå âûïîëíåíèÿ òàêîãî êîäà: a = [1 , 2] b = a a = [3 , 4] print ( b ) áóäåò âûâåäåíî [1, 2]. Ñíà÷àëà â ïàìÿòè ñîçäàåòñÿ îáúåêò [1, 2] è ê íåìó ïðèâÿçûâàåòñÿ ññûëêà a, çàòåì ê òîìó æå îáúåêòó ïðèâÿçûâàåòñÿ ññûëêà b, à çàòåì ñîçäàåòñÿ íîâûé îáúåêò [2, 3], ê êîòîðîìó ïðèâÿçûâàåòñÿ ññûëêà a (îòâÿçàâøèñü îò ñâîåãî ïðåäûäóùåãî çíà÷åíèÿ). Ïðè ýòîì ññûëêà b íå èçìåíèëàñü (îíà ìîæåò èçìåíèòüñÿ òîëüêî åñëè b áóäåò ó÷àñòâîâàòü â ëåâîé ÷àñòè ïðèñâàèâàíèÿ) è ïî-ïðåæíåìó ïîêàçûâàåò íà [1, 2]. Åñëè ñïèñêè ïåðåäàíû â ôóíêöèþ â êà÷åñòâå ïàðàìåòðîâ, òî èõ ñîäåðæèìîå òàêæå ìîæåò áûòü èçìåíåíî ýòîé ôóíêöèåé: def r e p l a c e F i r s t ( myList ) : myList [ 0 ] = ' x ' nowList = l i s t ( ' a b c d e f ' ) r e p l a c e F i r s t ( nowList ) print ( nowList ) Âûâîäå ýòîé ïðîãðàììû áóäåò ['x', 'b', 'c', 'd', 'e', 'f']. Îäíàêî, ñàìà ññûëêà âíóòðè ôóíêöèè íå ìîæåò áûòü èçìåíåíà, åñëè îíà ïåðåäàíà êàê ïàðàìåòð ôóíêöèè. Ðàññìîòðèì ïðèìåð: def r e v e r s e L i s t ( f u n c L i s t ) : funcList = funcList [:: −1] m a i n L i s t = l i s t ( ' abc ' ) r e v e r s e L i s t ( mainList ) print ( m a i n L i s t ) Ýòà ïðîãðàììà íå ðàçâåðíåò ñïèñîê, ò.å. âûâîä áóäåò ['a', 'b', 'c']. Çäåñü â îñíîâíîé ïðîãðàììå êîíñòðóèðóåòñÿ îáúåêò ['a', 'b', 'c'] è ê íåìó ïðèâÿçûâàåòñÿ ññûëêà mainList. Ïðè ïåðåäà÷å mainList â êà÷åñòâå ïàðàìåòðà â ôóíêöèþ ñîçäàñòñÿ åùå îäíà ññûëêà funcList, ïîêàçûâàþùàÿ íà îáúåêò ['a', 'b', 'c'].  ðåçóëüòàòå ïðèìåíåíèÿ ñðåçà ñîçäàñòñÿ íîâûé îáúåêò ['c', 'b', 'a'] è ññûëêà funcList íà÷íåò óêàçûâàòü íà íåãî. Îäíàêî, çíà÷åíèå ññûëêè mainList ïðè ýòîì íå èçìåíèòñÿ è ñî çíà÷åíèÿìè ïî ññûëêå mainList òàêæå íè÷åãî íå ïðîèçîéäåò (íàïîìíèì, ÷òî îïåðàöèÿ ñðåçà ñîçäàåò íîâûé îáúåêò, íå èçìåíÿÿ ñòàðûé). 46 5.7 ЛЕКЦИЯ 5. КОРТЕЖИ, ЦИКЛ FOR, СПИСКИ Методы split и join, функция map Ñòðîêè èìåþò äâà ïîëåçíûõ ìåòîäà, êîòîðûå ïðèãîäÿòñÿ ïðè ðàáîòå ñî ñïèñêàìè. Ìåòîä split ïîçâîëÿåò ðàçðåçàòü ñòðîêó (string) íà îòäåëüíûå ñëîâà (¾òîêåíû¿).  êà÷åñòâå ðàçäåëèòåëÿ ìîæåò âûñòóïàòü ïðîáåë, ñèìâîë òàáóëÿöèè èëè ïåðåâîäà ñòðîêè. Ýòîò ìåòîä íå èçìåíÿåò ñòðîêó è âîçâðàùàåò ñïèñîê ñòðîê-òîêåíîâ. Íàïðèìåð, åñëè çàóïñòèòü òàêóþ ïðîãðàììó print ( ' r e d g r e e n blue ' . s p l i t ( ) ) òî áóäåò íàïå÷àòàíî ['red', 'green', 'blue']. Êîëè÷åñòâî ðàçäåëèòåëåé ìåæäó òîêåíàìè íå èãðàåò ðîëè. ×òîáû íàó÷èòüñÿ ÷èòàòü ÷èñëà èç îäíîé ñòðîêè íóæíî íàó÷èòüñÿ åùå îäíîé ôóíêöèè map. Ôóíêöèÿ map ïðèíèìàåò äâà ïàðàìåòðà: ïåðâûé ýòî ôóíêöèè, à âòîðîé iterable ýëåìåíòîâ, ê êîòîðîìó íóæíî ïðèìåíèòü ýòó ôóíêöèþ.  ðåçóëüòàòå ïîëó÷àåòñÿ iterable ñ ðåçóëüòàòîì ïðèìåíåíèÿ ôóíêöèè ê êàæäîìó ýëåìåíòó ñïèñêà ïàðàìåòðà. Íàïðèìåð, òàêîé êîä: print ( l i s t (map( len , [ ' red ' , ' green ' , ' blue ' ] ) ) ) íàïå÷àòàåò [3, 5, 4] ñïèñîê ñ ðåçóëüòàòîì ïðèìåíåíèÿ ôóíêöèè len ê ñïèñêó ['red', 'green', 'blue']. Ìåòîä split â ñî÷åòàíèè ñ ôóíêöèåé map óäîáíî èñïîëüçîâàòü äëÿ ñ÷èòûâàíèÿ ñïèñêà ÷èñåë, çàïèñàííûõ â îäíó ñòðîêó è ðàçäåëåííûõ ïðîáåëàìè. Òàêîå ñ÷èòûâàíèå áóäåò âûãëÿäåòü òàê: numList = l i s t (map( int , input ( ) . s p l i t ( ) ) ) Ñíà÷àëà îñóùåñòâëÿåòñÿ ñ÷èòûâàíèå ñòðîêè, çàòåì âûïîëíÿåòñÿ ìåòîä split, êîòîðûé ñîçäàåò ñïèñîê òîêåíîâ, ñîñòîÿùèõ èç öèôð, à çàòåì ê êàæäîìó òîêåíó ïðèìåíÿåòñÿ ôóíêöèÿ int.  ðåçóëüòàòå ýòîãî ïîëó÷àåòñÿ ñïèñîê öèôð. Ìåòîä join ïîçâîëÿåò îáúåäèíèòü iterable ñòðîê, èñïîëüçóÿ òó ñòðîêó, ê êîòîðîé îí ïðèìåíåí, â êà÷åñòâå ðàçäåëèòåëÿ. Íàïðèìåð, òàêîé êîä: print ( ' , ' . j o i n ( [ ' Veni ' , ' V i d i ' , ' V i c i ' ] ) ) âûâåäåò Veni, Vidi, Vici. Ñòðîêà ', ' áóäåò âûñòóïàòü â êà÷åñòâå ðàçäåëèòåëÿ êîòîðûé áóäåò âñòàâëÿòüñÿ ïîñëå êàæäîé ñòðîêè èç ñïèñêà-ïàðàìåòðà (êðîìå ïîñëåäíåé). Ìåòîä join ïîçâîëÿåò áûñòðî è êîðîòêî âûâîäèòü ñïèñêè ÷èñåë. Ïðîáëåìà â òîì, ÷òî îí óìååò ïðèíèìàòü â êà÷åñòâå ïàðàìåòðà òîëüêî iterable ñòðîê. Íî ñ ïîìîùüþ ôóíêöèè map ìû ìîæåì ëåãêî ïîëó÷èòü iterable èç ñïèñêà ÷èñåë, ïðèìåíèâ ê êàæäîìó ýëåìåíòó ôóíêöèþ str. Âûâîä ñïèñêà ÷èñåë numList ðàçäåëåííûõ ïðîáåëàìè áóäåò âûãëÿäåòü òàê: numList = [ 1 , 2 , 3 ] print ( ' ' . j o i n (map( str , numList ) ) ) 5.8 Другие полезные методы для работы со списками Ê ïåðåìåííûì òèïà ñïèñîê ìîæíî ïðèìåíÿòü ìåòîäû, ïåðå÷èñëèì íåêîòîðûå èç íèõ: Ìåòîäû, íå èçìåíÿþùèå ñïèñîê è âîçâðàùàþùèå çíà÷åíèå: 5.9. ПОЧЕМУ СОЗДАНИЕ НОВОГО ЛУЧШЕ УДАЛЕНИЯ 47 count(x) ïîäñ÷èòûâàåò ÷èñëî âõîæäåíèé çíà÷åíèÿ x â ñïèñîê. Работает за время O(N) index(x) íàõîäèò ïîçèöèþ ïåðâîãî âõîæäåíèÿ çíà÷åíèÿ x â ñïèñîê. Работает за время O(N) index(x, from) íàõîäèò ïîçèöèþ ïåðâîãî âõîæäåíèÿ çíà÷åíèÿ x â ñïèñîê, íà÷èíàÿ ñ ïîçèöèè from. Работает за время O(N) Ìåòîäû, íå âîçâðàùàþùèå çíà÷åíèå, íî èçìåíÿþùèå ñïèñîê: append(x) äîáàâëÿåò çíà÷åíèå x â êîíåö ñïèñêà extend(otherList) äîáàâëÿåò âñå ñîäåðæèìîå ñïèñêà otherList â êîíåö ñïèñêà.  îòëè÷èå îò îïåðàöèè + èçìåíÿåò îáúåêò ê êîòîðîìó ïðèìåíåí, à íå ñîçäàåò íîâûé remove(x) óäàëÿåò ïåðâîå âõîæäåíèå ÷èñëà x â ñïèñîê. Работает за время O(N) insert(index, x) âñòàâëÿåò ÷èñëî x â ñïèñîê òàê, ÷òî îíî îêàçûâàåòñÿ íà ïîçèöèè index. ×èñëî, ñòîÿâøåå íà ïîçèöèè index è âñå ÷èñëà ïðàâåå íåãî ñäâèãàþòñÿ íà îäèí âïðàâî. Работает за время O(N) reverse() Ðàçâîðà÷èâàåò ñïèñîê (ìåíÿåò çíà÷åíèå ïî ññûëêå, à íå ñîçäàåò íîâûé ñïèñîê êàê myList[::-1]). Работает за время O(N) Ìåòîäû, âîçâðàùàþùèå çíà÷åíèå è èçìåíÿþùèå ñïèñîê: pop() âîçâðàùàåò ïîñëåäíèé ýëåìåíò ñïèñêà è óäàëÿåò åãî pop(index) âîçâðàùàåò ýëåìåíò ñïèñêà íà ïîçèöèè index è óäàëÿåò åãî. Работает за время O(N) 5.9 Почему создание нового лучше удаления Ðàññìîòðèì òàêóþ çàäà÷ó: íåîáõîäèìî âûáðàòü âñå íå÷åòíûå ýëåìåíòû ñïèñêà myList è óäàëèòü èõ èç íåãî. Ïîïðîáóåì ðåøèòü çàäà÷ó â ëîá ïðîñòî áóäåì ïåðåáèðàòü âñå ïîçèöèè â ñòðîêå è, åñëè íà ýòîé ïîçèöèè ñòîèò íå÷åòíîå ÷èñëî, áóäåì óäàëÿòü åãî. numbers = l i s t (map( int , input ( ) . s p l i t ( ) ) ) f o r i in range ( len ( numbers ) ) : i f numbers [ i ] % 2 != 0 : numbers . pop ( i ) print ( ' ' . j o i n (map( str , numbers ) ) ) Òàêîå ðåøåíèå áóäåò ðàáîòàòü íåïðàâèëüíî â ñèòóàöèè, êîãäà â ñïèñêå åñòü õîòü îäíî íå÷åòíîå ÷èñëî. Ýòî ñâÿçàíî ñ òåì, ÷òî îáúåêò áåç íàçâàíèÿ ñ òèïîì iterable è çíà÷åíèåì range(len(numbers)) ñãåíåðèðóåòñÿ îäèí ðàç, êîãäà èíòåðïðåòàòîð âïåðâûå äîéäåò äî ýòîãî ìåñòà è óæå íèêîãäà íå èçìåíèòñÿ. Åñëè â ïðîöåññå ìû âûêèíåì èç ñïèñêà numbers õîòü îäíî çíà÷åíèå, òî â ïðîöåññå ïåðåáîðà âñåõ èíäåêñîâ âûéäåì çà ïðåäåëû íàøåãî ñïèñêà. range, èñïîëüçóåìûé â for, íå áóäåò ìåíÿòü ñâîå çíà÷åíèå åñëè â ïðîöåññå ðàáîòû èçìåíèëèñü ïàðàìåòðû ôóíêöèè range. Ðåøåíèå ìîæíî ïåðåïèñàòü ñ ïîìîùüþ while: numbers = l i s t (map( int , input ( ) . s p l i t ( ) ) ) i = 0 while i < len ( numbers ) : i f numbers [ i ] % 2 != 0 : numbers . pop ( i ) 48 ЛЕКЦИЯ 5. КОРТЕЖИ, ЦИКЛ FOR, СПИСКИ else : print ( ' i += 1 ' . j o i n (map( str , numbers ) ) ) Òàêîå ðåøåíèå áóäåò ðàáîòàòü, íî îíî íå î÷åíü ýôôåêòèâíî. Êàæäûé ðàç ïðè óäàëåíèè ýëåìåíòà íàì ïðèäåòñÿ ñîâåðøàòü êîëè÷åñòâî îïåðàöèé, ïðîïîðöèîíàëüíîå äëèíå ñïèñêà. Èòîãîâîå êîëè÷åñòâî îïåðàöèé â õóäøåì ñëó÷àå áóäåò ïðîïîðöèîíàëüíî êâàäàðòó êîëè÷åñòâà ýëåìåíòîâ â ñïèñêå.  ñëó÷àå, åñëè íåò î÷åíü ñòðîãîãî îãðàíè÷åíèÿ â ïàìÿòè, â çàäà÷àõ, ãäå íóæíî óäàëèòü ÷àñòü ýëåìåíòîâ ñïèñêà ãîðàçäî ïðîùå ñîçäàòü íîâûé ñïèñîê, â êîòîðûé íóæíî äîáàâëÿòü òîëüêî ïîäõîäÿùèå ýëåìåíòû. numbers = l i s t (map( int , input ( ) . s p l i t ( ) ) ) newList = [ ] f o r i in range ( len ( numbers ) ) : i f numbers [ i ] % 2 == 0 : newList . append ( numbers [ i ] ) print ( ' ' . j o i n (map( str , newList ) ) ) Ñëîæíîñòü òàêîãî ðåøåíèÿ ïðîïîðöèîíàëüíà äëèíå èñõîäíîãî ñïèñêà, ÷òî íàìíîãî ëó÷øå. Лекция 6 Сортировка, лямбда-функции, именованные параметры 6.1 Сортировка списков  ïðîãðàììèðîâàíèè î÷åíü ÷àñòî óäîáíåå ðàáîòàòü ñ îòñîðòèðîâàííûìè äàííûìè.  ÿçûêå Ïèòîí ñóùåñòâóåò âîçìîæíîñòü îòñîðòèðîâàòü ñïèñêè äâóìÿ ñïîñîáàìè. Ðàññìîòðèì èõ íà ïðèìåðå ðåøåíèÿ ïðîñòîé çàäà÷è î ñîðòèðîâêå ïîñëåäîâàòåëüíîñòè ÷èñåë ïî íåóáûâàíèþ (ýòî êàê ïî âîçðàñòàíèþ, íî, âîçìîæíî, ñ îäèíàêîâûìè ÷èñëàìè). Âîò ïåðâûé ñïîñîá óïîðÿäî÷èòü åãî: myList = l i s t (map( int , input ( ) . s p l i t ( ) ) ) myList . s o r t ( ) print ( ' ' . j o i n (map( str , myList ) ) )  ýòîì ïðèìåðå èñïîëüçóåòñÿ ìåòîä sort, ïðèìåíÿåìûé ê ñïèñêó. Ýòîò ìåòîä èçìåíÿåò ñîäåðæèìîå ñïèñêà ïîñëå ïðèìåíåíèÿ ìåòîäà sort ýëåìåíòû â ñïèñêå ñòàíîâÿòñÿ óïîðÿäî÷åííûìè. Òàêîé ìåòîä îïðåäåëåí òîëüêî äëÿ îáúåêòîâ òèïà ñïèñîê, åãî íåëüçÿ ïðèìåíèòü ê êîðòåæó èëè iterable èëè ñòðîêå. Âòîðîé ñïîñîá ñîñòîèò â ïðèìåíåíèè ôóíêöèè sorted, êîòîðàÿ âîçâðàùàåò îòñîðòèðîâàííûé ñïèñîê, íî íå èçìåíÿåò çíà÷åíèå ñâîåãî ïàðàìåòðà: myList = l i s t (map( int , input ( ) . s p l i t ( ) ) ) s o r t e d L i s t = sorted ( myList ) print ( ' ' . j o i n (map( str , s o r t e d L i s t ) ) ) Èñïîëüçîâàíèå ôóíêöèè sorted îïðàâäàíî â ñëó÷àå, åñëè èñõîäíûå äàííûå íóæíî ñîõðàíèòü â íåèçìåííîì âèäå ñ êàêîé-òî öåëüþ. Íàïðèìåð, sorted ìîæíî èñïîëüçîâàòü âíóòðè ñâîåé ôóíêöèè äëÿ ñîçäàíèÿ îòñîðòèðîâàííîé êîïèè, ÷òîáû íå ïîðòèòü ïåðåäàííûé íàì ñïèñîê. ×òîáû îòñîðòèðîâàòü ñïèñîê ïî íåâîçðàñòàíèþ (óáûâàíèþ), íåîáõîäèìî ïåðåäàòü â ìåòîä èëè ôóêíöèþ èìåíîâàííûé ïàðàìåòð reversed. Íàïðèìåð, ýòî áóäåò âûãëÿäåòü êàê myList.sort(reversed=True) èëè sorted(myList, reversed=True). Ôóíêöèÿ sorted ìîæåò ïðèíèìàòü â êà÷åñòâå ïàðàìåòðà íå òîëüêî ñïèñîê, íî è ÷òî óãîäíî èòåðèðóåìîå: êîðòåæè, iterable èëè ñòðîêè: print ( sorted ( ( 1 , 3 , 2 ) ) ) print ( sorted ( range ( 1 0 , − 1, − 2))) 49 50ЛЕКЦИЯ 6. СОРТИРОВКА, ЛЯМБДА-ФУНКЦИИ, ИМЕНОВАННЫЕ ПАРАМЕТРЫ print ( sorted ( " cba " ) ) Ïðè ýòîì sorted âñåãäà âîçâðàùàåò ñïèñîê, ò.å. âûâîä ýòîé ïðîãðàììû áóäåò òàêîé: [1, 2, 3] [0, 2, 4, 6, 8, 10] [’a’, ’b’, ’c’] Ñîðòèðîâêó ìîæíî ïðèìåíÿòü ê ñïèñêàì, âñå ýëåìåíòû êîòîðûõ ñðàâíèìû ìåæäó ñîáîé. Îáû÷íî ýòî îäíîðîäíûå ñïèñêè (ñîñòîÿùèå èç ýëåìåíòîâ îäíîãî òèïà) èëè, â ðåäêèõ ñëó÷àÿõ, öåëûå è âåùåñòâåííûå ÷èñëà âïåðåìåøêó. 6.2 Сравнение кортежей и списков Äâà êîðòåæà èëè ñïèñêà ìîæíî òàêæå ñðàâíèâàòü ìåæäó ñîáîé. Íàïðèìåð, âûðàæåíèå (1, 2, 3) < (2, 3, 4) áóäåòå èñòèííûì, à [1, 2, 3] < [1, 2] ëîæíûì. Ñðàâíåíèå êîðòåæåé è ñïèñêîâ ïðîèñõîäèò ïîýëåìåíòíî, êàê è ñðàâíåíèå ñòðîê. Êàê òîëüêî íà êàêèõ-òî ïîçèöèÿõ êîðòåæà èëè ñïèñêà âñòðåòèëèñü ðàçëè÷íûå ýëåìåíòû, òî âçàèìíûé ïîðÿäîê êîðòåæåé òàêîé æå, êàê ó ýòèõ ýëåìåíòîâ. Åñëè æå ðàçëè÷èé íàéäåíî íå áûëî, òî ìåíüøå òîò êîðòåæ, êîòîðûé êîðî÷å. Âñ¼ â òî÷íîñòè êàê ïðè ñðàâíåíèè ñòðîê. Åñòåñòâåííî, ñðàâíèâàåìûå êîðòåæè èëè ñïèñêè äîëæíû ñîäåðæàòü íà ñîîòâåòñòâóþùèõ ïîçèöèÿõ ñðàâíèìûå ýëåìåíòû. Ïîïûòêà ñðàâíèòü êîðòåæ (1, 2) ñ êîðòåæåì ("Some text 42) ïðèâåäåò ê îøèáêå (à ñðàâíåíèå (1, 2) ñ (42, "Some text") ê îøèáêå íå ïðèâåäåò). Îáû÷íî, âñ¼ æå, ñðàâíèâàþòñÿ êîðòåæè, ñîñòîÿùèå èç ýëåìåíòîâ îäèíàêîâîãî òèïà. Ýòî ñâîéñòâî êîðòåæåé ìîæíî èñïîëüçîâàòü äëÿ ðåøåíèÿ ñëîæíûõ çàäà÷ íà ñîðòèðîâêó. Íàïðèìåð, äëÿ êàæäîãî ÷åëîâåêà çàäàí åãî ðîñò è èìÿ, íåîáõîäèìî îïðåäåëèòü óïîðÿäî÷èòü ñïèñîê ëþäåé ïî ðîñòó, à â ñëó÷àå îäèíàêîãî ðîñòà â àëôàâèòíîì ïîðÿäêå. Ïðè ðåøåíèè ýòîé çàäà÷è äîñòàòî÷íî õðàíèòü îïèñàíèå êàæäîãî ÷åëîâåêà â âèäå êîðòåæà, ãäå ïåðâûì ýëåìåíòîì áóäåò ðîñò, à âòîðûì ôàìèëèÿ. Ðàññìîòðèì ïðèìåð: äëÿ êàæäîãî ÷åëîâåêà çàäàí ðîñò è åãî èìÿ. Íåîáõîäèìî óïîðÿäî÷èòü èõ ïî âîçðàñòàíèþ ðîñòà, à â ñëó÷àå îäèíàêîâîãî ðîñòà â àëôàâèòíîì ïîðÿäêå. n = i n t ( input ( ) ) peopleList = [ ] f o r i in range ( n ) : tempManData = input ( ) . s p l i t ( ) manData = ( i n t ( tempManData [ 0 ] ) , tempManData [ 1 ] ) p e o p l e L i s t . append ( manData ) peopleList . sort () f o r manData in p e o p l e L i s t : print ( ' ' . j o i n (map( str , manData ) ) )  ýòîì ïðèìåðå íàì ïîâåçëî è óäàëîñü ñîñòàâèòü êîðòåæ, êîòîðûé ñîäåðæèò ïàðàìåòðû ñðàâíèâàåìûõ ëþäåé ðîâíî â íóæíîì ïîðÿäêå. ×àñòî âñòðå÷àþòñÿ áîëåå íåïðèÿòíûå ñèòóàöèè. Ðàññìîòðèì òó æå çàäà÷ó, íî òåïåðü ëþäåé íóæíî óïîðÿäî÷èòü ïî óáûâàíèþ ðîñòà, íî â ñëó÷àå îäèíàêîâîãî ðîñòà îíè ïî-ïðåæíåìó äîëæíû áûòü óïîðÿäî÷åíû ïî àëôàâèòó. Ïðîñòîå èñïîëüçîâàíèå reversed=True íå ïðèâåäåò ê æåëàåìîìó ðåçóëüòàòó: ëþäè ñ îäèíàêîâûì ðîñòîì áóäóò ñòîÿòü â íåïðàâèëüíîì ïîðÿäêå. 6.3. ПАРАМЕТР KEY В ФУНКЦИИ SORT 51 Çäåñü ìîæíî ïðèìåíèòü õèòðîñòü è ïðåâðàòèòü ðîñò êàæäîãî ÷åëîâåêà â îòðèöàòåëüíîå ÷èñëî, ìîäóëü êîòîðîãî áóäåò ðàâåí èñõîäíîìó ðîñòó. Ïîñëå ýòîãî ñïèñîê ìîæíî ïðîñòî óïîðÿäî÷èòü ïî âîçðàñòàíèþ ñàìûå âûñîêèå ëþäè áóäóò èìåòü íàèìåíüøèé îòðèöàòåëüíûé ¾ðîñò¿, ïî êîòîðîìó ïðîèñõîäèò ñðàâíåíèå â ïåðâóþ î÷åðåäü. Ïåðåä âûâîäîì íåîáõîäèìî ïðåâðàòèòü ðîñò îáðàòíî â ïîëîæèòåëüíîå ÷èñëî. n = i n t ( input ( ) ) peopleList = [ ] f o r i in range ( n ) : tempManData = input ( ) . s p l i t ( ) manData = (− i n t ( tempManData [ 0 ] ) , tempManData [ 1 ] ) p e o p l e L i s t . append ( manData ) peopleList . sort () f o r badManData in p e o p l e L i s t : manData = (−badManData [ 0 ] , badManData [ 1 ] ) print ( ' ' . j o i n (map( str , manData ) ) ) Ýòîò êîä ìàëîïîíÿòåí è ïëîõ. 6.3 Параметр key в функции sort Äëÿ ðåàëèçàöèè íåñòàíäàðòíûõ ñîðòèðîâîê ëó÷øå íå óðîäîâàòü èñõîäíûå äàííûå, à èñïîëüçîâàòü ïàðàìåòð key, ïåðåäàþùèéñÿ â ôóíêöèþ ñîðòèðîâêè. Çíà÷åíèåì ýòîãî ïàðàìåòðà äîëæíà áûòü ôóíêöèÿ, êîòîðàÿ ïðèìåíÿåòñÿ ê êàæäîìó ýëåìåíòó ñïèñêà è çàòåì ñðàâíåíèå ýëåìåíòîâ ïðîèñõîäèò ïî çíà÷åíèþ ýòîé ôóíêöèè (îíî íàçûâàåòñÿ êëþ÷îì). Ðàññìîòðèì òàêîé ïðèìåð: íåîáõîäèìî óïîðÿäî÷èòü ââåä¼ííûå ñòðîêè ïî äëèíå, à â ñëó÷àå ðàâíîé äëèíû îñòàâèòü èõ â òîì ïîðÿäêå, êàê îíè øëè âî âõîäíîì ôàéëå. Íàïðèìåð, äëÿ âõîäíûõ ñòðîê c, abb, b ïðàâèëüíûì îòâåòîì äîëæíî áûòü c, b, abb (c èäåò ðàíüøå b, ò.ê. îíè èìåþò ðàâíóþ äëèíó, à c ñòîÿëî âî âõîäíûõ äàííûõ ðàíüøå b). Ê ñ÷àñòüþ, ñîðòèðîâêà, èñïîëüçóåìàÿ â Ïèòîíå îáëàäàåò ñâîéñòâîì óñòîé÷èâîñòè (stable), ò.å. äëÿ ýëåìåíòîâ ñ ðàâíûì êëþ÷îì ñîõðàíÿåòñÿ èõ âçàèìíûé ïîðÿäîê. Ðåøåíèå ýòîé çàäà÷è áóäåò âûãëÿäåòü ñëåäóþùèì îáðàçîì: n = i n t ( input ( ) ) strings = [ ] f o r i in range ( n ) : s t r i n g s . append ( input ( ) ) print ( ' \n ' . j o i n ( sorted ( s t r i n g s , key=len ) ) )  êà÷åñòâå åùå îäíîãî ïðèìåðà ðàññìîòðèì çàäà÷ó î ñîðòèðîâêå òî÷åê íà ïëîñêîñòè, çàäàííûõ ïàðîé öåëûõ êîîðäèíàò 𝑥 è 𝑦 ïî íåóáûâàíèþ ðàññòîÿíèÿ îò íà÷àëà êîîðäèíàò.  äàííîì ñëó÷àå â êà÷åñòâå ôóíêöèè äëÿ ãåíåðàöèè êëþ÷à, ïî êîòîðîìó áóäóò ñðàâíèâàòüñÿ ýëåìåíòû, ìû íàïèøåì ñâîþ ôóíêöèþ, êîòîðàÿ áóäåò âîçâðàùàòü êâàäðàò ðàññòîÿíèÿ îò òî÷êè äî íà÷àëà êîîðäèíàò. Êâàäðàò ðàññòîÿíèÿ ìû èñïîëüçóåì äëÿ òîãî, ÷òîáû îñòàâàòüñÿ â öåëûõ ÷èñëàõ è èçáàâèòñÿ îò íåîáõîäèìîñòè ñ÷èòàòü êâàäðàòíûé êîðåíü (ìåäëåííî è íåòî÷íî): 52ЛЕКЦИЯ 6. СОРТИРОВКА, ЛЯМБДА-ФУНКЦИИ, ИМЕНОВАННЫЕ ПАРАМЕТРЫ def d i s t ( p o i n t ) : return p o i n t [ 0 ] ** 2 + p o i n t [ 1 ] ** 2 n = i n t ( input ( ) ) points = [ ] f o r i in range ( n ) : p o i n t = tuple (map( int , input ( ) . s p l i t ( ) ) ) p o i n t s . append ( p o i n t ) p o i n t s . s o r t ( key=d i s t ) f o r p o i n t in p o i n t s : print ( ' ' . j o i n (map( str , p o i n t ) ) ) Çäåñü êàæäûé ýëåìåíò ñïèñêà êîðòåæ èç äâóõ ÷èñåë. Èìåííî òàêîé ïàðàìåòð ïðèíèìàåò íàøà ôóíêöèÿ. Âîçìîæíî, âû õîòåëè áû èñïîëüçîâàòü ôóíêöèþ hypot èç áèáëèîòåêè math, ÷òîáû íå ïèñàòü ñâîþ ôóíêöèþ ïîäñ÷åòà êëþ÷à, îäíàêî ýòî íåâîçìîæíî îíà îæèäàåò íà âõîä äâà ÷èñëîâûõ ïàðàìåòðà, à íå êîðòåæ. 6.4 «Структуры» в Питоне Äëÿ õðàíåíèÿ ñëîæíûõ çàïèñåé âî ìíîãèõ ÿçûêàõ åñòü ñïåöèàëüíûå òèïû äàííûõ, òàêèå êàê struct â C++ èëè record â Ïàñêàëå. Ïåðåìåííàÿ òèïà ñòðóêòóðà ñîäåðæèò â ñåáå íåñêîëüêî èìåíîâàííûõ ïîëåé. Íàïðèìåð, âîçâðàùàÿñü ê çàäà÷å ñîðòèðîâêè ëþäåé ïî óáûâàíèþ ðîñòà, íàì áûëî áû óäîáíî õðàíèòü îïèñàíèå êàæäîãî ÷åëîâåêà â âèäå ñòðóêòóðû ñ äâóìÿ ïîëÿìè: ðîñòîì è èìåíåì.  ÷èñòîì âèäå òèïà äàííûõ ¾ñòðóêòóðà¿ â ñòàíäàðòå ÿçûêà Ïèòîí íåò. Åñòü íåñêîëüêî ñïîñîáîâ ðåàëèçàöèè àíàëîãà ñòðóêòóð: namedtuple èç áèáëèîòåêè collections, èñïîëüçîâàíèå ñëîâàðåé (áóäåò ðàññìîòðåíî â ñëåäóþùèõ ëåêöèÿõ) èëè èñïîëüçîâàíèå êëàññîâ â êà÷åñòâå ñòðóêòóð. Ðàññìîòðèì íà ïðèìåðå ïîñëåäíèé ñïîñîá. Íàïîìíèì óñëîâèå çàäà÷è: ëþäåé íóæíî óïîðÿäî÷èòü ïî óáûâàíèþ ðîñòà, íî â ñëó÷àå îäèíàêîâîãî ðîñòà îíè äîëæíû áûòü óïîðÿäî÷åíû ïî ôàìèëèè. Ðåøåíèå ñ èñïîëüçîâàíèåì êëàññîâ â êà÷åñòâå ñòðóêòóð áóäåò âûãëÿäåòü òàê: c l a s s Man : height = 0 name = ' ' def manKey (man ) : return (−man . h e i g h t , man . name ) n = i n t ( input ( ) ) peopleList = [ ] f o r i in range ( n ) : tempManData = input ( ) . s p l i t ( ) man = Man( ) man . h e i g h t = i n t ( tempManData [ 0 ] ) man . name = tempManData [ 1 ] p e o p l e L i s t . append (man) 6.5. ЛЯМБДА-ФУНКЦИИ 53 p e o p l e L i s t . s o r t ( key=manKey ) f o r man in p e o p l e L i s t : print (man . h e i g h t , man . name ) Äëÿ òîãî ÷òîáû ïîëüçîâàòüñÿ êëàññàìè êàê ñòðóêòóðàìè ìû ñîçäàåì íîâûé òèï äàííûõ Man.  îïèñàíèè êëàññà ìû ïåðå÷èñëÿåì èìåíà âñåõ ïîëåé è èõ çíà÷åíèÿ ïîóìîë÷àíèþ.  äàëüíåéøåì ìû ìîæåì ñîçäàâàòü îáúåêòû êëàññà Man (ýòî äåëàåòñÿ ñòðîêîé man = Man()), êîòîðûå ñíà÷àëà ïðîèíèöèàëèçèðóþò ñâîè ïîëÿ çíà÷åíèÿìè ïî óìîë÷àíèþ. Äîñòóï ê ïîëÿì êëàññà îñóùåñòâëÿåòñÿ ÷åðåç òî÷êó. Ôóíêöèÿ ñðàâíåíèÿ ïðèíèìàåò îáúåêò êëàññà è ãåíåðèðóåò êëþ÷, ïî êîòîðîìó ýòè îáúåêòû áóäóò ñðàâíèâàòüñÿ ïðè ñîðòèðîâêå. Èñïîëüçîâàíèå ñòðóêòóð äëÿ îïèñàíèÿ ñëîæíûõ îáúåêòîâ íàìíîãî ïðåäïî÷òèòåëüíåå, ÷åì èñïîëüçîâàíèå êîðòåæåé. Ïðè êîëè÷åñòâå ïàðàìåòðîâ áîëüøå äâóõ èñïîëüçîâàíèå êîðòåæåé çàïóòûâàåò ÷èòàòåëÿ è ïèñàòåëÿ êîäà, ò.ê. ñîâåðøåííî íåâîçìîæíî ïîíÿòü ÷òî õðàíèòñÿ â badNamedTuple[13] è ëåãêî ïîíÿòü ÷òî õðàíèòñÿ â goodNamedStruct.goodNamedField. 6.5 Лямбда-функции  ðÿäå ñëó÷àåâ ôóíêöèè, èñïîëüçóåìûå äëÿ ïîëó÷åíèÿ êëþ÷à ñîðòèðîâêè, òàê ïðîñòû, ÷òî íå õî÷åòñÿ îôîðìëÿòü èõ ñòàíäàðòíûì îáðàçîì, à õî÷åòñÿ íàïèñàòü èõ ïðÿìî íà ìåñòå è äàæå íå äàâàòü èì èìåíè. Ýòî ìîæíî îñóùåñòâèòü ñ ïîìîùüþ ëÿìáäà-ôóíêöèé, êîòîðûå ìîãóò çàìåíèòü ñîáîé ôóíêöèè, ñîäåðæàùèå â ñâîåì òåëå òîëüêî îïåðàòîð return. Çàïèñü ëÿìáäà-ôóíêöèè, âîçâîäÿùåé ÷èñëî â êâàäðàò ìîæåò âûãëÿäåòü òàê: lambda x : x ** 2 ×òî ýêâèâàëåíòíî ïðèâû÷íîé çàïèñè ôóíêöèè: def s q r ( x ) : return x ** 2 Îòëè÷èå ëÿìáäà-ôóíêöèè òàêæå çàêëþ÷àåòñÿ â òîì, ÷òî ó íå¼ íåò èìåíè è, ñëåäîâàòåëüíî, âûçîâ å¼ ïî èìåíè íåâîçìîæåí. Ïîêà åäèíñòâåííûì ïðèìåíåíèåì ëÿìáäàôóíêöèé äëÿ íàñ ìîæåò ñëóæèòü èõ ïåðåäà÷à â êà÷åñòâå ïàðàìåòðà â òàêèå ôóíêöèè êàê sort èëè map. Íàïðèìåð, ñ ïîìîùüþ ëÿìáäà-ôóíêöèè ìû ìîæåì âûâåñòè ñïèñîê êâàäðàòîâ âñåõ ÷èñåë îò 1 äî 100 âñåãî â îäíó ñòðîêó: print ( ' ' . j o i n (map( lambda x : s t r ( x * * 2 ) , range ( 1 , 1 0 1 ) ) ) )  ýòîé ïðîãðàììå ëÿìáäà ôóíêöèÿ ïðèíèìàåò â êà÷åñòâå ïàðàìåòðà ÷èñëî, à âîçâðàùàåò ñòðîêîâîå ïðåäñòàâëåíèå åãî êâàäðàòà. Âåðíåìñÿ ê çàäà÷å ñîðòèðîâêè òî÷åê ïî óäàëåííîñòè îò íà÷àëà êîîðäèíàò. Ýòà çàäà÷à òàêæå ìîæåò áûòü ðåøåíà ñ èñïîëüçîâàíèåì ëÿìáäà-ôóíêöèè: n = i n t ( input ( ) ) points = [ ] f o r i in range ( n ) : p o i n t = tuple (map( int , input ( ) . s p l i t ( ) ) ) p o i n t s . append ( p o i n t ) 54ЛЕКЦИЯ 6. СОРТИРОВКА, ЛЯМБДА-ФУНКЦИИ, ИМЕНОВАННЫЕ ПАРАМЕТРЫ p o i n t s . s o r t ( key=lambda p o i n t : p o i n t [ 0 ] * * 2 + p o i n t [ 1 ] * * 2 ) f o r p o i n t in p o i n t s : print ( ' ' . j o i n (map( str , p o i n t ) ) ) Ëÿìáäà-ôóíêöèÿ ìîæåò ïðèíèìàòü íåñêîëüêî ïàðàìåòðîâ (òîãäà ïîñëå ñëîâà lambda íóæíî çàïèñàòü èõ èìåíà ÷åðåç çàïÿòóþ), îäíàêî ïðè èñïîëüçîâàíèè èõ â sort èëè map ïàðàìåòð äîëæåí áûòü âñåãäà îäèí.  ÿçûêå Ïèòîí ôóíêöèÿ òàêæå ÿâëÿåòñÿ îáúåêòîì è ìû ìîæåì ñîçäàòü ññûëêó íà îáúåêò òèïà ôóíêöèÿ. Íàïðèìåð, äâå çàïèñè ôóíêöèè âîçâåäåíèÿ â êâàäðàò ýêâèâàëåíòíû: def t r a d i t i o n a l S q r ( x ) : return x ** 2 lambdaSqr = lambda x : x ** 2 print ( t r a d i t i o n a l S q r ( 3 ) ) print ( lambdaSqr ( 3 ) ) Òàêîé ïîäõîä ïîçâîëÿåò ïåðåèñïîëüçîâàòü ëÿìáäà-ôóíêöèè, íî â ïîäàâëÿþùåì áîëüøèíñòâå ñëó÷àåâ ñòîèò ïîëüçîâàòüñÿ ñòàíäàðòíûì îáúÿâëåíèåì ôóíêöèè ýòî óïðîùàåò ÷òåíèå è îòëàäêó ïðîãðàììû. 6.6 Именованные параметры и неопределенное число параметров Ìû óæå ìíîãî ðàç ïîëüçîâàëèñü ôóíêöèÿìè, êîòîðûå ìîãóò ïðèíèìàòü (èëè íå ïðèíèìàòü) èìåíîâàííûå ïàðàìåòðû. Íàïðèìåð, ýòî íåîáÿçàòåëüíûå èìåíîâàííûå èëè íåèìåíîâàííûå ïàðàìåòðû sep è end äëÿ ôóíêöèè print èëè ïàðàìåòð key äëÿ ìåòîäà sort è ôóíêöèè sorted. Ñåé÷àñ ìû íàó÷èìñÿ ñîçäàâàòü ôóíêöèè, êîòîðûå ïðèíèìàþò èìåíîâàííûå ïàðàìåòðû. Íàïðèìåð, íàïèøåì ôóíêöèþ, ïå÷àòàþùóþ ÷òî óãîäíî èòåðèðóåìîå, ñîñòîÿùåå èç ÷åãî óãîäíî ïðèâîäèìîãî ê ñòðîêå, ñ èìåíîâàííûì ïàðàìåòðîì sep, ïî-óìîë÷àíèþ ðàâíûì ïðîáåëó: def p r i n t L i s t ( myList , s e p= ' ' ) : print ( s e p . j o i n (map( str , myList ) ) ) printList ([1 , 2 , 3]) p r i n t L i s t ( [ 3 , 2 , 1 ] , s e p= ' \n ' ) Èìåíîâàííûé ïàðàìåòð â îáúÿâëåíèè ôóíêöèè äîëæåí èäòè ïîñëå îñíîâíûõ ïàðàìåòðîâ.  ñïèñêå ïàðàìåòðîâ çàïèñûâàåòñÿ åãî èìÿ, à çàòåì çíà÷åíèå ïî-óìîë÷àíèþ (ò.å. òî çíà÷åíèå, êîòîðîå áóäåò ïîäñòàâëÿòüñÿ íà ìåñòî ñîîòâåòñòâóþùåãî ïàðàìåòðà, åñëè îí íå áûë ïåðåäàí ïðè âûçîâå ôóíêöèè). Òàêæå ìû ïîëüçîâàëèñü ôóíêöèÿìè, êîòîðûå óìåþò ïðèíèìàòü ïðîèçâîëüíîå êîëè÷åñòâî ïàðàìåòðîâ. Íàïðèìåð, â ôóíêöèþ print ìîæíî ïåðåäàòü ëþáîå êîëè÷åñòâî ïàðàìåòðîâ. Ìîæíî íàïèñàòü ñîáñòâåííûå ôóíêöèè, êîòîðûå áóäóò ïðèíèìàòü ïðîèçâîëüíîå êîëè÷åñòâî ïàðàìåòðîâ. Ïðè ýòîì ïàðàìåòðû ôóíêöèè áóäóò óïàêîâàíû â 6.7. ЧТЕНИЕ ДО КОНЦА ВВОДА 55 ñïèñîê. Íàïðèìåð, ôóíêöèÿ ïîäñ÷åòà ñóììû âñåõ ïåðåäàííûõ ïàðàìåòðîâ ìîæåò âûãëÿäåòü òàê: def mySum( * a r g s ) : nowSum = 0 f o r now in a r g s : nowSum += now return nowSum print (mySum( 1 , 2 ) ) print (mySum( 1 , 2 , 3 , 4 ) ) Ôóíêöèÿ ïðèíèìàåò îäèí ïàðàìåòð, ïåðåä êîòîðûì íàïèñàíà çâåçäî÷êà ýòî ïðèçíàê òîãî, ÷òî àðãóìåíòû áóäóò óïàêîâàíû â ñïèñîê. Ìîæíî ïèñàòü ôóíêöèè, êîòîðûå ïðèíèìàþò íå ìåíåå îïðåäåëåííîãî êîëè÷åñòâà ïàðàìåòðîâ. Íàïðèìåð, ìû ìîæåì íàïèñàòü ôóíêöèþ ïîèñêà ìèíèìóìà ñðåäè íåîïðåäåëåííîãî ÷èñëà àðãóìåíòîâ, íî â íåå äîëæíî áûòü ïåðåäàíî íå ìåíåå îäíîãî àðãóìåíòà: def myMin( f i r s t , * o t h e r s ) : nowMin = f i r s t f o r now in o t h e r s : i f now < nowMin : nowMin = now return nowMin print (myMin ( 1 ) ) print (myMin ( 3 , 1 , 2 ) ) Ïàðàìåòð ñî çâåçäî÷êîé âñåãäà äîëæåí áûòü ïîñëåäíèì, çà èñêëþ÷åíèåì ñèòóàöèè, êîãäà â ôóíêöèè òàêæå îïðåäåëåíû èìåíîâàííûå ïàðàìåòðû. 6.7 Чтение до конца ввода Âî ìíîãèõ çàäà÷àõ çàðàíåå íåèçâåñòíî, ñêîëüêî äàííûõ íàì ïðåäñòîèò ñ÷èòàòü. Îñîáåííî ÿðêèé ïðèìåð ýòî îáðàáîòêà òåêñòà, êîãäà ìû çàðàíåå íå çíàåì, ñêîëüêî ñòðîê íàì áóäåò ââåäåíî. Íàèáîëåå óäîáíî ðàáîòàòü ñ òàêèìè äàííûìè íå ïîëüçóÿñü ôóíêöèåé input, èñïîëüçóÿ ìåòîäû ÷òåíèÿ ôàéëà (èëè ââîäà ñ êîíñîëè) öåëèêîì èëè ïîñòðî÷íî. Ðàñììîòðèì ïðîñòîé ïðèìåð: ñ÷èòàòü âñå ñòðîêè ôàéëà input.txt è âûâåñòè êàæäóþ ñòðîêó ðàçâåðíóòîé â ôàéë output.txt: i n F i l e = open ( ' i n p u t . t x t ' , ' r ' , e n c o d i n g= ' u t f 8 ' ) o u t F i l e = open ( ' output . t x t ' , 'w ' , e n c o d i n g= ' u t f 8 ' ) lines = inFile . readlines () f o r l i n e in l i n e s : print ( l i n e [ − 2 : : − 1 ] , f i l e =o u t F i l e ) inFile . close () outFile . close () 56ЛЕКЦИЯ 6. СОРТИРОВКА, ЛЯМБДА-ФУНКЦИИ, ИМЕНОВАННЫЕ ПАРАМЕТРЫ Äëÿ îòêðûòèÿ ôàéëà èñïîëüçóåòñÿ ôóíêöèÿ open, ïðèíèìàþùàÿ äâà ïàðàìåòðà: èìÿ ôàéëà è ðåæèì îòêðûòèÿ (r äëÿ ÷òåíèÿ è w äëÿ çàïèñè), à òàêæå èìåíîâàííûé ïàðàìåòð encoding (çíà÷åíèå êîäèðîâêè utf8 ïîäõîäèò äëÿ áîëüøèíñòâà ñîâðåìåííûõ òåêñòîâûõ ôàéëîâ). Ýòà ôóíêöèÿ âîçâðàùàåò ññûëêó íà îáúåêò òèïà ôàéë. Äëÿ ÷òåíèÿ âñåõ ñòðîê èç ôàéëà èñïîëüçóåòñÿ ìåòîä readlines, êîòîðûé âîçâðàùàåò ñïèñîê âñåõ ñòðîê (â ñìûñëå lines) ôàéëà. Îáðàòèòå âíèìàíèå, ÷òî ñòðîêè ïîïàäàþò â ñïèñîê âìåñòå ñ ñèìâîëîì ïåðåâîäà ñòðîêè, â íàøåé ïðîãðàììå ýòî ó÷èòûâàåòñÿ ïðè ñîçäàíèè ñðåçà (ýòîò ñèìâîë ïîñëåäíèé â ñòðîêå).  òåñòèðóþùåé ñèñòåìå âñå âõîäíûå ôàéëû èìåþò ïåðåíîñ ñòðîêè ïîñëå ïîñëåäíåé ñòðîêè, â ðåàëüíîé æèçíè ýòî ìîæåò îêàçàòüñÿ íå òàê è òîãäà ïðîãðàììà áóäåò ðàáîòàòü íåâåðíî. Äëÿ ïå÷àòè â ôàéë ìû ïîëüçóåìñÿ ñòàíäàðòíîé ôóíêöèåé print, êîòîðîé ïåðåäàåòñÿ èìåíîâàííûé ïàðàìåòð le ñ óêàçàíèåì, â êàêîé ôàéë ïå÷àòàòü. Ïîñëå îêîí÷àíèÿ ðàáîòû ñ ôàéëàìè íóæíî âûçâàòü äëÿ íèõ ìåòîäû close.  ýòîé çàäà÷å, íà ñàìîì äåëå, ìîæíî áûëî îáîéòèñü áåç çàïîìèíàíèÿ âñåãî ôàéëà â ïàìÿòè (÷òî îñîáåííî àêòóàëüíî äëÿ áîëüøèõ ôàéëîâ). Ðåøåíèå áåç çàïîìèíàíèÿ âñåãî ôàéëà ìîæíî áûëî ðåàëèçîâàòü òàê: i n F i l e = open ( ' i n p u t . t x t ' , ' r ' , e n c o d i n g= ' u t f 8 ' ) o u t F i l e = open ( ' output . t x t ' , 'w ' , e n c o d i n g= ' u t f 8 ' ) f o r l i n e in i n F i l e : print ( l i n e [ − 2 : : − 1 ] , f i l e =o u t F i l e ) inFile . close () outFile . close () Ïåðåìåííûå òèïà ôàéë ÿâëÿþòñÿ iterable è óìåþò âîçâðàùàòü î÷åðåäíóþ ñòðîêó èç ôàéëà, íå õðàíÿ åãî öåëèêîì â ïàìÿòè. Òàêæå ñóùåñòâóåò ìåòîä read, êîòîðûé ïîçâîëÿåò ñ÷èòàòü âñå ñîäåðæèìîå ôàéëà â îäíó ñòðîêîâóþ ïåðåìåííóþ (ïðè ýòîì ñîäåðæàùóþ â ñåáå ïåðåâîäû ñòðîêè ∖𝑛).  ïðèíöèïå, ÷èòàòü äî êîíöà ââîäà ìîæíî è èç êîíñîëè. Äëÿ ýòîãî íóæíî ïîäêëþ÷èòü áèáëèîòåêó sys è èñïîëüçîâàòü îïðåäåëåííûé â íåé ôàéëîâûé äåñêðèïòîð stdin â êà÷åñòâå ôàéëà. Ââåñòè ïðèçíàê êîíöà ôàéëà â êîíñîëè ìîæíî íàæàâ Ctrl+Z â Windows èëè Ctrl+D â Unix-ñèñòåìàõ. 6.8 Сортировка подсчетом  ðÿäå çàäà÷ âîçìîæíûå çíà÷åíèÿ â ñîðòèðóåìîì ñïèñêå ñèëüíî îãðàíè÷åíû. Íàïðèìåð, åñëè ìû õîòèì îòñîðòèðîâàòü îöåíêè îò 0 äî 10, òî ìîæåò îêàçàòüñÿ ýôôåêòèâíåå ïîäñ÷èòàòü, ñêîëüêî ðàç âñòðå÷àëàñü êàæäàÿ èç îöåíîê è çàòåì âûâåñòè å¼ ñòîëüêî ðàç. Ðåàëèçàöèÿ òàêîãî ïîäõîäà î÷åíü ïðîñòà: marks = map( int , input ( ) . s p l i t ( ) ) cntMarks = [ 0 ] * 11 f o r mark in marks : cntMarks [ mark ] += 1 f o r nowMark in range ( 1 1 ) : print ( ( s t r ( nowMark ) + ' ' ) * cntMarks [ nowMark ] , end= ' ' )  ýòîé ïðîãðàììå ìû ñîçäàëè ñïèñîê, ñîñòîÿùèé èç 11 íóëåé â îäíó ñòðîêó. Ýòîò ïðè¼ì ÷àñòî ïðèãîæäàåòñÿ è â äðóãèõ çàäà÷àõ. 6.9. 6.9 СВЯЗЬ ЗАДАЧ ПОИСКА И СОРТИРОВКИ 57 Связь задач поиска и сортировки Âî ìíîãèõ çàäà÷àõ ëèíåéíîãî ïîèñêà (íàïðèìåð, ïîèñê ìèíèìàëüíîãî ýëåìåíòà) âîçíèêàåò ñîáëàçí âîñïîëüçîâàòüñÿ ñîðòèðîâêîé. Ñ ýòèì ñîáëàçíîì ñëåäóåò áîðîòüñÿ, ò.ê. ñëîæíîñòü ñîðòèðîâêè â ÿçûêå Ïèòîí ñîñòàâëÿåò 𝑂(𝑁 𝑙𝑜𝑔𝑁 ), ò.å. äëÿ ñîðòèðîâêè ñïèñêà èç 𝑁 ýëåìåíòîâ íóæíî ñîâåðøèòü ïîðÿäêà 𝑁 𝑙𝑜𝑔𝑁 äåéñòâèé. Ïðè ýòîì àëãîðèòìû ëèíåéíîãî ïîèñêà ðàáîòàþò çà 𝑂(𝑁 ), ÷òî çàìåòíî àñèìïòîòè÷åñêè áûñòðåå, ÷åì ñîðòèðîâêà. Ïîýòîìó â çàäà÷àõ ëèíåéíîãî ïîèñêà (äàæå äëÿ ïîèñêà òðåòüåãî ïî âåëè÷èíå ýëåìåíòà) ñëåäóåò ðåàëèçîâûâàòü ëèíåéíûé ïîèñê, à íå ïîëüçîâàòüñÿ ñîðòèðîâêîé. Ïî èðîíèè ñóäüáû, ñîðòèðîâêà â èíòåðïðåòàòîðå CPython ìîæåò îêàçàòüñÿ áûñòðåå ðóêîïèñíîãî ëèíåéíîãî ïîèñêà (èç-çà òîãî, ÷òî îíà ðåàëèçîâàíî ìàêñèìàëüíî ýôôåêòèâíî è íà ÿçûêå Ñè). Íî ýòî äîñàäíîå íåäîðàçóìåíèå íå äîëæíî ïîáîðîòü â âàñ æåëàíèå ïèñàòü ëèíåéíûé ïîèñê ðóêàìè. 58ЛЕКЦИЯ 6. СОРТИРОВКА, ЛЯМБДА-ФУНКЦИИ, ИМЕНОВАННЫЕ ПАРАМЕТРЫ Лекция 7 Множества, словари, полезные методы для строк 7.1 Множества и хеш-функции  ÿçûêå Ïèòîí ìíîæåñòâà èìåþò òîò æå ñìûñë, ÷òî è â ìàòåìàòèêå: íàáîð îáúåêòîâ áåç îïðåäåëåííîãî ïîðÿäêà.  ìíîæåñòâî ìîæíî äîáàâëÿòü è óäàëÿòü îáúåêòû, ïðîâåðÿòü ïðèíàäëåæíîñòü îáúåêòó ìíîæåñòâà è ïåðåáèðàòü âñå îáúåêòû ìíîæåñòâà. Òàêæå íàä ìíîæåñòâàìè ìîæíî ñîâåðøàòü ãðóïïîâûå îïåðàöèè, íàïðèìåð, ïåðåñåêàòü è îáúåäèíÿòü äâà ìíîæåñòâà. Ïðîâåðêà ïðèíàäëåæíîñòè ýëåìåíòà ìíîæåñòâó, à òàêæå îïåðàöèè óäàëåíèÿ è äîáàâëåíèÿ ýëåìåíòîâ, îñóùåñòâëÿþòñÿ çà 𝑂(1) (åñëè áû ìû õðàíèëè ýëåìåíòû â ñïèñêå è õîòåëè áû ïðîâåðèòü ïðèíàäëåæíîñòü ýëåìåíòà ñïèñêó, òî íàì ïîòðåáîâàëîñü áû 𝑂(𝑁 ) îïåðàöèé, ãäå 𝑁 äëèíà ñïèñêà). Òàêàÿ ñêîðîñòü äîñòèãàåòñÿ èñïîëüçîâàíèåì õåø-òàáëèö. Õåø-òàáëèöà ýòî ìàññèâ äîñòàòî÷íî áîëüøîãî ðàçìåðà (íàçîâåì ýòîò ðàçìåð 𝐾 ). Êàæäîìó íåèçìåíÿåìîìó îáúåêòó ìîæíî ñîïîñòàâèòü ïî íåêîòîðîìó ïðàâèëó ÷èñëî 𝑀 îò 0 äî 𝐾 è ïîìåñòèòü ýòîò îáúåêò â ÿ÷åéêó ñïèñêà ñ èíäåêñîì 𝑀 . Íàïðèìåð, äëÿ öåëûõ ÷èñåë òàêèì ïðàâèëîì ñîïîñòàâëåíèÿ ìîæåò áûòü ïðîñòî ïîäñ÷åò îñòàòêà îò äåëåíèÿ öåëîãî ÷èñëà íà 𝐾 . Îïåðàöèþ âçÿòèÿ îñòàòêà áóäåò íàøåé õåø-ôóíêöèåé. Òåïåðü åñëè íàì íóæíî ïðîâåðèòü, ïðèíàäëåæèò ëè íåêîòîðîå ÷èñëî ìíîæåñòâó, ìû ïðîñòî ñ÷èòàåì õåø-ôóíêöèþ îò íåãî è ïðîâåðÿåì, ëåæèò ëè â ÿ÷åéêå ñ èíäåêñîì, ðàâíûì ðåçóëüòàòó âû÷èñëåíèÿ õåø-ôóíêöèè íàø îáúåêò èëè íåò. Äëÿ äðóãèõ òèïîâ äàííûõ ìîæíî ïðèìåíèòü òàêîé ïîäõîä: ëþáîé îáúåêò òàê èëè èíà÷å ÿâëÿåòñÿ ïîñëåäîâàòåëüíîñòüþ áàéò. Áóäåì èíòåðïðåòèðîâàòü ýòó ïîñëåäîâàòåëüíîñòü áàéò êàê ÷èñëî è ïîäñ÷èòàåì õåø-ôóíêöèþ äëÿ ýòîãî ÷èñëà. Åñòåñòâåííî, ìîæåò îêàçàòüñÿ, ÷òî íåñêîëüêî îáúåêòîâ äàþò îäèí è òîò æå õåø (îòîáðàæåíèå ìåæäó îãðîìíûì ìíîæåñòâîì ðàçëè÷íûõ îáúåêòîâ è ñêðîìíûì ðàçìåðîì ìíîæåñòâà äîïóñòèìûõ õåøåé íå ìîæåò áûòü áèåêòèâíûì). Òàêèå ïðîáëåìû ìîæíî ðàçðåøèòü, íå óõóäøàÿ àñèìïòîòè÷åñêóþ ñëîæíîñòü. Ïîäðîáíåå òàêèå ìåòîäû âû áóäåòå èçó÷àòü íà êóðñå àëãîðèòìîâ. Ïîñêîëüêó, íàïðèìåð, ÷èñëà, ìîãóò áûòü äîñòàòî÷íî äëèííûìè, òî îïåðàöèÿ ïîäñ÷åòà õåø-ôóíêöèè ïðè êàæäîé îïåðàöèè ñ ýòèì îáúåêòîâ â ìíîæåñòâå ìîæåò áûòü î÷åíü ìåäëåííîé. Ïîýòîìó êàæäûé íåèçìåíÿåìûé îáúåêò â Ïèòîíå èìååò çàðàíåå íàñ÷èòàííûé õåø, êîòîðûé ïîäñ÷èòûâàåòñÿ îäèí ðàç ïðè åãî ñîçäàíèè. Êñòàòè, ñ ïîìîùüþ ýòèõ 59 60 ЛЕКЦИЯ 7. МНОЖЕСТВА, СЛОВАРИ, ПОЛЕЗНЫЕ МЕТОДЫ ДЛЯ СТРОК æå õåøåé ìîæíî ïîíèìàòü, åñòü ëè óæå îáúåêò â ïàìÿòè è íå ñîçäàâàòü íîâûõ îáúåêòîâ, à ïðîñòî ïîäâåøèâàòü åùå îäíó ññûëêó íà óæå ñóùåñòâóþùèé îáúåêò. Èçìåíÿåìûå òèïû, òàêèå êàê ñïèñîê, íå èìåþò çàðàíåå íàñ÷èòàííûõ õåøåé. Èçìåíåíèå âñåãî îäíîãî ýëåìåíòà â ñïèñêå ïðèâåëî áû ê ïîëíîìó ïåðåñ÷åòó õåøà äëÿ âñåãî ñïèñêà, ÷òî êàòàñòðîôè÷åñêè çàìåäëèëî áû ðàáîòó ñî ñïèñêàìè. Ïîýòîìó ó èçìåíÿåìûõ îáúåêòîâ íåò õåøà è îíè íå ìîãóò áûòü äîáàâëåíû â ìíîæåñòâî. Ñàìî ìíîæåñòâî òàêæå ÿâëÿåòñÿ èçìåíÿåìûì îáúåêòîì è íå ìîæåò áûòü, íàïðèìåð, ýëåìåíòîì äðóãîãî ìíîæåñòâà. Ñóùåñòâóþò òàêæå íåèçìåíÿåìûå ìíîæåñòâà, êîòîðûå ñîçäàþòñÿ ñ ïîìîùüþ ôóíêöèè frozenset. 7.2 Создание множеств Ìíîæåñòâî â òåëå ïðîãðàììû ìîæåò áûòü ñîçäàíî ñ ïîìîùüþ çàïèñè ýëåìåíòîâ ÷åðåç çàïÿòóþ â ôèãóðíûõ ñêîáêàõ: mySet = { 3 , 1 , 2} print ( mySet ) Âûâîä ñ ïîìîùüþ print îñóùåñòâëÿåòñÿ â òîì æå ôîðìàòå. Ïîðÿäîê ýëåìåíòîâ â ìíîæåñòâå ìîæåò áûòü ñëó÷àéíûì, ò.ê. õåø ôóíêöèÿ íå ãàðàíòèðóåò, ÷òî åñëè 𝐴 > 𝐵 , òî ℎ(𝐴) > ℎ(𝐵). Åñëè ïðè çàäàíèè ìíîæåñòâà ïðèñóòñòâîâàëî íåñêîëüêî îäèíàêîâûõ ýëåìåíòîâ, òî îíè ïîïàäóò â ìíîæåñòâî â åäèíñòâåííîì ýêçåìïëÿðå: f i r s t S e t = { 1 , 2 , 1 , 3} s e c o n d S e t = { 3 , 2 , 1} print ( f i r s t S e t == s e c o n d S e t ) Ýòà ïðîãðàììû âûâåäåò True (ìíîæåñòâà ìîæíî ñðàâíèâàòü íà ðàâåíñòâî). Òàêæå ìíîæåñòâà ìîæíî ñîçäàâàòü ñ ïîìîùüþ ôóíêöèè set, êîòîðàÿ ìîæåò ïðèíèìàòü â êà÷åñòâå ïàðàìåòðà ÷òî óãîäíî èòåðèðóåìîå: setFromList = set ( [ 1 , 2 , 3 ] ) print ( s e t F r o m L i s t ) setFromTuple = s e t ( ( 4 , 5 , 6 ) ) print ( setFromTuple ) setFromStr = s e t ( " l o l " ) print ( setFromStr ) setFromRange = s e t ( range ( 2 , 2 2 , 3 ) ) print ( setFromRange ) setFromMap = s e t (map( abs , ( 1 , 2 , 3 , − 2, − 4))) print ( setFromMap ) setFromSet = s e t ( { 1 , 2 , 3 } ) print ( setFromSet ) Âûâîä ýòîé ïðîãðàììû òàêîé: {1, 2, 3} {4, 5, 6} 7.3. РАБОТА С ЭЛЕМЕНТАМИ МНОЖЕСТВ 61 {’l’, ’o’} {2, 5, 8, 11, 14, 17, 20} {1, 2, 3, 4} {1, 2, 3} Ìíîæåñòâî òàêæå ÿâëÿåòñÿ èòåðèðóåìûì îáúåêòîì (åùå ðàç: îáúåêòû èäóò â ¾ñëó÷àéíîì¿ ïîðÿäêå, íå ïî âîçðàñòàíèþ!). Ìíîæåñòâî ìîæåò ñîäåðæàòü â ñåáå îáúåêòû ðàçíûõ òèïîâ: mixedSet = { 1 , 3 . 1 4 , ( 1 , 2 , 3 ) , " i have no i d e a why i 'm h e r e " } print ( mixedSet ) Ïî àíàëîãèè ñî ñòðîêàìè, ñïèñêàìè è êîðòåæàìè, êîëè÷åñòâî ýëåìåíòîâ â ìíîæåñòâå ìîæíî óçíàòü ñ ïîìîùüþ ôóíêöèè len. Èç ìíîæåñòâà ìîæíî ñäåëàòü ñïèñîê èëè êîðòåæ ñ ïîìîùüþ ôóíêöèé list è tuple ñîîòâåòñòâåííî. Ïðèìåíåíèå ôóíêöèè str ê ìíîæåñòâó äàñò íàì òåêñòîâîå ïðåäñòàâëåíèå (ýëåìåíòû â ôèãóðíûõ ñêîáêàõ, ðàçäåëåííûå çàïÿòûìè). ×àñòîé îïåðàöèåé ÿâëÿåòñÿ âûâîä óïîðÿäî÷åííûõ ýëåìåíòîâ ìíîæåñòâà. Ýòî ìîæíî ñäåëàòü, ïðèìåíèâ ôóíêöèþ sorted ñðàçó ê ìíîæåñòâó (âåäü îíî èòåðèðóåìî): mySet = { ' abba ' , ' a ' , ' l o n g s t r i n g ' } print ( ' , ' . j o i n ( mySet ) ) print ( ' , ' . j o i n ( sorted ( mySet ) ) ) Âûâîä ýòîé ïðîãðàììû áóäåò: long string, a, abba a, abba, long string Ê ìíîæåñòâó ìîæíî ïðèìåíÿòü ôóíêöèþ map. 7.3 Работа с элементами множеств ×òîáû ñîçäàòü ïóñòîå ìíîæåñòâî íóæíî íàïèñàòü: emptySet = s e t ( ) Ïèñàòü ïóñòûå ôèãóðíûå ñêîáêè íåëüçÿ (âî âòîðîé ÷àñòè ëåêöèè óçíàåòå ïî÷åìó). Äîáàâëåíèå ýëåìåíòà â ìíîæåñòâî îñóùåñòâëÿåòñÿ ñ ïîìîùüþ ìåòîäà add, åñëè ýëåìåíò óæå áûë â ìíîæåñòâå, òî îíî íå èçìåíèòñÿ. Ïåðåáðàòü ýëåìåíòû ìíîæåñòâà ìîæíî ñ ïîìîùüþ for (for óìååò õîäèòü ïî ëþáûì èòåðèðóåìûì îáúåêòàì): mySet = { 1 , ' 2 ' , 2 , ' 1 ' } f o r elem in mySet : print ( elem , end= ' ' ) Âûâîä òàêîé ïðîãðàììû áóäåò 1 1 2 2, íî óïîðÿäî÷åííîñòü ÿâëÿåòñÿ ÷èñòîé ñëó÷àéíîñòüþ. ×òîáû ïðîâåðèòü, âõîäèò ëè ýëåìåíò X â ìíîæåñòâî A äîñòàòî÷íî íàïèñàòü X in A. Ðåçóëüòàòîì ýòîé îïåðàöèè áóäåò True èëè False. ×òîáû ïðîâåðèòü, ÷òî ýëåìåíò íå ëåæèò â ìíîæåñòâå ìîæíî ïèñàòü not X in A, èëè, áîëåå ïî-÷åëîâå÷åñêè X not in A. 62 ЛЕКЦИЯ 7. МНОЖЕСТВА, СЛОВАРИ, ПОЛЕЗНЫЕ МЕТОДЫ ДЛЯ СТРОК mySet = { 1 , 2 , 3} i f 1 in mySet : print ( ' 1 i n s e t ' ) else : print ( ' 1 not i n s e t ' ) x = 42 i f x not in mySet : print ( ' x not i n s e t ' ) else : print ( ' x i n s e t ' ) Âûâîä ýòîé ïðîãðàììû áóäåò: 1 in set x not in set ×òîáû óäàëèòü ýëåìåíò èç ìíîæåñòâà, ìîæíî âîñïîëüçîâàòüñÿ îäíèì èç äâóõ ìåòîäîâ: discard èëè remove. Åñëè óäàëÿåìîãî ýëåìåíòà â ìíîæåñòâå íå áûëî, òî discard íå èçìåíèò ñîñòîÿíèÿ ìíîæåñòâà, à remove âûïàäåò ñ îøèáêîé. 7.4 Групповые операции над множествами  Ïèòîíå ìîæíî ðàáîòàòü íå òîëüêî ñ îòäåëüíûìè ýëåìåíòàìè ìíîæåñòâ, íî è ñ ìíîæåñòâàìè â öåëîì. Íàïðèìåð, äëÿ ìíîæåñòâ îïðåäåëåíû ñëåäóþùèå îïåðàöèè: Îïåðàöèÿ Îïèñàíèå A|B Îáúåäèíåíèå ìíîæåñòâ A&B Ïåðåñå÷åíèå ìíîæåñòâ A-B Ìíîæåñòâî, ãäå ýëåìåíòû âõîäÿò â A, íî íå âõîäÿò â B AB Ýëåìåíòû âõîäÿò â A | B, íå íå âõîäÿò â A & B  ðåçóëüòàòå ýòèõ îïåðàöèé ñîçäàåòñÿ íîâîå ìíîæåñòâî, îäíàêî äëÿ íèõ îïðåäåëåíà è ñîêðàùåííàÿ çàïèñü: | =, &=, -= è =. Òàêèå îïåðàöèè èçìåíÿþò ìíîæåñòâî, íàõîäÿùååñÿ ñëåâà îò çíàêà îïåðàöèè. Äëÿ ìíîæåñòâ òàêæå îïðåäåëåíû îïåðàöèè ñðàâíåíèÿ: Îïåðàöèÿ Îïèñàíèå A == B Âñå ýëåìåíòû ñîâïàäàþò A != B Åñòü ðàçëè÷íûå ýëåìåíòû A <= B Âñå ýëåìåíòû A âõîäÿò â B A >= B Âñå ýëåìåíòû B âõîäÿò â A A>B A >= B è A != B A<B A <= B è A != B Âñå ãðóïïîâûå îïåðàöèè è ñðàâíåíèÿ ïðîâîäÿòñÿ íàä ìíîæåñòâàìè çà âðåìÿ, ïðîïîðöèîíàëüíîå êîëè÷åñòâó ýëåìåíòîâ â ìíîæåñòâàõ. 7.5 Словари  æèçíè íåðåäêî âîçíèêàåò íåîáõîäèìîñòü ñîïîñòàâèòü êëþ÷ó çíà÷åíèå. Íàïðèìåð, â àíãëî-ðóññêîì ñëîâàðå àíãëèéñêîìó ñëîâó ñîïîñòîâëÿåòñÿ îäíî èëè íåñêîëüêî ðóññêèõ ñëîâ. Çäåñü àíãëèéñêîå ñëîâî ÿâëÿåòñÿ êëþ÷àì, à ðóññêîå çíà÷åíèåì. 7.5. СЛОВАРИ 63  ÿçûêå Ïèòîí åñòü ñòðóêòóðà äàííûõ ñëîâàðü, êîòîðàÿ ïîçâîëÿåò ðåàëèçîâûâàòü ïîäîáíûå îïåðàöèè. Ïðè ýòîì îáúåêòû-êëþ÷è óíèêàëüíû è êàæäîìó èç íèõ ñîïîñòàâëåí íåêîòîðûé îáúåêò-çíà÷åíèå. Îãðàíè÷åíèÿ íà êëþ÷è òàêèå æå, êàê íà ýëåìåíòû ìíîæåñòâà, à âîò çíà÷åíèÿ ìîãóò áûòü è èçìåíÿåìûìè. Ïî-ñóòè, ñëîâàðü ÿâëÿåòñÿ ìíîæåñòâîì, ãäå êàæäîìó ýëåìåíòó-êëþ÷ó ñîïîñòàâëåí åùå è îáúåêò-çíà÷åíèå. Ñîçäàòü ñëîâàðü â èñõîäíîì òåêñòå ïðîãðàììû ìîæíî çàïèñàâ â ôèãóðíûõ ñêîáêàõ ïàðû êëþ÷-çíà÷åíèÿ ÷åðåç çàïÿòóþ, à âíóòðè ïàðû êëþ÷ îòäåëÿåòñÿ îò çíà÷åíèÿ äâîåòî÷èåì: c o u n t r i e s = { ' R u s s i a ' : ' Europe ' , ' Germany ' : ' Europe ' , ' A u s t r a l i a ' : ' A u s t r a Äîáàâëÿòü ïàðû êëþ÷ çíà÷åíèå â ñëîâàðü î÷åíü ïðîñòî: ýòî äåëàåòñÿ ïî àíàëîãèè ñî ñïèñêàìè: s q r s = {} sqrs [ 1 ] = 1 sqrs [ 2 ] = 4 s q r s [ 1 0 ] = 100 print ( s q r s ) Ïóñòîé ñëîâàðü ìîæíî ñîçäàòü, íàïèñàâ ïóñòûå ôèãóðíûå ñêîáêè (ýòî áóäåò ñëîâàðü, à íå ìíîæåñòâî). Ñëîâàðü òàêæå ìîæíî êîíñòðóèðîâàòü èç äðóãèõ îáúåêòîâ ñ ïîìîùüþ ôóíêöèè dict: myDict = d i c t ( [ [ ' key1 ' , ' v a l u e 1 ' ] , ( ' key2 ' , ' v a l u e 2 ' ) ] ) print ( myDict ) Íà âõîä ôóíêöèè äîëæåí ïîäàâàòü iterable, êàæäûé ýëåìåíò êîòîðîãî, â ñâîþ î÷åðåäü, ÿâëÿåòñÿ iterable ñòðîãî ñ äâóìÿ ýëåìåíòàìè êëþ÷îì è çíà÷åíèåì. Óçíàâàòü çíà÷åíèå ïî êëþ÷ó ìîæíî òàêæå ñ ïîìîùüþ çàïèñè êëþ÷à ïîñëå èìåíè ñëîâàðÿ â êâàäðàòíûõ ñêîáêàõ: phones = { ' p o l i c e ' : 1 0 2 , ' ambulance ' : 1 0 3 , ' f i r e f i g h t e r s ' : 101} print ( phones [ ' p o l i c e ' ] ) Åñëè òàêîãî êëþ÷à â ñëîâàðå íåò, òî âîçíèêíåò îøèáêà. Óäàëåíèå ýëåìåíòà èç ñëîâàðÿ äåëàåòñÿ ñïåöèàëüíîé êîìàíäîé del. Ýòî íå ôóíêöèÿ, ïîñëå ñëîâà del ñòàâèòñÿ ïðîáåë, çàòåì ïèøåòñÿ èìÿ ñëîâàðÿ, à çàòåì, â êâàäðàòíûõ ñêîáêàõ, óäàëÿåìûé êëþ÷: phones = { ' p o l i c e ' : 1 0 2 , ' ambulance ' : 1 0 3 , ' f i r e f i g h t e r s ' : 101} del phones [ ' p o l i c e ' ] print ( phones ) Ïðîâåðêà ïðèíàäëåæíîñòè êëþ÷à ñëîâàðþ îñóùåñòâëÿåòñÿ ñ ïîìîùüþ îïåðàöèè key in dictionary (òî÷íî òàêæå, êàê ïðîâåðêà ïðèíàäëåæíîñòè ýëåìåíòà ìíîæåñòâó). Ñëîâàðü ÿâëÿåòñÿ iterable è âîçâðàùàåò êëþ÷è â ñëó÷àéíîì ïîðÿäêå. Íàïðèìåð, òàêîé êîä íàïå÷àòàåò ñîäåðæèìîå ñëîâàðÿ: phones = { ' p o l i c e ' : 1 0 2 , ' ambulance ' : 1 0 3 , ' f i r e f i g h t e r s ' : 101} f o r s e r v i c e in phones : print ( s e r v i c e , phones [ s e r v i c e ] ) 64 ЛЕКЦИЯ 7. МНОЖЕСТВА, СЛОВАРИ, ПОЛЕЗНЫЕ МЕТОДЫ ДЛЯ СТРОК Òàêæå ñóùåñòâóåò ìåòîä items, êîòîðûé âîçâðàùàåò iterable, ñîäåðæàùèé â ñåáå êîðòåæè êëþ÷-çíà÷åíèå äëÿ âñåâîçìîæíûõ êëþ÷åé. phones = { ' p o l i c e ' : 1 0 2 , ' ambulance ' : 1 0 3 , ' f i r e f i g h t e r s ' : 101} f o r s e r v i c e , phone in phones . i t e m s ( ) : print ( s e r v i c e , phone ) 7.6 Когда нужно использовать словари 1. Ïî ïðÿìîìó íàçíà÷åíèþ: ñîïîñòàâëåíèå êëþ÷à çíà÷åíèþ (íàçâàíèÿ äíåé íåäåëè, ïåðåâîäû ñëîâ è ò.ä.). 2. Äëÿ ïîäñ÷åòà ÷èñëà îáúåêòîâ. Ïðè î÷åðåäíîé âñòðå÷å îáúåêòà ñ÷åò÷èê óâåëè÷èâàåòñÿ íà åäèíèöó. Ýòî ïîõîæå íà ñîðòèðîâêó ïîäñ÷¼òîì. 3. Äëÿ õðàíåíèÿ ðàçðåæåííûõ ìàññèâîâ. Íàïðèìåð, åñëè ìû õîòèì õðàíèòü öåíó 92, 95 è 98 áåíçèíà, òî ìîãëè áû ñîçäàòü ìàññèâ èç 99 ýëåìåíòîâ è õðàíèòü â í¼ì. Íî áîëüøàÿ ÷àñòü ýëåìåíòîâ íå íóæíû ìàññèâ ðàçðåæåííûé. Ñëîâàðü çäåñü ïîäõîäèò áîëüøå. Äëÿ ïîäñ÷åòà ÷èñëà ýëåìåíòîâ óäîáíî èñïîëüçîâàòü ìåòîä get. Îí ïðèíèìàåò äâà ïàðàìåòðà: êëþ÷ äëÿ êîòîðîãî íóæíî âåðíóòü çíà÷åíèÿ è çíà÷åíèå, êîòîðîå áóäåò âîçâðàùåíî, åñëè òàêîãî êëþ÷à íåò. Íàïðèìåð, ïîäñ÷èòàòü ñêîëüêî ðàç âõîäèò â ïîñëåäîâàòåëüíîñòü êàæäîå èç ÷èñåë ìîæíî ñ ïîìîùüþ òàêîãî êîäà: s e q = map( int , input ( ) . s p l i t ( ) ) c o u n t D i c t = {} f o r elem in s e q : c o u n t D i c t [ elem ] = c o u n t D i c t . g e t ( elem , 0 ) + 1 f o r key in sorted ( c o u n t D i c t ) : print ( key , c o u n t D i c t [ key ] , s e p = ' : ' ) 7.7 Полезные методы строк It's dangerous to go alone! Take this. isalpha ïðîâåðÿåò, ÷òî âñå ñèìâîëû ñòðîêè ÿâëÿþòñÿ áóêâàìè. isdigit ïðîâåðÿåò, ÷òî âñå ñèìâîëû ñòðîêè ÿâëÿþòñÿ öèôðàìè. isalnum ïðîâåðÿåò, ÷òî âñå ñèìâîëû ñòðîêè ÿâëÿþòñÿ áóêâàìè èëè öèôðàìè. islower ïðîâåðÿåò, ÷òî âñå ñèìâîëû ñòðîêè ÿâëÿåþòñÿ ìàëåíüêèìè (ñòðî÷íûìè) áóêâàìè. isupper ïðîâåðÿåò, ÷òî âñå ñèìâîëû ñòðîêè ÿâëÿåþòñÿ áîëüøèìè (çàãëàâíûìè, ïðîïèñíûìè) áóêâàìè. lstrip îáðåçàåò âñå ïðîáåëüíûå ñèìâîëû â íà÷àëå ñòðîêè. rstrip îáðåçàåò âñå ïðîáåëüíûå ñèìâîëû â êîíöå ñòðîêè. strip îáðåçàåò âñå ïðîáåëüíûå ñèìâîëû â íà÷àëå è êîíöå ñòðîêè. 7.8. 7.8 ПРИМЕР РЕШЕНИЯ СЛОЖНОЙ ЗАДАЧИ НА СЛОВАРИ 65 Пример решения сложной задачи на словари Ðàññìîòðèì òàêóþ çàäà÷ó: ñëîâàðü çàäàí â âèäå íàáîðà ñòðîê, â êàæäîé ñòðîêå çàïèñàíî ñëîâî íà àíãëèéñêîì ÿçûêå, çàòåì ñëåäóåò ñèìâîë -, çàòåì, ÷åðåç çàïÿòóþ, ïåðå÷èñëåíû âîçìîæíûå ïåðåâîäû ñëîâà íà ëàòûíü. Òðåáóåòñÿ ñîñòàâèòü ëàòèíî-àíãëèéñêèé ñëîâàðü è âûâåñòè åãî â òîì æå âèäå. Âñå ñëîâà äîëæíû áûòü óïîðÿäî÷åíû ïî àëôàâèòó. Âîçìîæíûå ïåðåâîäû îäíîãî ñëîâà äîëæíû áûòü òàêæå óïîðÿäî÷åíû ïî àëôàâèòó. Íàïðèìåð, äëÿ ââîäà: 3 apple - malum, pomum, popula fruit - baca, bacca, popum punishment - malum, multa Âûâîä äîëæåí âûãëÿäåòü òàê: 7 baca - fruit bacca - fruit malum - apple, punishment multa - punishment pomum - apple popula - apple popum - fruit Èäåÿ ðåøåíèÿ çàêëþ÷àåòñÿ â ñëåäóþùåì: ðàçðåæåì êàæäóþ ñòðîêó íà àíãëèéñêîå è ëàòèíñêèå ñëîâà. Êàæäîå èç ëàòèíñêèõ ñëîâ âîçüìåì â êà÷åñòâå êëþ÷à è äîáàâèì ê åãî çíà÷åíèÿì àíãëèéñêîå ñëîâî (ïåðåâîäîâ ìîæåò áûòü íåñêîëüêî). Çàòåì ïðîéäåì ïî ñîðòèðîâàííûì êëþ÷àì è äëÿ êàæäîãî êëþ÷à âûâåäåì îòñîðòèðîâàííûé ñïèñîê ïåðåâîäîâ: n = i n t ( input ( ) ) l a t i n E n g l i s h = {} f o r i in range ( n ) : l i n e = input ( ) e n g l i s h = l i n e [ : l i n e . f i n d ( '− ' ) ] . s t r i p ( ) l a t i n s S t r = l i n e [ l i n e . f i n d ( '− ' ) + 1 : ] . s t r i p ( ) l a t i n s = map( lambda s : s . s t r i p ( ) , l a t i n s S t r . s p l i t ( ' , ' ) ) f o r l a t i n in l a t i n s : i f l a t i n not in l a t i n E n g l i s h : latinEnglish [ latin ] = [ ] l a t i n E n g l i s h [ l a t i n ] . append ( e n g l i s h ) print ( len ( l a t i n E n g l i s h ) ) f o r l a t i n in sorted ( l a t i n E n g l i s h ) : print ( l a t i n , '− ' , ' , ' . j o i n ( sorted ( l a t i n E n g l i s h [ l a t i n ] ) ) ) 66 ЛЕКЦИЯ 7. МНОЖЕСТВА, СЛОВАРИ, ПОЛЕЗНЫЕ МЕТОДЫ ДЛЯ СТРОК Лекция 8 Элементы функционального программирования 8.1 Парадигмы программирования ßçûêè ïðîãðàììèðîâàíèÿ ïðåäëàãàþò ðàçëè÷íûå ñðåäñòâà äëÿ äåêîìïîçèöèè çàäà÷è. Ñóùåñòâóåò íåñêîëüêî ïàðàäèãì ïðîãðàììèðîâàíèÿ: ∙ Èìïåðàòèâíîå (ñòðóêòóðíîå, ïðîöåäóðíîå) ïðîãðàììèðîâàíèå: ïðîãðàììû ÿâëÿþòñÿ ïîñëåäîâàòåëüíîñòüþ èíñòðóêöèé, êîòîðûå ìîãóò ÷èòàòü è çàïèñûâàòü äàííûå èç ïàìÿòè. Ïðè èçó÷åíèè ïðåäûäóùèõ òåì ìû ïîëüçîâàëèñü, â îñíîâíîì, èìïåðàòèâíîé ïàðàäèãìîé. Ðÿä ÿçûêîâ, òàêèå êàê Ïàñêàëü (íå Object Pascal) èëè C ÿâëÿþòñÿ ÿðêèìè ïðåäòàâèòåëÿìè èìïåðàòèâíûõ ÿçûêîâ. ∙ Äåêëàðàòèâíîå ïðîãðàììèðîâàíèå: îïèñûâàåòñÿ çàäà÷à è îæèäàåìûé ðåçóëüòàò, íî íå îïèñûâàþòñÿ ïóòè å¼ ðåøåíèÿ. ßðêèì ïðåäñòàâèòåëåì ÿâëÿåòñÿ ÿçûê çàïðîñîâ ê áàçàì äàííûõ SQL: áîëüøàÿ ÷àñòü âíóòðåííåãî óñòðîéñòâà ñêðûòà â ÑÓÁÄ, ïðîãðàììèñò îïèñûâàåò òîëüêî ñòðóêòóðó áàçû äàííûõ è îæèäàåìûé ðåçóëüòàò çàïðîñîâ. ∙ Îáúåêòíî-îðèåíòèðîâàííîå ïðîãðàììèðîâàíèå: ïðîãðàììû ìàíèïóëèðóþò íàáîðàìè îáúåêòîâ, ïðè ýòîì îáúåêòû îáëàäàþò ñîõðàíÿþùèìñÿ âî âðåìåíè ñîñòîÿíèåì è ìåòîäàìè äëÿ èçìåíåíèÿ ýòîãî ñîñòîÿíèÿ (èëè ñîçäàíèÿ íîâûõ îáúåêòîâ). Ìû ïîçíàêîìèìñÿ ñ ÎÎÏ ïîäðîáíåå íà îäíîé èç ñëåäóþùèõ ëåêöèé. Ïðèìåðîì ÿçûêà ñ îáúåêòíî-îðèåíòèðîâàííîé ïàðàäèãìîé ÿâëÿåòñÿ Java, ÎÎÏ òàêæå ïîääåðæèâàåòñÿ â Ïèòîíå è C++. ∙ Ôóíêöèîíàëüíîå ïðîãðàììèðîâàíèå: çàäà÷à ðàçáèâàåòñÿ íà íàáîð ôóíêöèé.  èäåàëå, ôóíêöèè òîëüêî ïðèíèìàþò ïàðàìåòðû è âîçâðàùàþò çíà÷åíèÿ, íå èçìåíÿÿ ñîñòîÿíèÿ îáúåêòîâ èëè ïðîãðàììû. Ïðåäñòàâèòåëåì ôóíêöèîíàëüíûõ ÿçûêîâ ÿâëÿåòñÿ Haskell. Èíîãäà, òàêæå, âûäåëÿþò è äðóãèå ïàðàäèãìû ïðîãðàììèðîâàíèÿ. Íåêîòîðûå ÿçûêè ïðåäíàçíà÷åíû, â îñíîâíîì, äëÿ íàïèñàíèÿ ïðîãðàìì â ðàìêàõ îäíîé ïàðàäèãìû, äðóãèå æå ïîääåðæèâàþò íåñêîëüêî ïàðàäèãì. Íàïðèìåð, Ïèòîí è C++ ïîääåðæèâàþò ðàçëè÷íûå ïàðàäèãìû ïðîãðàììèðîâàíèÿ. Ðàçíûå ÷àñòè ïðîãðàììû ìîæíî ïèñàòü â ðàçíûõ ïàðàäèãìàõ, íàïðèìåð, èñïîëüçîâàòü ôóíêöèîíàëüíûé 67 68 ЛЕКЦИЯ 8. ЭЛЕМЕНТЫ ФУНКЦИОНАЛЬНОГО ПРОГРАММИРОВАНИЯ ñòèëü äëÿ îáðàáîòêè áîëüøèõ äàííûõ, îáúåêòíî-îðèåíòèðîâàííûé ïîäõîä äëÿ ðåàëèçàöèè èíòåðôåéñà è èìïåðàòèâíîå ïðîãðàììèðîâàíèå äëÿ ïðîìåæóòî÷íîé ëîãèêè. 8.2 Функциональное программирование Íåñìîòðÿ íà òî, ÷òî â ôóíêöèîíàëüíîì ñòèëå ïèñàòü äîñòàòî÷íî ñëîæíî è íåïðèâû÷íî, ôóíêöèîíàëüíîå ïðîãðàììèðîâàíèå èìååò ìàññó ïëþñîâ: ∙ Äîñòàòî÷íî ëåãêî äîêàçàòü ôîðìàëüíóþ êîððåêòíîñòü àëãîðèòìîâ. Õîòÿ äîêàçàòåëüñòâî, äàæå äëÿ ôóíêöèîíàëüíûõ ïðîãðàìì, ÷àñòî íàìíîãî äëèííåå, ÷åì ñàìà ïðîãðàììà, íî äëÿ ôóíäàìåíòàëüíûõ àëãîðèòìîâ, êîòîðûå øèðîêî èñïîëüçóþòñÿ, ëó÷øå èìåòü ôîðìàëüíîå äîêàçàòåëüñòâî, ÷òîáû íå ïîïàäàòü â ãëóïûå ñèòóàöèè. Ñòðîèòü ôîðìàëüíûå äîêàçàòåëüñòâà èìïåðàòèâíûõ ïðîãðàìì íàìíîãî ñëîæíåå. ∙ Äëÿ ïðîãðàìì, íàïèñàííûõ â ôóíêöèîíàëüíîì ñòèëå, ëåãêî ïðîâîäèòü äåêîìïîçèöèþ, îòëàäêó è òåñòèðîâàíèå. Êîãäà âñÿ ïðîãðàììà ðàçáèòà íà ôóíêöèè, âûïîëíÿþùèå ýëåìåíòàðíûå äåéñòâèÿ, òî èõ ðàçðàáîòêà è ïðîâåðêà çàíèìàåò íàìíîãî ìåíüøå âðåìåíè. ∙ Äëÿ ôóíêöèîíàëüíûõ ïðîãðàìì ëåãêî àâòîìàòè÷åñêè ïðîâîäèòü ðàñïàðàëëåëèâàíèå, âåêòîðèçàöèþ è êîíâåéåðèçàöèþ. Çàäà÷à ðàñïàðàëëåëèâàíèÿ âûïîëíåíèÿ ïðîãðàìì êðàéíå àêòóàëüíà ñåé÷àñ, êîãäà ñêîðîñòè ÿäåð ïðîöåññîðîâ ïðàêòè÷åñêè ïåðåñòàëè ðàñòè. Åäèíñòâåííûì ñïîñîáîì óñêîðèòü âûïîëíåíèå ïðîãðàìì ÿâëÿåòñÿ èõ ïàðàëëåëüíîå âû÷èñëåíèå íà íåñêîëüêèõ óñòðîéñòâàõ. Ïîñëåäíèå óñïåõè â ðåøåíèè çàäà÷ ìàøèííîãî îáó÷åíèÿ ñâÿçàíû ñ èñïîëüçîâàíèåì áîëüøîãî êîëè÷åñòâà ïðîñòûõ âû÷èñëèòåëüíûõ óñòðîéñòâ, íàïðèìåð, ðàññ÷åòîâ íà âèäåîêàðòå.  ôóíêöèîíàëüíûõ ïðîãðàììàõ íå ïðèíÿòî âíîñèòü èçìåíåíèÿ â îáúåêòû (è, âîîáùå ãîâîðÿ, æåëàòåëüíî, ÷òîáû âñå îáúåêòû áûëè íåèçìåíÿìûìè). Ïîýòîìó, åñëè íàì íóæíî ïîñ÷èòàòü ðåçóëüòàò âû÷èñëåíèÿ äâóõ ôóíêöèé, òî âî ìíîãèõ ñëó÷àÿõ ìîæíî äåëàòü ýòî ïàðàëëåëüíî íà ðàçíûõ ÿäðàõ ïðîöåññîðà. Òàêîå ðàñïàðàëëåëèâàíèå ëåãêî ñäåëàòü àâòîìàòè÷åñêè. Âåêòîðèçàöèÿ ýòî êîãäà îäíè è òå æå äåéñòâèÿ âûïîëíÿþòñÿ íàä áîëüøèì íàáîðîì äàííûõ. Òîãäà äàííûå ìîæíî íàðåçàòü íà êóñêè è ðàñêèäàòü ïî ðàçíûì âû÷èñëèòåëüíûì óñòðîéñòâàì, à çàòåì ñîáðàòü ðåçóëüòàò âû÷èñëåíèé â îäèí îáúåêò. Êîíâåéåðèçàöèÿ ýòî ðàçáèåíèå âû÷èñëåíèé íà íåñêîëüêî ýòàïîâ, ïðè÷¼ì äàííûå ïîñòóïàþò íà ñëåäóþùèé ýòàï îáðàáîòêè ïî âðåìåíè ãîòîâíîñòè. Íàïðèìåð, åñëè íàì íóæíî ïîïàðíî ïåðåìíîæèòü çíà÷åíèÿ â âåêòîðàõ A è B, à çàòåì ñëîæèòü ñî çíà÷åíèÿìè â âåêòîðå C, òî ìû ìîæåì ïîñ÷èòàòü íåñêîëüêî ïåðâûõ ðåçóëüòàòîâ ïîäñ÷åòà ïðîèçâåäåíèÿ è óæå âûïîëíÿòü ñ íèìè ñëîæåíèå, íå äîæèäàÿñü ïîäñ÷åòà îñòàëüíûõ çíà÷åíèé. Ýòî ïîçâîëÿåò áûñòðåå ïîëó÷èòü ïåðâûå ðåçóëüòàòû è çàíÿòü åùå áîëüøîå êîëè÷åñòâî âû÷èñëèòåëüíûõ óñòðîéñòâ ïàðàëëåëüíî. 8.3. 8.3 ИТЕРАТОРЫ И ГЕНЕРАТОРЫ 69 Итераторы и генераторы  Ïèòîíå èòåðàòîðû ýòî îáúåêòû, êîòîðûå èìåþò âíóòðåííåå ñîñòîÿíèå è ìåòîä __next__ äëÿ ïåðåõîäà ê ñëåäóþùåìó ñîñòîÿíèþ. Íàïðèìåð, ìîæíî ñêîíñòðóèðîâàòü èòåðàòîð îò ñïèñêà è ïåðåáðàòü âñå çíà÷åíèÿ: myList = [ 1 , 2 , 3 ] f o r i in i t e r ( myList ) : print ( i ) f o r i in myList : print ( i )  ýòîé ïðîãðàììå äâà öèêëà ýêâèâàëåíòíû.  Ïèòîíå ìîæíî ñîçäàâàòü è ñâîè èòåðàòîðû. Èõ ðàçóìíî èñïîëüçîâàòü â òîì ñëó÷àå, åñëè íóæíî ïåðåáðàòü áîëüøîå êîëè÷åñòâî çíà÷åíèé è ñóùåñòâóåò ïðàâèëî, ïî êîòîðîìó ìîæíî ïîëó÷èòü ñëåäóþùåå çíà÷åíèå, îäíàêî õðàíåíèé âñåõ ýòèõ çíà÷åíèé íå èìååò ñìûñëà, ò.ê. îíè ïðèãîäÿòñÿ òîëüêî îäèí ðàç. Äëÿ ñîçäàíèÿ èòåðàòîðîâ â Ïèòîíå èñïîëüçóåòñÿ ñïåöèàëüíûé âèä ôóíêöèé, íàçûâàåìûõ ãåíåðàòîðàìè.  îáû÷íîé ôóíêöèè return ïðåêðàùàåò ðàáîòó ôóíêöèè.  ãåíåðàòîðå âìåñòî return èñïîëüçóåòñÿ îïåðàòîð yield, êîòîðûé òàêæå âîçâðàùàåò çíà÷åíèå, íî íå ïðåêðàùàåò âûïîëíåíèå ôóíêöèè, à ïðèîñòàíàâëèâàåò åãî äî òåõ ïîð, ïîêà íå ïîòðåáóåòñÿ ñëåäóþùåå çíà÷åíèå èòåðàòîðà. Ïðè ýòîì ðàáîòà ôóíêöèè ïðîäîëæèòñÿ ñ òîãî ìåñòà è â òîì ñîñòîÿíèè, â êîòîðîì îíà íàõîäèëàñü íà ìîìåíò âûçîâà yield. Ïîñìîòðèì, êàê ìîæåò áûòü ðåàëèçîâàí ãåíåðàòîð, àíàëîãè÷íûé ñòàíäàðòíîìó range ñ îäíèì ïàðàìåòðîì: def myRange ( n ) : i = 0 while i < n : yield i i += 1 f o r i in myRange ( 1 0 ) : print ( i ) Ãåíåðàòîðû ìîãóò èìåòü è ñëîæíóþ ðåêóðñèâíóþ ñòðóêòóðó. Íàïðèìåð, ìû ìîæåì íàïèñàòü ãåíåðàòîð, êîòîðûé áóäåò âûäàâàòü âñå ÷èñëà çàäàííîé äëèíû, öèôðû â êîòîðûõ íå óáûâàþò è ñòàðøàÿ öèôðà íå ïðåâîñõîäèò çàäàííîãî ïàðàìåòðà: def genDecDigs ( c n t D i g i t s , maxDigit ) : if cntDigits > 0: f o r nowDigit in range ( maxDigit + 1 ) : f o r t a i l in genDecDigs ( c n t D i g i t s − 1 , nowDigit ) : else : y i e l d nowDigit * 10 ** ( c n t D i g i t s − 1 ) + t a i l yield 0 print ( * genDecDigs ( 2 , 3 ) ) Âûâîä ýòîé ïðîãðàììû áóäåò âûãëÿäåòü òàê: 0 10 11 20 21 22 30 31 32 33  ýòîé ïðîãðàììå ðåêóðñèâíûé ãåíåðàòîð ïåðåáèðàë âñå äîïóñòèìûå öèôðû â êà÷åñòâå òîé, êîòîðàÿ äîëæíà ñòîÿòü íà çàäàííîé ïîçèöèè è ãåíåðèðîâàë âñå âîçìîæíûå 70 ЛЕКЦИЯ 8. ЭЛЕМЕНТЫ ФУНКЦИОНАЛЬНОГО ПРОГРАММИРОВАНИЯ ïîñëåäóþùèå öèôðû. Òàêæå â ýòîé ïðîãðàììå ìû èñïîëüçîâàëè îäíó îñîáåííîñòü ôóíêöèè print: åñëè ïåðåäè èìåíåì iterable (à ðåçóëüòàò, âîçâðàùàåìûé ãåíåðàòîðîì ÿâëÿåòñÿ iterable) ïîñòàâèòü *, òî áóäóò íàïå÷àòíû âñå çíà÷åíèÿ ÷åðåç ïðîáåë. Ðåçóëüòàò ðàáîòû ãåíåðàòîðà ìîæíî ñîõðàíèòü, íàïðèìåð, â ñïèñîê ñ ïîìîùüþ ôóíêöèè list, êàê ìû óæå äåëàëè ýòî ñ ðåçóëüòàòîì ðàáîòû range. 8.4 Встроенные функции для работы с последовательностями  ÿçûêå Ïèòîí åñòü ìíîãî ôóíêöèé, êîòîðûå ïðèíèìàþò â êà÷åñòâå ïàðàìåòðà iterable è ìîãóò ñäåëàòü ÷òî-òî ïîëåçíîå. Ñ íåêîòîðûìè èç íèõ, òàêèìè êàê sorted èëè map ìû óæå íåìíîãî çíàêîìû. Ðàññìîòðèì åùå íåêîòîðûå èç íèõ: sum íàõîäèò ñóììó âñåõ ýëåìåíòîâ iterable. min, max íàõîäèò ìèíèìóì è ìàêñèìóì â ïîñëåäîâàòåëüíîñòè iterable. map óìååò ïðèíèìàòü áîëåå äâóõ ïàðàìåòðîâ. Íàïðèìåð, òàêàÿ çàïèñü map(f, iterA, iterB) âåðíåò iterable ñî çíà÷åíèÿìè f(iterA[0], iterB[0]), f(iterA[1], iterB[2]), . . . . lter(predicate, iterable) ïðèìåíÿåò ôóíêöèþ predicate êî âñåì ýëåìåíòàì iterable è âîçâðùàåò iterable, êîòîðûé ñîäåðæèò òîëüêî òå ýëåìåíòû, êîòîðûå óäîâëåòâîðÿëè ïðåäèêàòû (ò.å. ôóíêöèÿ predicate âåðíóëà True). Íàïðèìåð, òàê ìîæåò âûãëÿäåòü ðåøåíèå çàäà÷è î ïîèñêå ìèíèìàëüíîãî ïîëîæèòåëüíîãî ýëåìåíòà â ñïèñêå: print ( min ( f i l t e r ( lambda x : x > 0 , map( int , input ( ) . s p l i t ( ) ) ) ) ) Çäåñü â êà÷åñòâå ïðåäèêàòà èñïîëüçîâàíà ëÿìáäà-ôóíêöèÿ, êîòîðàÿ âîçâðàùàåò True ïðè çíà÷åíèè ïàðàìåòðà áîëüøå 0, à â êà÷åñòâå âõîäíîãî iterable ðåçóëüòàò âûçîâà map äëÿ ôóíêöèè int è íàðåçàííîãî íà ñëîâà ââîäà. Ôóíêöèÿ max ïðèìåíåíà ê òîìó iterable, êîòîðûé áûë âîçâðàùåí ôóíêöèåé lter. enumerate âîçâðàùàåò êîðòåæè èç íîìåðà ýëåìåíòà (ïðè íóìåðàöèè ñ íóëÿ) è íîìåðà î÷åðåäíîãî ýëåìåíòà. Ñ ïîìîùüþ enumerate, íàïðèìåð, óäîáíî ïåðåáèðàòü ýëåìåíòû iterable (äîñòóï ïî èíäåêñó â êîòîðûõ íåâîçìîæåí) è âûâîäèòü íîìåðà ýëåìåíòîâ, êîòîðûå îáëàäàþò íåêîòîðûì ñâîéñòâîì: f = open ( ' data . t x t ' , ' r ' , e n c o d i n g= ' u t f 8 ' ) f o r i , l i n e in enumerate ( f ) : i f l i n e . s t r i p ( ) == ' ' : print ( ' Blank l i n e a t l i n e ' , i ) any, all âîçâðàùàþò èñòèíó, åñëè õîòÿ áû îäèí èëè âñå ýëåìåíòû iterable èñòèííû ñîîòâåòñòâííî. Íàïðèìåð, òàê ìîæíî ïðîâåðèòü, íå ïðåâûøàþò ëè âñå ÷ëåíû ïîñëåäîâàòåëüíîñòè 100 ïî ìîäóëþ: print ( a l l (map( lambda x : abs ( i n t ( x ) ) <= 1 0 0 , input ( ) . s p l i t ( ) ) ) ) zip(iterA, iterB, . . . ) êîíñòðóèðóåò êîðòåæè èç ýëåìåíòîâ (iterA[0], iterB[0], . . . ), (iterA[1], iterB[1], . . . ), . . . Ñ ïîìîùüþ ýòèõ ôóíêöèÿ ìîæíî ðåøèòü äîñòàòî÷íî ñëîæíûå çàäà÷è, áåç èñïîëüçîâàíèÿ öèêëîâ è óñëîâíûõ îïåðàòîðîâ. Íàïðèìåð, çàäà÷ó èç äîìàøíåãî çàäàíèÿ ïî ñîðòèðîâêàì ïðî òàêñè: â ïåðâîé ñòðîêå çàäàíî êîëè÷åñòâî ëþäåé è àâòîìîáèëåé òàêñè, 8.5. ГЕНЕРАЦИЯ КОМБИНАТОРНЫХ ОБЪЕКТОВ ITERTOOLS 71 â ñëåäóþùèõ äâóõ ñòðîêàõ ðàññòîÿíèå â êèëîìåòðàõ äëÿ êàæäîãî ÷åëîâåêà è öåíà çà êèëîìåòð äëÿ êàæäîãî òàêñè. Íåîáõîäèìî ñîïîñòàâèòü êàæäîìó ÷åëîâåêó íîìåð òàêñè, ÷òîáû ñóììàðíàÿ öåíà ïîåçäîê áûëà ìèíèìàëüíà. Èäåÿ ðåøåíèÿ çàêëþ÷àåòñÿ â òîì, ÷òîáû ëþäè, êîòîðûì åõàòü äàëüøå åõàëè íà áîëåå äåøåâûõ òàêñè: n = i n t ( input ( ) ) p e o p l e L i s t = map( int , input ( ) . s p l i t ( ) ) p e o p l e s = sorted ( l i s t ( enumerate ( p e o p l e L i s t ) , key=lambda x : x [ 1 ] ) ) t a x i L i s t = map( int , input ( ) . s p l i t ( ) ) t a x i s = sorted ( l i s t ( enumerate ( t a x i L i s t ) ) , key=lambda x : x [ 1 ] , r e v e r s e=True ) ans = sorted ( zip ( p e o p l e s , t a x i s ) , key=lambda x : x [ 0 ] [ 0 ] ) print ( *map( lambda x : x [ 1 ] [ 0 ] + 1 , ans ) ) 8.5 Генерация комбинаторных объектов itertools  Ïèòîíå åñòü áèáëèîòåêà itertools, êîòîðàÿ ñîäåðæèò ìíîãî ôóíêöèé äëÿ ðàáîòû ñ èòåðàòîðûìè. Ñ ýòèìè ôóíêöèÿìè ìîæíî îçíàêîìèòüñÿ â îôèöèàëüíîé äîêóìåíòàöèè ê ÿçûêó. Íàì íàèáîëåå èíòåðåñíû ôóíêöèè, ãåíåðèðóþùèå êîìáèíàòîðíûå îáúåêòû. itertools.combinations(iterable, size) ãåíåðèðóåò âñå ïîäìíîæåñòâà ìíîæåñòâà iterable ðàçìåðîì size â âèäå êîðòåæåé. Ýòî ìîæåò áûòü èñïîëüçîâàíî âìåñòî âëîæåííûõ öèêëîâ ïðè îðãàíèçàöèè ïåðåáîðà. Íàïðèìåð, ìû ìîæåì íåýôôåêòèâíî ðåøèòü çàäà÷ó î ïîèñêå òðåõ ÷èñåë â ïîñëåäîâàòåëüíîñòè, äàþùèõ íàèáîëüøåå ïðîèçâåäåíèå: from i t e r t o o l s import c o m b i n a t i o n s nums = l i s t (map( int , input ( ) . s p l i t ( ) ) ) combs = c o m b i n a t i o n s ( range ( len ( nums ) ) , 3 ) print (max(map( lambda x : nums [ x [ 0 ] ] * nums [ x [ 1 ] ] * nums [ x [ 2 ] ] , combs ) ) ) itertools.permutations(iterable) ãåíåðèðóåò âñå ïåðåñòàíîâêè iterable. Ñóùåñòâóåò âàðèàíò ôóíêöèè ñ äâóìÿ ïàðàìåòðàìè, âòîðîé ïàðàìåòð ÿâëÿåòñÿ ðàçìåðîì ïîäìíîæåñòâà. Òîãäà ãåíåðèðóþòñÿ âñå ïåðåñòàíîâêè âñåõ ïîäìíîæåñòâ çàäàííîãî ðàçìåðà. itertools.combinations_with_replacement(iterable, size) ãåíåðèðóåò âñå ïîäìíîæåñòâà iterable ðàçìåðîì size ñ ïîâòîðåíèÿìè, ò.å. îäíî è òî æå ÷èñëî ìîæíî âõîäèòü â ïîäìíîæåñòâî íåñêîëüêî ðàç. 8.6 partial, reduce, accumulate Ìîäóëü functools ñîäåðæèò íåêîòîðûå ôóíêöèè, êîòîðûå ìîãóò ïîëåçíû äëÿ îáðàáîòêè ïîñëåäîâàòåëüíîñòåé è íå òîëüêî. Ôóíêöèÿ functools.partial ïðåäíàçíà÷åíà äëÿ îáåðà÷èâàíèÿ ñóùåñòâóþùèõ ôóíêöèé ñ ïîäñòàíîâêîé íåêîòîðûõ ïàðàìåòðîâ. Íàïðèìåð, ìû ìîæåì ñîçäàòü ôóíêöèþ äëÿ ïå÷àòè â ôàéë, ÷òîáû êàæäûé ðàç íå óêàçûâàòü êàêèå-òî ïàðàìåòðû. Íàïðèìåð, ñóùåñòâóåò âàðèàíò ôóíêöèè int ñ äâóìÿ ïàðàìåòðàìè: ïåðâûé ýòî ïåðåìåííàÿ, êîòîðóþ íåîáõîäèìî ïðåîáðàçîâàòü â ÷èñëî, à âòîðîé ñèñòåìà ñ÷èñëåíèÿ â êîòîðîé çàïèñàíî ÷èñëî. Ñ ïîìîùüþ partial ìû ìîæåì ñîçäàòü ôóíêöèþ-îá¼ðòêó, ïðåîáðàçóþùóþ ñòðîêè èç 0 è 1 â ÷èñëà: 72 ЛЕКЦИЯ 8. ЭЛЕМЕНТЫ ФУНКЦИОНАЛЬНОГО ПРОГРАММИРОВАНИЯ from f u n c t o o l s import p a r t i a l b i n S t r T o I n t = p a r t i a l ( int , b a s e =2) print ( b i n S t r T o I n t ( ' 10010 ' ) )  ìîäóëå functools òàêæå ñîäåðæàòñÿ ôóíêöèè äëÿ îáðàáîòêè ïîñëåäîâàòåëüíîñòåé. functools.reduce(func, iterable) ïîçâîëÿåò ïðèìåíèòü ôóíêöèþ êî âñåì ýëåìåíòàì ïîñëåäîâàòåëüíîñòè, èñïîëüçóÿ â êà÷åñòâå ïåðâîãî àðãóìåíòà íàêîïëåííûé ðåçóëüòàò. Íàïðèìåð, åñëè â ïîñëåäîâàòåëüíîñòè áûëè ýëåìåíòû myList = [A, B, C], òî ðåçóëüòàòîì ïðèìåíåíèÿ reduce(f, myList) áóäåò f(f(A, B), C). Ñ ïîìîùüþ reduce, íàïðèìåð, ìîæíî íàéòè ÍÎÄ âñåõ ÷èñåë â iterable: from f u n c t o o l s import reduce def gcd ( a , b ) : while b != 0 : a, b = b, a % b return a print ( reduce ( gcd , map( int , input ( ) . s p l i t ( ) ) ) ) itertools.accumulate(func, iterable), êîòîðàÿ âîçâðàùàåò iterable ñî âñåìè ïðîìåæóòî÷íûìè çíà÷åíèÿìè, ò.å. äëÿ ñïèñêà [A, B, C] accumulate âåðíåò çíà÷åíèÿ A, f(A, B), f(f(A, B), C). Íàïðèìåð, ìîæíî óçíàòü ìàêñèìàëüíûé ýëåìåíò äëÿ êàæäîãî ïðåôèêñà (íåêîòîðîãî êîëè÷åñòâà ïåðâûõ ýëåìåíòîâ) çàäàííîé ïîñëåäîâàòåëüíîñòè: from i t e r t o o l s import accumulate print ( * accumulate (map( int , input ( ) . s p l i t ( ) ) , max ) ) Лекция 9 Объектно-ориентированное программирование 9.1 Объектно-ориентированное программирование Îáúåêòíî-îðèåíòèðîâàííîå ïðîãðàììèðîâàíèå (ÎÎÏ) ÿâëÿåòñÿ îäíîé èç ïàðàäèãì ïðîãðàììèðîâàíèÿ, ñîçäàííîé íà áàçå èìïåðàòèâíîãî ïðîãðàììèðîâàíèÿ äëÿ áîëåå óäîáíîãî ïîâòîðíîãî èñïîëüçîâàíèÿ êîäà è îáëåã÷åíèÿ ÷èòàåìîñòè ïðîãðàìì. ÎÎÏ íå ÿâëÿåòñÿ ¾ñåðåáðÿíîé ïóëåé¿, êîòîðàÿ ðåøàåò âñå çàäà÷è íàèáîëåå óäîáíûì îáðàçîì. Èìïåðàòèâíîå ïðîãðàììèðîâàíèå óäîáíî äëÿ ðåøåíèÿ ïðîñòûõ çàäà÷, èñïîëüçóþùèõ ñòàíäàðòíûå îáúåêòû. Ïîâòîðíîå èñïîëüçîâàíèå êîäà â èìïåðàòèâíîé ïàðàäèãìå îáåñïå÷èâàåòñÿ ñ ïîìîùüþ öèêëîâ è ôóíêöèé, íàïèñàííûõ â èìïåðàòèâíîì ñòèëå. Ôóíêöèîíàëüíîå ïðîãðàììèðîâàíèå óäîáíî äëÿ çàäà÷, ãäå ñóùåñòâóåò ÿðêî âûðàæåííûé ïîòîê äàííûõ (data ow), êîòîðûé ¾ïåðåòåêàåò¿ èç îäíîé ôóíêöèè â äðóãóþ, èçìåíÿÿñü ïî ïóòè. ÎÎÏ æå ïîçâîëÿåò îáåñïå÷èòü ïîâòîðíîå èñïîëüçîâàíèå êîäà çà ñ÷åò òîãî, ÷òî îáðàáàòûâàåìûå ïðîãðàììîé îáúåêòû èìåþò ìíîãî îáùåãî è ëèøü íåçíà÷èòåëüíûå îòëè÷èÿ â ñâîåì ïîâåäåíèè. ÎÎÏ îñíîâàíî íà òð¼õ êîíöåïöèÿõ: èíêàïñóëÿöèÿ, íàñëåäîâàíèå, ïîëèìîðôèçì. Èíêàïñóëÿöèÿ ýòî ïîìåùåíèå â ¾êàïñóëó¿: ëîãè÷åñêîå îáúåäèíåíèå äàííûõ è ôóíêöèé äëÿ ðàáîòû ñ íèìè, à òàêæå ñîêðûòèå âíóòðåííåãî óñòðîéñòâà îáúåêòà ñ ïðåäîñòàâëåíèåì èíòåðôåéñà âçàèìîäåéñòâèÿ ñ íèì (ïóáëè÷íûå ìåòîäû). Íàñëåäîâàíèå ýòî ïîëó÷åíèå íîâîãî òèïà îáúåêòîâ íà îñíîâå óæå ñóùåñòâóþùåãî ñ ÷àñòè÷íî èëè ïîëíîñòüþ çàèìñòâîâàííûé ó ðîäèòåëüñêîãî òèïà ôóíêöèîíàëüíîñòüþ. Ïîëèìîðôèçì ýòî ïðåäîñòàâëåíèå îäèíàêîâûõ ñðåäñòâ âçàèìîäåéñòâèÿ ñ îáúåêòàìè ðàçíîé ïðèðîäû. Íàïðèìåð, îïåðàöèÿ + ìîæåò ðàáîòàòü êàê ñ ÷èñëàìè, òàê è ñî ñòðîêàìè, íåñìîòðÿ íà ðàçíóþ ïðèðîäó ýòèõ îáúåêòîâ. Êëàññîì â Ïèòîíå íàçûâàåòñÿ îïèñàíèå ñòðóêòóðû îáúåêòà (ïîëåé ñòðóêòóðû) è ìåòîäîâ (ôóíêöèé) äëÿ ðàáîòû ñ äàííûìè â ýòîé ñòðóêòóðå. Îáúåêòîì íàçûâàåòñÿ ýêçåìïëÿð êëàññà, ãäå ïîëÿ çàïîëíåíû êîíêðåòíûìè çíà÷åíèÿìè. Îáúåêòû íàõîäÿòñÿ â ïàìÿòè ïðîãðàììû è ìîãóò èçìåíÿòü ñâî¼ ñîñòîÿíèå èëè âûïîëíÿòü êàêèå-òî äåéñòâèÿ ñ ïîìîùüþ âûçîâà ìåòîäîâ êëàññà äëÿ ýòîãî îáúåêòà. 73 74 ЛЕКЦИЯ 9. 9.2 Инкапсуляция и конструкторы ОБЪЕКТНО-ОРИЕНТИРОВАННОЕ ПРОГРАММИРОВАНИЕ Ìû óæå èñïîëüçîâàëè êëþ÷åâîå ñëîâî class äëÿ ñîçäàíèÿ ñòðóêòóð íàáîðà èìåíîâàííûõ ïîëåé, ñîâîêóïíîñòü êîòîðûõ îïèñûâàåò îáúåêò. Îäíàêî, ìû ïîëüçîâàëèñü äëÿ èõ îáðàáîòêè îòäåëüíî ëåæàùèìè ôóíêöèÿìè èëè êóñêàìè êîäà. Áûëî áû íàìíîãî óäîáíåå, åñëè áû îïèñàíèå ñòðóêòóðû îáúåêòà è ìåòîäîâ ðàáîòû ñ íèì ëåæàëî ðÿäîì, äëÿ óäîáñòâà èçó÷åíèÿ, ìîäèôèêàöèè è èñïîëüçîâàíèÿ. Ìû áóäåì ðàññìàòðèâàòü ýëåìåíòû ÎÎÏ íà ïðèìåðå êîìïëåêñíûõ (óäàðåíèå íà ¾å¿) ÷èñåë. Ýòî çàáàâíûé ìàòåìàòè÷åñêèé îáúåêò, êîòîðûé ñîñòîèò èç äåéñòâèòåëüíîé (real) √ è ìíèìîé (imaginary) ÷àñòè. Çàïèñü ýòî ÷èñëà âûãëÿäèò êàê 𝑟𝑒 + 𝑖𝑚 × 𝑖, ãäå 𝑖 ýòî −1. Ãëóáîêîå ìàòåìàòè÷åñêîå ïîíèìàíèå êîìïëåêñíûõ ÷èñåë íàì íå ïîíàäîáèòñÿ: äîñòàòî÷íî ïîíèìàòü, ÷òî ýòî ñòðóêòóðà ñ äâóìÿ ïîëÿìè re è im, ãäå îáà ýòè ïîëÿ âåùåñòâåííûå ÷èñëà. Äëÿ ñîçäàíèÿ íîâûõ îáúåêòîâ êëàññà èñïîëüçóåòñÿ ñïåöèàëüíûé ìåòîä, êîòîðûé íàçûâàåòñÿ ¾êîíñòðóêòîð¿. Ìåòîäû êëàññà çàïèñûâàþòñÿ âíóòðè îïèñàíèÿ êëàññà êàê ôóíêöèè, êîíñòðóêòîð äîëæåí íàçûâàòüñÿ __init__.  êà÷åñòâå ïåðâîãî ïàðàìåòðà îíè äîëæíû ïðèíèìàòü ïåðåìåííóþ self êîíêðåòíûé îáúåêò êëàññà, ñ êîòîðûì îíè ðàáîòàþò. Ðàññìîòðèì êëàññ äëÿ âåùåñòâåííîãî ÷èñëà, âûçîâ êîíñòðóêòîðà è ïå÷àòü ïîëåé îáúåêòà: c l a s s Complex : def __init__ ( s e l f , r e =0, im =0): s e l f . re = re s e l f . im = im a = Complex ( 1 , 2 ) b = Complex ( 3 ) c = Complex ( ) print ( a . re , a . im ) print ( b . re , b . im ) print ( c . re , c . im ) Çäåñü êîíñòðóêòîð ñîäåðæèò òðè ïàðàìåòðà: self ïóñòîé îáúåêò êëàññà Complex, re è im ïî óìîë÷àíèþ ðàâíûå íóëþ. Âûçîâ êîíñòðóêòîðà îñóùåñòâëÿåòñÿ ñ ïîìîùüþ íàïèñàíèÿ íàçâàíèÿ êëàññà, â ñêîáêàõ óêàçûâàþòñÿ ïàðàìåòðû êîíñòðóêòîðà (âñå, êðîìå self). Íàçâàíèÿ êëàññîâ ïðèíÿòî çàïèñûâàòü ñ áîëüøîé áóêâû, à îáúåêòû ñ ìàëåíüêîé. Âûâîä ýòîé ïðîãðàììû áóäåò: 12 30 00 Îáðàòèòå âíèìàíèå, ÷òî ìû ìåíÿåì ïåðåìåííûå êîíêðåòíîãî îáúåêòà êëàññà, êîòîðûé ïåðåäàí â êà÷åñòâå ïàðàìåòðà self. Åñëè ìû ñîçäàëè êàêèå-òî ïåðåìåííûå â îïèñàíèè êëàññà, òî èõ çíà÷åíèÿ áûëè áû äîñòóïíû âî âñåõ îáúåêòàõ ýòîãî êëàññà è èõ ìîæíî áûëî áû äàæå èçìåíèòü, ïåðå÷èñëèâ èõ èìåíà â íà÷àëå ìåòîäà ïîñëå âûðàæåíèÿ nonlocal. Òàêèå ïåðåìåííûå íàçûâàþòñÿ ñòàòè÷åñêèìè, îáû÷íî îíè ïðåäíàçíà÷åíû äëÿ õðàíåíèÿ êàêèõ-òî êîíñòàíò (÷òî î÷åíü óäîáíî åñëè âû, íàïðèìåð, îïèñûâàåòå êàêîé-òî êëàññ äëÿ ôèçè÷åñêèõ âû÷èñëåíèé). Èõ èçìåíåíèå ìîæåò ïîíàäîáèòñÿ â ýêçîòè÷åñêèõ 9.3. ОПРЕДЕЛЕНИЕ МЕТОДОВ И СТАНДАРТНЫЕ ФУНКЦИИ 75 ñèòóàöèÿõ, íàïðèìåð, ïðè ïîäñ÷åòå êîëè÷åñòâà îáúåêòîâ êëàññà. Ìû íå áóäåì çàîñòðÿòü íà íèõ âíèìàíèå. 9.3 Определение методов и стандартные функции Íåêîòîðûå ñòàíäàðòíûå ôóíêöèè ÿçûêà Ïèòîí ÿâëÿþòñÿ âñåãî-ëèøü îáåðòêàìè íàä âûçîâîì ìåòîäà äëÿ ïåðåäàâàåìîãî ïàðàìåòðà. Íàïðèìåð, ôóíêöèÿ str âûçûâàåò ìåòîä __str__ äëÿ ñâîåãî ïàðàìåòðà. Åñëè ìû îïèøåì òàêîé ìåòîä äëÿ íàøåãî êëàññà, òî ìîæíî áóäåò ïðèìåíÿòü ê íåìó ôóíêöèþ str ÿâíî è íåÿâíî (íàïðèìåð, îíà àâòîìàòè÷åñêè âûçîâåòñÿ ïðè âûçîâå print äëÿ îáúåêòà íàøåãî êëàññà). Ìû áû õîòåëè, ÷òîáû __str__ âîçâðàùàë òåêñòîâîå ïðåäñòàâëåíèå íàøåãî êîìïëåêñíîãî ÷èñëà. Íàïðèìåð, ÷èñëî ñ äåéñòâèòåëüíîé ÷àñòüþ 1 è ìíèìîé 2 äîëæíî áûòü ïðåäñòàâëåíî â âèäå ñòðîêè 1+2i, à ÷èñëî ñ äåéñòâèòåëüíîé ÷àñòüþ 3 è ìíèìîé -4.5 êàê 3-4.5i. Ïîëíîå îïèñàíèå êëàññà ñ äîáàâëåííûì ìåòîäîì áóäåò âûãëÿäåòü òàê: c l a s s Complex : def __init__ ( s e l f , r e =0, im =0): s e l f . re = re s e l f . im = im def __str__( s e l f ) : strRep = s t r ( s e l f . r e ) i f s e l f . im >= 0 : strRep += '+ ' strRep += s t r ( s e l f . im ) + ' i ' return strRep a = Complex ( 1 , 2 ) print ( a ) b = Complex ( 3 , − 4.5) print ( b ) 9.4 Переопределение операторов  ÿçûêå Ïèòîí ìîæíî ïåðåîïðåäåëèòü è ïîâåäåíèå îïåðàòîðîâ. Íàïðèìåð, åñëè ó íàñ åñòü äâà ÷èñëà x è y, òî çàïèñü x + y ðåàëüíî ïðåîáðàçóåòñÿ â âûçîâ ìåòîäà x.__add__(y). Çíà÷îê îïåðàöèè + ÿâëÿåòñÿ âñåãî ëèøü óäîáíûì äëÿ ÷åëîâåêà ïåðåîïðåäåëåíèåì âûçîâà ìåòîäà add. Äëÿ âåùåñòâåííûõ ÷èñåë ëîãè÷íî îïðåäåëåíà îïåðàöèÿ ñëîæåíèÿ: ýòî ñëîæåíèå îòäåëüíî äåéñòâèòåëüíûõ è îòäåëüíî ìíèìûõ ÷àñòåé.  ðåçóëüòàòå âûçîâà ìåòîäà äëÿ ñëîæåíèÿ äâóõ ÷èñåë äîëæåí êîíñòðóèðîâàòüñÿ íîâûé îáúåêò êëàññà Complex, à ïåðåäàííûå â êà÷åñòâå ïàðàìåòðîâ îáúåêòû íå äîëæíû èçìåíÿòüñÿ. Äåéñòâèòåëüíî, êîãäà ìû âûïîëíÿåì îïåðàöèÿ z = x + y äëÿ îáû÷íûõ ÷èñåë, òî îæèäàåì, ÷òî ñêîíñòðóèðóåòñÿ íîâûé îáúåêò, ê êîòîðîìó ïðèâÿæåòñÿ ññûëêà z, à x è y îñòàíóòñÿ áåç èçìåíåíèÿ. Áóäåì ïðèäåðæèâàòüñÿ ýòîé æå ëîãèêè ïðè ðåàëèçàöèè ìåòîäà äëÿ ñëîæåíèÿ äâóõ êîìïëåêñíûõ ÷èñåë. Íàø ìåòîä _add äîëæåí ïðèíèìàòü äâà ïàðàìåòðà, êàæäûé èç êîòîðûõ ÿâëÿåòñÿ êîìïëåêñíûì ÷èñëîì. 76 ЛЕКЦИЯ 9. ОБЪЕКТНО-ОРИЕНТИРОВАННОЕ ПРОГРАММИРОВАНИЕ c l a s s Complex : def __init__ ( s e l f , r e =0, im =0): s e l f . re = re s e l f . im = im def __str__( s e l f ) : strRep = s t r ( s e l f . r e ) i f s e l f . im >= 0 : strRep += '+ ' strRep += s t r ( s e l f . im ) + ' i ' return strRep def __add__( s e l f , o t h e r ) : newRe = s e l f . r e + o t h e r . r e newIm = s e l f . im + o t h e r . im return Complex ( newRe , newIm ) a = Complex ( 1 , 2 ) b = Complex ( 3 , − 4.5) print ( a + b ) Ïåðåîïðåäåëÿòü ìåòîä add èìååò ñìûñë òîëüêî â òåõ ñèòóàöèÿõ, êîãäà ïðîãðàììèñòó, èñïîëüçóþùåìó âàø êëàññ, áóäåò î÷åâèäåí ñìûñë îïåðàöèè +. Íàïðèìåð, åñëè áû âû ñîçäàëè êëàññ äëÿ îïèñàíèå íåêîòîðûõ õàðàêòåðèñòèê ÷åëîâåêà, òî îïåðàöèÿ + äëÿ äâóõ îáúåêòîâ-ëþäåé âîñïðèíèìàëàñü ðàçíûìè ïîëüçîâàòåëÿìè âàøåãî êëàññà ñîâåðøåííî ïî-ðàçíîìó, â çàâèñèìîñòè îò ðàçâèòîñòè ôàíòàçèè ÷èòàòåëÿ. Òàêîãî íåîäíîçíà÷íîãî ïîíèìàíèÿ ëó÷øå èçáåãàòü è âîâñå íå ïåðåîïðåäåëÿòü îïåðàöèþ +, åñëè ðåçóëüòàò å¼ ðàáîòû íå î÷åâèäåí. 9.5 Проверка класса объекта Ïåðåîïðåäåëèì äëÿ êîìïëåêñíûõ ÷èñåë åù¼ îäíó îïåðàöèþ óìíîæåíèå. Ïðè ýòîì ìû õîòèì óìåòü óìíîæàòü êîìïëåêñíûå ÷èñëà êàê íà öåëûå èëè äåéñòâèòåëüíûå, òàê è íà äðóãèå êîìïëåêñíûå ÷èñëà. Ïðè óìíîæåíèè êîìïëåêñíîãî ÷èñëà âèäà 𝑎 + 𝑏 × 𝑖 íà öåëîå èëè âåùåñòâåííîå ÷èñëî 𝑥 ðåçóëüòàòîì áóäåò êîìïëåêñíîå ÷èñëî 𝑎 × 𝑥 + 𝑏 × 𝑥 × 𝑏. Ïåðåìåíîæåíèå äâóõ êîìïëåêñíûõ ÷èñåë ïðîèçâîäèòñÿ àíàëîãè÷íî óìíîæåíèþ äâóõ ìíîãî÷ëåíîâ ïåðâîé ñòåïåíè: (𝑎 + 𝑏 × 𝑖) × (𝑐 + 𝑑 × 𝑖) = 𝑎 × 𝑐 + (𝑎 × 𝑑 + 𝑏 × 𝑐) × 𝑖 + 𝑏 × 𝑑 × 𝑖2 Ìû çíàåì, ÷òî 𝑖2 = −1. Çíà÷èò îêîí÷àòåëüíî ðåçóëüòàò óìíîæåíèÿ áóäåò âûãëÿäåòü òàê: 𝑎 × 𝑐 − 𝑏 × 𝑑 + (𝑎 × 𝑑 + 𝑏 × 𝑐) × 𝑖 Íàì îñòàëîñü ïîíÿòü, êàê îïðåäåëèòü, ïåðåäàíî ëè â íàø ìåòîä êîìïëåêñíîå èëè íå êîìïëåêñíîå ÷èñëî.  ÿçûêå Ïèòîí ñóùåñòâóåò ôóíêöèÿ isinstance, êîòîðàÿ â êà÷åñòâå ïåðâîãî ïàðàìåòðà ïðèíèìàåò îáúåêò, à â êà÷åñòâå âòîðîãî íàçâàíèå êëàññà. Îíà âîçâðàùàåò èñòèíó, 9.5. ПРОВЕРКА КЛАССА ОБЪЕКТА 77 åñëè îáúåêò îòíîñèòñÿ ê äàííîìó êëàññó è ëîæü â ïðîòèâíîì ñëó÷àå. Ýòà ôóíêöèÿ ïîçâîëèò íàì äîáèòüñÿ íóæíîé ôóíêöèîíàëüíîñòè îò ìåòîäà __mul__, óìíîæàþùåãî ÷èñëà. c l a s s Complex : def __init__ ( s e l f , r e =0, im =0): s e l f . re = re s e l f . im = im def __str__( s e l f ) : strRep = s t r ( s e l f . r e ) i f s e l f . im >= 0 : strRep += '+ ' strRep += s t r ( s e l f . im ) + ' i ' return strRep def __add__( s e l f , o t h e r ) : newRe = s e l f . r e + o t h e r . r e newIm = s e l f . im + o t h e r . im return Complex ( newRe , newIm ) def __mul__( s e l f , o t h e r ) : i f i s i n s t a n c e ( o t h e r , Complex ) : newRe = s e l f . r e * o t h e r . r e − s e l f . im * o t h e r . im newIm = s e l f . r e * o t h e r . im + s e l f . r e * o t h e r . im e l i f i s i n s t a n c e ( o t h e r , i n t ) or i s i n s t a n c e ( o t h e r , f l o a t ) : newRe = s e l f . r e * o t h e r newIm = s e l f . im * o t h e r return Complex ( newRe , newIm ) __rmul__ = __mul__ a = Complex ( 1 , 2 ) b = Complex ( 3 , − 4.5) print ( a * b ) print ( a * 2 ) Êðîìå äîáàâëåííîãî ìåòîäà __mul__ âíèìàíèÿ òàêæå çàñëóæèâàåò ñòðîêà __rmul__ = __mul__. Ýòî ïðèñâàèâàíèå îäíîãî ìåòîäà (ôóíêöèè) äðóãîìó, ò.å. ïðè âûçîâå ìåòîäà __rmul__ áóäåò âûçûâàòüñÿ òîò æå ñàìûé ìåòîä __mul__.  ÿçûêå ïèòîí îïåðàöèÿ a * b çàìåíÿåòñÿ íà âûçîâ ìåòîäà a.__mul__(b). Åñëè a áûëî êîìïëåêñíûì ÷èñëîì, à b âåùåñòâåííûì, òî âûçîâåòñÿ ìåòîä __mul__ äëÿ îáúåêòà a íàøåãî êëàññà Complex. Îäíàêî, åñëè a áûëî âåùåñòâåííûì ÷èñëîì, à b êîìëåêñíûì, òî ïðîèçîéäåò ïîïûòêà âûçâàòü ìåòîä __mul__ äëÿ îáúåêòà êëàññà oat. Åñòåñòâåííî, ðàçðàáîò÷èêè ñòàíäàðòíîé áèáëèîòåêè ÿçûêà Ïèòîí íå ìîãëè ïðåäïîëîæèòü, ÷òî âû êîãäà-íèáóäü íàïèøèòå êëàññ Complex è áóäåòå ïûòàòüñÿ óìíîæèòü íà íåãî âåùåñòâåííîå ÷èñëî, ïîýòîìó ìåòîä __mul__, ãäå â êà÷åñòâå ïàðàìåòðà ïåðåäàåòñÿ íå÷òî íåèçâåñòíîå, áóäåò çàêàí÷èâàòü ñâîþ ðàáîòó ñ îøèáêîé. ×òîáû èçáåæàòü òàêèõ ñèòóàöèé â ÿçûêå Ïèòîí ïîñëå íåóäà÷íîé ïîïûòêè ñîâåðøèòü a.__mul__(b) ïðîñõîäèò ïîïûòêà ñîâåðøèòü äåéñòâèå b.__rmul__(a) è â íàøåì ñëó÷àå îíà çàêàí÷èâàåòñÿ óñïåõîì. 78 ЛЕКЦИЯ 9. 9.6 Обработка ошибок ОБЪЕКТНО-ОРИЕНТИРОВАННОЕ ПРОГРАММИРОВАНИЕ Âðåìÿ îò âðåìåíè â ïðîãðàììàõ âîçíèêàþò îøèáî÷íûå ñèòóàöèè, êîòîðûå íå ìîãóò áûòü îáðàáîòàíû â òîì ìåñòå, ãäå âîçíèêëà îøèáêà, à äîëæíû áûòü îáðàáîòàíû òåì èëè èíûì îáðàçîì â áîëåå âíåøíåé ÷àñòè ïðîãðàììû. Íàïðèìåð, åñëè íà ýòàïå âûïîëíåíèÿ ïðîìåæóòî÷íîé ëîãèêè îáíàðóæèëîñü, ÷òî âû ïûòàåòåñü çàïèñàòü ñòðîêó â òî, ÷òî äîëæíî áûòü ÷èñëîì, òî âû íè÷åãî íå ìîæåòå ñ ýòèì ñäåëàòü.  òàêîì ñëó÷àå íóæíî âûâàëèâàòüñÿ èç ñòåêà âûçîâîâ ôóíêöèé èëè ìåòîäîâ ïðîìåæóòî÷íîé ëîãèêè äî òåõ ïîð, ïîêà ìû íå äîéäåì äî ôðîíòåíäà, êîòîðûé ñîîáùèò ïîëüçîâàòåëþ î òîì, ÷òî îí ââåë íåäîïóñòèìîå çíà÷åíèå è ïîïðîñèò, íàïðèìåð, ââåñòè åãî çàíîâî. Íàâåðíÿêà âû ñòàëêèâàëèñü ñ ñèòóàöèåé çàïîëíåíèÿ îãðîìíîé ôîðìû, ïîïûòêà îòïðàâèòü êîòîðóþ ïðèâîäèëà ê òîìó, ÷òî ïîÿâëÿëîñü îêîøêî ñî ñëîâîì ¾îøèáêà¿ áåç êàêèõ-ëèáî óòî÷íåíèé. Ýòî ïëîõîé ñòèëü, ñîîáùåíèå îá îøèáêå äîëæíî áûòü èíôîðìàòèâíûì, ÷òîáû ïîçâîëèòü áûñòðî å¼ íàéòè è èñïðàâèòü. Òàêèì îáðàçîì, ïðè ñîçäàíèè îøèáêè íóæíî ïåðåäàâàòü èñ÷åðïûâàþùóþ èíôîðàìàöèþ î íåé.  íàøåì ïðèìåðå ñ âåùåñòâåííûìè ÷èñëàìè ìû ìîæåì ðàññìîòðåòü òàêîé ïðèìåð îøèáêè: óìíîæåíèå êîìïëåêñíîãî ÷èñëà íà ÷òî-òî, îòëè÷íîå îò öåëîãî, âåùåñòâåííîãî èëè êîìïëåêñíîãî ÷èñëà. Êîãäà ìû äîøëè äî ýòàïà óìíîæåíèÿ ìû óæå íè÷åãî íå ìîæåì ïðåäïðèíÿòü äëÿ èñïðàâëåíèÿ ýòîé îøèáêè, êðîìå êàê ïðîñèãíàëèçèðîâàòü î íåé â òî ìåñòî, îòêóäà áûëà âûçâàíà íàøà îïåðàöèÿ óìíîæåíèÿ. Ïðè ýòîì íà ýòàïå âûçîâà îïåðàöèè óìíîæåíèÿ ìû óæå ìîæåì ïðåäïðèíÿòü êàêèå-òî äåéñòâèÿ. Íàïðèìåð, ñîîáùèòü ïîëüçîâàòåëþ î òîì, êàêóþ ôèãíþ îí ââåë è ïîïðîñèòü ââåñòè âñå-òàêè êîìïëåêñíîå ÷èñëî. Èëè, åñëè ìû îáðàáàòûâàåì ïîñëåäîâàòåëüíîñòü, èç êîòîðîé íóæíî âû÷ëåíèòü è ïåðåìíîæèòü êîìïëåêñíûå ÷èñëà ïðîñòî ïåðåéòè ê ñëåäóþùåìó ýëåìåíòó ïîñëåäîâàòåëüíîñòè. Íà ýòàïå êîãäà ìû äîøëè äî íåóäà÷íîãî âûïîëíåíèÿ îïåðàöèÿ óìíîæåíèÿ ìû íå çíàåì è íå ìîæåì çíàòü êàê äîëæíà ñåáÿ âåñòè êîíêðåòíàÿ ïðîãðàììà ïðè âîçíèêíîâåíèè òàêîé îøèáêè. Êîãäà ìû äîéäåì äî îøèáî÷íîé îïåðàöèè ìû ìîæåì ñêîíñòðóèðîâàòü ñïåöèàëüíûé êëàññ, ñîäåðæàùèé ïîäðîáíîå îïèñàíèå îøèáêè è âûáðîñèòü åãî â òî ìåñòî, êîòîðîå ñïîñîáíî åãî îáðàáîòàòü. Âûáðàñûâàåòñÿ îøèáêà ñ ïîìîùüþ êîìàíäû raise, à ëîâèòñÿ áëîêîì try-except. Äëÿ ñëó÷àÿ óìíîæåíèÿ êîìïëåêñíîãî ÷èñëà íà ìóñîð ìû ìîæåì ñêîíñòðóèðîâàòü êëàññ îøèáêè, ñîäåðæàùèé â ñåáå ññûëêó êàê íà êîìïëåêñíîå ÷èñëî, òàê è íà âòîðîé àðãóìåíò ìåòîäà óìíîæåíèÿ. Êëàññ äëÿ îøèáêè äîëæåí áûòü íàñëåäíèêîì ñòàíäàðòíîãî êëàññà BaseError. Ïîêà äëÿ íàñ ýòî çíà÷èò òîëüêî òî, ÷òî ïðè ñîçäàíèè îïèñàíèÿ êëàññà îøèáêè ìû äîëæíû íàïèñàòü â ñêîáêàõ ïîñëå åãî íàçâàíèÿ BaseError. Ïîòåíöèàëüíî îøèáî÷íûå äåéñòâèÿ äîëæíû âûïîëíÿòüñÿ â áëîêå try, à êîìàíäû äëÿ îáðàáîòêè îøèáêè äîëæíû áûòü â áëîêå except. Ïðèìåð ñ îáðàáîòêîé îøèáêè áóäåò âûãëÿäåòü òàê: c l a s s ComplexError ( BaseException ) : def __init__ ( s e l f , Complex , o t h e r ) : s e l f . a r g 1 = Complex s e l f . arg2 = other c l a s s Complex : def __init__ ( s e l f , r e =0, im =0): 9.7. НАСЛЕДОВАНИЕ И ПОЛИМОРФИЗМ 79 s e l f . re = re s e l f . im = im def __str__( s e l f ) : strRep = s t r ( s e l f . r e ) i f s e l f . im >= 0 : strRep += '+ ' strRep += s t r ( s e l f . im ) + ' i ' return strRep def __add__( s e l f , o t h e r ) : newRe = s e l f . r e + o t h e r . r e newIm = s e l f . im + o t h e r . im return Complex ( newRe , newIm ) def __mul__( s e l f , o t h e r ) : i f i s i n s t a n c e ( o t h e r , Complex ) : newRe = s e l f . r e * o t h e r . r e − s e l f . im * o t h e r . im newIm = s e l f . r e * o t h e r . im + s e l f . r e * o t h e r . im e l i f i s i n s t a n c e ( o t h e r , i n t ) or i s i n s t a n c e ( o t h e r , f l o a t ) : newRe = s e l f . r e * o t h e r newIm = s e l f . im * o t h e r else : r a i s e ComplexError ( s e l f , o t h e r ) return Complex ( newRe , newIm ) __rmul__ = __mul__ a = Complex ( 1 , 2 ) try : r e s = a * ' abcd ' except ComplexError a s c e : print ( ' E r r o r i n mul with a r g s : ' , c e . arg1 , c e . a r g 2 ) Âûâîä ýòîé ïðîãðàììû áóäåò: Error in mul with args: 1+2i abcd Ïî íåìó ëåãêî ïîíÿòü, ÷òî îøèáêà âîçíèêàåò ïðè îïåðàöèè óìíîæåíèÿ è óâèäåòü, ÷òî áûëî ïåðåäàíî â íå¼ â êà÷åñòâå àðãóìåíòîâ. Ïîñëå êîìàíäû except ìû ìîæåì óêàçàòü èìÿ êëàññà îøèáêè, êîòîðûé îí äîëæåí îáðàáàòûâàòü, çàòåì íàïèñàòü as è óêàçàòü èìÿ ïåðåìåííîé â êîòîðóþ ïîïàäåò îáúåêò ñ îïèñàíèåì êîíêðåòíîé îøèáêè. Áëîêîâ except ìîæåò áûòü íåñêîëüêî äëÿ îáðàáîòêè îøèáîê ðàçíûõ òèïîâ. Ïðâîåðêè âûïîëíÿþòñÿ ïîñëåäîâàòåëüíî, áóäåò âûïîëíåí òîò áëîê êîìàíä, ó êîòîðîãî èìÿ êëàññà ñîâïàäàåò ñ èìåíåì êëàññà îøèáêè èëè ÿâëÿåòñÿ åãî ïðåäêîì â äåðåâå èåðàðõèè íàñëåäîâàíèÿ. 9.7 Наследование и полиморфизм Îïåðàöèè ñëîæåíèÿ è óìíîæåíèÿ íà âåùåñòâåííîå èëè öåëîå ÷èñëî äëÿ êîìïëåêñíûõ ÷èñåë î÷åíü ïîõîæè íà ïîâåäåíèå ñâîáîäíûõ âåêòîðîâ íà ïëîñêîñòè. Îíè ñîîòâåòñòâóþò ñëîæåíèþ âåêòîðîâ èëè óìíîæåíèå âåêòîðà íà ÷èñëî, ãäå äåéñòâèòåëüíàÿ ÷àñòü 80 ЛЕКЦИЯ 9. ОБЪЕКТНО-ОРИЕНТИРОВАННОЕ ПРОГРАММИРОВАНИЕ êîìïëåêñíîãî ÷èñëà ÿâëÿåòñÿ x-êîîðäèíàòîé âåêòîðà, à ìíèìàÿ y-êîîðäèíàòîé. Êðîìå òîãî, ñâîáîäíûé âåêòîð îáëàäàåò íåêîòîðûìè îïåðàöèÿìè, êîòîðûå õàðàêòåðíû òîëüêî äëÿ íåãî, íî íå äëÿ âåùåñòâåííîãî ÷èñëà. Íàïðèìåð, ýòî ìîæåò áûòü ìåòîä length, âû÷èñëÿþùèé äëèíó âåêòîðà. Íàì íå õîòåëîñü áû çàñîðÿòü êîä äëÿ îïèñàíèÿ êîìïëåêñíîãî ÷èñëà ìåòîäàìè äëÿ ðàáîòû ñî ñâîáîäíûì âåêòîðîì, íî ñ äðóãîé ñòîðîíû íå õîòåëîñü áû çàíîâî ïåðåïèñûâàòü ìåòîäû ñëîæåíèÿ è óìíîæåíèÿ äëÿ ñâîáîäíûõ âåêòîðîâ.  òàêîé ñèòóàöèè ðàçóìíî ñîçäàòü íîâûé êëàññ äëÿ îïèñàíèÿ ñâîáîäíîãî âåêòîðà (èëè òî÷êè íà ïëîñêîñòè, ÷òî òî æå ñàìîå), êîòîðûé óíàñëåäîâàë áû âñå ìåòîäû êîìïëåêñíûõ ÷èñåë è äîáàâèë áû íîâûé ìåòîä length. Ìû óæå çíàåì, ÷òî äëÿ òîãî, ÷òîáû ïðîíàñëåäîâàòü êëàññ îò äðóãîãî äîñòàòî÷íî â îïèñàíèè êëàññà óêàçàòü â êðóãëûõ ñêîáêàõ, îò êîãî îí íàñëåäóåòñÿ. Òàêèì îáðàçîì, ìû ìîæåì çàïèñàòü íàøå îïèñàíèå êëàññà Point ñ îïðåäåëåííûì ìåòîäîì length òàê: c l a s s ComplexError ( BaseException ) : def __init__ ( s e l f , Complex , o t h e r ) : s e l f . a r g 1 = Complex s e l f . arg2 = other c l a s s Complex : def __init__ ( s e l f , r e =0, im =0): s e l f . re = re s e l f . im = im def __str__( s e l f ) : strRep = s t r ( s e l f . r e ) i f s e l f . im >= 0 : strRep += '+ ' strRep += s t r ( s e l f . im ) + ' i ' return strRep def __add__( s e l f , o t h e r ) : newRe = s e l f . r e + o t h e r . r e newIm = s e l f . im + o t h e r . im return Complex ( newRe , newIm ) def __mul__( s e l f , o t h e r ) : i f i s i n s t a n c e ( o t h e r , Complex ) : newRe = s e l f . r e * o t h e r . r e − s e l f . im * o t h e r . im newIm = s e l f . r e * o t h e r . im + s e l f . r e * o t h e r . im e l i f i s i n s t a n c e ( o t h e r , i n t ) or i s i n s t a n c e ( o t h e r , f l o a t ) : newRe = s e l f . r e * o t h e r newIm = s e l f . im * o t h e r else : r a i s e ComplexError ( s e l f , o t h e r ) return Complex ( newRe , newIm ) __rmul__ = __mul__ c l a s s Po in t ( Complex ) : def l e n g t h ( s e l f ) : 9.8. ПЕРЕОПРЕДЕЛЕНИЕ МЕТОДОВ 81 return ( s e l f . r e ** 2 + s e l f . im * * 2 ) * * ( 1 / 2 ) a = P oi nt ( 3 , 4 ) b = Complex ( 1 , 2 ) print ( a . l e n g t h ( ) ) c = a + b print ( c ) Âûâîä ýòîé ïðîãðàììû áóäåò 5.0 4+6i Çäåñü ìû íå òîëüêî óáåäèëèñü â òîì, ÷òî ñâåæåñîçäàííûé ìåòîä ðàáîòàåò, íî è ñäåëàëè äîâîëüíî ñòðàííóþ âåùü: ñëîæèëè òî÷êó íà ïëîñêîñòè ñ êîìïëåêñíûì ÷èñëîì. Äåëî â òîì, ÷òî îáúåêòà êëàññà Point òàêæå îäíîâðåìåííî ÿâëÿåòñÿ è îáúåêòîì òèïà Complex, ò.ê. Point ïðîíàñëåäîâàí îò Complex. Point ëèøü ðàñøèðÿåò è äîïîëíÿåò Complex, à çíà÷èò Point ìîæåò ñìåëî áûòü èíòåðïðåòèðîâàí êàê Complex, íî íå íàîáðîò.  ýòîì ïðèìåðå áóäóò èñòèííû âûðàæåíèÿ isinstance(a, Point) è isinstance(a, Complex), íî áóäåò ëîæíî âûðàæåíèå isinstance(b, Point). 9.8 Переопределение методов Åñëè ìû ïîïûòàåìñÿ íàïå÷àòàòü îáúåêò òèïà Point, òî îí íàïå÷àòàåòñÿ êàê êîìïëåêñíîå ÷èñëî. Íàì õîòåëîñü áû, ÷òîáû òî÷êè íà ïëîñêîñòè ïå÷àòàëèñü â âèäå (x, y), à íå x+yi.  ÿçûêå Ïèòîí ëþáîé ìåòîä ìîæíî ïåðåîïðåäåëèòü â íàñëåäíèêå, ÷òî ìû è ñäåëàåì äëÿ ìåòîäà __str__ äëÿ êëàññà Point: c l a s s ComplexError ( BaseException ) : def __init__ ( s e l f , Complex , o t h e r ) : s e l f . a r g 1 = Complex s e l f . arg2 = other c l a s s Complex : def __init__ ( s e l f , r e =0, im =0): s e l f . re = re s e l f . im = im def __str__( s e l f ) : strRep = s t r ( s e l f . r e ) i f s e l f . im >= 0 : strRep += '+ ' strRep += s t r ( s e l f . im ) + ' i ' return strRep def __add__( s e l f , o t h e r ) : newRe = s e l f . r e + o t h e r . r e newIm = s e l f . im + o t h e r . im return Complex ( newRe , newIm ) def __mul__( s e l f , o t h e r ) : 82 ЛЕКЦИЯ 9. ОБЪЕКТНО-ОРИЕНТИРОВАННОЕ ПРОГРАММИРОВАНИЕ i f i s i n s t a n c e ( o t h e r , Complex ) : newRe = s e l f . r e * o t h e r . r e − s e l f . im * o t h e r . im newIm = s e l f . r e * o t h e r . im + s e l f . r e * o t h e r . im e l i f i s i n s t a n c e ( o t h e r , i n t ) or i s i n s t a n c e ( o t h e r , f l o a t ) : newRe = s e l f . r e * o t h e r newIm = s e l f . im * o t h e r else : r a i s e ComplexError ( s e l f , o t h e r ) return Complex ( newRe , newIm ) __rmul__ = __mul__ c l a s s Po in t ( Complex ) : def l e n g t h ( s e l f ) : return ( s e l f . r e ** 2 + s e l f . im * * 2 ) * * ( 1 / 2 ) def __str__( s e l f ) : return s t r ( ( s e l f . re , s e l f . im ) ) a = P oi nt ( 3 , 4 ) print ( a ) Íàø ìåòîä îáÿçàí âîçâðàùàòü ñòðîêó, íî ìû ìîæåì âîñïîëüçîâàòüñÿ ôóíêöèåé str îò êîðòåæà, êîòîðàÿ âûäàñò íàì íóæíûé ðåçóëüòàò. 9.9 Проектирование структуры классов Ñòðóêòóðà îïèñàíèÿ êëàññîâ ïðåäñòàâëÿåò ñîáîé äåðåâî (íà ñàìîì äåëå â Ïèòîíå àöèêëè÷åñêèé ãðàô), ïðîíàñëåäîâàííûé îò åäèíîãî êîðíÿ áàçîâîãî ïóñòîãî êëàññà. Ñ ïîìîùüþ ãðàìîòíî ñïðîåêòèðîâàííîé ñòðóêòóðû êëàññîâ ìîæíî äîáèòüñÿ ëåãêîé ÷èòàåìîñòè è ìàêñèìàëüíîãî ïîâòîðíîãî èñïîëüçîâàíèÿ êîäà, îáåñïå÷åíèÿ åäèíîãî èíòåðôåéñà è ìíîæåñòâî äðóãèõ ðàäîñòåé. Îäíàêî, âíåñåíèå ôè÷è èëè èçìåíåíèå íà âûñîêîì óðîâíå èåðàðõèè êëàññîâ ìîæåò ïðèâåñòè ê íåîáõîäèìîñòè âûïîëíèòü îãðîìíîå êîëè÷åñòâî ðàáîòû ïî ìîäèôèêàöèè âñåõ ïîòîìêîâ ýòîãî êëàññà, à òàêæå ê ïîëíîé íåñîâìåñòèìîñòè ñ ïðåäûäóùåé âåðñèåé. Ìíîãî÷èñëåííûå èçìåíåíèÿ òàêîãî ðîäà ïðèâîäÿò ê óðîäëèâûì êîíñòðóêöèÿì, êîòîðûå íåâîçìîæíî ïîíèìàòü è îòëàæèâàòü.  òî æå âðåìÿ, çàêëàäûâàíèå ïåðñïåêòèâíûõ ôè÷åé â ñòðóêòóðó êëàññîâ âåäåò ê ïåðåóñëîæíåíèþ è ñâîäèò íà íåò âñå ïîâòîðíîå èñïîëüçîâàíèå êîäà çà ñ÷åò ãðîìîçäêîñòè êîíñòðóêöèé. Êðîìå òîãî, ïåðñïåêòèâíûå ôè÷è ìîãóò áûòü íåäîñòàòî÷íî îáäóìàíû è ïðèâåäóò ê åùå áîëüøåìó óðîäñòâó, êîãäà äåëî äîéäåò äî èõ ðåàëüíîé ðåàëèçàöèè (åñëè äîéäåò). Òàêèì îáðàçîì, ãðàìîòíîå ïðîåêòèðîâàíèå ñèñòåìû êëàññîâ òðåáóåò íå òîëüêî õîðîøåãî çíàíèÿ ïàòòåðíîâ ïðîåêòèðîâàíèÿ, íî è áîëüøîãî ïðàêòè÷åñêîãî îïûòà. Íà íà÷àëüíîì ýòàïå ñòîèò îáó÷àòüñÿ ïðîåêòèðîâàíèþ ñèñòåì, â êîòîðûå íå ïëàíèðóåòñÿ âíåñåíèå èçìåíåíèé.