Автоматизирай Това Начало на книгата

Основи на Python

Езикът за програмимране Python се състои от множество синтактични конструкции, стандартни библиотечни функции и възможности на интерактивната среда за разработка. За радост не е нужно да се знае всичко това. С малко учене могат да се пишат малки помощни програми.

Все пак трябва да се знаят някои основни концепции от програмирането. В началото тези концепции изглеждат мистериозни, или пък дори скучни, но те приличат на магическа пръчка, с чиято помощ компютърът върши чудеса. Както всеки начинаещ магьосник - трябват знания и упражнения за използване на магическата пръчка.

Следват няколко примера, които се изпълняват в интерактивната конзола(shell), наричана още REPL (Read-Evaluate-Print Loop, Цикъл Прочети-Изпълни-Принтирай). Конзолата позволява стартирането (или изпълняването) на една Python команда и веднага показва резултат. Използването на интерактивната конзола е великолепен начин за изучаване на основните Python команди, така че най-добре примерите да се въвеждат и изпълняват в нея. Ученето чрез изпълнение на примерите е много по-успешно, отколкото само четене им.

Въвеждане на инструкции в интерактивната конзола

Един вариант за използване на интерактивна конзола е след стартиране на редактора Mu (инструкции за инсталирането на редактора има във Въведение). На Windows Mu се стартира с отваряне на Start менюто, написване на "Mu" и кликане на иконата на Mu. За macOS се отваря папката Applications, двоен клик върху Mu. След това се натиска бутона New и се записва празния файл като blank.py. При изпълнение на този файл (с натискане на бутона Run или натискане на клавиша F5) в долната част на редактора се появява интерактивната конзола. Индикатор за конзолата е >>>.

Въвеждането на 2 + 2 указва на Python да сметне проста математическа задача. Прозорецът на Mu би трябвало да изглежда по подобен начин :

>>> 2 + 2
4
>>>

В Python 2 + 2 е един израз (expression), който е най-простият вид програмна инструкция. Изразите се състоят от стойности (например 2) и оператори (например +). Всеки израз може да се пресметне до проста стойност. Това означава, че израз и стойност са взаимозаменяеми в кода на Python - ако някъде се използва проста стойност може да се използва и израз.

В предния пример 2 + 2 се пресмята до проста стойност 4. Простите стойности сами по себе си са изрази, дори без да има оператори. Те се пресмятат до себе си, както може да се провери :

>>> 2
2
>>>

В изразите могат да се използват още много други оператори. В следващата таблица са показани всички математически опратори в Python.

Математически оператори от най-висок до най-нисък приоритет
Оператор Операция Пример Пресмята се до ...
** Експонента (Exponent) 2 ** 3 8
% Деление по модул/остатък 22 % 8 6
// Целичислено деление 22 // 8 2
/ Деление 22 / 8 2.75
* Умножение 3 * 5 15
- Изваждане 5 - 2 3
+ Събиране 2 + 2 4

Редът на изчисляване (също наричан приоритет, precedence) на математическите оператори в Python е подобен на познатия от математиката. Първо се пресмята операторът **, след това операторите *, /, // и % се пресмятат отляво надясно. Накрая се пресмятат операторите + и -, отново отляво надясно. За промяна на нормалния ред на изчисляване се използват скоби. По принцип интервалите между операторите и стойностите нямат значение в Python, но приетата конвенция е да се използва по един интервал между тях. Ето няколко примера :

>>> 2 + 3 * 6
20
>>> (2 + 3) * 6
30
>>> 4856878 * 578453
28093077826734
>>> 2 ** 8
256
>>> 23 / 7
3.2857142857142856
>>> 23 // 7
3
>>> 23 % 7
2
>>> 2 + 2
4
>>> (5 - 1)*((7 + 1)/(3 - 1))
16.0

Програмистът трябва да въведе изразите, но Python върши по-тежката работа по изчисляването на крайната стойност. Python пресмята всяка част от израза, докато не стигне до крайния резултат.

Примерен ред на пресмятане

Правилата за комбиниране на оператори и стойности са основата на програмния език Python. Те отговарят на граматиката на езика, на който си говорим. Ето пример:

Това изречение на български език е граматически правилно.

Това не език български правилно е граматически изречение на.

Вторият ред е труден за четене, защото не спазва правилата на българския език. По същия начин Python не може да чете неправилни инструкции. В такива случаи той показва SyntaxError, както в следващите примери :

>>> 5 +
File "<stdin>", line 1
  5 +
     ^
SyntaxError: invalid syntax
>>> 42 + 5 + * 2
File "<stdin>", line 1
 42 + 5 + * 2
                ^
SyntaxError: invalid syntax

Винаги може да се провери дали дадена инструкция работи с въвеждането ѝ в интерактивната конзола. В най-лошият случай Python ще покаже съобщение за грешка. Професионалните софтуерни разработчици гледат съобщения за грешки по цял ден.

Типове данни - целочислени, числа с плаваща запетая и низове.

Изразите са просто комбинация от стойности и оператори, която винаги се пресмята до единична стойност. Всяка стойност има точно определен тип (data type). В таблицата отдолу са показани най-често използваните типове данни в Python. Например -2 и 30 са целочислени (integer) стойности. Целочисления (наричан още int) тип показва, че стойността е цяло число. Числата с десетична запетая, например 3.14, се наричат числа с плаваща запетая (float). Важно е да се прави разлика между двата типа - стойността 42 е целочислена, а 42.0 е число с плаваща запетая.

Често използвани типове данни
Тип Примери
Целочислен -2, -1, 0, 1, 2, 3, 4, 5
Числа с плаваща запетая -1.25, -1.0, -0.5, 0.0, 0.5, 1.0, 1.25
Низове 'a', 'aa', 'aaa', 'Здравей', '11 котки'

В програмите на Python може да има и текстови стойности, наречени низове (strings или str). Те винаги трябва да се ограждат с единични кавички ('), за да може Pyhton да разбере откъде започват и къде свършват. Може да се направи и низ без символи, '', наричан празен низ (blank string или empty string). Низовете са описани в големи детайли в Глава 4

Ако низ не е затворен с единична кавичка Python показва съобщение за грешка SyntaxError: EOL while scanning string literal, както в следващия пример :

>>> 'Hello, world!
File "<stdin>", line 1
 'Hello, world!
                     ^
SyntaxError: EOL while scanning string literal

Слепване и размножаване на низове

Действието на даден оператор може да се променя според типът на данните, върху които се прилага. Например + е оператор за добавяне, когато се прилага върху две целочислени или с плаваща запетая числа. Ако обаче се използва с две низови стойности + вече е оператор за слепване (concatenation) на низове, който ги съединява. Проба в интерактивната конзола :

>>> 'Мария' + 'Иван'
'МарияИван'

Изразът се пресмята до нова низова стойност, която представлява обединение на текста от двата низа. Но в случай на употреба на оператора + върху една стойност от тип низ и една - от целочислен тип, се показва съобщение за грешка, защото Python не знае какво се цели.

>>> 'Мария' + 42
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: must be str, not int

Съобщението за грешка must be str, not int означава, че Python иска да изпълни операция, за която е необходим низ, а е подадена целичислена стойност. Кодът трябва да преобразува целочислената стойност до низ, защото Python не го прави автоматично.(Преобразуването между типовете данни е обяснено в секцията "Дисекция на програмата" , където са описани функциите str(), int() и float().)

Операторът * умножава две целочислени или числа с плаваща запетая. Но ако операторът * се приложи върху един низ и целочислена стойност, той се превръща в размножаване на низ. В интерактивната конзола може да се види действието на оператора.

>>> 'Мария' * 5
'МарияМарияМарияМарияМария'

Изразът се пресмята до нов низ, чиято стойност представлява оригиналния низ, повторен брой пъти колкото е числото. Размножаването на низове е полезно, но не толкова често използвано, колкото слепването на низове.

Операторът * може да се използва само с две числени стойности(които се умножават) или низ и целочислена стойност(за размножаване на низ). В останалите случаи Python ще покаже съобщение за грешка:

>>> 'Мария' * 'Иван'
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: can't multiply sequence by non-int of type 'str'
>>> 'Мария' * 5.0
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: can't multiply sequence by non-int of type 'float'

Нормално е Python да не разбира тези изрази. Думите не могат да се умножават една по друга, а е трудно случаен низ да се размножи отчасти.

Съхраняване на стойности в променливи

Променливата е като кутийка в паметта на компютъра, в която може да се съхранява една стойност. Запазването на резултат от израз в променлива е начин за използването на тази стойност по-късно в програмата.

Присвояване на стойност

Запазването на стойност в променлива става чрез присвояване на стойност (assignment statement). Присвояването на стойност се състои от име на променлива, знак за равенство (наричан оператор за присвояване) и стойността, която трябва да се запази. При използване на присвояване spam = 42 в променлива с име spam ще се запази целочислената стойност 42

Като идея променливата може да се визуализира като надписана кутия, със стойността в нея :

Променлива като надписана кутия
spam = 42 казва на програмата : "Променливата spam вече съдържа целочистената стойност 42"

Примери в интерактивната конзола :

➊>>> spam = 40
>>> spam
40
>>> eggs = 2
➋>>> spam + eggs
42
>>> spam + eggs + spam
82
➌>>> spam = spam + 2
>>> spam
42

Променливата се инициализира (или създава) при първото записване на стойност в нея ➊. След това променливата може да се използва в изрази с други стойности или променливи ➋. Ако на променливата се присвои нова стойност ➌, старата стойност се забравя (което обяснява защо spam се пресмята като 42, а не 40 на последния ред от примера). Това се нарича презаписване (overwriting) на променлива. В интерактивната конзола може да се демонстрира и презаписване на низ:

>>> spam = 'Hello'
>>> spam
'Hello'
>>> spam = 'Goodbye'
>>> spam
'Goodbye'

Както е показано в картинката по-долу, променливата spam съдържа 'Hello', докато не се замени с 'Goodbye'.

Презаписване на променлива
При присвояване на нова стойност старата се забравя.

Именуване на променливи

Добре е имената на променливите да описват данните, които съдържат. Не е много полезна кутията, на която пише просто Нещо. В примерите (и документацията на Python) се използват общи имена като spam, eggs, bacon, които идват от скеч на Монти Пайтън. В истинските програми кодът е много по-четим, ако се използват описателни имена.

В Python има някои ограничения при именуването на променливи. За да е валидно името трябва да отговаря на следните правила:

  • В него не трябва да има интервали.
  • Съдържа само букви, цифри и символът подчертавка(_).
  • Не започва с цифра.
Валидни и невалидни имена на променливи
Валидни имена Невалидни имена
current_balance current-balance (не са позволени тирета)
currentBalance current balance (не са позволени интервали)
account4 4account (не може да започва с цифра)
_42 42 (не може да започва с цифра)
TOTAL_SUM TOTAL_$UM (не са позволени специални символи като $)
hello 'hello' (не са позволени специални символи като ')

Python прави разлика между малки и големи букви, така че spam, SPAM, Spam и sPaM са четири различни променливи. Принципно Spam е валидно име на променлива, но по конвенция в Python всички променливи започват с малка буква.

Примерите използват camelCase, вместо подчертавки, за по-сложните имена на променливи (lookLikeThis, а не look_like_this).

Първа програма

Интерактивната конзола е удобна за изпълняване на по една инструкция, но за създаване на цяла Python програма се използва файлов редактор. Файловият редактор прилича на редакторите за текст, като Notepad и TextMate, като има допълнителни възможности, свързани с въвеждането на програмен код. За създаване на нов файл в редактора Mu се използва бутона New от най-горния ред.

В новопоявилия се прозорец има мигащ курсор, подканящ въвеждането на инструкции. Все пак този прозорец се различава от интерактивната конзола, която веднага изпълнява въведената инструкция. Във файловият редактор могат да се въведат много инструкции, след това файлът да се запише и накрая да се стартира въведената програма. Как се различава интерактивна конзола от файлов редактор ?

  • Интерактивната конзола винаги има индикатор >>>
  • Прозорецът на файлов редактор няма индикатор >>>

Време е за създаване на програма! В прозореца на файлов редактор се въвежда:

➊ # Тази програма казва Здравей и пита за име
➋ print('Здравей, свят!')
print('Как се казваш ?') #пита за име
➌ myName = input()
➍ print('Здравей,' + myName)
➎ print('Дължината на името е :')
print(len(myName))
➏ print('На каква възраст си?') #пита за възраст
myAge = input()
print('Ще си на ' + str(int(myAge) + 1) + ' след година.')

След въвеждането на програмния код той може да се запише, за да не се налага да се пише отново. Това става с натискане на бутона Save, след това избиране на име, например hello.py и натискане на Save.

Препоръчително е програмата да се записва през определен интервал от време. По този начин няма да се загуби прогресът, ако компютърът забие или Mu се затвори неочаквано. Записването лесно се постига с натискане на Ctrl-S(Windows или Linux ) или Command-S(при използване на MacOS).

След записване на програмата тя може да се пусне с натикане на клавиша F5. Програмата се пуска в прозореца на интерактивната конзола. Клавишът F5 трябва да се натиска само в прозореца на файловия редактор, но не и в интерактивната конзола. Трябва да се въведе име, когато програмата попита. След изпълнението на програмата интерактивната конзола ще изглежда по подобен начин :

Здравей, свят!
Как се казваш ?
Станимир
Здравей,Станимир
Дължината на името е :
8
На каква възраст си?
4
Ще си на 5 след година.
>>>

След изпълнение на всички редове код, Python програмата приключва, иначе казано - спира се изпълнението ѝ.

Затварянето на файловия редактор става чрез натискане на бутона X в горната част на прозореца. За зареждане на записана програма се избира File▸Open от менюто. От показалия се прозорец се избира желания файл и се натиска бутон Open. Записаната програма се показва в прозореца на файловия редактор.

Дисекция на програмата

Следва бърз преглед на действието на всички инструкции, които се използват в горната програма.

Коментари

Следващият ред се нарича коментар.

➊ # Тази програма казва Здравей и пита за име

Python игнорира коментарите, те се използват от програмистите за писане на бележки по кода. Често коментарите описват целта на кода. Коментарът започва с диез (#) и продължава до края на реда.

Програмистите понякога поставят # в началото на ред код, за да го изключат временно. Такъв код се нарича коментиран. Коментирането на редове с код може да бъде полезно при тестване на програмите, когато трябва да се разбере защо програмата не работи. След това се премахват сложените #, за да се изпълнят редовете.

Python игнорира и празните редове след коментар. Добавянето на празни редове се използва за подобряване на четимостта на кода, също както в книгите се използват параграфи.

Функцията print()

Функцията print() показва на екрана символния низ, който се намира в скобите.

➋ print('Здравей, свят!')
print('Как се казваш ?') #пита за име

Редът print('Здравей, свят!') означава - "Покажи на екрана текста 'Здравей, свят!'." При изпълнението на този ред Python изпълнява две операции - извиква (calling) функцията print() и предава (passing) стойността на символния низ на функцията. Предадената по време на извикване на функция стойност е аргумент(argument) или параметър. Кавичките не се показват на екрана. Те просто отбелязват началото и края на текста, но не са част от стойността.

БЕЛЕЖКА

Тази функция може да се използва и за показване на празни редове на екрана. Постига се чрез извикване на print() без подаване на параметър

Отварящата и затварящата скоба след името на функцията определят, че това е име на функция, а не променлива. По тази причина се използва print(), а не print. Глава 3 описва функциите по-подробно.

Функцията input()

Функцията input() изчаква въвеждането на текст с клавиатурата, докато се натисне ENTER.

➌ myName = input()

Резултатът от извикването на функцията е символен низ, равен на въведения от потребителя текст. След това този резултат се присвоява на променливата myName.

Извикването на функцията input() може да се смята за израз, който се пресмята до текста, въведен от потребителя. Ако потребителят въведе Станимир изразът се пресмята до myName = 'Станимир'.

След извикването на input() може да се види съобщение за грешка, например NameError: name 'Станимир' is not defined. Това означава, че се използва Python версия 2, а не правилната версия 3.

Принтиране на името на потребителя

Следващото извикване на print() съдържа в скобите израза 'Здравей,' + myName.

➍ print('Здравей,' + myName)

Всеки израз може да се пресметне до стойност. На ред ➌ в променливата myName се записва някаква стойност (например 'Станимир'). След това изразът се пресмята до 'Здравей, Станимир'. Тази низова стойност се предава на функцията print(), която го принтира на екрана.

Функцията len()

На функцията len() се подава низова стойност или променлива, съдържаща низ. Функцията се пресмята до целочислената стойност равна на броя на символите в низа.

➎ print('Дължината на името е :')
print(len(myName))

Следват няколко примера :

>>> len('Здравей')
7
>>> len('Кучето ми бягаше по двора дълго време.')
38 >>> len('')
0

Точно като в примерите, len(myName) се пресмята до цяло число. Тази стойност се предава на print() и се показва на екрана. Функцията print() приема целочислени стойност или символен низ. Трябва да се обърне внимание на грешката при писане на следната команда в интерактивната конзола :

>>> len('Аз съм на ' + 29 + ' години')
TypeError Traceback (most recent call last)
in
----> 1 len('Аз съм на ' + 29 + ' години')

TypeError: must be str, not int

Тази грешка не е причинена от функцията print(), а от израза, който се подава на print(). Същата грешка се получава и при въвеждане в интерактивната конзола на самия израз :

>>> 'Аз съм на ' + 29 + ' години'
TypeError Traceback (most recent call last)
in
----> 1 'Аз съм на ' + 29 + ' години'

TypeError: must be str, not int

Python показва тази грешка, защото операторът + може да се приложи само върху две целочислени или два низа. Не може да се използва за прибавяне на целочислена стойност към низ. В Python тази операция не е граматически коректна. За поправяне на грешката трябва да се използва числото като низ, както е показано по-долу.

Функциите str(), int() и float()

За слепване на число, например 29, с низ, за да се подаде на print(), е необходимо да се преобразува до стойността '29' (версия на 29 като низ). Това се постига с използването на функцията str(). Тя приема целочислена стойност и се пресмята до низова стойност, която отговаря на числото.

>>> str(29)
'29'
>>> print('Аз съм на ' + str(29) + ' години.')
Аз съм на 29 години.

str(29) се пресмята до '29', изразът 'Аз съм на ' + str(29) + ' години.' се пресмята до 'Аз съм на ' + '29' + ' години.', което на свой ред се пресмята до Аз съм на 29 години.. Това е и стойността, която се предава на функцията print()

Функциите str(), int() и float() се пресмятат съответно до низ, целочислено или число с плаваща запетая, което отговаря на подадената стойност. В интерактивната конзола могат да се опитат различни преобразувания на стойности :

>>> str(0)
'0'
>>> str(-3.14)
'-3.14'
>>> int('42')
42
>>> int('-99')
-99
>>> int(1.25)
1
>>> int(1.99)
1
>>> float('3.14')
3.14
>>> float(10)
10.0

В тези примери функциите str(), int() и float() се извикват със стойности с други типове, за да се получат стойности от тип съответно низ, целочислен или с плаваща запетая.

Функцията str() е подходяща за слепване на число към низ. Функцията int() е подходяща, ако число е представено като низ, а трябва да се използва в математически изчисления. Пример за това е при използване на функцията input(), която винаги връща низ, дори когато е въведено число. След въвеждане на spam = input() в интерактивната конзола и 101 при запитване за текст, се получава следния резултат :

>>> spam = input()
101
>>> spam
'101'

Записаната в spam стойност не е числото 101, а низ '101'. За използването на spam в математически операции трябва да се използва функцията int(), с която се получава целочисленото представяне на spam. Тази целочислена стойност може да се запише отново в spam.

>>> spam = int(spam)
>>> spam
101

Вече променливата spam може да се третира като число, а не низ :

>>> spam * 10 / 5
202.0

Pyhton показва грешка, ако предадената на int() стойност не може да се пресметне до целочислена.

>>> int('99,99')
ValueError Traceback (most recent call last)
in
----> 1 int('99.99')

ValueError: invalid literal for int() with base 10: '99.99'
>>> int('десет')
ValueError Traceback (most recent call last)
in
----> 1 int('десет')

ValueError: invalid literal for int() with base 10: 'десет'

Друга употреба на функцията int() е за закръгляне надолу :

>>> int(7,7)
7
>>> int(7,7) + 1
8

В програмата по-горе се използват функциите int() и str() за получаване на стойност от подходящия тип.

➏ print('На каква възраст си?') #пита за възраст
myAge = input()
print('Ще си на ' + str(int(myAge) + 1) + ' след година.')

Променливата myAge съдържа стойността, върната от input(). Функцията input() винаги връща низ (дори ако потребителят въведе число), така че трябва да се използва int(myAge) за получаване на целочислената стойност на низа в myAge. Към тази целочислена стойност се добавя 1 в израза int(myAge) + 1.

Резултатът от това добавяне се предава на функцията str(): str(int(myAge) + 1). След това низовата стойност на този израз се слепва с низовете 'Ще си на ' и ' след година.' за получаване на една голяма низова стойност. Накрая този голям низ се предава на print(), за да се покаве на екрана.

Нека потребителят е въвел низа '4' за myAge. Низът '4' се конвертира до цяло чилсо, за да може да се прибави единица към него. Резултатът е 5. Функцията str() преобразува резултата отново в низ, за да може да се слепи с останалите низове. Така се постига крайната цел - показване на цялото съобщение. Стъпките по време на пресмятането изглеждат по подобен начин :

Стъпките по време на пресмятането

Обобщение

Изчисляване на изрази може да се върши с калкулатор, слепването на низове е възможно с текстов редактор. Размножаването на низове е лесно постижимо с копиране на текст. Но изразите и техните компоненти - стойности, оператори, променливи и извикване на функции, са основните блокове, от които са съставени програмите. Овладяването им позволява да се инструктира Python да обработва огромни количестша данни.

Добре е да се запомнят различните типове оператори ( +, -, *, /, //, % и ** за математически действия и + и * за низове ) и трите типа данни (цели числа, числа с плаваща запетая и символни низове), които са представени в тази глава.

Представиха се и няколко функции. Функциите print() и input() позволяват лесен начин за показване на текст (на екрана) и въвеждане (от клавиатурата). Функцията len() приема символен низ и се пресмята до цяло число, равно на броя на символи в низа. Функциите str(), int() и float() се пресмятат до низова, целочислена или с плаваща запетая стойност, отговаряща на подадената стойност.

В следващата глава се описва как Python може да взема решения кой код да изпълни, кой код да пропусне и кой код да изпълни повторно. Това се нарича управление на изпълнението (flow control) и позволява да се пишат програми, които вземат интелигентни решения.

Упражнения

  1. Кое е оператор и кое - стойност?

    *
    'Здравей'
    -88.8
    -
    /
    +
    5

  2. Кое от двете е променлива и кое - символен низ ?

    spam
    'spam'

  3. Имена на три типа данни ?
  4. От какво са съставени изразите ? Какво е характерно за всички изрази ?
  5. В текста са използвани операции за присвояване на стойност от типа spam = 10. Каква е разликата между израз и операция ?
  6. Какво съдържа променливата bacon след изпълнението на следния код ?

    bacon = 20
    bacon + 1

  7. До какво ще се пресметнат следните два израза ?

    'spam' + 'spamspam'
    'spam' * 3

  8. Защо eggs е валидно име за променлива, но 100 не е ?
  9. Коя функция може да се използва за получаване на цяло число от дрига стойност ? За получаване на число с плаваща запетая ? На символен низ ?
  10. Защо този израз причинява грешка ? Как може да се поправи ?

    'Изядох ' + 12 + ' кюфтета.'

Подкрепете автора чрез покупка на оригиналната книга от No Starch Press или Amazon.