Глава 11. Хитрости и хакове
В настоящата глава ще разгледаме някои хитрости, хакове и техники, които ще улеснят работата ни с езика Python в средата за разработка PyCharm. По-специално ще се запознаем:
- Как правилно да форматираме код.
- С конвенции за именуване на елементи от код.
- С някои бързи клавиши (keyboard shortcuts).
- С някои шаблони с код (code snippets).
- С техники за дебъгване на код.
Форматиране на кода
Правилното форматиране на нашия код ще го направи по-четим и разбираем, в случай че се наложи някой друг да работи с него. Това е важно, защото в практиката ще е необходимо да работим в екип с други хора и е от голямо значение дали пишем кода си така, че колегите ни да могат бързо да се ориентират в него.
Има определени правила за правилно форматиране на кода, които събрани в едно се наричат конвенции. Конвенциите са група от правила, общоприети от програмистите на даден език, и се ползват масово. Тези конвенции помагат за изграждането на норми в дадени езици – как е най-добре да се пише и какви са добрите практики. Приема се, че ако един програмист ги спазва, то кодът му е лесно четим и разбираем.
Езикът Python е създаден от огранизацията Python Software Foundation (PSF). Добрите практики за писане може да се различават между проектите, но общоприетите такива са дело на авторите на езика (основно Guido van Rossum). Трябва да знаете, че дори да не спазвате конвенциите, препоръчани от PSF, кодът ви ще работи (стига да е написан правилно), но просто няма да бъде лесно разбираем. Това, разбира се, не е фатално на основно ниво, но колкото по-бързо свикнете да пишете качествен код, толкова по-добре.
Официалната Python код конвенция на PSF е публикувана в страницата PEP 8 – Style Guide for Python Code: https://www.python.org/dev/peps/pep-0008/. Важно е да се отбележи, че в примерите, които сме давали до сега и ще даваме занапред в тази книга, се ръководим основно от нея.
За форматиране на кода от PSF се препоръчва всяко ниво на влагане да бъде 4 празни полета навътре (или една табулация), както е в примера по-долу. Езикът не позволява смесването на табулации и интервали:
if some_condition:
print("Inside the if statement")
Възможно е вместо 4, да се използват 2 интервала, но не се препоръчва.
Ето как изглеждат две вложени конструкции. Всеки блок започва с 4 интервала навътре. Броят интервали в началото на всеки ред определя какво е нивото му на влагане:
if some_condition:
print("Start of outer if statement")
if another_condition:
print("Inside the inner if statement")
print("End of outer if statement")
В Python форматирането на кода е от изключително важно значение за функционирането му. Код, който не е форматиран правилно, дава грешка.
Ето това е пример за лошо форматиран код спрямо общоприетите конвенции за писане на код на езика Python:
if some_condition:
print("Inside the if statement")
Когато бъде стартиран, кодът дава следната грешка и програмата спира работа:
IndentationError: expected an indented block
Командата вътре в if
конструкцията трябва да бъде 4 празни полета навътре (един таб). Веднага след ключовата дума if
и преди условието на проверката се оставя интервал.
Същото правило важи и за for
цикли и всякакви други вложени конструкции. Ето още един пример:
Правилно:
for i in range(5):
print(i)
Грешно:
for i in range(5):
print( i )
За наше удобство има бързи клавиши в PyCharm, за които ще обясним по-късно в настоящата глава, но засега ни интересува една комбинация. Тя е за форматиране на кода в целия документ: [CTRL + ALT + L].
Нека използваме грешния пример от преди малко:
for i in range(5):
print( i )
Ако натиснем [Ctrl + Alt + L], което е нашата комбинация за форматиране на целия документ, ще получим код, форматиран според общоприетите конвенции за Python, който ще изглежда по следния начин:
for i in range(5):
print(i)
Тази комбинация може да ни помогне, ако попаднем на лошо форматиран код. Автоматичното форматиране обаче не влияе на именуването на нашите променливи (както и на други елементи на кода), за което ние трябва да се погрижим сами.
Именуване на елементите на кода
В тази секция ще се фокусираме върху общоприетите конвенции за именуване на проекти, файлове и променливи, наложени от PSF.
Именуване на проекти и файлове
За именуване на проекти и файлове се препоръчва описателно име, което подсказва каква е ролята на въпросния файл / проект и в същото време се препоръчва lowercase_with_underscores
конвенцията. Tова е конвенция за именуване на елементи, при която всяка дума, включително първата, започва с малка буква, а отделните думи са съединени с долни черти (_
), например expression_calculator
. Допустимо е да именуваме проекти и по конвенцията PascalCase
– всяка дума, включително и първата, започва с главна буква, а отделните думи са долепени – ExpressionCalculator
.
Пример: в този курс се започва с лекция на име First steps in coding и следователно едно примерно именуване на проекта за тази лекция може да бъде first_steps_in_coding
или FirstStepsInCoding
. Файловете в даден проект задължително трябва да спазват конвенцията lowercase_with_underscores
. Ако вземем за пример първата задача от лекцията First steps in coding, тя се казва Hello World и следователно нашият файл в проекта ще се казва hello_world.py
.
Именуване на променливи
В програмирането променливите пазят някакви данни и за да е по-разбираем кодът, името на една променлива трябва да подсказва нейното предназначение. Ето и още няколко препоръки за имената на променливите:
- Името трябва да е кратко и описателно и да обяснява за какво служи дадената променлива.
- Името трябва да се състои само от буквите a-z, A-Z, цифрите 0-9, както и символа '_'.
- В Python е прието променливите да спазват конвенцията
lowercase_with_underscores
. - Трябва да се внимава за главни и малки букви, тъй като Python прави разлика между тях. Например
age
иAge
са различни променливи. - Имената на променливите не могат да съвпадат със служебна дума (keyword) от езика Python, например
for
е невалидно име на променлива.
Въпреки че използването на главни букви в имената на променливите е разрешено, в Python това не се препоръчва и се счита за лош стил на именуване. |
Ето няколко примера за добре именувани променливи:
first_name
age
start_index
last_negative_number_index
Ето няколко примера за лошо именувани променливи, макар и имената да са коректни от гледна точка на интерпретатора на Python:
firstName
(именувана е по друга конвенция, неприета в Python).AGE
(изписана е с главни букви).Start_Index
(съдържа главни букви).lastNegativeNumber_Index
(няма '_' около всяка дума).
Първоначално всички тези правила може да ви се струват безсмислени и ненужни, но с течение на времето и натрупването на опит ще видите нуждата от норми за писане на качествен код, за да може да се работи по-лесно и по-бързо в екип. Ще разберете, че е изключително досадна работата с код, който е написан без да се спазват никакви правила за качествен код.
Бързи клавиши в PyCharm
В предната секция споменахме за една от комбинациите, които се отнасят за форматиране на код: [Ctrl + Alt + L], която беше за форматиране на целия код в даден файл. Тези комбинации се наричат бързи клавиши и сега ще дадем по-подробна информация за тях.
Бързи клавиши са комбинации, които ни предоставят възможността да извършваме някои действия по-лесно и по-бързо, като всяка среда за разработка на софтуер си има своите бързи клавиши, въпреки че повечето се повтарят. Сега ще разгледаме някои от бързите клавиши в PyCharm.
Комбинация | Действие |
---|---|
[CTRL + F] | Отваря търсачка, с която можем да търсим в нашия код. |
[CTRL + /] | Закоментира част от кода. Разкоментира код, който е вече закоментиран. |
[CTRL + Z] | Връща една промяна назад (т.нар. Undo). |
[CTRL + SHIFT + Z] | Има противоположно действие на [CTRL + Z] (т.нар. Redo). |
[CTRL + ALT + L] | Форматира кода според конвенциите по подразбиране. |
[CTRL + Backspace] | Изтрива думата вляво от курсора. |
[CTRL + Del] | Изтрива думата вдясно от курсора. |
[CTRL + S] | Запазва всички файлове в проекта. |
Повече за бързите клавиши в PyCharm може да намерите в сайта на JetBrains: https://www.jetbrains.com/help/pycharm/mastering-keyboard-shortcuts.html.
Шаблони с код (code snippets)
В PyCharm съществуват т.нар. шаблони с код (live templates), при изписването на които се изписва по шаблон някакъв блок с код. Примерно, при изписването на кратък код "iter
" и натискане на [Tab] се генерира кодът for ... in ...:
в тялото на нашата програма, на мястото на краткия код. Това се нарича “разгъване на шаблон за кратък код”. На фигурата по-долу е показано действието на шаблона "iter
":
Да си направим собствен шаблон за код
В тази секция ще покажем как сами да си направим собствен шаблон. Ще разгледаме как се прави live template за два вложени цикъла. Като за начало ще си създадем нов празен проект и ще отидем на [File] -> [Settings], както е показано на снимката:
В отворилия се прозорец трябва да изберем [Editor] -> [Live Templates], а от появилите се секции трябва да изберем стрелката преди отметката Python. Там се намират всички съществуващи шаблони за езика Python:
Избираме някой snippet, например iter
и го разглеждаме:
Виждаме доста непознати неща, но няма страшно, по-нататък ще се запознаем и с тях. Засега искаме да създадем собствен шаблон. За целта избираме бутона Add (зеленият + вдясно). От появилия се списък избираме [1. Live Template]. В долната част на прозореца, на Abbreviation пишем краткото име, с което ще извикваме шаблона (например ff
, от for, for
), за Description даваме полезно описание, а при Template Text въвеждаме следното:
for $I$ in $LIST1$:
for $J$ in $LIST2$:
$END$
Получаваме предупреждение, че трябва да изберем контекст, т.е. в кои случаи да се показва нашият шаблон (червеният текст под Template text). Избираме Define и от появилото се меню слагаме отметка пред Python:
Вече когато напишем ff
в PyCharm, нашият нов live template се появява:
Техники за дебъгване на кода
Дебъгването играе важна роля в процеса на създаване на софтуер, която ни позволява постъпково да проследим изпълнението на нашата програма. С помощта на тази техника можем да следим стойностите на локалните променливи, тъй като те се променят по време на изпълнение на програмата, и да отстраним евентуални грешки (бъгове). Процесът на дебъгване включва:
- Забелязване на проблемите (бъговете).
- Намиране на кода, който причинява проблемите.
- Коригиране на кода, причиняващ проблемите, така че програмата да работи правилно.
- Тестване, за да се убедим, че програмата работи правилно след нанесените корекции.
PyCharm ни предоставя вграден дебъгер (debugger), чрез който можем да поставяме точки на прекъсване (или breakpoints), на избрани от нас места. При среща на стопер (breakpoint), програмата спира изпълнението си и позволява постъпково изпълнение на останалите редове от кода. Дебъгването ни дава възможност да вникнем в детайлите на програмата и да видим къде точно възникват грешките и каква е причината за това.
За да демонстрираме работа с дебъгера ще използваме следната програма:
for i in range(1, 100):
print(i)
Ще сложим стопер (breakpoint) на функцията print(…)
. За целта трябва да преместим курсора на реда, който печата на конзолата, и да натиснем [CTRL + F8]. Появява се стопер, където програмата ще спре изпълнението си:
За да стартираме програмата в режим на дебъгване, избираме [Run] -> [Debug...] или натискаме [Alt + Shift + F9]:
След стартиране на програмата виждаме, че тя спира изпълнението си на ред 2, където сложихме стопера (breakpoint). Кодът на текущия ред се оцветява с жълт цвят и можем да го изпълняваме постъпково. За да преминем на следващ ред използваме клавиш [F8]. Забелязваме, че кодът на текущия ред все още не е изпълнен. Изпълнява се, когато преминем на следващия ред:
От прозореца Debugger можем да наблюдаваме промените по локалните променливи. Той се отваря, когато започнем да дебъгваме. За да отворите прозореца ръчно, трябва да изберем [View] -> [Tool Windows] -> [Debug]:
Справочник с хитрости
В тази секция ще припомним накратко хитрости и техники от програмирането с езика Python, разглеждани вече в тази книга, които ще са ви много полезни, ако ходите на изпит по програмиране за начинаещи:
Вкарване на променливи в стринг (string)
text = "some text"
print(f"{text}")
# Tова ще отпечата на конзолата "some text"
В случая използваме placeholder – {x}
, където x е името на променливата, която искаме да покажем. Възможно е да използваме повече от една променлива, примерно:
text = "some text"
number = 5
print(f"{text} {number} {text}")
# Tова ще отпечата "some text 5 some text"
В този пример забелязваме, че можем да подаваме не само текстови променливи. Също така можем да използваме дадена променлива няколко пъти.
Закръгляне на числа
При нужда от закръгляне можем да използваме един от следните методи:
round(num, digits)
– приема два параметър – първият е числото, което искаме да закръглим, а вторият – числото, което определя с колко символа след десетичния знак да се извърши закръглянето (това число винаги трябва да бъде цяло число). Закръглянето се извършва по основното математическо правило – ако десетичната част е по-малка 5, числото се закръгля надолу и обратно: ако е по-голяма от 5 – нагоре:
first_number = 5.431
print(round(first_number, 2))
# Това ще отпечата на конзолата "5.43"
second_number = 5.539
print(round(second_number, 2))
# Това ще отпечата на конзолата "5.54"
math.floor(…)
– в случай, че искаме закръглянето да е винаги надолу. Важно е да отбележим, че тази функция закръгля до цяло число. Например, ако имаме числото 5.99 и използвамеmath.floor(5.99)
, ще получим числото 5:
number_to_floor = 5.99
print(math.floor(number_to_floor))
# Tова ще отпечата на конзолата "5"
math.ceil(…)
– в случай, че искаме закръглянето да е винаги нагоре. Тази функция също закръгля до цяло число. Например, ако имаме числото 5.11 и използвамеmath.ceil(5.11)
, ще получим числото 6:
number_to_ceil = 5.11
print(math.ceil(number_to_ceil))
# Tова ще отпечата на конзолата "6"
math.trunc(…)
– в случай, че искаме да премахнем дробната част. Например, ако имаме числото 2.63 и използвамеmath.trunc(2.63)
, ще получим 2:
number_to_truncate = 2.63
print(math.trunc(number_to_truncate))
# Tова ще отпечата на конзолата "2"
Закръгляне чрез placeholder
number = 5.432424
print(f"{number:.2f}")
В случая след числото добавяме :.2f
, което ще ограничи числото до 2 цифри след десетичния знак. Поведението ще е като на функцията round(…)
. Трябва да имаме предвид, че числото преди буквата f
означава до колко цифри след десетичния знак да е закръглено числото (т.е. може да е примерно 3f
или 5f
). Не забравяйте и точката преди числото – тя е задължителна.
Как се пише условна конструкция?
Условната if
конструкция се състои от следните елементи:
- Ключова дума
if
. - Булев израз (условие).
- Тяло на условната конструкция.
- Незадължително:
else
клауза.
if условие:
# Тяло
else:
# Тяло
За улеснение може да използваме live template за if
конструкция:
if
+ [Tab]
Как се пише for цикъл?
За for
цикъл ни трябват няколко неща:
- Инициализационен блок, в който се декларира променливата брояч (
i
). - Граници за повторение:
range(5)
са числата от0
до4
включително. - Тяло на цикъла.
for i in range(5):
# Тяло
За улеснение може да използваме live template за for
цикъл:
for
+ [Tab]- или
iter
+ [Tab]
Какво научихме от тази глава?
В настоящата глава се запознахме как правилно да форматираме и именуваме елементите на нашия код, някои бързи клавиши (shortcuts) за работа в PyCharm, шаблони с код (Live Templates) и разгледахме как се дебъгва код.