Вступ до програмування

Посилання на оригінальну статтю: https://www.teamten.com/lawrence/programming/intro/

 

У цій книзі будуть представлені різні концепції комп’ютерного програмування. У цих поясненнях є деякі спрощення. Не приймайте нічого занадто буквально.

 

Розділ 1: Мови програмування

 

Мета програмування — розповісти комп’ютеру, що робити. Комп’ютери краще роблять деякі речі, ніж ви, як шеф-кухар краще приготує, ніж ви. Легше попросити шеф-кухаря приготувати їжу, ніж приготувати її самостійно. Чим точніше ви знаходитесь у своєму запиті, тим більше ваша їжа вийде, як вам це подобається. У більшості сценаріїв, як це в реальному житті, невеликі обсяги неоднозначності і неправильного тлумачення є прийнятними. Можливо, шеф-кухар варять вашу картоплю перед тим, як затирати її, а не випікати. Проте з комп’ютерами неоднозначність рідко буває прийнятною. Програми настільки складні, що якщо комп’ютер просто здогадався про значення неоднозначних або нечітких запитів, це може спричинити проблеми настільки тонкі, що ніколи не знайдете їх. Мови програмування, таким чином, були розроблені, щоб прийняти тільки повністю ясні і однозначні заяви. Програма, як і раніше, може мати проблеми, але винуватість тут прямо на вас, а не на припущення комп’ютера. Велика частина труднощів у програмуванні виникає з того, щоб бути абсолютно точним та однозначним в усьому.

 

Або, як каже мій друг Ден Колленс: «Написання програмного забезпечення подібне до написання інструкцій для 12-річного брата, який намагається взяти все, що ви говорите буквально, просто щоб вас дратувати». «Так, але я мав на увазі…”

 

Деякі мови вимагають повної деталізації. C і C++ є такими мовами і називаються мовами низького рівня. Інші мови будуть робити всілякі припущення, і це дає змогу програмісту вказати менше деталей. Python і Basic є такими мовами і називаються мовами високого рівня. Загалом, мови високого рівня простіше програмувати, але надають менше контролю. Контроль іноді важливий, наприклад, якщо ви хочете, щоб ваша програма йшла якомога швидше. Більшу частину часу повний контроль і швидкість не є необхідними, і оскільки комп’ютери стають швидшими, мови високого рівня стають більш популярними. Тут ми будемо займатися виключно мовами високого рівня. Мови низького рівня зазвичай подібні, за винятком того, що часто потрібно писати декілька рядків коду, щоб виконати те ж саме. (Код є скороченим для програмного коду, термін, який посилається на текст, який ви пишете, щоб повідомити комп’ютеру, що робити після запуску програми.)

 

Зауважте, що менше деталей не означає менш точне. Всі мови вимагають чіткого написання. Щоб повернутися до аналогії з приготуванням, мова високого рівня нагадує запитання: «Я хочу дві чашки пюре», тоді як мова з низьким рівнем мови вимагає, щоб ви точно вказали, як робити картопляне пюре. Мова високого рівня має специфікацію, яка точно визначає, як саме готують ці пюре, так що на комп’ютері все ще немає жодних припущень.

 

Розділ 2: Ствердження

 

Більшість мов програмування мають концепцію висловлювання. Оператор – це команда, яку програміст передає комп’ютеру. Наприклад:

print "Hello, world!"

 

Ця команда має дієслово (“print”) та інші деталі (що друкувати). У цьому випадку команда print означає “показувати на екрані”, а не “друкувати на принтері”. команду в ній. Ви можете створити файл з назвою “hi.txt”, використовуючи програму, подібну до програми “Блокнот”. (Детальна інформація про те, як це зробити, залежить від мови та системи, тому вони не будуть висвітлені тут. Це лише вступ до понять.)

 

Якщо у вас більше ніж одна команда у файлі, кожна з них буде виконана в порядку, зверху вниз. Таким чином, файл може містити:

 

print "Hello, world!"
print "Strange things are afoot..."

 

Комп’ютер буде виконувати кожну з цих команд послідовно. Це неоціненно, щоб мати можливість «грати на комп’ютері» під час програмування. Запитайте себе: «Якби я був комп’ютером, що б я зробив з цими твердженнями? Зупиніть і перевірте посібник для мови програмування, який ви використовуєте.

 

У вищенаведеному випадку комп’ютер розгляне першу заяву, визначить, що це виписка з друку, подивіться, що потрібно надрукувати, і покажіть цей текст на екрані комп’ютера. Це виглядатиме так:

 

Hello, world!

 

Зауважте, що лапки не існують. Їхня мета в програмі полягає в тому, щоб розповісти комп’ютеру, де починається і закінчується текст, подібно до англійської прози. Після цього комп’ютер перейде до наступного оператора, виконає свою команду, а екран буде виглядати так:

 

Hello, world!
Strange things are afoot...

 

Коли комп’ютер потрапляє до кінця текстового файлу, він зупиняється і чекає подальших інструкцій. Весь цей процес називається запуском або виконанням програми. Під час запуску програми комп’ютер переглядає файл програми та виконує відповідні дії для кожного оператора.

 

Існує багато різних типів операторів, залежно від того, яка мова програмування використовується. Наприклад, може виникнути запис звукового сигналу, який змушує комп’ютер виводити звуковий сигнал на своєму динаміку, або оператор window, що викликає відкриття нового вікна.

 

Крім того, спосіб написання операторів залежить від мови програмування. Мова програмування Python використовує твердження, які виглядають так, як показано вище. У C ви пишете:

 

puts("Hello, world!");
puts("Strange things are afoot...");

 

Зверніть увагу на кілька відмінностей:

  1. Параметри (текст у лапках, які друкують, щоб визначити, що відображатиме), оточені дужками.
  2. Кожен оператор припиняється крапкою з комою.
  3. Друк дієслова називається print, для “put string”. Текстовий рядок є терміном комп’ютера для деякого тексту. Він походить від “рядка букв”. “Покласти” означає “покласти на екран”.

Ці відмінності досить поверхневі. Набір правил, як і перші два, називається синтаксисом мови програмування. Набір дієслів називається його бібліотекою. Це трохи нагадує граматику та словниковий запас природної мови.

 

Розділ 3: Синтаксис

 

Кожна мова має багато синтаксичних правил. Наприклад, якщо ви хочете, щоб комп’ютер відображав дві різні речі, ви могли б написати:

 

print "I have a dog.  His name is Bort."

 

або ви можете написати:

 

print "I have a dog.  " + "His name is Bort."

 

Другий приклад має дві рядки, кожна з яких укладена в лапки. Між ними є знак “плюс” (+), що означає “Приєднайте два рядки разом, перетворюючи їх на один рядок”.

Поєднання двох рядків називається concatenation. Рядки зверху будуть відображатися так:

 

I have a dog.  His name is Bort.

 

У наведених вище прикладах немає жодної причини, чому ви використовуєте + і два рядки, коли ви можете просто використовувати один рядок, як у першому прикладі, але пізніше ми побачимо випадки, коли конкатенація рядків є необхідною. Мови Python і Java використовують плюс (+) для конкатенації рядків, Perl і PHP використовують період (.), А Visual Basic використовує амперсанд (&). Знову ж таки, ці відмінності поверхневі; важливою є концепція конкатенації рядків і синтаксису мови для виконання конкатенації. Розділіть у своїй свідомості основну концепцію та спосіб висловлення цієї концепції певною мовою.

 

Ви можете запитати, чому люди придумали мови з поверхневими відмінностями, подібними до них. Ці відмінності, як правило, є результатом компромісів, іноді для ясності, іноді для простоти програмування, іноді для того, щоб програма виконувалася якомога швидше. Один дизайнер мови, можливо, відчув, що знак «плюс» є найяскравішим способом об’єднання двох рядків. Інший, можливо, вирішив, що це неоднозначно з значенням плюса в математиці для чисел, і вибрав замість нього амперсанд. Третій вважає, що амперсанд означає «і», який слід використовувати для логічних запитів, а не для маніпуляції рядками, і вибирає період. Четвертий дизайнер вирішив, що, оскільки є багато способів приєднати два рядки разом (внутрішньо до комп’ютера), він не хотів вибирати жодного для програміста, а замість того, щоб програміст написав кілька рядків детального коду це просте завдання.

 

У дизайні мови існує багато різних філософій. Мова програмування Perl, наприклад, намагається бути дуже лаконічним, так що ви можете досягти багато чого з дуже маленьким набором. Це перевага для тих, хто любить набирати менше, але недолік для тих, хто вважає, що короткий код криптовий. Мова програмування Java – це все про безпеку, і вона встановлює мережу безпеки навколо програми, щоб погано написана програма не зірвалася. Це призводить до того, що отримана програма буде працювати повільніше, тому, чи використовуєте ви Java, залежить від того, чи ви цінуєте швидкість або безпеку. Мова C – навпаки: він не має мережі безпеки і дозволяє вашій програмі працювати якомога швидше. Оскільки мережа безпеки може заощадити вас (програміста) під час написання програми, ви можете побачити компроміс як економію часу комп’ютера або економію часу.

 

Існує стара традиція демонстрації синтаксису мови програмування, написавши програму, яка відображає текст “Привіт, світ!” На мові, яку ми будемо використовувати в цій книзі, це виглядатиме так:

 

print "Hello, world!"

 

Сторінка «Список hello worlds у програмах» у Вікіпедії має більш ніж 100 мов програмування. Перегляньте його, щоб побачити величезну різноманітність синтаксису.

Розділ 4: Змінні

 

Скажімо, у вас була програма, яка розповідала про вашу собаку. Це може виглядати так:

 

print "I have a dog.  It is called Bort."
print "Bort likes to eat dog food."
print "My children and Bort get along very well."
print "My dog Bort barks at my neighbor, whose name is also Bort."

 

Ви могли б продовжувати подібні дії на деякий час, попросивши комп’ютер відобразити багато таких цікавих речей про вашу собаку. Якщо одного дня ви змінили назву собаки або хотіли б поговорити про іншу собаку, або передали цю програму другу, і вони хотіли змінити її, щоб посилатися на свою собаку, вам доведеться пройти через програми і змінити кожне входження “Bort” на нову назву. Для цього ви можете скористатися функцією пошуку та заміни вашого текстового редактора, але це непросто, і ви можете робити помилки. Наприклад, ви можете випадково замінити ім’я сусіда, коли ви збираєтеся змінити лише ім’я собаки.

 

Мови програмування вирішують цю проблему, дозволяючи писати ім’я собаки лише один раз, а потім звертатися до неї за допомогою мітки. Це схоже на використання займенників на природних мовах. Отже, ви можете написати:

 

dog = "Bort"

 

Якщо ви “граєте в комп’ютер” і переходите до вищезазначеного висловлювання, ви подумаєте: “Пам’ятайте рядок Bort, і всякий раз, коли використовується слово dog, заміните слово Bort”. Це називається оператором присвоювання, тому що ви присвоєння значення слову dog. Наступне твердження могло б сказати:

 

print dog

 

Зауважте, що тут немає жодних лапок. Ви не хочете буквально друкувати слово «собака», ви хочете, щоб комп’ютер запам’ятав текст, який він раніше пов’язував з цим словом. Це трохи схоже на відмінність між висловом «Він сказав свого віку» і “Він сказав, його вік”. У першому випадку це число, а в другому — слова “його вік”. Слово dog є змінною. Це символ, який комп’ютер асоціює з чимось іншим, в даному випадку — словом “Bort”. Наша оригінальна програма тепер може бути написана так:

 

print "I have a dog.  It is called " + dog + "."
print dog + " likes to eat dog food."
print "My children and " + dog + " get along very well."
print "My dog " + dog + " barks at my neighbor, whose name is Bort."

 

Зверніть увагу, що конкатенація рядків (використовуючи знак “плюс”) була потрібна тут, оскільки іноді ми хотіли використовувати лапки (щоб означати буквальний текст), а іноді ми і не зробили (посилатися на змінну). Комп’ютер побачить заяву типу:

 

print dog + " likes to eat dog food."

 

і спочатку замінити слово dog за допомогою рядка “Bort”:

 

print "Bort" + " likes to eat dog food."

 

потім об’єднати рядки:

 

print "Bort likes to eat dog food."

 

потім виконайте операцію, показуючи це на екрані:

 

Bort likes to eat dog food.

 

Зазначимо також, що ім’я сусіда не було замінено посиланням на собаку. Змінна собака відноситься до назви собаки. Це весь сенс використання змінної: відстежувати конкретну концепцію. Ви можете мати іншу змінну, щоб відстежувати ім’я сусіда:

 

neighbor = "Bort"

 

і змінити останній рядок нашої програми на:

 

print "My dog " + dog + " barks at my neighbor, whose name is " + neighbor + "."

 

Таким чином, ви можете легко змінити назву вашої собаки або ближнього в верхній частині файлу, а решта програми працюватиме правильно. Я вилучив слово “також” з лінії, оскільки тепер, коли ми використовуємо змінні, я більше не можу бути впевнений, що ці імена однакові. Я б не хотіла змінювати одну з двох, і щоб у моїй програмі все ще виводилося слово “також”. Пізніше ми побачимо спосіб відображення слова “також”, лише якщо обидва імена однакові.

 

Вся програма зараз виглядає так:

 

dog = "Bort"
neighbor = "Bort"

print "I have a dog.  It is called " + dog + "."
print dog + " likes to eat dog food."
print "My children and " + dog + " get along very well."
print "My dog " + dog + " barks at my neighbor, whose name is " + neighbor + "."

 

Порожній рядок між операторами призначення та набором друкованих операцій не є необхідним. Комп’ютер ігнорується. Це є для вас на користь, так що ви можете візуально побачити розрив між двома блоками коду. Оскільки ці два блоки виконують принципово різні речі, приємно, що вони візуально відокремлені. Використовуйте порожні рядки ліберально в коді, щоб розділити блоки коду, які концептуально відрізняються.

 

Важливо пам’ятати про дві змінні. По-перше, змінна повинна бути встановлена ​​до її використання. Тому ви повинні написати:

 

dog = "Bort"
print dog

 

і ні:

 

print dog                             (Wrong!)
dog = "Bort"

 

Пам’ятайте, коли “грає комп’ютер”, що ви повинні дивитися на кожну заяву окремо і в порядку зверху вниз. У другому прикладі вище ви б спочатку дісталися до висловлювання «print dog» і не знаєте, про що йшла змінна собака. Різні мови по-різному реагують на цю проблему. Деякі вважають, що змінною є порожній рядок (“”), але більшість зупиняє програму і повідомляє про помилку.

По-друге, коли ви “граєте в комп’ютер” і бачите другий рядок правильної програми:

 

dog = "Bort"
print dog

 

дуже важливо, щоб ви не “поверталися назад” до першого рядка, щоб побачити, на що посилається собака. Перша лінія давно минула. Ви можете переглядати лише один рядок за раз, і завжди послідовно. Перший рядок вказує десь (у пам’яті), що собака називає «Борта», але потім сама лінія залишається поза і забувається. Другий рядок перевіряє пам’ять і отримує значення змінної там, а не безпосередньо з першого рядка. Це може здатися тривіальним розрізненням, але ми будемо використовувати змінні в більш складних способах пізніше, і це не буде працювати, щоб “повернутися назад”, щоб знайти, де була встановлена ​​змінна; вам доведеться думати про змінну та її значення як про збереження в пам’яті.

 

Слово, яке ви використовуєте для назви змінної, важливе лише для вас. Для комп’ютера важливо лише бути послідовними. Отже, ви можете написати:

 

dog = "Bort"
print dog

 

і це буде працювати так само добре, як:

 

xyz = "Bort"
print xyz

 

Ви повинні використовувати одне і те ж ім’я в обох місцях, щоб комп’ютер міг зрозуміти, що ви маєте на увазі те ж саме, але фактичне слово (собака або xyz) видно тільки вам програмісту, а не користувачеві Програма. У цьому прикладі перший випадок кращий, тому що назва dog являє собою те, для чого ви використовуєте змінну. Для когось, хто читає програму, буде ясно, що рядок “Bort” – це ім’я собаки. Якщо ви використовували ім’я змінної xyz, це не було б зрозумілим для тих, хто читав програму.

 

Змінна слово означає, що змінні можуть змінюватися, і вони дійсно можуть. Можна написати таку програму:

 

dog = "Bort"
print "My first dog was called " + dog + "."
dog = "Milou"
print "And my second dog was called " + dog + "."

 

Комп’ютер побачить перший рядок, асоціює рядок “Bort” зі змінною собакою, використовує цю рядок у другому рядку, змінює асоціацію змінної собаки з “Milou” в третьому рядку і використовує нову асоціацію в четверте. У пам’яті змінна собака може бути пов’язана тільки з одним рядком. Третій рядок замінює стару асоціацію з новою. Друга і четверта лінії розглядають пам’ять, щоб побачити, що таке асоціація, і при кожному вираженні значення відрізняється, тому що значення в пам’яті відрізняється на той момент у виконанні програми. Ви побачите:

 

My first dog was called Bort.
And my second dog was called Milou.

 

Розділ 5: Математика

 

Коли комп’ютер бачить математичну формулу, він автоматично виконує арифметику. Наприклад, ви можете написати:

 

print 5 + 6

 

Зверніть увагу ще раз, що немає жодних лапок. Якщо б вони були, комп’ютер би брав це буквально і друкував «5 + 6». Знак плюс називається оператором, оскільки він виконує операції над іншими значеннями. Коли комп’ютер побачить вищевказану лінію, він виконає арифметику і отримає:

 

print 11

 

Виконання операції просто надрукує номер:

 

11

 

Зауважте, що наступні дві операції показуватимуть одне й те саме:

 

print 11
print "11"

 

за винятком того, що в першому випадку комп’ютер знає це число, тоді як у другому випадку це просто рядок. Математика може бути досить складною:

 

print (5 + 12) * 9 / 14

 

Комп’ютер крок за кроком виконуватиме арифметику, як і в голові. Спочатку буде додано доповнення, оскільки воно знаходиться в дужках:

 

print 17 * 9 / 14

 

Потім множення, оскільки воно знаходиться зліва:

 

print 153 / 14

 

Потім поділ: (слеш означає “розділити”, тому що немає клавіші “÷” на клавіатурі.)

 

print 10

 

І ви побачите це, якщо ви запустили початковий рядок:

 

10

 

Зверніть увагу, що 153 ділиться на 14, насправді щось на кшталт 10.928, але комп’ютер надрукував кругле число нижче реального значення. Це пояснюється тим, що існує два типи номерів, з якими більшість мов мають справу: цілі та реалі. Integers є круглими числами, подібними до вищезазначених. Reals — це числа з десятковою крапкою, наприклад 10,928. Коли комп’ютер бачить формулу з використанням цілих чисел, вона продовжує використовувати цілі числа, щоб виконати математику, навіть якщо результат дійсно повинен бути реальним. Якби ми написали:

 

print (5.0 + 12.0) * 9.0 / 14.0

 

після чого комп’ютер виконав би математику за допомогою реальних знань, і ми побачили б щось на зразок цього:

 

10.9285714286

 

Це химерний результат історичного розвитку комп’ютерів. Це може призвести до химерних результатів, таких як цей рядок:

 

print 1 / 2

 

відображення “0” замість очікуваного “0,5”. Бувають випадки, коли поточна поведінка бажана, але часто це не так, і ви повинні зберігати відмінність між цілими числами і реалами на увазі. Також зверніть увагу на те, що наведені вище правила щодо цілих чисел і реалій застосовуються до найбільш часто використовуваних мов програмування, але кожна мова може вільно складати свої власні правила для роботи з числами, і ви можете одного разу використовувати мову, яка робить різні речі, такі як внесення результату “1/2” в “0,5”.

 

Змінні можна використовувати для позначення чисел, а також рядків. Ви можете написати:

 

x = 5
print x

 

для друку «5». Або ви можете написати:

 

age = 33
print age * 2

 

дізнатися вдвічі більше вашого віку. Знову ж таки, перший рядок створює в пам’яті зв’язок між змінною, ім’я якої є віком з номером 33. Другий рядок дивиться в пам’ять, захоплює число, пов’язане з віком, і виконує арифметику. Зауважимо, що перший рядок не є алгеброю. Це не рівняння, яке робить вік і число 33 однаковими. Це призначення значення 33 до змінного віку. Різниця важлива, коли ви бачите рядок так:

 

x = x + 5

 

Наведена вище лінія неможлива в алгебрі. Значення x не може бути рівним значенню x плюс п’ять. Але в мові програмування рядок читається так: “Знайти значення змінної x в пам’яті, додати 5 до неї, потім асоціювати результат зі змінною x.” Той факт, що x використовується як у математичній формулі на Праворуч від знаку рівності і як місце для зберігання результатів не має значення. Його значення використовується в математичній формулі, перш ніж результат зберігається назад у змінну. Зліва від знаку рівності можна помістити лише одну змінну. Це змінна, яка буде пов’язана з будь-яким правом на знак рівності. Подумайте про знак рівності як стрілку з лівою стрілкою, яка переміщує значення з правої сторони до змінної з лівої сторони. Насправді, деякі мови, такі як Pascal, використовують “: =” (який виглядає трохи як стрілка з лівою стрілкою), щоб було зрозуміло, що дані переміщуються справа наліво:

 

age := 33                  (in Pascal)

 

Ось ще один приклад:

 

x = 5
y = x + 2
print x
print y

 

Ви отримаєте:

 

5
7

 

Але тепер, якщо ви пишете (новий рядок виділено):

 

x = 5
y = x + 2
x = 10
print x
print y

 

Ви отримаєте:

 

10
7

 

Пройдіть по кожному рядку і “грайте в комп’ютер”, щоб переконати себе, чому вищезгадане буде вести себе так. Використовуйте аркуш паперу, щоб відстежувати змінні x і y, якщо це необхідно. Якщо вищезгадане не зрозуміло, зупиніть та перечитайте цей розділ або той, що стосується змінних. Це дуже поширений камінь спотикання для нових програмістів.

 

Ви могли помітити, що ми використовуємо символ плюс (+) для позначення як “конкатенації рядків”, так і “числового додавання”. Це нормально і зазвичай ясно, але що робити з комп’ютером із такою заявою:

 

print "5" + 6

 

Чи повинні бути додані цифри 5 і 6 до виходу 11? Якщо рядок “5” з’єднується з рядком “6”, щоб отримати “56”? Чи повинен комп’ютер зупинитися і повідомити про помилку? Кожна мова по-різному стосується цієї неоднозначності. У Python вищевказана лінія буде помилкою. Вам доведеться чітко повідомити комп’ютер, яку саме інтерпретацію ви хочете. В Java “6” буде перетворено в рядок, що призведе до виведення рядка “56”. У Perl, PHP і Visual Basic оператор конкатенації рядків не є плюсом, він є періодом для Perl і PHP і амперсанда в Visual Basic, тому завжди ясно, що потрібно зробити на основі того, який оператор використовується. (Це одна з переваг використання різних операторів для різних речей.)

 

Щоб дати вам інший приклад того, як синтаксис може змінюватись на різних мовах, тут ви можете додати два числа в наш мова, схожий на Python:

 

5 + 6

 

Ось як ви робите це на мові програмування Lisp:

 

(+ 5 6)

 

Зверніть увагу на дві відмінності: все це повинно бути оточене дужками; перший – знак плюс. Знову ж таки, відокремити у своєму розумінні концепцію додавання з конкретного синтаксису для додавання, що використовується мовою, яку ви вивчаєте.

 

Розділ 6: Умови

 

Скажімо, у нас була проста програма, яка відображала ваш вік:

 

age = 25
print "You are " + age + " years old."

 

Якщо ви запустили цю програму, вона буде відображати:

 

You are 25 years old.

 

У наступному році ви можете змінити перший рядок на “вік = 26”, і вихід програми буде належним чином оновлений. Фактично ви могли б дати цю програму будь-кому, і вони могли б змінити перший рядок так, щоб друга лінія друкувала потрібний вік. Як тільки ви виповнилися 30 років, ви можете змінити його так:

 

age = 30
print "You are " + age + " years old."
print "Your warranty has expired!"

 

Це спрацювало належним чином, за винятком того, що якщо ви тепер подарували його комусь, кому було 25 років, вони не тільки мали б змінити перший рядок, але й не забули видалити третій рядок. Але навіщо змушувати людину знімати третю лінію? Комп’ютер повинен мати можливість автоматично відображати або не відображати третю лінію в залежності від значення віку. Ми можемо використовувати заяву “if”, щоб сказати комп’ютеру зробити це саме так:

 

age = 30
print "You are " + age + " years old."
if age > 29:
    print "Your warranty has expired!"

 

Знову ж таки, давайте «грати на комп’ютері»: коли ви потрапите на третій рядок, ви подивитеся на вік слова, зрозумієте, що вона є змінною, і отримаєте його значення (30) з пам’яті (вона була збережена на рядку 1):

 

if 30 > 29:

 

Цей рядок говорить: “Якщо 30 більше 29, виконайте оператори, які мають відступ. Якщо ні, пропустіть вступні висловлювання. ”Оскільки 30 перевищує 29, виконується відступ, а на екрані відображається жарт. Якщо друг змінює перший рядок на “вік = 25”, то третій рядок буде порівнювати від 25 до 29, а оскільки 25 не перевищує 29, четвертий рядок буде пропущено.

 

Це умовно. Чи запускається четверта лінія, залежить від математичної формули третього рядка. Ця формула може бути більш складною, наприклад:

 

if age >= 40 and age < 50:
    print "You are in your forties."

 

Символ> = означає “більше або дорівнює” (зазвичай записується як “≥” у математиці). Тут рядок “друк” не буде запущено, якщо вік не перевищує 40 і 49 років.

 

if age >= 50 and age < 60:
    print "You are in your fifties."
    print "Mid-life crisis yet?"

 

Якщо вік людини становить від 50 до 59, обидві лінії будуть відображатися; інакше не буде. Тепер зверніть увагу, що якщо вік користувача дорівнює 1, у другому рядку нашої початкової програми відобразиться граматична помилка:

 

You are 1 years old.

 

Це має бути “рік”, а не “роки”. Ми можемо використовувати умовне, щоб виправити цю помилку. (Помилка — це помилка програми.)

 

age = 25
if age == 1:
    print "You are " + age + " year old."
if age != 1:
    print "You are " + age + " years old."

 

Значення == означає “дорівнює”. Існують два знаки рівності, щоб відрізнити його від оператора присвоєння, в якому використовується єдиний знак рівності (як у першому рядку нашої програми). Це пов’язано з тим, що ми писали раніше про комп’ютерні мови, які завжди бажали бути цілком зрозумілими щодо того, що вони призначені. Значення! = Означає “не дорівнює”. Подумайте про математичний символ знака рівності з косою рискою, «≠», а потім уявіть, що знак оклику є такою рискою. Тепер, якщо ви встановите вік до 1, ви отримаєте таке:

 

You are 1 year old.

 

Що правильно. Якщо вік не дорівнює 1, то перший «друк» буде пропущено, а другий буде виконуватися, відображаючи версію тексту з множиною «років». Досить часто хочеться зробити одну річ, якщо умова є істинною (наприклад, “вік == 1”), а інша, якщо ця умова не відповідає дійсності (“вік! = 1”). Таким чином, комп’ютерні мови мають ярлик, щоб врятувати вас від необхідності повторно вводити повну операцію “if” з оберненим умовою. Ви просто пишете це:

 

age = 25
if age == 1:
    print "You are " + age + " year old."
else:
    print "You are " + age + " years old."

 

Це означає: «Якщо вік дорівнює 1, запустіть першу операцію друку. Якщо ні (інакше), запустіть другий оператор друку. ”Знову ж, ви можете мати декілька операторів у першій або другій секції:

 

age = 25
if age == 1:
    print "You are " + age + " year old."
    print "You're an infant!"
else:
    print "You are " + age + " years old."
    print "You're not an infant."

 

Тепер ви можете дати цю програму комусь іншому, і їм потрібно лише змінити перший рядок, щоб отримати кілька рядків точного тексту, що відображається про них. Можна собі уявити, що це може бути як завгодно складним, а випробувані дуже складні умови. Розгляньте це:

 

age = 25
if age == 1:
    print "You are " + age + " year old."
    print "You're an infant!"
else:
    print "You are " + age + " years old."

    if age < 25:
        print "You're young."
    else:
        print "You're mature!"

 

Це називається “вкладеним, якщо“. Другий «якщо» (той, що порівнює вік з 25) вкладається (всередині) першим «якщо». Оскільки вона має відступ, другий “if” буде виконуватися лише тоді, коли перша умова (“вік == 1”) не відповідає дійсності. Якщо вік насправді 1, то перша «друк» буде запущена, і весь другий розділ, включаючи другий «якщо», буде пропущено. Отже, програма покаже лише одну з них: «Ви – немовля!» Або «Ви молоді» або «Ви зрілі!». Ви повинні “грати комп’ютер” через цю програму з різними віковими значеннями, такими як 1, 5, 25 і 30.

 

Умови є надзвичайно корисними. У нашому прикладі було б можливо (хоча і незручно) кожній людині додавати або видаляти «друковані» заяви, оскільки вони змінювали вік у першому рядку, але насправді значення для віку було б з іншої точки, наприклад, форма або база даних, і програма повинна запускатися як є, незмінена, і відображати правильний текст для будь-якого значення віку, який він може отримати.

 

Ми можемо дивитися на умови в C, щоб знову показати, що основні поняття доступні в різних мовах програмування з лише поверхневими відмінностями:

 

if (age > 29)
    puts("Your warranty has expired!");

 

Зверніть увагу на ці відмінності: навколо стану є корінець; “Друк”, як і раніше, замінено на “puts”; текст для відображення оточений дужками; і закінчується крапкою з комою в кінці оператора “puts”. Якщо ви хочете відобразити більше одного рядка, вам доведеться написати це так:

 

if (age >= 50 && age < 60) {
    puts("You are in your fifties.");
    puts("Mid-life crisis yet?");
}

 

Зверніть увагу на ці дві додаткові відмінності: “і” було замінено на “&&” в умові; і є фігурні фігурні дужки навколо пари “заяв”. У C (і мови, отримані з C, такі як C ++, Java і C #), відступ проігнорується, так що оператор “if” буде вважати, що тільки наступний оператор буде умовно виконуватися. Якщо ви хочете більше ніж один оператор, ви повинні згрупувати їх за допомогою фігурних дужок, щоб сказати мові, що всі вони умовно виконуються. У нашому Python-подібному мовою вище, відступ використовується для того, щоб сказати, які твердження знаходяться під контролем ліній “if” і “else”.

 

Розділ 7: Введення

 

У попередніх прикладах вік був розміщений прямо в вихідному коді, на рядку 1:

 

age = 25

 

Це називається жорстким кодуванням віку. Важко виходить з того, що як тільки програма написана таким чином, вік завжди 25. Якщо користувач хоче запустити програму з різним віком, їм потрібно змінити вихідний код. Але це передбачає, що вони розуміють програмування. Оскільки більшість користувачів не розуміють програмування, нам дуже хотілося б просто запитати користувача про вік, щоб вони взагалі не мали бачити вихідний код.

 

Ми можемо використовувати рядок так:

 

age = input()

 

Щоб ввести щось означає помістити його в комп’ютер. Вихідні дані є зворотними, подібно вимогам до друку, які ми використовували.

 

Тому наша програма тепер виглядає приблизно так:

 

print "What is your age?"
age = input()
if age == 1:
    print "You are " + age + " year old."
else:
    print "You are " + age + " years old."

 

Коли користувач запускає програму, замість того, щоб відразу побачити “Ви є. . . ”Текст, вони спочатку побачать це:

 

What is your age?

 

і система, здається, зупиниться. Після цього користувач зможе ввести свій вік, натиснути клавішу Enter, і програма буде продовжувати, як і раніше, при цьому вік змінного значення буде встановлено на будь-який номер, введений користувачем.

 

Можливо, вам буде цікаво встановити набір дужок після введення слова. Якщо ви не мали таких, наприклад:

 

age = input

 

вхідне слово буде схоже на змінну. Оскільки комп’ютери завжди хочуть бути абсолютно зрозумілими про те, що потрібно зробити, ми додаємо дужки, щоб означати: “Це не змінна, це команда. Зробити щось розумне. ”Вхід () є функцією. Ми будемо охоплювати функції пізніше, але на даний момент ви можете думати про них як про біти коду, які роблять цікаві речі (наприклад, отримувати номер з клавіатури) і створювати в результаті деяке значення (для присвоєння віку в цьому випадку). Коли комп’ютер бачить цей рядок:

 

age = input()

 

Спочатку він бачить вхід функції (), робить розумну річ (отримує номер з клавіатури) і замінює функцію на значення, яке вона отримала:

 

age = 25

 

(якщо користувач набрав 25). Потім завдання продовжується, як і раніше, зберігаючи значення 25 в пам’яті і пов’язуючи його зі словом age.

 

Розділ 8: Цикли

 

Скажімо, ми хотіли написати програму, яка запитала користувача, скільки разів вони хотіли повторити фразу. (Так, це дійсно необхідно мати ці дурні приклади. Більш реалістичні приклади часто занадто складні, щоб продемонструвати єдину нову концепцію.)

 

print "How many times?"
count = input()
if count == 1:
    print "Are we there yet?"
if count == 2:
    print "Are we there yet?"
    print "Are we there yet?"
if count == 3:
    print "Are we there yet?"
    print "Are we there yet?"
    print "Are we there yet?"
if count == 4:
    print "Are we there yet?"
    print "Are we there yet?"
    print "Are we there yet?"
    print "Are we there yet?"

 

Якщо ви запустите цю програму, користувачеві буде запропоновано “Скільки разів?”, І комп’ютер буде чекати відповіді. Після цього користувач може ввести число від 1 до 4, а слово “ми ще є?” Буде відображатися багато разів. Існує кілька проблем з цією програмою. По-перше, він може в більшості випадків обробляти кількість 4. Якщо користувач хоче, щоб він відображався 5 разів, програма повинна бути розширена для обробки цього випадку. По-друге, з ростом кількості випадків буде важко переконатися, що програма є правильною. Якщо ви простягаєтеся до, скажімо, 20 разів, важко перевірити, використовуючи ваш текстовий редактор, що справа для 17 дійсно містить у собі 17 рядків. Можливо, ви зробили помилку і лише 16-кратно вставили рядок. Ми могли б бути розумними і переписати його так:

 

print "How many times?"
count = input()
if count >= 1:
    print "Are we there yet?"
if count >= 2:
    print "Are we there yet?"
if count >= 3:
    print "Are we there yet?"
if count >= 4:
    print "Are we there yet?"

 

Це дещо складно, тому важливо ретельно дотримуватися логіки, як це зробив комп’ютер. Скажімо, кількість — це 3. Перша операція “if” перевірить, чи 3 більше або дорівнює 1, і оскільки вона є, надрукуйте першу фразу. Наступний “if” буде порівнювати відлік до 2 і друкувати другу фразу. Те ж саме відбуватиметься, коли тест count> = 3, оскільки 3 більше або дорівнює 3. Але четвертий тест не працюватиме, оскільки 3 не більше або не дорівнює 4. Отже, четверта фраза не буде відображатися. . Фраза буде відображатися 3 рази (один раз для кожної з перших трьох заяв “if”), що ми і хотіли, оскільки кількість — 3.

 

Цей новий спосіб написання програми простіший для перевірки на правильність. Треба просто переконатися, що кожне число в послідовних операціях «якщо» є одним більше, ніж попереднє число. Оскільки кожне твердження “if” друкує лише один рядок, ми не ризикуємо помилковим підрахунком кількості рядків “друку”, як у першому прикладі. Але продовжувати програму, щоб обробляти більш високі значення підрахунку, все-таки дещо нудно. Ви повинні вирізати і вставляти дві лінії і не забувати збільшувати число в операторі “if”.

 

Ми могли б зробити це трохи легше з цією новою версією:

 

print "How many times?"
count = input()
if count >= 1:
    print "Are we there yet?"
    count = count - 1
if count >= 1:
    print "Are we there yet?"
    count = count - 1
if count >= 1:
    print "Are we there yet?"
    count = count - 1
if count >= 1:
    print "Are we there yet?"
    count = count - 1

 

Тепер програма є більш складною, але кожна заява “if” ідентична. Це значно полегшує різання та вставки – ми можемо просто утримувати клавішу Ctrl-V (Paste) і мати програму, яка обробляє дуже великі значення count. Ось як працює нова програма. Перша операція “if”, як і раніше, порівнює кількість від 1 до 1 і друкує фразу, якщо кількість перевищує або дорівнює 1. Але вона також робить щось інше: воно зменшує значення count на одиницю. Ця заява:

 

count = count - 1

 

виконує три речі: знаходить значення count в пам’яті, віднімає з нього 1 і повертає результат у пам’ять, замінюючи старе значення count. Отже, якщо лічильник 3, підрахунок на правій стороні замінюється його значенням:

 

count = 3 - 1

 

потім виконується арифметика:

 

count = 2

 

і нове значення зберігається в пам’яті, як і раніше, замінюючи 3, яке було там. Ви можете задатися питанням, чому тільки підрахунок на правій стороні знаку рівності замінюється його значенням, а не лівим. Чому комп’ютер не замінює обидва слова значенням 3, наприклад:

 

3 = 3 - 1

 

Очевидно, це не було б дуже корисно. Оператор присвоєння шукає тільки існуюче значення змінних, коли вони з’являються праворуч від знака рівності (призначення). Одну змінну ліворуч від знака рівності використовують як-це знати, яке ім’я асоціювати з результатом арифметики справа.

 

Тому після відображення першої фрази кількість зменшується на одиницю, а наступний “if” перевіряється. Це той самий тест, порівнюючи підрахунок з 1. При першому «якщо» ми побачимо відображену фразу і підрахунок стане 2. У другому «якщо» ми побачимо фразу, а кількість буде: 1. На третьому «якщо» ми побачимо фразу і На четвертому “якщо” тест “0> = 1” не буде вірним, тому фраза не буде відображатися, і кількість не зменшиться. Незалежно від того, скільки ще операцій “if” ви маєте після цього, значення count залишатиметься 0, і жодна з операцій друку не буде виконуватися. Ви побачите фразу тричі, що ми хотіли, оскільки первісно було 3 числа.

 

У нашій програмі тепер є одна остання проблема: незалежно від того, скільки разів ми вирізали і вставляли ці три рядки, користувач завжди міг би ввести число, яке вище. Ви могли б вставити заяву “if” 500 разів, і якщо користувач введе “510”, ваша програма буде показувати фразу лише 500 разів, один раз для кожного “if”. Програма закінчиться змінною “count”, встановленою на 10, оскільки є ще 10 фраз, але останні 10 “if” заяв не будуть там.

 

Цю останню проблему можна виправити за допомогою циклу, наприклад:

 

print "How many times?"
count = input()
while count >= 1:
    print "Are we there yet?"
    count = count - 1

 

Це вся програма. Зокрема, це цикл while (існує кілька різних типів). Ми видалили всі заяви “якщо”, окрім однієї, і замінили слово, якщо зі словом while. Вона майже читається як англійське речення: “Хоча кількість перевищує або дорівнює 1, надрукуйте цю фразу і зменшіть її на одиницю”. Давайте “граємо на комп’ютері” з початковим значенням лічильника. оператор, порівняти 3 на 1, побачити, що 3 більше або дорівнює 1, відображати фразу, зменшувати кількість на 1 (до 2), і повертати назад до оператора while. Знову ж таки, комп’ютер порівнюватиме кількість від 1 до 1, а оскільки 2 більше або дорівнює 1, то виведе заяву, зменшить кількість до 1, поверне цикл, порівняти кількість з 1, а оскільки 1 більше або дорівнює 1 , відобразити фразу і зменшити кількість змінних до нуля. Потім вона повертається назад до оператора “while”, порівнюватиме кількість до 1, і так як 0 не перевищує або дорівнює 1, вступний вираз не буде запущений, а цикл “while” завершиться, перейшовши до наступні заяви. У цій програмі немає наступних заяв, тому програма закінчиться. Кожен раз через цикл називається ітерацією.

 

Існує кілька різних типів петель. Який з них використовувати, залежить як від того, що доступно на мові програмування, яку ви використовуєте, так і від того, що має найбільше значення для того, що ви намагаєтеся зробити. Наприклад, у наведеному вище прикладі ми могли б надрукувати значення count у кожній ітерації, наприклад:

 

print "How many times?"
count = input()
while count >= 1:
    print "Are we there yet?"
    print count
    count = count - 1

 

Запуск програми виглядатиме приблизно так (якщо користувач набрав “3” на запит):

 

How many times?
3                     (what the user types in)
Are we there yet?
3
Are we there yet?
2
Are we there yet?
1

 

Цифри 3, 2, 1 є значеннями відліку на кожній ітерації. Що робити, якщо, навпаки, просто хотіли порахувати вгору? Або що, якщо ви не хотіли змінювати кількість, тому що ви хотіли використовувати його пізніше в програмі? Можна використовувати цикл for, наприклад:

 

print "How many times?"
count = input()
for i = 1 to count:
    print "Are we there yet?"
    print count

 

(Примітка: поки мова, яку ми використовували для прикладів, була подібна до популярної мови програмування Python. Але Python не має for циклу. Наведений вище синтаксис заснований на мові Basic.)

 

Це for циклу означає: “Виконати вступні висловлювання один раз для кожного значення між 1 і підрахунком, і встановити змінну i на це значення”. Якщо користувач введе 3, ви побачите це:

 

How many times?
3
Are we there yet?
1
Are we there yet?
2
Are we there yet?
3

 

1, 2, 3 є значеннями i на кожній ітерації. Зауважте, що нам більше не потрібно зменшувати значення count у кожній ітерації. Комп’ютер автоматично збільшує i на 1 кожну ітерацію, доки він не досягне кількості. Фактично, кількість не змінилася після завершення циклу. Цей цикл:

 

for i = 1 to count:
    print i

 

по суті ідентична цій версії:

 

i = 1
while i <= count:
    print i
    i = i + 1

 

Цикл for зазвичай краще, ніж цикли while, коли ви хочете покрити діапазон чисел. Це коротше і легше читати. Проте цикл while є більш гнучким, оскільки ви виконуєте всю роботу самостійно. Ви можете збільшити я на 2 на кожній ітерації, щоб побачити тільки непарні числа, або ви могли б подвоїти значення i, щоб побачити всі можливості двох:

 

print "What is the maximum?"
maximum = input()
i = 1
while i <= maximum:
    print i
    i = i * 2

 

What is the maximum?
128
1
2
4
8
16
32
64
128

 

Ви не можете зробити for за допомогою простого циклу. До речі, в циклі for початкове і кінцеве значення (1 і count у нашому прикладі) можуть бути будь-якою парою чисел. Ви можете:

 

for i = 20 to 24:
    print i

 

для відображення значень 20, 21, 22, 23 і 24. Тут використовується змінна i, але може використовуватися будь-яка змінна. i – часто використовувана змінна для циклів for; воно означає індекс. Можна також використовувати ім’я змінної, що має більше сенсу у вашому конкретному контексті, наприклад:

 

for year = 1992 to 2004:
    print "The year is " + year

 

Іншим типом циклу є цикл foreach. Це схоже на цикл for за винятком того, що змінна не просто переходить через числовий діапазон, вона фактично встановлюється для кожного елемента в наборі чисел:

 

foreach year in [1992, 1996, 2000, 2004]:
    print "The " + year + " Olympic Games."

 

Це також збігається з англійським реченням: «Для кожного року у списку 1992, 1996, 2000, 2004 року надрукуйте цю заяву». (Зауважте: Python не має такого for циклу, за винятком слово for використовується замість foreach.)

 

Є кілька інших типів циклів, але вони зазвичай є варіаціями на вищезазначених трьох типах.

 

Розділ 9: Простий приклад

 

У цьому розділі ми будемо слідувати дуже простому прикладу, який використовує концепції, які ми дізналися до цих пір. Ми збираємося написати програму, яка обчислює відгук у ресторані.

 

Існує багато способів розробки та написання програми. Один із способів, який часто працює добре, це уявити когось, хто використовує програму, і описати, що це було б. Це має перевагу в тому, щоб програма була корисною після написання. (Це може здатися очевидним, що потрібно від програми, але ви будете здивовані, як багато програм закінчуються марними, тому що їхні дизайнери не думали про те, що вони хотіли б використовувати.)

 

Отже, ми уявляємо свого користувача, називаємо його Томом, в ресторані. Рахунок приходить, і він повинен записати чайові, і хоче використовувати програму для розрахунку чайових для нього. Тому, принаймні, програма повинна відобразити підказку для запису. Але чайові залежить від вартості векселя, тому в якийсь момент програма повинна надати цю інформацію. Це призводить до наступної взаємодії:

 

  • Програма запитує у Тома, яка вартість векселя.
  • Том вводить значення.
  • Програма відображає відгук.

 

Це називається випадок використання — фіктивна, але реалістична взаємодія між користувачем і програмою. Вони стають особливо корисними при розробці великих програм. Випадок використання для Microsoft Word може бути: “Користувач хоче додати зміст до свого документа.” Іноді після написання випадку використання стає очевидним, що користувачеві потрібно робити занадто багато роботи або розуміти занадто багато абстрактних понять. або виконувати занадто багато кроків для досягнення чогось простого. Це чудовий спосіб побачити світ з точки зору користувача.

 

Тепер ми хочемо бачити програму з точки зору комп’ютера. Давайте переформувати наведені вище кроки з точки зору програми:

 

  • Запитайте користувача, яка вартість рахунку.
  • Користувач дає нам вартість рахунку.
  • Відображення підказки для користувача.

 

Переведемо це в код:

 

print "What was the value of the bill?"
bill = input()
print tip

 

Перший рядок буде підказувати користувачеві, другий буде чекати, доки користувач не введе значення, а третій буде показувати чайові. Але пам’ятайте з глави про змінні, що змінна повинна бути встановлена, перш ніж вона може бути використана. У третьому рядку вище використовується змінна tip, але вона ніколи не встановлюється в програмі. Ми повинні дещо підрахувати кінчик. Додамо це до наших кроків:

 

  • Запитайте користувача, яка вартість рахунку.
  • Користувач дає нам вартість рахунку.
  • Розрахуйте пораду з рахунку.
  • Відображення підказки для користувача.

 

Як ми повинні перетворити цей новий третій крок у код? Ми знаємо, що хочемо встановити змінну порада. Тому ми знаємо, що будемо використовувати оператор призначення, тому ми отримали принаймні таке:

 

tip =

 

Тепер ми повинні з’ясувати, що поставити на праву сторону знаку рівності. Скажімо, ми хочемо, щоб чайові становили 15% від рахунку. Обчислення 15% чогось подібного до множення на 0,15. І ми хочемо 15% від рахунку. Отже, математика:

 

bill * 0.15

 

Це дає нам такий рядок:

 

tip = bill * 0.15

 

Пам’ятайте, що це робить: він витягує значення змінної рахунку з пам’яті, помножує це значення на 0,15 і зберігає продукт у пам’яті, пов’язуючи його з новою змінною tip. І вся програма виглядає так:

 

print "What was the value of the bill?"
bill = input()
tip = bill * 0.15
print tip

 

Спробуйте:

 

What was the value of the bill?
12.50
1.875

 

Зауважте, що користувач не вводить знак долара (або будь-яку валюту), і його вихід також не має. Комп’ютер має справу з номерами, і ви повинні йти (досить далеко), щоб зрозуміти, що ви маєте справу з грошима. (Microsoft Excel робить цей вигляд простим, але коли ви пишете власні програми, це не так.)

 

Зверніть увагу також на те, що хоча $ 1.87 правильно, комп’ютер друкує додаткові “5” пізніше. Точне значення становить 15% від $ 12,50. Ми не сказали комп’ютеру, щоб він об’їхався до найближчого копійки, так що це не так. Це нормально, користувач може зробити це в голові. (Це не дуже важко зробити, але ми не будемо відволікатися на це тут.) Давайте спробуємо інше значення для рахунку:

 

What was the value of the bill?
12.92
1.9379999999999999

 

Ой! $1,93 виглядає правильно, але що за все це сміття після? Комп’ютер означає “1.938”, але замість цього виводить значення, яке дуже близьке до цього. Причина досить складна, але в основному комп’ютер не працює в базі 10 (десяткові), як у людей, але замість цього працює в базі 2 (двійкова). У базі 2 деякі числа (наприклад, 12.92) важко уявити, як і в базовій 10, деякі числа (наприклад, повторення 3,333) важко уявити. Таким чином, цифри, які ми вважаємо, повинні бути легкими, як у випадку 1,938 у цьому випадку, виглядати неправильно, коли відображаються. Ми можемо це виправити шляхом округлення до найближчого копійку, але залишимо це в інший час.

 

Давайте замість цього додамо деякі функції до нашої програми. Том, наш уявний користувач, іноді отримує хороший сервіс і іноді отримує поганий сервіс. За хороший сервіс він хотів би переказати 20%, а за погану послугу — 15%. Тепер у нас є два випадки використання:

 

  • Програма запитує у Тома, яка вартість векселя.
  • Том вводить значення.
  • Програма запитує у Тома, як це було.
  • Том каже, що це було добре.
  • Програма відображає чайові (20% від рахунку).

 

і:

 

  • Програма запитує у Тома, яка вартість векселя.
  • Том вводить значення.
  • Програма запитує у Тома, як це було.
  • Том каже, що це було погано.
  • Програма відображає чайові (15% від рахунку).

 

З точки зору комп’ютера:

 

  • Запитайте користувача, яка вартість рахунку.
  • Користувач дає нам вартість рахунку.
  • Запитайте користувача, як це було.
  • Користувач відповідає добре чи погано.
  • Розрахуйте наконечник з рахунку та якість послуги.
  • Відображення підказки для користувача.

 

Давайте зробимо більш конкретні в цьому другому кроці:

 

  • Якщо сервіс був хорошим, розрахуйте його як 20% від рахунку; в іншому випадку розрахуйте чайові як 15% від суми рахунку.

 

Перші чотири рядки коду досить прості:

 

print "What was the value of the bill?"
bill = input()
print "How was the service?"
service = input()

 

Тепер ми хочемо розрахувати іншу пораду в залежності від якості послуги. Ми можемо використовувати оператор if:

 

if service == "good":
    tip = bill * 0.20
else:
    tip = bill * 0.15

 

Якщо це не має сенсу, перегляньте розділ про умови. Останній рядок так само, як і раніше:

 

print tip

 

Дозвольте спробувати круглий номер для рахунку, наприклад $10:

 

What was the value of the bill?
10
How was the service?
good
2.0

 

і:

 

What was the value of the bill?
10
How was the service?
bad
1.5

 

Зауважте, що значення не відображається, як для валюти (2.00 та 1.50). Знову ж таки, це тому, що комп’ютер просто має справу з номерами, а не з грошима.

 

Схоже, наша програма працює, і вона корисна. Про щось про програму, яка, однак, не ідеальна. У цьому if стверженні:

 

if service == "good":
    tip = bill * 0.20
else:
    tip = bill * 0.15

 

розрахунок проводиться у двох окремих місцях, причому одне число (відсоток) різне. Це те, що ми хотіли, але будь-коли ви бачите повторюваний код, подібний до цього, ви повинні задатися питанням, чи не слід знайти кращий спосіб написання програми. Повторний код означає, що якщо ви зміните один рядок, вам доведеться змінити інший. Розрахунок може стати більш складним, наприклад, зняття податку з рахунку до розрахунку чайових. (Деякі користувачі обчислюють 15% від проміжної суми до оподаткування.) Після цього ви отримаєте щось подібне, якщо ваш місцевий податок становить 8%:

 

if service == "good":
    tip = bill / 1.08 * 0.20
else:
    tip = bill / 1.08 * 0.15

 

У цьому простому прикладі це не так уже й погано, але ви можете собі уявити більш складну програму або розрахунок, де оновлювати обидві одиниці можна було б помилками. Ви можете змінити одного, а не іншого. Було б краще зробити цей розрахунок лише в одному місці. Наступний розділ покаже вам один спосіб зробити це (з функціями), але тут ми будемо використовувати інший. Давайте уявімо, що ви змушені мати лише вказані вище розрахунки в одному місці. Ну а розрахунок враховує відсоток, який відрізняється залежно від сервісу, тому чіткий відсоток не може бути частиною цього розрахунку. Схоже на хорошу можливість для змінної:

 

tip = bill * percentage

 

Тепер треба спершу встановити відсоткову змінну. Ось новий код розрахунку порад:

 

if service == "good":
    percentage = 0.20
else:
    percentage = 0.15
tip = bill * percentage

 

Давайте покроково розглянемо, що відбувається з цією новою версією. Значення службової змінної витягується з пам’яті і порівнюється з рядком “good”. Якщо вони рівні (тобто, якщо користувач ввів “хороший”), то змінна відсотка в пам’яті буде встановлена ​​на значення 0,20. В іншому випадку (якщо користувач вводить щось інше, наприклад, «погано»), відсоток змінних буде встановлено на значення 0,15. Потім, після цього, змінна поради буде встановлена ​​на продукт змінної рахунку (даної нам користувачем) і відсоткової змінної (яка тільки що була встановлена).

 

Тепер, якщо ви хочете змінити програму, щоб врахувати податок, змінитиметься лише один рядок:

 

if service == "good":
    percentage = 0.20
else:
    percentage = 0.15
tip = bill / 1.08 * percentage

 

Це менше можливостей для помилок, і коли ваша програма стає великою, вам потрібно якомога менше з цих можливостей. Процес, який ми пройшли, називається рефакторингом. Це переставляє код таким чином, що він функціонує однаково, але дає нам певну перевагу, в цьому випадку зменшення кількості вирівнювань, що розраховуються, у нашій програмі. Ось вся наша програма:

 

print "What was the value of the bill?"
bill = input()
print "How was the service?"
service = input()
if service == "good":
    percentage = 0.20
else:
    percentage = 0.15
tip = bill * percentage
print tip

 

Наша програма стає досить складною. Якщо ми повернемося до неї через три місяці, нам буде важко зрозуміти, що вона робить. Давайте запишемо в самій програмі деякі примітки, щоб пояснити майбутнім читачам коду (можливо, самих себе), що відбувається. Ми можемо зробити це з коментарями. Коментарі — це нотатки в коді, які є виключно на користь програміста. Комп’ютер повністю ігнорує їх. У нашій мові коментарі починаються з символу #, іноді вимовляється “фунт” або “хеш”. Це вся наша програма, з коментарями:

 

# Get the value of the bill from the user. This
# is the total amount, including tax, but without
# any currency symbol.
print "What was the value of the bill?"
bill = input()

# Find out how the service was. This should be
# the word "good" or "bad".  Any word other than
# "good" will be considered the same as "bad".
print "How was the service?"
service = input()

# Good service gets a 20% tip.  Bad service gets 15%.
if service == "good":
    percentage = 0.20
else:
    percentage = 0.15

# Calculate and display the tip.  The tip here is based
# on the whole bill, including tax.  XXX We could
# remove the tax first. Perhaps ask the user whether they
# want the tax included in the calculation?
tip = bill * percentage
print tip

 

Зверніть увагу, що коментарі не тільки пояснюють, що відбувається (“Розрахувати і відобразити чайові”), але також вказують на різні вимоги (“але без будь-якого символу валюти”) і тонкощі (“Будь-яке слово, крім” хорошого “буде вважатися те ж, що і “поганий” ”). Приємно розбити програму на логічні блоки, як це було зроблено вище. Дві лінії, які вимагають і отримують вартість векселя, йдуть разом. Вони повинні бути візуально згруповані, з порожнім рядком між ними і наступним блоком. (Пусті рядки ігноруються комп’ютером.)

 

Зверніть увагу на коментар, який починається з “XXX”. Це звичайна річ для написання коментарів, коли існує потенційна проблема або відкрите питання. Тут коментар вказує на те, що програму можна було б поліпшити, запитавши користувача, чи хотіли б вони видалити податок, перш ніж розраховувати чайові. Якщо ви коли-небудь шукаєте способи покращити свою програму, ви можете легко знайти “XXX” у текстовому редакторі.

 

Використовуйте коментарі агресивно. Корисно навіть писати коментарі, перш ніж писати код, або, як ви його пишете, а не як потім. Мій друг Дрю Ольбріх винайшов стиль програмування під назвою Extreme Commenting. Його коментарі дуже детально і детально. Схоже, що багато робіт, коли спочатку їх писали, але ви впевнені, що з радістю через шість місяців вам доведеться розуміти і модифікувати цей код.

 

Розділ 10: Функції

 

Давайте напишемо програму, щоб переконатися, що ви і ваш товариш сумісні. Ми попросимо ваш знак зодіаку, знак вашого партнера і подивимося, що астрологія пророкує про кожного з вас. (Ми залишимо за вами, щоб інтерпретувати результати.)

 

Давайте почнемо з вашого запиту:

 

print "What's your sign?"
your_sign = input()

 

Зверніть увагу, що змінна your_sign має символ підкреслення для розділення двох слів. До цих пір всі наші змінні були єдиним англійським словом, як собака, вік, кількість і чайові. У цьому випадку ми хочемо використовувати два слова, оскільки у нас буде одна змінна для вашого знака та одна для знака вашого партнера. Існує кілька різних способів назвати змінну, якщо ви хочете, щоб вона була більш ніж одним словом. Один з варіантів — запустити всі слова разом, як yoursign. Це було поширене у 1970-х роках, але його сьогодні не використовують багато, тому що його важко читати. Іншим варіантом є використання символу підкреслення, наприклад, your_sign. Підкреслення виглядає трохи схоже на простір, тому два слова виглядають так само, як коли б вони писалися англійською мовою. Третій варіант – запустити слова разом і набрати велике слово кожному слову, наприклад YourSign, або, можливо, скористатися великими буквами всіма словами, але першим, наприклад, yourSign. Капіталізація полегшує перегляд кожного слова. Такі мови, як Lisp, використовують дефіси, як і your-sign, але ми не можемо зробити це тут, тому що дефіс нашої мови використовується для віднімання, і виглядатиме так, як ви намагаєтеся відняти знак змінної your зі змінної sign. У жодному з сучасних мов ви не можете зробити очевидну річ, яка полягає у використанні простору, як your sign. Це тому, що простір вже використовується для відокремлення змінних від інших речей. Наприклад, якщо ви хочете надрукувати значення цієї змінної, напишіть:

 

print your_sign

 

Якщо ви могли б використовувати пробіли в іменах змін, це було б:

 

print your sign

 

Але що, якщо у вас є змінна, яка починається зі слова print, як, наприклад, змінна під назвою print count, яка зберігається, скільки разів ви хотіли щось надрукувати? Якщо ви хочете встановити цю змінну до 5, напишіть:

 

print count = 5

 

і комп’ютер буде дуже заплутаний, оскільки спочатку буде схоже, що ви хочете показати значення змінної “count”, а потім пізніше стане зрозуміло, що ви дійсно хочете встановити значення відліку друку до 5.  Мови розроблені таким чином, щоб мінімізувати кількість випадків, коли виникають угадування чи можлива плутанина, дизайнери мови не допускають пробілів. Підкреслення прекрасно працює, уявіть собі простір, коли ви його побачите. Комп’ютер побачить підкреслення, до якого він звертається так само, як і будь-який інший лист, тому він не буде плутати між:

 

print_count = 5

 

i:

 

print count

 

Так повернемося до нашої програми. Це виглядає так:

 

print "What's your sign?"
your_sign = input()

 

Тепер у нас є змінна, your_sign, яка зберігає ваш знак зодіаку як рядок. Ми можемо використовувати значення цієї змінної для відображення різних речей. Наприклад, для Овна:

 

if your_sign == "Aries":
   print "Assertive, impulsive, defensive"

 

Зіставляє змінну your_sign з рядком “Aries”. Якщо вони однакові, ми надрукуємо декілька прикметників. Якщо вони не збігаються (якщо ви не Овен), то ми нічого не робимо і рухаємося далі. Ми можемо написати цілу групу поспіль, щоб перевірити всі різні ознаки:

 

if your_sign == "Aries":
    print "Assertive, impulsive, defensive"
if your_sign == "Taurus":
    print "Resourceful, thorough, indulgent"
if your_sign == "Gemini":
    print "Logical, inquisitive, fast"
if your_sign == "Cancer":
    print "Protective, sensitive, clinging"
if your_sign == "Leo":
    print "Generous, proud, theatrical"
if your_sign == "Virgo":
    print "Practical, efficient, critical"
if your_sign == "Libra":
    print "Co-operative, fair, lazy"
if your_sign == "Scorpio":
    print "Passionate, sensitive, anxious"
if your_sign == "Sagittarius":
    print "Free, straightforward, careless"
if your_sign == "Capricorn":
    print "Prudent, cautious, suspicious"
if your_sign == "Aquarius":
    print "Democratic, unconventional, detached"
if your_sign == "Pisces":
    print "Imaginative, sensitive, distracted"

 

Давайте повторимо все це для вашого партнера, використовуючи замість цього змінну mate_sign і змінюючи запитання на першому рядку:

 

print "What's your mate's sign?"
mate_sign = input()
if mate_sign == "Aries":
    print "Assertive, impulsive, defensive"
if mate_sign == "Taurus":
    print "Resourceful, thorough, indulgent"
if mate_sign == "Gemini":
    print "Logical, inquisitive, fast"
if mate_sign == "Cancer":
    print "Protective, sensitive, clinging"
if mate_sign == "Leo":
    print "Generous, proud, theatrical"
if mate_sign == "Virgo":
    print "Practical, efficient, critical"
if mate_sign == "Libra":
    print "Co-operative, fair, lazy"
if mate_sign == "Scorpio":
    print "Passionate, sensitive, anxious"
if mate_sign == "Sagittarius":
    print "Free, straightforward, careless"
if mate_sign == "Capricorn":
    print "Prudent, cautious, suspicious"
if mate_sign == "Aquarius":
    print "Democratic, unconventional, detached"
if mate_sign == "Pisces":
    print "Imaginative, sensitive, distracted"

 

Ось так. Тепер ви можете запустити цю програму, і комп’ютер повідомить вам щось про вас і вашого партнера:

 

What's your sign?
Aquarius
Democratic, unconventional, detached
What's your mate's sign?
Scorpio
Passionate, sensitive, anxious

 

У цьому прикладі можна зробити висновок, що ви і ваш друг дуже сумісні. Під час тестування програм завжди потрібно намагатися не тільки ввести правильний вхід, але й ввести неправильний вхід. Дозвольте спробувати недійсний вхід, щоб дізнатися, як поводиться програма:

 

What's your sign?
Yogurt
What's your mate's sign?
Volvo

 

Добре, це не так вже й добре. Жодна з вищезгаданих тверджень if не відповідала, тому нічого не було надруковано ні для вашого знака, ні для знака вашого партнера. Це не дуже приємно. Повідомляємо користувачеві, що введений текст не є дійсним знаком. Це тривале if, якщо виписка буде робити трюк:

 

if your_sign != "Aries" and your_sign != "Taurus" and \
    your_sign != "Gemini" and your_sign != "Cancer" and \
    your_sign != "Leo" and your_sign != "Virgo" and \
    your_sign != "Libra" and your_sign != "Scorpio" and \
    your_sign != "Sagittarius" and your_sign != "Capricorn" and \
    your_sign != "Aquarius" and your_sign != "Pisces":

    print "That's not a valid sign."
    stop()

 

Є кілька нових речей, які можна пояснити в цьому рядку. Зазвичай ми пишемо, якщо такі if висловлювання:

 

if age == 30:

 

Ми також написали більш складні, наприклад:

 

if age >= 40 and age < 50:

 

Ви можете отримати все більш складні:

 

if (age >= 20 and age < 30) or (age >= 60 and age < 70):

 

Якщо б у вас було ще багато речей, щоб перевірити все відразу, лінія буде отримати дуже довго. Ви можете продовжувати додавати їх до тієї ж лінії, і комп’ютер буде приймати це, але у вашому текстовому редакторі буде важко керувати. Вам доведеться багато використовувати горизонтальну смугу прокручування, або текстовий редактор автоматично переносить текст на вас, що може не виглядати правильно. Ви можете поділити лінію самостійно. З цим останнім прикладом можна написати:

 

if (age >= 20 and age < 30) or
   (age >= 60 and age < 70):

 

Це виглядає красиво і акуратно, тому що дві пари дужок в рядку. Але це може заплутати комп’ютер, оскільки комп’ютер очікує, що один рядок тексту буде одним висловом. Таким чином, ви явно вказуєте, що вищезазначені два рядки повинні розглядатися як єдиний рядок, як якщо б ви написали їх усі на одному рядку. Це зроблено з використанням зворотної риски в кінці першого рядка:

 

if (age >= 20 and age < 30) or \
   (age >= 60 and age < 70):

 

Уявіть, що зворотний слеш означає: «Ігноруйте цей кінець рядка, прикиньтеся, що наступний рядок продовжується прямо на цій лінії». Це пояснює п’ять зворотких косих ліінй у нашому довгому виразі if вище: вони роблять усю шестизначну if лінію виглядати, наче одна лінія на комп’ютері, що вам і потрібно з тих пір, як if ствердження мусять бути на одному рядку.

 

Далі, давайте подивимося, що робить логіка. Порівнюючи змінну your_sign з рядком “Овен”, щоб побачити, чи вони рівні. Якщо вони не є, а також your_sign не дорівнює “Taurus”, а також не дорівнює “Gemini”, то він друкує повідомлення. Пам’ятайте, що! = Означає “не дорівнює”. Давайте «граємо комп’ютер», вважаючи, що your_sign є рядком «Йогурт». Комп’ютер побачить перше порівняння, подивиться на значення your_sign, дізнається, що це “Йогурт”, і порівняйте його з “Овен”:

 

if "Yogurt" != "Aries" and ...

 

Що це, безумовно, вірно, рядок “Йогурт” і “Овен” різні. Тоді це зробить те ж саме з наступним знаком, знову знайде, що «Йогурт» не дорівнює «Таурусу» і так далі. Оскільки всі дванадцять порівнянь будуть успішними, повідомлення буде написано користувачеві. Наступний рядок:

 

stop()

 

Це повідомляє комп’ютеру припинити роботу програми. Ми не хочемо продовжувати і просити про знак матері. У більш красивій програмі ми б не зупинилися, ми б повернулися назад і запитали ваш знак знову, але ми не додамо цього ускладнення.

 

Якщо знак є дійсним, скажіть “Терези”, то це одне порівняння буде невдалим:

 

... and your_sign != "Libra" and ...

 

Це перетворюється на:

 

... and "Libra" != "Libra" and ...

 

але це не так, “Libra” не є рівною з “Libra”. Отже, вся операція if, якщо вона буде помилковою, повідомлення не буде надруковано, і програма не зупиниться. Пам’ятайте, що якщо у вас є купа речей, розділених and, вони повинні бути вірними для того, щоб if досяг успіху. Якщо ви не знайомі з правилами логіки, перегляньте вищезгаданий if випадок, якщо це буде зроблено обережно, доки це не матиме сенсу.

 

Повернутися до нашої програми. Ми одразу після цього отримаємо знак від користувача:

 

print "What's your sign?"
your_sign = input()
if your_sign != "Aries" and your_sign != "Taurus" and \
    your_sign != "Gemini" and your_sign != "Cancer" and \
    your_sign != "Leo" and your_sign != "Virgo" and \
    your_sign != "Libra" and your_sign != "Scorpio" and \
    your_sign != "Sagittarius" and your_sign != "Capricorn" and \
    your_sign != "Aquarius" and your_sign != "Pisces":

    print "That's not a valid sign."
    stop()
if your_sign == "Aries":
    print "Assertive, impulsive, defensive"
...

 

Чудово, тепер наша програма поводиться трохи приємніше, коли ви надаєте недійсний ввід:

 

What's your sign?
Sweden
That's not a valid sign.

 

Звичайно, не забудьте додати це для знака партнера надто пізніше в програмі:

 

...
print "What's your mate's sign?"
mate_sign = input()
if mate_sign != "Aries" and mate_sign != "Taurus" and \
    mate_sign != "Gemini" and mate_sign != "Cancer" and \
    mate_sign != "Leo" and mate_sign != "Virgo" and \
    mate_sign != "Libra" and mate_sign != "Scorpio" and \
    mate_sign != "Sagittarius" and mate_sign != "Capricorn" and \
    mate_sign != "Aquarius" and mate_sign != "Pisces":

    print "That's not a valid sign."
    stop()
if mate_sign == "Aries":
    print "Assertive, impulsive, defensive"

 

І все ж щось треба турбувати нас про це рішення. Важливою метою цієї книги є навчити вас писати хороший код, а не тільки функціональний код. І гарний код гарний. Вище, якщо заява не красива. Я не маю на увазі, що це виглядає потворно, хоча це і є. Я маю на увазі, що ми порівняємо змінну your_sign з кожним знаком двічі. Один раз, щоб побачити, чи дійсно, і знову пізніше роздрукувати відповідний опис. Це повинно викликати в наших головах попереджувальні дзвони. Потрібно мати кращий спосіб написати це так, щоб нам потрібно було лише один раз порівняти його. Врешті-решт, якщо нічого не відображається, знак недійсний. Ми повинні мати можливість використовувати це для визначення валідності знака.

 

У попередньому розділі ми використали оператор else, щоб зробити щось за замовчуванням, у випадку, якщо оператор if не зробив нічого:

 

if age < 25:
    print "You're young."
else:
    print "You're mature!"

 

Якщо було лише один знак зодіака, ми могли б використовувати цю ж техніку тут, щоб вирішити нашу проблему:

 

if your_sign == "Aries":
    print "Assertive, impulsive, defensive"
else:
    print "That's not a valid sign."
    stop()

 

Якби у нас було два знаки, ми могли б написати:

 

if your_sign == "Aries":
    print "Assertive, impulsive, defensive"
else:
    if your_sign == "Taurus":
        print "Resourceful, thorough, indulgent"
    else:
        print "That's not a valid sign."
        stop()

 

(Зупиніться і працюйте через логіку цього, якщо не зрозуміло, що відбувається.) Три знаки:

 

if your_sign == "Aries":
    print "Assertive, impulsive, defensive"
else:
    if your_sign == "Taurus":
        print "Resourceful, thorough, indulgent"
    else:
        if your_sign == "Gemini":
            print "Logical, inquisitive, fast"
        else:
            print "That's not a valid sign."
            stop()

 

Це буде працювати дуже красиво, але ми продовжуємо відступати праворуч від кожного знаку. З дванадцятьма знаками ми будемо йти до правого боку екрана. Це загальна проблема, тому мова дає твердження, яке називається “інакше, якщо”, написане elif для короткого. Ці три знаки будуть написані так:

 

if your_sign == "Aries":
    print "Assertive, impulsive, defensive"
elif your_sign == "Taurus":
    print "Resourceful, thorough, indulgent"
elif your_sign == "Gemini":
    print "Logical, inquisitive, fast"
else:
    print "That's not a valid sign."
    stop()

 

Ви можете побачити, як це буде поширюватися на дванадцять знаків. Насправді ми могли б взяти наші оригінальні дванадцять if, якщо твердження, написати “ел” перед усіма, крім першого, і додати наш else пункт в кінці, щоб зловити помилки. Що ж станеться, то це те, що перша if, якщо буде перевірена. Якщо це вдасться, перша заява про друк відбудеться, і програма буде продовжуватися після всього розділу. Пам’ятайте, що elif означає “інакше, якщо”, так що, якщо if вдалося, немає необхідності керувати частиною “інакше”, і ми пропускаємо решту.

 

Але якщо перший if не вдалося, то ми перевіряємо другий, то третій, і так далі, поки не знайдемо той, який відповідає. Якщо ніхто не збігається, ми покажемо повідомлення про помилку. Давайте модифікуємо все це і знову пам’ятаємо, щоб оновити розділ mate’s. Ось досі вся програма:

 

print "What's your sign?"
your_sign = input()
if your_sign == "Aries":
    print "Assertive, impulsive, defensive"
elif your_sign == "Taurus":
    print "Resourceful, thorough, indulgent"
elif your_sign == "Gemini":
    print "Logical, inquisitive, fast"
elif your_sign == "Cancer":
    print "Protective, sensitive, clinging"
elif your_sign == "Leo":
    print "Generous, proud, theatrical"
elif your_sign == "Virgo":
    print "Practical, efficient, critical"
elif your_sign == "Libra":
    print "Co-operative, fair, lazy"
elif your_sign == "Scorpio":
    print "Passionate, sensitive, anxious"
elif your_sign == "Sagittarius":
    print "Free, straightforward, careless"
elif your_sign == "Capricorn":
    print "Prudent, cautious, suspicious"
elif your_sign == "Aquarius":
    print "Democratic, unconventional, detached"
elif your_sign == "Pisces":
    print "Imaginative, sensitive, distracted"
else:
    print "That's not a valid sign."
    stop()
print "What's your mate's sign?"
mate_sign = input()
if mate_sign == "Aries":
    print "Assertive, impulsive, defensive"
elif mate_sign == "Taurus":
    print "Resourceful, thorough, indulgent"
elif mate_sign == "Gemini":
    print "Logical, inquisitive, fast"
elif mate_sign == "Cancer":
    print "Protective, sensitive, clinging"
elif mate_sign == "Leo":
    print "Generous, proud, theatrical"
elif mate_sign == "Virgo":
    print "Practical, efficient, critical"
elif mate_sign == "Libra":
    print "Co-operative, fair, lazy"
elif mate_sign == "Scorpio":
    print "Passionate, sensitive, anxious"
elif mate_sign == "Sagittarius":
    print "Free, straightforward, careless"
elif mate_sign == "Capricorn":
    print "Prudent, cautious, suspicious"
elif mate_sign == "Aquarius":
    print "Democratic, unconventional, detached"
elif mate_sign == "Pisces":
    print "Imaginative, sensitive, distracted"
else:
    print "That's not a valid sign."
    stop()

 

Оновлення цієї другої частини дратує. Кожного разу, коли ми виходимо з поліпшенням коду для вашого знака, ми повинні зробити це для знака партнера. Код виглядає практично ідентичним, за винятком змінної your_sign замінюється на mate_sign. Що ще гірше, ви ризикуєте вводити помилки щоразу, коли ви змінюєте інший код. А що, якщо ви показували знаки 15 осіб? Чи потрібно було б змінити 15 складних частин коду? Знову ж таки, слід погасити попередження. Не дуже приємно мати дублювання коду. Для цього має бути більш елегантний спосіб. Нарешті, ми переходимо до цієї функції, функції.

 

Функція є частиною коду, яку ви пишете один раз, але використовуєте в багатьох місцях у вашій програмі. У нашій астрологічній програмі ми хотіли б використовувати всю послідовність if двічі, але для зручності ми хотіли б написати її лише один раз. Почнемо з більш простого прикладу. Цей приклад не ілюструє переваги функцій, тільки їх синтаксис і форму. Потім ми можемо повернутися до нашого більш складного прикладу вище. Давайте напишемо програму для відображення імені нашої собаки тричі:

 

print "My dog's name is Bort."
print "My dog's name is Bort."
print "My dog's name is Bort."

 

Це дублювання коду, тому давайте поставимо цей код у функцію. Ми робимо це так:

 

def display_the_name_of_my_dog():
    print "My dog's name is Bort."

 

Def є коротким для “define (функція)”. Ми повідомляємо комп’ютеру, що ми збираємося описати, що має виконувати ця функція. Далі йде назва функції. Це може бути що завгодно, але ви повинні описати, що робить функція. (Ім’я функції трохи нагадує назву змінної, за винятком того, що функція носить ім’я того, що вона робить, тоді як змінна називається після того, що вона зберігає.) Тут ми вибрали “display_the_name_of_my_dog”. Необхідно встановити набір дужок після імені; Я буду обговорювати їх пізніше. Після цієї лінії надходить те, що називається тілом функції. Саме так виконує функція, код, який ви хочете запустити під час використання функції. Тіло має відступ, подібно до частини оператора if, що виконується, коли if виконано.

 

Коли ми хочемо використовувати функцію, запишемо її ім’я, за яким йдуть дужки:

 

display_the_name_of_my_dog()

 

Насправді нам потрібен цей рядок три рази, оскільки ми хотіли, щоб ім’я відображалося тричі:

 

display_the_name_of_my_dog()
display_the_name_of_my_dog()
display_the_name_of_my_dog()

 

Тут дужки збігаються з тими у визначенні функції, і я знову роз’яснить їх пізніше. Коли ми використовуємо таку функцію, ми говоримо, що ми викликаємо функцію. Це схоже на те, щоб подзвонити комусь і попросити їх щось зробити. Раніше ми бачили кілька викликів функцій. Ми бачили функцію введення:

 

age = input()

 

і функцію зупинки. Обидва зробили щось, хоча вам не довелося їх визначати, вони прийшли з вбудованою мовою. Тут ми визначаємо нашу власну функцію. Кожен раз, коли ви викликаєте функцію, комп’ютер шукає функцію за назвою, знаходить тіло, яке ви його надали, і запускає оператори в тілі. Тіло може мати багато операторів, і все буде виконуватися кожного разу, коли функція буде викликана. Це трохи схоже на те, щоб у великій програмі створити міні-програму.

 

Функції корисні, оскільки вони зменшують копіювання коду. Ви можете написати щось один раз замість багаторазового. Але якщо б це було їх єдиною перевагою, вони не були б такою корисною. Наприклад, ми не зможемо використовувати їх для нашої астрологічної програми, оскільки код не є ідентичним: ім’я змінної відрізняється. Функції стають дійсно корисними, коли вони мають параметр.

 

Параметр функції — це змінна, яку ви надаєте функції, коли вона починається. Зазвичай в програмі потрібно визначити кожну змінну перед її використанням. Параметр є змінною, яка вже встановлена, коли функція починається. Ви надаєте його, коли ви викликаєте функцію. У нашому спрощеному прикладі скажемо, що назва нашої собаки не завжди була “Bort”, і ми хотіли, щоб ця функція відображала різноманітні імена. Ми б змінили визначення, щоб виглядати так:

 

def display_the_name_of_my_dog(name):
    print "My dog's name is " + name + "."

 

Для цього потрібні ці дужки. Ось де йдуть параметри. Коли ви викликаєте функцію, ви надасте значення імені параметра:

 

display_the_name_of_my_dog("Bort")
display_the_name_of_my_dog("Milou")
display_the_name_of_my_dog("Rocky")

 

Давайте уважно подивимося, що відбувається тут. У визначенні вам повідомляється, що ви хочете визначити функцію display_the_name_of_my_dog, яка приймає один параметр з назвою name. У тілі функції ви можете використовувати ім’я як змінну, в цьому випадку використовувати її разом з деяким текстом. (Пам’ятайте, що + з рядками — конкатенація, або відображення рядків один за одним.)

 

Коли ми вперше викликаємо цю функцію, ми надаємо рядок “Bort”. Це викликає функцію і встановлює ім’я змінної на рядок «Bort», але тільки для цього виклику. Коли функція завершена, ми продовжуємо нашу програму на другому рядку, знову викликаючи функцію, але з іменем “Milou”. Це відбувається втретє з «Роккі». Коли ми запускаємо нашу програму, ми бачимо це:

 

My dog's name is Bort.
My dog's name is Milou.
My dog's name is Rocky.

 

Функція може мати будь-яку кількість аргументів, розділених комами:

 

def display_the_name_of_my_pet(pet, name):
    print "My " + pet + "'s name is " + name + "."

display_the_name_of_my_pet("dog", "Bort")
display_the_name_of_my_pet("cat", "Milou")
display_the_name_of_my_pet("mouse", "Rocky")

 

Це відображатиметься:

 

My dog's name is Bort.
My cat's name is Milou.
My mouse's name is Rocky.

 

Зверніть увагу, що коли ви викликаєте функцію, ви повинні надати стільки параметрів (розділених комами), скільки є у визначенні. Також зверніть увагу, що ви повинні визначити функцію, перш ніж викликати її. Це схоже на встановлення змінної перед її використанням.

 

Так повернемося знову до нашої астрологічної програми. Як ми використовуємо функцію, щоб уникнути необхідності оновлення обох частин програми? Давайте розділити розділ if у функцію, наприклад:

 

def display_sign_information(sign):
    if sign == "Aries":
        print "Assertive, impulsive, defensive"
    elif sign == "Taurus":
        print "Resourceful, thorough, indulgent"
    elif sign == "Gemini":
        print "Logical, inquisitive, fast"
    elif sign == "Cancer":
        print "Protective, sensitive, clinging"
    elif sign == "Leo":
        print "Generous, proud, theatrical"
    elif sign == "Virgo":
        print "Practical, efficient, critical"
    elif sign == "Libra":
        print "Co-operative, fair, lazy"
    elif sign == "Scorpio":
        print "Passionate, sensitive, anxious"
    elif sign == "Sagittarius":
        print "Free, straightforward, careless"
    elif sign == "Capricorn":
        print "Prudent, cautious, suspicious"
    elif sign == "Aquarius":
        print "Democratic, unconventional, detached"
    elif sign == "Pisces":
        print "Imaginative, sensitive, distracted"
    else:
        print "That's not a valid sign."
        stop()

 

Ми використовували загальний знак назви для параметра замість your_sign або mate_sign, оскільки ми не знаємо, чиїм він є. Це лише загальна функція для відображення інформації для будь-якого знаку.

 

Наша головна програма просто набагато простіше:

 

print "What's your sign?"
your_sign = input()
display_sign_information(your_sign)

print "What's your mate's sign?"
mate_sign = input()
display_sign_information(mate_sign)

 

Це весь if розділ може бути написаний тільки один раз зараз, але використовується двічі в нашій програмі. Є й інші переваги. Наприклад, розділ if тепер має ім’я (display_sign_information), що допомагає пояснити, що він робить. Хтось читає код, може бачити назву функції і швидко розуміти, що він робить, а не читати код. Ще однією перевагою є те, що наша головна програма набагато коротша і зрозуміліша. Ми можемо подивитися на ці шість ліній і швидко зрозуміти, що вона робить. Перш ніж нам довелося прочитати більше 58 рядків, щоб отримати високий рівень огляду програми.

 

Давайте зробимо результат цієї програми трохи кращим. Замість того, щоб просто викинути деякі прикметники, ми можемо написати краще речення, наприклад:

 

Scorpio people are passionate, sensitive, anxious.

 

Ми могли б змінити всі оператори друку. Доброю новиною є те, що, поставивши наш код у функцію, нам потрібно було б змінити 12 рядків замість 24. Погана новина у тому, що повторні твердення, як ці, вимагають лише одну єдину лінію змін, не дванадцять. Дванадцять надрукованих тверджень показують, що ми не пишемо наш код у дуже елегантний або зручний спосіб. Ми можемо рефакторувати код, щоб помістити прикметники до змінної, наприклад:

 

def display_sign_information(sign):
    if sign == "Aries":
        adjectives = "assertive, impulsive, defensive"
    elif sign == "Taurus":
        adjectives = "resourceful, thorough, indulgent"
    elif sign == "Gemini":
        adjectives = "logical, inquisitive, fast"
    elif sign == "Cancer":
        adjectives = "protective, sensitive, clinging"
    elif sign == "Leo":
        adjectives = "generous, proud, theatrical"
    elif sign == "Virgo":
        adjectives = "practical, efficient, critical"
    elif sign == "Libra":
        adjectives = "co-operative, fair, lazy"
    elif sign == "Scorpio":
        adjectives = "passionate, sensitive, anxious"
    elif sign == "Sagittarius":
        adjectives = "free, straightforward, careless"
    elif sign == "Capricorn":
        adjectives = "prudent, cautious, suspicious"
    elif sign == "Aquarius":
        adjectives = "democratic, unconventional, detached"
    elif sign == "Pisces":
        adjectives = "imaginative, sensitive, distracted"
    else:
        print "That's not a valid sign."
        stop()
    print adjectives

 

Тут я помістив прикметники в змінну (так називаються прикметники), зробив першу букву кожного рядка нижнього регістру (щоб його можна було використовувати у реченні), і перемістив дванадцять друкованих виписок до одного в кінці. Таким чином, рефакторуючи мій код, я можу легко змінити відображення, змінивши цей останній рядок:

 

    print sign + " people are " + adjectives + "."

 

Якщо я пізніше захочу змінити його знову, я можу зробити це легко. Насправді, можливо, головна програма хоче контролювати те, що показувати. Ще краще написати:

 

You are democratic, unconventional, detached.

 

і:

 

Your mate is passionate, sensitive, anxious.

 

Існує два способи зробити це. Один із варіантів полягає в тому, щоб додати до нашої функції інший параметр, який визначає, як висловити фразу:

 

def display_sign_information(sign, prefix):
    if sign == "Aries":
        adjectives = "assertive, impulsive, defensive"
    elif sign == "Taurus":
        adjectives = "resourceful, thorough, indulgent"
    elif sign == "Gemini":
        adjectives = "logical, inquisitive, fast"
    elif sign == "Cancer":
        adjectives = "protective, sensitive, clinging"
    elif sign == "Leo":
        adjectives = "generous, proud, theatrical"
    elif sign == "Virgo":
        adjectives = "practical, efficient, critical"
    elif sign == "Libra":
        adjectives = "co-operative, fair, lazy"
    elif sign == "Scorpio":
        adjectives = "passionate, sensitive, anxious"
    elif sign == "Sagittarius":
        adjectives = "free, straightforward, careless"
    elif sign == "Capricorn":
        adjectives = "prudent, cautious, suspicious"
    elif sign == "Aquarius":
        adjectives = "democratic, unconventional, detached"
    elif sign == "Pisces":
        adjectives = "imaginative, sensitive, distracted"
    else:
        print "That's not a valid sign."
        stop()
    print prefix + " " + adjectives + "."

 

Наша головна програма виглядатиме так:

 

print "What's your sign?"
your_sign = input()
display_sign_information(your_sign, "You are")

print "What's your mate's sign?"
mate_sign = input()
display_sign_information(mate_sign, "Your mate is")

 

Але що, якщо головна програма хоче зробити щось інше з прикметниками? Можливо, він хоче відображати обидва набори разом, наприклад:

 

You are democratic, unconventional, detached; they are passionate, sensitive, anxious.

 

Це було б незручно з функцією, як написано вище. Насправді функція має досить обмежену корисність, оскільки робить припущення про те, як головна програма бажає відображення результатів. Було б більш корисним, якби вона просто розповіла головній програмі, що таке прикметники, і нехай програма робить з ними все, що захоче. Ми робимо це із зворотним значенням. Ось як це працює, знову ж таки з першим спрощеним прикладом:

 

def get_square_of_number(x):
     return x * x

width = input()
area = get_square_of_number(width)
print area

 

Ми визначили функцію під назвою get_square_of_number, яка приймає один параметр x. Він обчислює квадрат x (шляхом множення його на себе) і повертає це значення до головної програми, використовуючи оператор return. Це обернений процес параметра. За допомогою параметра головна програма посилає значення функції; з оператором return функція посилає значення назад до головної програми. У основній програмі повертається значення, яке викликається функцією. У наведеному вище прикладі була викликана функція введення і те, що введено користувачем, відображається на місці “input ()”, що означає, що вона призначена змінної ширини. Тоді значення ширини передається до функції get_square_of_number як параметр (хоча всередині функції це у змінній x). Повернене значення (квадрат x), потім відображається в основній програмі і присвоюється області, яка потім відображається.

 

У нашій астрологічній програмі ми можемо повернути функції прикметників замість їх друку:

 

def get_sign_information(sign):
    if sign == "Aries":
        adjectives = "assertive, impulsive, defensive"
    elif sign == "Taurus":
        adjectives = "resourceful, thorough, indulgent"
    elif sign == "Gemini":
        adjectives = "logical, inquisitive, fast"
    elif sign == "Cancer":
        adjectives = "protective, sensitive, clinging"
    elif sign == "Leo":
        adjectives = "generous, proud, theatrical"
    elif sign == "Virgo":
        adjectives = "practical, efficient, critical"
    elif sign == "Libra":
        adjectives = "co-operative, fair, lazy"
    elif sign == "Scorpio":
        adjectives = "passionate, sensitive, anxious"
    elif sign == "Sagittarius":
        adjectives = "free, straightforward, careless"
    elif sign == "Capricorn":
        adjectives = "prudent, cautious, suspicious"
    elif sign == "Aquarius":
        adjectives = "democratic, unconventional, detached"
    elif sign == "Pisces":
        adjectives = "imaginative, sensitive, distracted"
    else:
        print "That's not a valid sign."
        stop()

    return adjectives

 

Ми перейменували цю функцію, щоб пояснити, що функція використовується для отримання прикметників, пов’язаних зі знаком. Зауважимо, що наше використання змінної прикметників раніше зробило цю зміну дуже легкою. Ми змінили лише перший і останній рядок функції. Основна програма виглядає так:

 

print "What's your sign?"
your_sign = input()
your_adjectives = get_sign_information(your_sign)
print "You are " + your_adjectives + "."

print "What's your mate's sign?"
mate_sign = input()
mate_adjectives = get_sign_information(mate_sign)
print "Your mate is " + mate_adjectives + "."

 

Це набагато гнучкіше. Замість цих двох друкованих заяв ми можемо мати один такий:

 

print "You are " + your_adjectives + "; they are " + mate_adjectives + "."

 

Але ми цього не зробимо. Замість цього ми знову помітимо, що ці вісім рядків містять багато дублювань. Перші чотири рядки практично ідентичні чотирьох. Давайте поставимо їх у функцію:

 

def display_sign_information(whose, prefix):
    print "What's " + whose + " sign?"
    sign = input()
    adjectives = get_sign_information(sign)
    print prefix + " " + adjectives + "."

 

Зверніть увагу, що функції можуть викликати інші функції. Зараз головна програма:

 

display_sign_information("your", "You are")
display_sign_information("your mate's", "Your mate is")

 

Дублювання коду мінімізовано! Тепер ми могли б запитати про будь-яку кількість людей, додавши лише одну лінію до нашої основної програми. Це набагато краще, ніж дублювати 29 рядків (і потрібно змінювати їх кожного разу, коли ви отримуєте поліпшення). Структура нашої програми на високому рівні теж зараз очевидна: ми запитаємо про ознаки двох людей. Процес запиту також очевидний: ми задаємо питання, отримуємо відповідь, отримуємо прикметники на основі цієї відповіді і друкуємо ці прикметники. Наш код прекрасний!

 

Функції розбивають програми на невеликі шматки. Вони корисні, тому що вони зменшують копіювання коду, але вони також допомагають нам думати про те, що робить програма, як вона структурована і які її важливі процеси. Ось наша остаточна програма:

 

def get_sign_information(sign):
    if sign == "Aries":
        adjectives = "assertive, impulsive, defensive"
    elif sign == "Taurus":
        adjectives = "resourceful, thorough, indulgent"
    elif sign == "Gemini":
        adjectives = "logical, inquisitive, fast"
    elif sign == "Cancer":
        adjectives = "protective, sensitive, clinging"
    elif sign == "Leo":
        adjectives = "generous, proud, theatrical"
    elif sign == "Virgo":
        adjectives = "practical, efficient, critical"
    elif sign == "Libra":
        adjectives = "co-operative, fair, lazy"
    elif sign == "Scorpio":
        adjectives = "passionate, sensitive, anxious"
    elif sign == "Sagittarius":
        adjectives = "free, straightforward, careless"
    elif sign == "Capricorn":
        adjectives = "prudent, cautious, suspicious"
    elif sign == "Aquarius":
        adjectives = "democratic, unconventional, detached"
    elif sign == "Pisces":
        adjectives = "imaginative, sensitive, distracted"
    else:
        print "That's not a valid sign."
        stop()

    return adjectives

def display_sign_information(whose, prefix):
    print "What's " + whose + " sign?"
    sign = input()
    adjectives = get_sign_information(sign)
    print prefix + " " + adjectives + "."

display_sign_information("your", "You are")
display_sign_information("your mate's", "Your mate is")

 

Порівняйте це з програмою, яку ми мали до того, як ми розбили її на функції:

 

print "What's your sign?"
your_sign = input()
if your_sign == "Aries":
    print "Assertive, impulsive, defensive"
elif your_sign == "Taurus":
    print "Resourceful, thorough, indulgent"
elif your_sign == "Gemini":
    print "Logical, inquisitive, fast"
elif your_sign == "Cancer":
    print "Protective, sensitive, clinging"
elif your_sign == "Leo":
    print "Generous, proud, theatrical"
elif your_sign == "Virgo":
    print "Practical, efficient, critical"
elif your_sign == "Libra":
    print "Co-operative, fair, lazy"
elif your_sign == "Scorpio":
    print "Passionate, sensitive, anxious"
elif your_sign == "Sagittarius":
    print "Free, straightforward, careless"
elif your_sign == "Capricorn":
    print "Prudent, cautious, suspicious"
elif your_sign == "Aquarius":
    print "Democratic, unconventional, detached"
elif your_sign == "Pisces":
    print "Imaginative, sensitive, distracted"
else:
    print "That's not a valid sign."
    stop()
print "What's your mate's sign?"
mate_sign = input()
if mate_sign == "Aries":
    print "Assertive, impulsive, defensive"
elif mate_sign == "Taurus":
    print "Resourceful, thorough, indulgent"
elif mate_sign == "Gemini":
    print "Logical, inquisitive, fast"
elif mate_sign == "Cancer":
    print "Protective, sensitive, clinging"
elif mate_sign == "Leo":
    print "Generous, proud, theatrical"
elif mate_sign == "Virgo":
    print "Practical, efficient, critical"
elif mate_sign == "Libra":
    print "Co-operative, fair, lazy"
elif mate_sign == "Scorpio":
    print "Passionate, sensitive, anxious"
elif mate_sign == "Sagittarius":
    print "Free, straightforward, careless"
elif mate_sign == "Capricorn":
    print "Prudent, cautious, suspicious"
elif mate_sign == "Aquarius":
    print "Democratic, unconventional, detached"
elif mate_sign == "Pisces":
    print "Imaginative, sensitive, distracted"
else:
    print "That's not a valid sign."
    stop()

 

Розділ 11: Масиви

 

У останньому розділі ми мали довгу послідовність коду, яка виглядала так:

 

if sign == "Aries":
    adjectives = "assertive, impulsive, defensive"
elif sign == "Taurus":
    adjectives = "resourceful, thorough, indulgent"
elif sign == "Gemini":
    adjectives = "logical, inquisitive, fast"
elif sign == "Cancer":
    ...

 

Повна послідовність if / else багатогранна, повторювана і утомлива для написання. Це має означати, що комп’ютер повинен робити це замість вас. (Комп’ютери перевищують при повторних і нудних завданнях.) Нам тут потрібний масив. Можна використовувати array для об’єднання однієї речі з іншою. У цьому випадку ми хочемо пов’язати рядок «Овен» з рядком «напористий, імпульсивний, захисний». Ми також хочемо пов’язати рядок “Taurus” з рядком “винахідливий, ретельний, відданий, терплячий, поблажливий”. І так далі для інших 10 знаків.

 

Як тільки ви зробите 12 асоціацій, ви можете просто запитати у комп’ютера те, що пов’язано з “Gemini”, і ви отримаєте прикметники для нього. Масив є змінною. Поки що ми розглядали змінні, які зберігали числа (наприклад, 25) і рядки (наприклад, “Йогурт”). Можна також зберігати масив у змінній. Скажімо, наш масив називається знаками, і ми хочемо повідомити комп’ютер про асоціацію Gemini. Ми напишемо це так:

 

signs["Gemini"] = "logical, inquisitive, fast"

 

Справді, цей синтаксис виглядає дивно, але він має сенс після того, як ви почнете використовувати матриці більше. Тут ми говоримо, що в масиві, що називається знаками, ми хочемо пов’язати рядок “Близнюки” з рядком “логічний, допитливий, швидкий”. Це трохи, як якщо б ми створили спеціальну змінну:

 

signs_gemini = "logical, inquisitive, fast"

 

Це була б звичайна змінна з назвою adjective_gemini, яка мала значення «логічний, допитливий, швидкий». Перевага використання масиву полягає в тому, що пізніше, коли ви хочете шукати прикметники для знака, ви можете зробити це:

 

print "What's your sign?"
sign = input()
adjectives = signs[sign]
print adjectives

 

Ви отримуєте рядок від користувача, використовуючи функцію “input ()” і вкладаєте результати в знак змінної. Потім ви шукаєте рядок, пов’язаний з цим рядком у знаках масиву, і покладіть результат у прикметники змінних.

 

Це дуже тонке, що відбувається тут, тому ми перейдемо до цього ще раз. Зазвичай, коли ви зберігаєте рядок у змінну, наприклад:

 

signs_gemini = "logical, inquisitive, fast"

 

Ви можете отримати значення лише за допомогою посилання на змінну за назвою, наприклад:

 

print signs_gemini

 

Ім’я змінної встановлюється в камені під час написання програми. Якщо користувач не є Близнюком, то цей документ не відображатиме правильну інформацію. Ось чому нам потрібна така довга послідовність операторів if / else: щоб переконатися, що ми показуємо правильну змінну.

 

Масиви потрібні лише для однієї змінної. Замість того, щоб асоціювати прикметники зі змінною під назвою signs_gemini, ми пов’язуємо їх з рядком “Gemini” у знаках масиву. Той факт, що ми використовуємо рядок із вмістом «Близнюки», є важливою частиною. Оскільки ми встановлюємо асоціацію з рядком, це означає, що ми можемо отримати значення, використовуючи рядок, рядок, який ми отримуємо від користувача. Так що немає більше, якщо / ще заяви.

 

Можливо, нам слід написати невелику програму для ілюстрації того, як працюють масиви. Давайте напишемо програму, яка, враховуючи рок, папір або ножиці, повідомляє нам, який предмет він б’є. Без масивів ми запишемо це так:

 

print "What object?"
object = input()
if object == "rock":
    rule = "Breaks scissors."
elif object == "paper":
    rule = "Covers rock."
elif object == "scissors":
    rule = "Cuts paper."
print rule

 

Масиви ми запишемо так:

 

rules["rock"] = "Breaks scissors."
rules["paper"] = "Covers rock."
rules["scissors"] = "Cuts paper."

print "What object?"
object = input()
rule = rules[object]
print rule

 

 

Перший розділ встановлює асоціації в правилах масиву. Є три асоціації, по одному для кожного правила. Потім ми отримуємо ім’я об’єкта від користувача, шукаємо правило, пов’язане з цим об’єктом, і роздруковуємо його. Давайте «грати комп’ютер». У першому рядку ми зробимо нову змінну з назвою правила, яка буде масивом. У ній ми пов’язуємо рядок «рок» з рядком «Розрив ножицями». (Асоціація – це тільки один шлях. Ви можете перейти від першого рядка до другого.) Друга і третя рядки працюють однаково. Після третього рядка правила масиву містять три асоціації. Після того, як ми отримаємо об’єкт від користувача, ми переходимо до цього рядка:

 

rule = rules[object]

 

Скажімо, змінна об’єкта містить рядок “paper”. У цьому рядку ми попросимо комп’ютер знайти масив, який називається правилами, і перевірити, чи не було пов’язано нічого з рядком «папір». У цьому випадку комп’ютер знаходить (в пам’яті), що дійсно рядок «папір» асоціюється з рядком «Кришки рок». Це ставиться в змінну «правило», а в наступному рядку друкується.

Друга версія цієї програми, яка використовує масив, набагато приємніше дивитися. Це чистіше, коротше і легше читати. Ви можете поглянути на перші три рядки, щоб побачити правила. Не потрібно стежити за незручною послідовністю операцій if / else. Тільки з цих причин варто використовувати масив. Але є й інші переваги. У послідовності операторів if / else послідовність встановлюється в камені (жорстке кодування) під час написання програми. Але масив є просто змінною, як будь-яка інша, тому її можна встановити, коли програма запущена! Замість того, щоб кодувати наші правила, ми могли б отримати їх від користувача. Ось програма, яка робить саме таке:

 

while true:
    print "New rule. What object?"
    object = input()

    if object == "done":
        break

    print "What rule?"
    rule = input()

    rules[object] = rule

print "What object?"
object = input()
rule = rules[object]
print rule

 

Перша частина цієї програми (цикл while) є новою. Друга частина ідентична програмі, яку ми мали вище. Таким чином, ми замінили три рядки, які кодували три правила, у цикл while, який створює його на льоту. Давайте пройдемо через цей код, тому що те, що він робить, дуже важливий для розуміння потужності програмування та масивів.

 

Ми вже бачили цикл while, наприклад:

 

while count >= 1:
    ...

 

Це означало, “Зробіть відступ з виразом до тих пір, поки значення змінної підрахунку більше або дорівнює 1.” Строго кажучи, те, що він дійсно говорить, це: “Зробіть відступ звинуваченнями до тих пір, поки лічильник формул> = 1 Тут наша виписка while виглядає так:

 

while true:
    ...

 

Це означає, “Зробіть відступ звинуваченнями до тих пір, поки вірно вірно.” Ну, формула істина завжди вірна. Це називається нескінченним циклом. Це дійсно кажуть: “Зробіть відступ із запізненням назавжди”. Ми будемо мати справу з “нескінченною” частиною пізніше.

 

Давайте подивимося на відступи. Ми намагаємося створити нове правило. Правила містять дві частини, об’єкт (рядок) і інший об’єкт, який він б’є (інший рядок). Ми повинні отримати від користувача, щоб створити наш набір правил. Спочатку отримуємо об’єкт:

 

 print "New rule. What object?"
    object = input()

 

Давайте поки пропустимо операцію if. Потім ми отримуємо правило:

 

print "What rule?"
    rule = input()

 

і ми пов’язуємо об’єкт з правилом в масиві правил:

 

rules[object] = rule

 

Ця остання лінія схожа на рядки, які ми мали раніше:

 

rules["rock"] = "Breaks scissors."

 

за винятком того, що рядки надаються нам користувачем замість того, щоб бути жорстко закодованими в програмі. Після створення цієї асоціації ми досягаємо кінця відступів, а цикл while знову починається наверх, назавжди. Ми не хочемо, щоб це продовжувалося назавжди, або ми ніколи не дісталися б до другої частини програми, де ми використовуємо масив правил. Таким чином, ми говоримо, що якщо користувач вводить об’єкт «зроблено», то ми зупиняємо цикл і переходимо з нашою програмою. Це твердження if відразу після отримання об’єкта:

 

if object == "done":
        break

 

Якщо об’єкт, введений користувачем, є рядком “done”, то зробіть відступ, що є розривом оператора. Ми не бачили цю заяву раніше. Це означає: “Зупиніть цикл прямо зараз, перейдіть до заяв відразу після нього”. Це розриває цикл. Таким чином ми вирішуємо проблему нескінченного циклу. Ви також можете використовувати оператори break з нескінченними циклами.

 

Ви можете подумати, що дивно встановити нескінченний цикл, а потім розірвати його на півдорозі. Це пояснюється тим, що цикл while налаштований для перевірки стану (наприклад, count> = 1) у верхній частині циклу. Потім виконується весь набір відступів, після чого знову перевіряється умова (рівняння після while). Цикл while може зупинятися тільки у верхній частині циклу. Але в нашому випадку ми не знаємо, що ми хочемо зупинитися, поки користувач не введе “зроблено” для об’єкта, і це половина шляху через безліч відступів. Незважаючи на те, що while заяви не налаштовані на перевірку на наявні умови. Таким чином, ми фальшиві while цикл в той час, як відбувається назавжди, і вирватися з нього на наших власних умовах на півдорозі.

 

Ми можемо запустити програму та ввести будь-який набір правил:

 

New rule. What object?
bear
What rule?
Mauls ninja.
New rule. What object?
cowboy
What rule?
Shoots bear.
New rule. What object?
ninja
What rule?
Dodges bullets of cowboy.
New rule. What object?
done
What object?
ninja
Dodges bullets of cowboy.

 

Спробуйте that з послідовністю if / else!

 

Це основи масивів. Вони трохи нагадують базу даних, яку можна створювати на льоту, а потім використовувати пізніше. Є кілька деталей для обговорення. По-перше, що відбувається, коли ми шукаємо те, що ніколи не було введено в масив? Наш оригінальний приклад масиву виглядав так:

 

rules["rock"] = "Breaks scissors."
rules["paper"] = "Covers rock."
rules["scissors"] = "Cuts paper."

print "What object?"
object = input()
rule = rules[object]
print rule

 

Що робити, якщо користувач вводить рядок “duck”. Це ніколи не було пов’язано ні з якими правилами масиву. Що робити комп’ютер, коли він намагається запустити цей рядок:

 

rule = rules[object]

 

і змінна об’єкта — це рядок “duck”? Це залежить від мови. Деякі мови зупиняють програму і показують повідомлення про помилку, а деякі просто встановлюють змінну правила на порожній рядок. На деяких мовах можна перевірити, чи існує певна асоціація. У Python, наприклад, ви можете написати:

 

if rules.has_key(object):
    rule = rules[object]
else:
    print "That's not a valid object."

 

Ця перша лінія має дуже дивний синтаксис, з функцією has_key після періоду. Ми не будемо пояснювати це тут, але в основному комп’ютер запитують, чи має масив правил асоціацію для ключового об’єкта. (Ключ масиву — це рядок, який ви шукаєте. Значенням, з яким пов’язаний ключ.)

 

До цих пір ми використовуємо масиви з рядками. І клавіші, і значення були рядками:

 

rules["rock"] = "Breaks scissors."

 

Чи можемо ми використовувати щось інше, аніж струни? Значенням (в даному випадку “Розривними ножицями”) може бути все, що можна призначити звичайній змінної, такі як рядок, ціле число, дійсне число або навіть інший масив. Ключ (у даному випадку “рок”) може бути рядком або цілим числом, наприклад 25. Якщо ви хочете зберегти деяку інформацію про різні роки, ви можете написати:

 

years[1066] = "Battle of Hastings"

 

Або, якщо ви хочете відстежувати свої улюблені п’ять пісень, ви можете написати:

 

songs[1] = "Imagine"
songs[2] = "Baby I Love You"
songs[3] = "Hallelujah I Just Love Her So"
songs[4] = "Only The Good Die Young"
songs[5] = "Holiday"

 

Потім ви можете відобразити їх у порядку:

 

for i = 1 to 5:
    print songs[i]

 

Другий приклад показує перевагу використання цілочисельного ключа: ви можете використовувати математику (як петлю) для обчислення ключа. У цьому випадку ми встановлюємо i на 1, а потім збільшуємо його, показуючи кожну пісню, поки не досягнемо 5. Фактично масиви, які мають малі цілі для ключів, обробляються спеціально комп’ютером, тому що вони працюють набагато швидше. Багато мов мають спеціальні правила щодо цих видів масивів, з додатковими обмеженнями (наприклад, фіксованою кількістю записів), але з додатковою швидкістю. Концептуально, однак, вони подібні до інших масивів, про які ми говорили.

 

Давайте завершимо цю главу, переписуючи нашу астрологічну програму, використовуючи масиви. Ми будемо використовувати функцію Python з дивним has_key, щоб визначити, що нам було надано недійсний знак:

 

def get_sign_information(sign):
    signs["Aries"] = "assertive, impulsive, defensive"
    signs["Taurus"] = "resourceful, thorough, indulgent"
    signs["Gemini"] = "logical, inquisitive, fast"
    signs["Cancer"] = "protective, sensitive, clinging"
    signs["Leo"] = "generous, proud, theatrical"
    signs["Virgo"] = "practical, efficient, critical"
    signs["Libra"] = "co-operative, fair, lazy"
    signs["Scorpio"] = "passionate, sensitive, anxious"
    signs["Sagittarius"] = "free, straightforward, careless"
    signs["Capricorn"] = "prudent, cautious, suspicious"
    signs["Aquarius"] = "democratic, unconventional, detached"
    signs["Pisces"] = "imaginative, sensitive, distracted"

    if signs.has_key(sign):
        adjectives = signs[sign]
    else:
        print "That's not a valid sign."
        stop()

    return adjectives

def display_sign_information(whose, prefix):
    print "What's " + whose + " sign?"
    sign = input()
    adjectives = get_sign_information(sign)
    print prefix + " " + adjectives + "."

display_sign_information("your", "You are")
display_sign_information("your mate's", "Your mate is")

 

Розділ 12: Проекти

 

Ви дізналися достатньо про програмування для написання корисних програм. Очевидно, що багато речей відсутня, наприклад, збереження речей на диск і створення хороших інтерфейсів користувача. Існує також більше понять для введення, таких як структури і об’єкти. Я планую написати іншу книгу проміжного програмування, щоб охопити деякі з цих речей. Тим часом виконайте нові навички з цих проектів:

 

Напишіть програму для відображення лірики пісні “Дванадцять днів Різдва”. Багато хто з них повторюється. Не вводити всі повторювані речі; Дайте комп’ютеру роботу за вас.

 

Напишіть програму для відстеження контактів. Кожен контакт матиме ім’я та номер телефону. Програма повинна мати можливість додавати новий контакт, шукати наявний контакт (по імені, даючи вам свій номер телефону) і видаляти контакт.

 

Напишіть програму для відтворення «рок, папір, ножиці» з користувачем. Слідкуйте за рахунком. Вам потрібен спосіб, щоб комп’ютер створив одну з них випадковим чином. Використовуйте цю функцію, яка вже визначена мовою:

 

x = random(3)

 

Це означає, “Встановіть змінну x на ціле число менше 3.” Кожного разу, коли ви його викликаєте, ви встановите x на число 0, 1 або 2, випадковим чином. Ви можете змінити “3” на що завгодно, але для цієї гри ви хочете зберегти “3”, оскільки це скільки типів об’єктів.

 

Написати програму для відтворення tic-tac-toe з користувачем. Цей досить просунутий, але не використовує жодних концепцій програмування, які ви ще не дізналися. Вам потрібно просто поєднати їх у спосіб, який є більш витонченим, ніж все, що ми зробили.