Към съдържанието

1. Въведение, синтаксис, типове данни и променливи ​

Занятие 1упражнения: 01-intro-syntax-types/ в homework repositoryпримерните данни

Днес ще се научите да:

  • се ориентирате в курса: целта, занятията, материалите;
  • казвате за какво е добър Python до SQL и SAS и как изпълнява кода ви;
  • подготвяте проект: Python, виртуална среда (virtual environment), pip и requirements.txt;
  • пускате Python код във VS Code, в терминала и в Jupyter notebook;
  • четете структурата на една програма: редове, отстъп, коментари, print();
  • работите с основните типове: int, float, str, bool, None;
  • използвате променливи и разбирате какво всъщност е едно име в Python;
  • смятате с операторите и с модула math;
  • преобразувате стойности между типовете и съставяте текст с f-strings;
  • смятате парични стойности точно с Decimal и ги закръгляте така, както го правят SAS и SQL.

От SQL към Python - един и същ въпрос, по два начина:

sql
SELECT SUM(outstanding) FROM loans WHERE stage = 3;
python
import pandas as pd

loans = pd.read_csv("data/loans.csv")
print(loans.loc[loans["stage"] == 3, "outstanding"].sum())
Променете кода и го изпълнете отново

До занятие 16 ще пишете такъв код всеки ден. Днес започваме от частите, от които е направен: стойности, типове, променливи и оператори.

1. За курса ​

Преподавателят ​

Ива Попова - LinkedIn, имейл iva.popova@sciscend.com. Преподавателският и професионалният ѝ опит: Преподавателят (и в страничното меню).

Целта ​

Плавно преминаване към Python като основен инструмент за същата ежедневна работа, която сега вършите в SQL и SAS: отчети, моделиране и ad-hoc анализи. Вие вече знаете как се работи с данни - joins, групи, филтри, формати. В този курс научавате същите неща на нов език, и това, което Python добавя отгоре: автоматизация на файлове и отчети, огромен избор от безплатни библиотеки и notebooks, които смесват код, таблици, графики и текст.

Занятията ​

16 занятия по 4 учебни часа. Пълният план е на страницата Програма:

ЗанятияТема
1 - 2Езикът: типове, променливи, оператори, условия и цикли
3 - 6Колекции: lists, tuples, sets, dictionaries; функции
7 - 9Текст, регулярни изрази, грешки и файлове
10 - 12Модули, Git, класове и обекти
13Бази данни: SQL от Python
14 - 16NumPy и pandas: версията на Python за вашата работа в SQL и SAS; финалният проект

Как работим ​

  • Теория с много примери. Всяка страница с лекция има примери, които могат да се пускат: натиснете Run под примера, променете го с Edit, пуснете го отново (вижте Как да ползвате тези страници).
  • Упражнения във VS Code. Всяко занятие има задачи за упражнение, които се проверяват сами и отпечатват OK или FAIL, и домашно. Разглеждаме домашното в началото на следващото занятие.
  • От това, което знаете. Всяка тема започва от своята версия в SQL или SAS: CASE WHEN, GROUP BY, JOIN, DATA step, PROC SORT, PROC MEANS, формати, макроси.
  • Измислени данни. Всички примери използват малък кредитен портфейл, който прилича на истински данни, но е измислен: примерните данни.
  • Въпроси по всяко време. Не чакайте края на занятието - питайте, щом нещо не е ясно. Обратната връзка също е добре дошла по всяко време: какво помага, какво не, какво е трудно.

Материалите ​

КаквоКъде
Лекциите (този сайт)https://ivapopova-courses.github.io/Python-Data-Analysts-UniCredit-Slides/
Задачи за упражнение и домашниhttps://github.com/ivapopova-courses/Python-Data-Analysts-UniCredit-Homework
Кодът, написан в часhttps://github.com/ivapopova-courses/Python-Data-Analysts-UniCredit-Labs
Анимации стъпка по стъпкаАнимации
Финалният проектФинален проект

2. Python до SQL и SAS ​

Какво е Python ​

Python е език за програмиране с общо предназначение: безплатен, с отворен код и един от най-използваните езици в света. Използва се за:

  • анализ на данни, статистика, машинно обучение и AI;
  • автоматизация: файлове, Excel отчети, имейли, задачи по график;
  • уеб приложения и уеб услуги;
  • системна администрация и облака;
  • наука, образование и малки устройства (Raspberry Pi).

За един анализатор основната причина са библиотеките: pandas и NumPy за таблици и числа, matplotlib за графики, statsmodels и scikit-learn за модели, openpyxl за Excel, SQLAlchemy за бази данни. Всички са безплатни.

SQL, SAS и Python - за какво е всеки от тях ​

SQLSASPython
Какво еезик за заявки на базата данникомерсиална система за данни и статистикаезик с общо предназначение, с библиотеки за данни
Къде са даннитев базата данниSAS data sets (.sas7bdat), библиотекив паметта: lists, dictionaries, pandas DataFrames; файлове и бази данни
Типична работаselect, join, групиране, филтриранеDATA step, PROCs, формати, макросивсичко изброено, плюс автоматизация, графики, модели
Ценачаст от базата даннилицензбезплатен

Няма да спрете да ползвате SQL. Най-доброто място за филтриране и съединяване на големи таблици все още е базата данни; Python изпраща SQL заявката и работи с резултата (занятие 13). Python заменя най-вече SAS частта от работата - и добавя това, което нито SQL, нито SAS правят добре.

Как идеите от SAS се пренасят в Python (повечето идват в следващите занятия):

SASPython
DATA stepцикъл по редовете (занятия 2 - 6) или pandas (занятия 14 - 16)
PROC SORTsorted(), DataFrame.sort_values()
PROC MEANS, PROC SUMMARYsum(), statistics, DataFrame.groupby().agg()
PROC FREQcollections.Counter, value_counts(), pd.crosstab()
PROC TRANSPOSEDataFrame.pivot(), melt()
формати (COMMA12.2, PERCENT8.2)f-strings: f"{x:,.2f}", f"{x:.2%}" - раздел 13
макроси, %LETфункции (занятие 4), променливи
LIBNAMEпътища до файлове, връзки към бази данни
SAS log-ътизходът в терминала; съобщенията за грешки (tracebacks)
проект в Enterprise GuideJupyter notebook - раздел 7

"Батериите са включени" (batteries included) ​

Python идва с голяма стандартна библиотека: модули за файлове, CSV, JSON, дати, точни десетични числа, регулярни изрази, бази данни SQLite, статистика и много други. Само ги импортирате с import. Всичко останало е в PyPI, Python Package Index (https://pypi.org): стотици хиляди безплатни пакети, които се инсталират с pip (раздел 4).

python
import statistics

rates = [8.83, 5.44, 4.79, 8.35]
print(statistics.mean(rates))
print(statistics.median(rates))
Променете кода и го изпълнете отново

The Zen of Python ​

Правилата, по които е създаден езикът, написани от Tim Peters. Пуснете import this, за да видите всичките 19:

python
import this
Променете кода и го изпълнете отново

Тези, които най-много ще усетите в този курс:

  • Readability counts. (Четимостта е важна.) Кодът се чете много по-често, отколкото се пише.
  • Explicit is better than implicit. (Явното е по-добро от неявното.) Python не превръща "5" в 5 вместо вас (SAS го прави, с бележка в log-а) - вие казвате какво искате (раздел 12).
  • Errors should never pass silently. (Грешките никога не трябва да минават тихо.) Проблемът спира програмата с ясно съобщение, вместо грешно число в отчета.
  • There should be one - and preferably only one - obvious way to do it. (Трябва да има един - и за предпочитане само един - очевиден начин да се направи нещо.)

Кратка история ​

  • 1991: първата версия, от Guido van Rossum в Нидерландия. Името идва от комедийното шоу Monty Python's Flying Circus, а не от змията.
  • 1994: Python 1.0. 2000: Python 2.0.
  • 2008: Python 3.0 - несъвместим с Python 2. Python 2 приключи през 2020: ако намерите код на Python 2 (print "hello" без скоби), той е стар.
  • От 2019 г. нова версия излиза всеки октомври (3.12 през 2023, 3.13 през 2024, 3.14 през 2025, 3.15 през 2026) и всяка версия получава поправки за сигурност в продължение на 5 години. В този курс използвате 3.12 или по-нова: става всяка версия от 3.12 до най-новата.

Реализации (implementations) ​

Python е език; програмата, която изпълнява Python код, е реализация (implementation):

РеализацияКакво е
CPythonстандартната, написана на C - Python-ът, който инсталирате от python.org. Когато се каже "Python", се има предвид CPython
PyPyпо-бърза реализация с JIT компилатор, за дълго работещ код на чист Python
PyodideCPython, компилиран за браузъра (WebAssembly) - той изпълнява примерите на този сайт
MicroPythonмалък Python за микроконтролери
Cythonне е реализация, а компилатор: код, подобен на Python, към C, за бързи разширения. Части от pandas са написани на него

По-стари имена, които още може да срещнете: Jython (Python върху Java) и IronPython (Python върху .NET) днес рядко се използват.

3. Как Python изпълнява кода ви ​

Машинен код, компилатори и интерпретатори ​

Процесорът разбира само машинен код: много прости инструкции в двоичен вид. Програма на "човешки" език трябва първо да се преведе. Има два класически начина:

  • Компилаторът превежда цялата програма предварително, във файл, който се изпълнява (.exe). Като преводач, който превежда цялата книга, и след това вие я четете. Езици: C, C++, Rust; Java и C# се компилират до bytecode за виртуална машина.
  • Интерпретаторът чете програмата и я изпълнява веднага, statement по statement, без .exe. Като преводач на среща, изречение по изречение. Езици: Python, JavaScript, PHP, Ruby. SAS работи по подобен начин: компилира и изпълнява по една DATA step или PROC наведнъж.

Python е интерпретируем език, с малък компилатор вътре:

  1. чете файла ви и проверява синтаксиса - SyntaxError спира всичко тук, преди да се изпълни първият ред;
  2. превежда кода до bytecode - прости инструкции за виртуалната машина на Python (импортираните модули пазят своя bytecode в папки __pycache__ с файлове .pyc - ще видите такава в Homework repository);
  3. виртуалната машина на Python изпълнява bytecode-а, инструкция по инструкция;
  4. резултатите отиват на екрана, във файлове, в база данни.

От вашия код до резултата: скрипт, REPL или клетка в notebook отиват при интерпретатора на Python, който ги превежда до bytecode и го изпълнява

Можете да видите bytecode-а с модула dis (инструкциите се различават малко между версиите на Python):

python
import dis

dis.dis("interest = outstanding * rate / 100")
Променете кода и го изпълнете отново

За напреднали: по-бърз Python

Python 3.13 добави два експеримента: JIT компилатор (превръща често изпълнявания bytecode в машинен код) и free-threaded версия без GIL (Python код може да работи на няколко ядра на процесора едновременно). И двата са изключени по подразбиране. От 3.14 free-threaded версията се поддържа официално, а инсталаторите за Windows и macOS включват JIT (все още изключен по подразбиране). При работа с данни скоростта идва от библиотеките: pandas и NumPy вършат тежката работа на C.

Кратко видео за компилаторите и интерпретаторите: How do computers read code? (Frame of Essence). Hello World на стотици езици: rosettacode.org.

4. Инсталиране на Python и пакети ​

Инсталирахте инструментите преди курса - вижте Инсталиране на Python на вашия компютър. Този раздел обяснява какво прави всяка стъпка, за да можете да я повторите за нов проект.

Python ​

  • Windows: инсталаторът от python.org/downloads. На първия екран сложете отметка Add python.exe to PATH. Python се инсталира в C:\Users\<you>\AppData\Local\Programs\Python\Python3xx\.
  • macOS: инсталаторът от python.org или Homebrew (Using Python on macOS).
  • Linux: обикновено е инсталиран; иначе - чрез пакетния мениджър на системата (Using Python on Unix).

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

powershell
py --version          # the Python launcher
python --version      # if Python is in PATH
bash
python3 --version

"python" отваря Microsoft Store?

На Windows python може да стартира Microsoft Store вместо вашия Python. Използвайте py или изключете псевдонимите на магазина: Settings > Apps > Advanced app settings > App execution aliases, изключете python.exe и python3.exe. Ако командата изобщо не се намира, Python не е в PATH: How to add Python to PATH.

Няколко версии на Python ​

Можете да имате няколко версии една до друга. На Windows Python launcher py избира една от тях:

powershell
py --list            # the installed versions (also: py -0)
py -3.12 --version   # run a given version
py -3.12 -m venv .venv   # a virtual environment with Python 3.12

На macOS и Linux инструментите за това са pyenv и uv (uv python install 3.12). За Windows python.org вече предлага на първо място Python install manager: с него py install 3.13 инсталира версия, а py list показва инсталираните. Класическият инсталатор на всяка версия (с Add python.exe to PATH) все още е на страницата за изтегляне за Windows.

Пакети и pip ​

Пакетът (package, или библиотека) е код, който някой е написал, за да го ползват други: pandas, NumPy, matplotlib. pip инсталира пакети от PyPI:

КомандаКакво прави
pip install pandasинсталира последната версия, която работи с вашия Python
pip install "pandas>=2.2"версия 2.2 или по-нова
pip install --upgrade pandasинсталира по-нова версия
pip uninstall pandasпремахва го
pip listинсталираните пакети
pip show pandasверсията, къде е, от какво има нужда
pip freezeинсталираните пакети с точните им версии
pip install -r requirements.txtвсичко, изброено във файла
pip helpвсички команди (документацията на pip)

python -m pip

python -m pip install ... е същото като pip install ..., но със сигурност използва pip на този python. Използвайте го, когато не сте сигурни кой Python е активен.

Виртуални среди (virtual environments) ​

Защо. Всеки проект има нужда от свои пакети, често в определена версия: миналогодишният отчет иска pandas 2.2, новият модел - pandas 3. Ако всички проекти инсталират в единствения Python на компютъра, нова инсталация може да счупи стар проект (това се нарича dependency hell).

Какво. Виртуалната среда (venv) е папка в проекта - обикновено .venv - със собствено копие на python и собствени пакети. Пакетите, инсталирани докато тя е активна, отиват там, и само там.

Системният Python и два проекта, всеки със своя папка .venv и свои версии на пакетите

Модулът venv идва с Python. Веднъж за всеки проект, в папката на проекта:

powershell
py -m venv .venv
bash
python3 -m venv .venv

Всеки път, когато работите по проекта, я активирайте:

powershell
.venv\Scripts\activate            # PowerShell and cmd
source .venv/Scripts/activate     # only in Git Bash
bash
source .venv/bin/activate

Промптът започва с (.venv). Сега python и pip са тези от .venv:

powershell
where.exe python   # the first line must end with .venv\Scripts\python.exe
deactivate         # leave the virtual environment
bash
which python       # must end with .venv/bin/python
deactivate         # leave the virtual environment

PowerShell: "running scripts is disabled on this system"

PowerShell може да откаже да изпълни Activate.ps1. Разрешете го само за текущия терминал, след което активирайте отново:

powershell
Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope Process
.venv\Scripts\activate

Или използвайте Command Prompt (cmd): във VS Code стрелката v до + на панела с терминала отваря нов терминал от друг вид.

requirements.txt: списъкът с пакети ​

Проектът изброява пакетите си в requirements.txt, така че всеки да може да изгради същата среда. Homework repository има такъв файл:

text
jupyterlab>=4.2
ipykernel>=6.29
numpy>=2.0
pandas>=2.2
openpyxl>=3.1
sqlalchemy>=2.0
matplotlib>=3.9
bash
pip install -r requirements.txt     # install all of them
pip freeze > requirements.txt       # or: write down the exact versions you have now

pip freeze дава точни версии (pandas==3.1.0): използвайте го, когато един отчет трябва да дава същия резултат и догодина, на друг компютър. Това се нарича замразяване на зависимостите (freezing the dependencies) - предпазва от "но на моята машина работи".

pandas 2 или pandas 3?

>= означава "тази версия или по-нова", така че pandas>=2.2 инсталира най-новия pandas - днес това е pandas 3 (3.1 през октомври 2026). Сайтът също работи с pandas 3, затова в този курс използваме pandas 3; където pandas 2.2 се държи различно (типът на текстовите колони, копията на DataFrame), занятия 14 - 16 го казват. Проверете своята версия с pip show pandas.

За какво са пакетите на този курс:

ПакетЗа каквоЗанятия
numpyбързи масиви и изчисления с числа14 - 16
pandasтаблици (DataFrame): четене, филтриране, групиране, съединяване, запис14 - 16 (кратък поглед днес)
matplotlibграфики16 (кратък поглед в раздел 7)
jupyterlab, ipykernelJupyter notebooks, в браузъра и във VS Codeвсички
openpyxlчетене и запис на Excel файлове9, 14 - 16
sqlalchemyвръзка на pandas с база данни13, 16

seaborn (по-хубави статистически графики, върху matplotlib) не е в списъка - инсталирайте го с pip, ако искате да го пробвате.

Без виртуална среда: пример ​

Скрипт, който има нужда от пакет, който не е инсталиран, спира на import:

text
> python simple_plot.py
Traceback (most recent call last):
  File "C:\course\simple_plot.py", line 1, in <module>
    import matplotlib.pyplot as plt
ModuleNotFoundError: No module named 'matplotlib'

Решението не е pip install в системния Python, а: активирайте venv-а на проекта (или го създайте), pip install matplotlib там, и пуснете скрипта отново.

Други инструменти ​

ИнструментКакво е
uvнов, много бърз инструмент: версии на Python, виртуални среди и пакети в едно (uv venv, uv pip install)
Poetry, pipenvуправляват пакетите и venv-а на проекта заедно, с lock файл с точните версии
condaпакети и среди, също и за софтуер, който не е на Python; идва с Anaconda и Miniconda

Anaconda във фирма

Anaconda Distribution и каналът ѝ за пакети по подразбиране изискват платен лиценз в организации с повече от 200 служители. Този курс използва стандартния Python от python.org с venv и pip, който е безплатен за всички.

5. VS Code ​

Редактори и IDE ​

  • Visual Studio Code - безплатен, с отворен код (в GitHub), от Microsoft, за всеки език; разширенията добавят това, което ви трябва. Използваме го в курса. Работи и в браузъра: vscode.dev.
  • PyCharm - IDE за Python от JetBrains (има безплатна и платена версия).
  • Sublime Text - бърз, лек редактор.
  • JupyterLab - notebooks в браузъра (раздел 7).

Частите на прозореца ​

ЧастКъдеЗа какво
Activity Barнай-влявоExplorer, Search, Source Control (Git), Extensions
Side Barвлявофайловете на папката (Explorer)
Editorв средатавашите файлове, в табове
PanelдолуTerminal, Problems, Output
Status Barнай-долуактивният Python (например 3.12.7 ('.venv')) - кликнете върху него, за да го смените

Още за четене: User interface.

Разширения и теми ​

Инсталирайте ги от изгледа Extensions (Ctrl+Shift+X); и двете са от Microsoft:

  • Python - изпълнение и debugging на Python; инсталира и още три разширения: Pylance (довършване на кода, грешки докато пишете), Python Debugger и Python Environments;
  • Jupyter - notebooks във VS Code.

Следващите лекции работят с файлове с данни. Тези разширения ви помагат да ги разглеждате, без да излизате от VS Code:

  • Data Wrangler (Microsoft) - DataFrame или CSV файл като таблица, която можете да сортирате и филтрирате, със статистики за всяка колона; пише pandas кода за стъпките за почистване, които избирате с клик (лекции 14 - 16);
  • Rainbow CSV (mechatroner) - всяка колона на CSV файл в свой цвят и заявки като в SQL върху файла;
  • SQLite Viewer (Florian Klampfer) - таблиците на SQLite база данни (лекция 13);
  • Spreadsheet Viewer (MESCIUS) - файлове .xlsx във VS Code.

Не е нужно да ги търсите едно по едно: папката Homework ги изброява всички в .vscode/extensions.json и VS Code предлага да ги инсталира, когато отворите папката. Как става и как да използвате същия списък във ваши проекти: Разширения на VS Code.

Цветова тема: Ctrl+K Ctrl+T (Themes).

Папката е работно пространство (workspace) ​

Винаги отваряйте папката на проекта, а не отделни файлове: File > Open Folder или десен клик върху папката в Windows Explorer > Open with Code. Папката е вашето работно пространство (workspace): VS Code помни отворените файлове и можете да държите настройки само за тази папка в .vscode/settings.json (Ctrl+Shift+P > Preferences: Open Workspace Settings). Още за четене: What is a VS Code workspace?

За този курс папките са:

text
course/
    Python-Data-Analysts-UniCredit-Homework/   your work: tasks and homework
    Python-Data-Analysts-UniCredit-Labs/       the code from the lessons (only git pull)

Изберете Python-а на проекта ​

Ctrl+Shift+P > Python: Select Interpreter > този в .venv. След това VS Code изпълнява файловете ви с него, а новите терминали активират venv-а сами.

Създайте и пуснете Python файл ​

  1. В Explorer направете десен клик върху папката > New File и го наречете hello.py.

  2. Напишете:

    python
    my_name = "Iva"  # put your name
    print("Hello, " + my_name)
  3. Пуснете го по един от тези начини:

    • бутонът Run Python File (триъгълникът горе вдясно);
    • десен клик в редактора > Run Python > Run Python File in Terminal;
    • в терминала: python hello.py;

Изходът се появява в панела Terminal.

Клавишни комбинации, които си струва да научите ​

КлавишиДействие
Ctrl+Shift+PCommand Palette: всяка команда, по име
Ctrl+Pотваряне на файл по име
Ctrl+Sзапис
Ctrl+Z / Ctrl+Yотмяна / повторение
Ctrl+`показване / скриване на терминала
Ctrl+Bпоказване / скриване на Side Bar
Ctrl+Jпоказване / скриване на Panel
Ctrl+/коментиране / разкоментиране на избраните редове
Ctrl+Dизбира следващото съвпадение на избраното (редакция на няколко места наведнъж)
Alt+Up / Alt+Downпреместване на реда нагоре / надолу
Shift+Enterизпълнява избраните редове в Python терминал
F5изпълнение с debugger

В терминала cls (cmd) или clear изчиства екрана. Всички клавишни комбинации: keyboard reference sheets.

Git във VS Code ​

Изгледът Source Control (Ctrl+Shift+G) показва променените файлове; напишете съобщение, Commit, след това Sync (push). Командите за Homework repository са в Как да ползвате тези страници; самият Git е темата на занятие 10.

6. Терминалът и REPL ​

Пускане на скрипт ​

Скриптът е файл .py. Пуснете го от терминал, в папката на проекта:

bash
python hello.py                                    # a file in this folder
python 01-intro-syntax-types/practice/task1-first-values.py
python -c "print(2 ** 10)"                         # one line of code
python -m pip --version                            # run a module

REPL ​

python (или py) без файл стартира интерактивния Python - REPL (read, evaluate, print, loop - чете, изчислява, отпечатва, повтаря). Напишете ред, натиснете Enter и вижте резултата. Промптът е >>>; ... означава "продължете statement-а":

text
>>> 1044231.30 * 8.83 / 100
92205.62379000001
>>> rate = 8.83
>>> rate * 2
17.66
>>> exit()

Излизате с exit() или Ctrl+Z и после Enter (Windows), Ctrl+D (macOS, Linux). От Python 3.13 REPL има цветове, редакция на цели блокове, а exit работи и без скобите.

REPL е добър за бърз опит. За всичко, което искате да запазите, пишете файл или notebook.

7. Jupyter notebooks ​

Notebook (файл .ipynb) е документ от клетки (cells). Клетката с код се изпълнява и резултатът ѝ - число, таблица, графика - се появява точно под нея. Текстовите клетки обясняват работата. Това е най-близкото в Python до проект в Enterprise Guide или SQL worksheet: идеално за изследване на данни и показване на резултати.

Notebook в JupyterLab: Markdown клетка със заглавие, клетка с код, чийто резултат е таблица, и клетка с код със стълбовидна графика

На картинката (JupyterLab в браузъра):

  • вляво - файловият браузър: notebook-ът е обикновен файл, до папката data;
  • "Portfolio check" - Markdown клетка: заглавие и един ред текст;
  • [1] - клетка с код и резултатът ѝ, таблица; синята лента показва избраната клетка;
  • [2] - клетка с код, чийто резултат е графика;
  • горе вдясно - kernel-ът, Python 3 (ipykernel), Python-ът, който изпълнява кода; Idle в лентата на състоянието значи, че чака работа.

Какво е Jupyter? ​

Project Jupyter е безплатният проект с отворен код зад notebooks. Името идва от три езика: Julia, Python и R - notebook може да изпълнява и други езици, но ние използваме само Python.

Notebook-ът е файлът; няколко програми могат да отворят един и същ .ipynb:

ПрограмаКъде работи
JupyterLabв браузъра, стартиран от вашия компютър (jupyter lab)
VS Codeв редактора - това използваме в курса
облачни платформи за данни (например Google Colab, Databricks)на сървър, отваря се в браузъра

Файлът .ipynb е текст (JSON), който пази кода, текста и последните резултати. Затова notebook-ът запазва таблиците и графиките си, когато го затворите, а GitHub го показва като страница, с резултатите, без да го изпълнява.

За какво се използват notebooks ​

  • Изследване на нови данни - заредете файл, разгледайте го, филтрирайте, бройте, стъпка по стъпка: като SQL заявки, пуснати една след друга в worksheet.
  • Ad-hoc анализ - въпрос от ръководството, с отговор в таблица и графика и обяснение до тях.
  • Отчети и документация на модели - кодът, резултатът и коментарът в един файл: колега може да го изпълни отново и да получи същите числа.
  • Пробване на идея - проверете логиката на изчисление върху няколко реда, преди да влезе в скрипт.
  • Учене - пробвайте един ред и вижте резултата веднага.

Notebooks не са подходящи за задача, която се изпълнява всеки месец без човек, или за код, който много отчети ползват общо - за това пишете скрипт или модул (вижте "Скрипт или notebook?" в края на тази секция и лекция 10).

Пробвайте без инсталиране

jupyter.org/try отваря JupyterLab в браузъра, без нищо за инсталиране. Използвайте го само с измислени данни, никога с данните на банката.

Клетки ​

Вид клеткаКакво съдържа
Код (Code)Python код; изходът се показва под клетката
Markdownтекст със заглавия, списъци, таблици, връзки (Markdown syntax); HTML също работи
Rawтекст, който не се изпълнява и не се форматира

Kernel ​

Kernel-ът е Python процесът зад notebook-а. Той пази променливите между клетките: една клетка може да използва променлива от клетка над нея. (На този сайт всеки пример работи самостоятелно - в notebook не е така.)

  • Числото в [3] до клетката е редът, в който са изпълнени клетките.
  • Ако изпълнявате клетките разбъркано или изтриете клетка, kernel-ът все още помни нейните променливи. Преди да се доверите на резултат: Restart на kernel-а и Run All.

Инсталиране на Jupyter ​

Notebook-ът има нужда от два пакета във venv-а на проекта: ipykernel (изпълнява notebook-а с Python-а на venv-а) и jupyterlab (notebooks в браузъра). И двата са в requirements.txt (раздел 4) - ако сте го инсталирали, ги имате. В нов проект, с активен venv:

bash
pip install jupyterlab ipykernel
jupyter lab --version     # check: prints the version

Във VS Code ви трябва и разширението Jupyter (раздел 5).

"Running cells requires the ipykernel package"

VS Code показва това съобщение, когато избраният kernel няма ipykernel - обикновено е избран системният Python вместо .venv. Изберете kernel-а на .venv или натиснете Install.

Notebooks във VS Code ​

  1. Ctrl+Shift+P > Create: New Jupyter Notebook (или нов файл analysis.ipynb).
  2. Select Kernel (горе вдясно) > Python Environments > .venv на проекта.
  3. Напишете код в клетка; Shift+Enter я изпълнява и минава към следващата клетка.

Или в браузъра: jupyter lab в терминала (с активен venv) отваря JupyterLab.

Клетка с графика - същото работи и в notebook:

python
import pandas as pd
import matplotlib.pyplot as plt

loans = pd.read_csv("data/loans.csv")
by_product = loans.groupby("product")["outstanding"].sum() / 1_000_000
by_product.sort_values().plot.barh(title="Outstanding by product, million EUR")
plt.tight_layout()
plt.show()
Променете кода и го изпълнете отново

Клавишни комбинации ​

Клетката е в режим на редакция (edit mode - пишете в нея) или в команден режим (command mode - работите с цели клетки). Esc минава в команден режим, Enter - в режим на редакция.

РежимКлавишиДействие
и дватаShift+Enterизпълнява клетката, минава към следващата
и дватаCtrl+Enterизпълнява клетката, остава на нея
и дватаCtrl+Sзапис
команденA / Bвмъква клетка над / под
команденM / Yсменя клетката на Markdown / код
команденD Dизтрива клетката
команденZотменя изтриването
команденC / X / Vкопиране / изрязване / поставяне на клетки
редакцияTabдовършване или отстъп
редакцияShift+Tabпомощ за функцията (JupyterLab)
редакцияCtrl+/коментира редовете

Всички команди: Command Palette - Ctrl+Shift+P във VS Code, Ctrl+Shift+C в JupyterLab. Всички клавишни комбинации: Help > Show Keyboard Shortcuts (JupyterLab).

Магически команди (magics) ​

Редовете, които започват с % (един ред) или %% (цялата клетка), са команди на notebook-а, а не Python (IPython magics):

MagicКакво прави
%pip install seabornинсталира пакет в средата на kernel-а
%timeit sum(range(1000))измерва колко време отнема един ред
%%timeизмерва цялата клетка
%%htmlклетката е HTML (например вградено видео)
!dir (Windows), !lsизпълнява команда на системата

Скрипт или notebook? ​

NotebookСкрипт (.py)
изследване на данни, пробване на идеизадача, която се пуска отново и отново
резултати с таблици и графики до кодапуска се от терминала или от планировчик
споделяне на анализ с текстлесен за преглед и за версии в Git

Често и двете: изследвайте в notebook, после преместете готовия код в скрипт.

8. Структурата на една програма ​

Statements, по един на ред ​

Програмата е поредица от statements (инструкции), които се изпълняват отгоре надолу. В Python:

  • statement-ът свършва в края на реда - без ; като в SQL и SAS (можете да сложите ; между два statements на един ред, но никой не го прави);
  • дълъг statement продължава на следващия ред, докато има отворена скоба (, [ или { (или след \ в края на реда - избягвайте го);
  • изразът (expression) е част от кода, която дава стойност: 42, rate, outstanding * rate / 100.
python
outstanding = 1044231.30
rate = 8.83
yearly_interest = (outstanding
                   * rate
                   / 100)
print(yearly_interest)
Променете кода и го изпълнете отново

Отстъпът създава блоковете ​

SAS има do; ... end;, SQL има BEGIN ... END. В Python блокът - редовете, които принадлежат на if, на цикъл или на функция - е редовете, отместени навътре (indented) под ред, който завършва с :. Отстъпът не е украса: той е синтаксисът.

Една и съща задача - сумата и произведението на четири числа - в SAS и в Python:

sas
data _null_;
    total = 0;
    product = 1;
    do i = 1 to 4;
        total = total + i;
        product = product * i;
    end;
    put total= product=;
run;
python
numbers = [1, 2, 3, 4]
product = 1

for i in numbers:
    product = product * i      # inside the loop: indented

total = sum(numbers)
print(total, product)
Променете кода и го изпълнете отново

(Циклите са темата на занятие 2.) Още примери на различни езици един до друг: rosettacode.org.

Правила:

  • използвайте 4 интервала за ниво (PEP 8); VS Code вмъква 4 интервала, когато натиснете Tab във файл .py;
  • всички редове на един блок имат еднакъв отстъп;
  • никога не смесвайте tabs и интервали - Python спира с TabError: inconsistent use of tabs and spaces in indentation.

Отстъп там, където не се очаква:

python
loan_id = "L000001"
    stage = 1
print(loan_id, stage)
Променете кода и го изпълнете отново

IndentationError: unexpected indent - и нищо не се изпълнява, дори първият ред (синтаксисът се проверява преди програмата да започне, раздел 3).

Грешен отстъп може и да не даде никаква грешка - само грешен резултат. Намерете бъга:

python
days_past_due = 120

if days_past_due > 90:
    print("*" * 5)
    print("Non-performing")
else:
    print("-" * 5)
print("Performing")
Променете кода и го изпълнете отново
Отговор

print("Performing") не е отместен, затова не е част от блока на else: изпълнява се винаги, също и за кредит със 120 дни просрочие. Трябват му 4 интервала отпред.

Коментари ​

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

python
# The report date of the sample data
report_date = "2026-09-30"

stage = 3          # 1, 2 or 3 (IFRS 9)
# print("not run")
print(report_date, stage)
Променете кода и го изпълнете отново

Коментарите са за хората:

  • обяснявайте защо, а не какво - кодът вече казва какво;
  • кратко описание в началото на файла: какво прави, какви са входът и изходът му;
  • за да изключите редове, докато търсите бъг (Ctrl+/ във VS Code).

SAS има /* ... */ и * ... ;, SQL има -- и /* ... */. Python има само # (текст в тройни кавички понякога се използва за по-дълги бележки - повече в занятие 4). Стил: PEP 8 - Comments.

print() записва стойности на екрана, разделени с интервали, и завършва с нов ред. Две опции променят това: sep (разделителят) и end (какво идва накрая).

python
print("L000001", "investment", 1044231.30)
print("L000001", "investment", 1044231.30, sep=";")
print("2026", "09", "30", sep="-")

print("Loading", end="")
print("...", end="")
print(" done")
print()            # an empty line
print("end")
Променете кода и го изпълнете отново

input(): питане на потребителя ​

input() показва съобщение, чака потребителят да въведе ред и да натисне Enter, и връща въведеното - винаги като текст (str), дори когато потребителят въведе число. Преобразувайте го сами (раздел 12):

python
amount_text = input("Amount: ")          # the user types 2500
print(type(amount_text))                 # <class 'str'>
amount = float(amount_text)
print("Amount with 10% fee:", amount * 1.1)

input() не работи на този сайт - пробвайте го във VS Code (python file.py) или в notebook. В аналитичната работа рядко ви трябва: данните идват от файлове и бази данни.

Escape sequences ​

В string обратната наклонена черта \ започва escape sequence - символ, който не можете да въведете директно:

ПоследователностРезултат
\nнов ред
\tтабулация (tab)
\''
\""
\\една \
python
print("line 1\nline 2")
print("L000001\tinvestment\t1044231.30")
print('Client\'s rating')
print("Client's rating")          # or simply use the other quotes
print("C:\\data\\loans.csv")
Променете кода и го изпълнете отново

Пътищата в Windows са капан: в "C:\new\table.csv" \n е нов ред, а \t е табулация. Пишете пътя с \\, с / (Python го приема и на Windows) или като raw string r"...", в който \ е просто символ:

python
print("C:\new\table.csv")         # wrong
print(r"C:\new\table.csv")        # right: a raw string
print("C:/new/table.csv")         # right: forward slashes
Променете кода и го изпълнете отново

Всички escape sequences: String and bytes literals. От Python 3.12 непознат escape като "\d" дава SyntaxWarning.

9. Стойности и типове ​

Всяка стойност в Python има тип. Типът решава какво може да прави стойността: 1 + 2 събира числа, "1" + "2" съединява текстове.

python
print(1 + 2)
print("1" + "2")
print(3 * 4)
print(3 * "4")
print(True + True)
Променете кода и го изпълнете отново

Основните типове:

ТипСтойностиSQLSAS
intцели числа: 42, -7, 1_000_000INTEGER, BIGINTчислов (numeric)
floatчисла с дробна част: 8.83, 0.0005, 1.5e-3FLOAT, DOUBLEчислов (той е float)
strтекст: "EUR", 'L000001'VARCHAR, CHARсимволен (character)
boolTrue, FalseBOOLEAN, BIT1 / 0
NoneTypeNone - "няма стойност"NULLлипсваща стойност (., " ")

type() дава типа на една стойност:

python
for value in [42, 8.83, "EUR", True, None]:
    print(repr(value), type(value).__name__)
Променете кода и го изпълнете отново

Всичко е обект ​

В Python всяка стойност - число, текст, True, дори функция - е обект: парче памет, което знае своя тип и своята стойност. Затова стойностите имат методи (функции, които им принадлежат):

python
print(type(1))
print(type(1.0004))
print(type("double quotes"), type('single quotes'), type("""triple quotes"""))
print(type([]))
print((8.83).is_integer())
print("eur".upper())
Променете кода и го изпълнете отново

int - цели числа ​

python
print(42, +42, -42)
print(1_000_000 + 2_000_000)     # _ only makes long numbers readable
print(2 ** 100)                  # no limit on the size
Променете кода и го изпълнете отново

int в Python няма максимум: расте, колкото е нужно. (В SQL INTEGER спира около 2.1 милиарда, BIGINT - при 9.2 * 10**18.)

float - числа с дробна част ​

python
print(3.1234, -0.255)
print(.44, -.55)                 # the 0 in front may be left out
print(1.5e-3)                    # scientific notation: 1.5 * 10**-3
print(0.00005)                   # very small numbers are shown that way
print(1044231.30)                # the trailing 0 is not kept
Променете кода и го изпълнете отново

float е двоично число с плаваща запетая от 64 бита (IEEE 754 "double") - точно същото като числова стойност в SAS. Има около 15 - 17 значещи цифри. Повечето десетични дроби не могат да се запазят точно - раздел 14 показва какво означава това за парите.

Python има и комплексни числа complex (3 + 4j), за инженерни и научни задачи; няма да ви трябват в този курс.

str - текст ​

String-ът е поредица от символи (Unicode - кирилицата също работи), в единични или двойни кавички - няма разлика. Тройните кавички """...""" или '''...''' позволяват няколко реда:

python
product = "investment"
region = 'Пловдив'
note = """The loan was restructured
in March 2026."""
print(product, region)
print(note)
print(len(region))                # the number of characters
Променете кода и го изпълнете отново

String в единични кавички не може да продължи на следващия ред:

python
note = 'The loan was restructured
in March 2026.'
Променете кода и го изпълнете отново

bool - True и False ​

Резултатът от сравнение е bool. Обърнете внимание на главните букви: True, False.

python
days_past_due = 120
is_late = days_past_due > 0
is_non_performing = days_past_due > 90
print(is_late, is_non_performing)
print(type(is_late))
Променете кода и го изпълнете отново

bool е вид int: True е 1, а False е 0. Затова можете да броите с него - като sum(dpd > 90) в SAS SQL:

python
print(True + True + False)
print(sum([120 > 90, 35 > 90, 200 > 90]))   # how many are over 90
Променете кода и го изпълнете отново

None - няма стойност ​

None означава "няма стойност (засега)" - като NULL в SQL и липсваща стойност в SAS.

python
industry = None             # retail clients have no industry code
print(industry)
print(industry is None)     # the right way to test for None
print(type(industry))
Променете кода и го изпълнете отново

None не е NULL

В SQL NULL = NULL не е истина и трябва да пишете IS NULL. В SAS липсващото . е по-малко от всяко число, затова if x < 0 е истина за липсващи стойности. В Python None == None е True, а None < 0 е грешка. Проверявайте с x is None. (pandas има свои липсващи стойности, NaN и NA - занятие 14.)

10. Променливи ​

Име за стойност ​

Променливата е име за стойност. Присвояването = изчислява израза отдясно и дава име на резултата:

python
loan_id = "L000001"
outstanding = 1044231.30
rate = 8.83

interest = outstanding * rate / 100
print(loan_id, interest)
Променете кода и го изпълнете отново
  • Няма деклариране: променливата съществува от първото си присвояване (за разлика от LENGTH в SAS или DECLARE в SQL).
  • Име, на което не сте присвоили стойност, е грешка:
python
outstanding = 1044231.30
print(outstandng)
Променете кода и го изпълнете отново

Имена, а не кутии ​

В много езици променливата е кутия, която съдържа стойност. В Python е по-точно да се каже: стойността е обект в паметта, а променливата е име (етикет), свързано с този обект. Присвояването свързва име с обект; id() дава идентичността на обекта (в CPython - адреса му в паметта):

python
x = 5
y = x            # y is bound to the same object as x
print(id(x), id(y))

x = 3            # x is bound to a new object; y still to 5
print(x, y)
print(id(x), id(y))
Променете кода и го изпълнете отново

Новото присвояване не променя стария обект: то премества името към нов. Обект, който вече няма име, се изтрива автоматично от garbage collector-а - никога не освобождавате памет сами.

Динамично типизиране (dynamic typing) ​

Типът принадлежи на обекта, а не на името. Едно и също име може да е свързано с int сега и със str по-късно:

python
value = 42
print(type(value))
value = "42"
print(type(value))
Променете кода и го изпълнете отново

В SAS типът на променливата се фиксира в DATA step; в SQL типът на колоната се фиксира в таблицата. Python проверява типовете едва когато кодът се изпълнява - грешката се появява като TypeError на този ред. Дръжте един тип за едно име: така кодът се чете по-лесно. (Type hints, като rate: float = 8.83, документират очаквания тип - занятие 4.)

Анимация

Имена и обекти: 5. Типът е на обекта

Правила за имената ​

Иначе: SyntaxError.

  • букви, цифри и _; без интервали, без -;
  • не трябва да започва с цифра;
  • не трябва да е ключова дума (keyword: if, for, class, None, True, ...);
  • имената различават малки и главни букви (case-sensitive): rate, Rate и RATE са три различни имена - не както в SAS и SQL, където това няма значение.
python
import keyword

print(keyword.kwlist)      # the words you cannot use as names
Променете кода и го изпълнете отново
python
first_name = "Ada"
print(first_Name)          # NameError: a different name
Променете кода и го изпълнете отново
python
sur-name = "Byron"         # SyntaxError: "-" is minus
Променете кода и го изпълнете отново

Конвенции за имената (PEP 8) ​

PEP 8 е ръководството за стил на Python. За имената:

КаквоСтилПример
променливи, функцииsnake_case: малки букви, думите свързани с _days_past_due, client_since
константи (стойности, които не се променят)UPPER_SNAKE_CASEREPORT_DATE = "2026-09-30"
класове (занятие 11)CapWordsLoan, RatingScale
  • Имена, които казват какво има вътре: outstanding, а не x или data2.
  • Булевите стойности - като въпрос: is_late, has_collateral.
  • camelCase (daysPastDue) се използва само в стар код, който вече го има.
  • Python няма истински константи: UPPER_CASE само казва на другите хора "не променяйте това".
  • Python позволява кирилски букви в имената, но пишете имената на английски.

Присвояване, в още форми ​

python
# several names at once
loan_id, stage = "L000001", 1
print(loan_id, stage)

# the same value for several names
x = y = 0
print(x, y)

# swap two values - no helper variable needed
a, b = 10, 20
a, b = b, a
print(a, b)
Променете кода и го изпълнете отново

Съкратеното присвояване (augmented assignment) променя променлива, като използва старата ѝ стойност:

StatementОзначава
total += 100total = total + 100
total -= 100total = total - 100
total *= 2total = total * 2
total /= 2total = total / 2
total //= 2, total %= 2, total **= 2същото с //, %, **
python
total = 0
total += 1044231.30
total += 651927.30
total += 644.25
print(total)
Променете кода и го изпълнете отново

del name премахва едно име (обектът изчезва, когато никое име не сочи към него):

python
temp = 42
del temp
print(temp)       # NameError
Променете кода и го изпълнете отново

11. Числа и оператори ​

Аритметични оператори ​

ОператорЗначениеПримерРезултат
+събиране7 + 29
-изваждане7 - 25
*умножение7 * 214
/деление - винаги float7 / 23.5
//целочислено деление: цялата част, закръглена надолу7 // 23
%остатък от деление (modulo)7 % 21
**степенуване7 ** 249
-xминус-7-7
python
print(5 - 3, 5 * 3, 5 / 3, 5 // 3, 5 % 3, 5 ** 3)
print(6 / 3)              # a float, even when it divides exactly
print(type(6 / 3))
print(2 + 3.0)            # int and float give a float
Променете кода и го изпълнете отново

// и % заедно разделят едно число на единици. 125 дни просрочие са колко месеца по 30 дни и колко дни отгоре?

python
days_past_due = 125
months = days_past_due // 30
days = days_past_due % 30
print(months, "months and", days, "days")
print(divmod(days_past_due, 30))      # both at once
Променете кода и го изпълнете отново

Деление в Python 2

В Python 2 5 / 3 беше 1 (като // сега). В Python 3 е 1.6666666666666667. Ако стар код дели цели числа, проверете кое от двете е имал предвид.

За напреднали: // и % с отрицателни числа

// закръгля надолу, към минус безкрайност: -7 // 2 е -4, а не -3, а -7 % 2 е 1. INT() в SAS и int() в Python отрязват дробната част към нулата: int(-3.5) е -3. При отрицателни стойности проверете кое ви трябва.

python
print(-7 // 2, -7 % 2, int(-7 / 2))
Променете кода и го изпълнете отново

Ред на операциите ​

Както в математиката и в SQL:

ПриоритетОператори
1 (първи)( )
2**
3-x (минус)
4*, /, //, %
5+, -
6сравнения: ==, !=, <, <=, >, >=
7not
8and
9 (последен)or

Операторите с еднакъв приоритет се изпълняват отляво надясно - освен **, който се изпълнява отдясно наляво. Когато се съмнявате, сложете скоби: така и кодът се чете по-лесно.

python
print(1000 + 2000 * 0.05)       # 1100.0
print((1000 + 2000) * 0.05)     # 150.0
print(-2 ** 2)                  # -4: ** comes before the minus
print(2 ** 3 ** 2)              # 512: 3 ** 2 first
Променете кода и го изпълнете отново

Анимация

Как се изчислява израз: 1. Приоритет, 2. Скоби, 3. ** и минус, 4. // и %

Оператори за сравнение ​

PythonSQLSASЗначение
====, EQравно
!=<>, !=^=, NEразлично
<, <=<, <=<, <= (LT, LE)по-малко (или равно)
>, >=>, >=>, >= (GT, GE)по-голямо (или равно)

= дава име, == сравнява. Резултатът е bool. Сравненията могат да се свързват във верига - като BETWEEN в SQL:

python
days_past_due = 45
print(days_past_due == 0)
print(days_past_due != 0)
print(30 < days_past_due <= 90)      # the same as 30 < dpd and dpd <= 90
print("EUR" == "eur")                # texts: case matters
Променете кода и го изпълнете отново

Логически оператори ​

and, or и not комбинират условия - с малки букви, като думи:

python
days_past_due = 45
rating = 10
print(days_past_due > 90 or rating == 10)     # stage 3?
print(days_past_due > 0 and rating < 5)
print(not days_past_due > 90)
Променете кода и го изпълнете отново

& и | не са and и or

В SAS & и | означават AND и OR. В Python те са други (побитови) оператори. pandas ги използва за условия върху цели колони (занятие 15) - но за отделни стойности пишете and, or, not.

if с условия и подробностите за and / or идват в занятие 2.

Анимация

Как се изчислява израз: 5. Верига от сравнения, 6. and / or

Оператори върху strings ​

+ съединява два strings (като || в SQL и SAS), а * повтаря string:

python
print("ala" + "bala")
print("1" + "2")
print("-" * 30)
print("ab" * 3)
Променете кода и го изпълнете отново

Python не смесва типовете вместо вас - "ябълки с круши" е грешка:

python
print("Stage " + 3)
Променете кода и го изпълнете отново
python
print("ab" * "3")
Променете кода и го изпълнете отново

Решението е явно преобразуване, "Stage " + str(3) (раздел 12), или f-string (раздел 13).

Анимация

Как се изчислява израз: 7. Смесени типове

Първи поглед към методите на string ​

Strings имат много методи - функции, които извиквате с точка след стойността. Няколко, за първи поглед (в занятие 7 са всички):

python
print("ada".capitalize())
print("alabala".count("a"))
print("Alabala".count("a"))        # "A" is not "a"
print("AlabAla".find("a"))          # the position of the first "a", from 0
print("alabala".replace("a", "o"))
print("L000001,C0080,investment".split(","))
print("  EUR ".strip())
Променете кода и го изпълнете отново

Справка: String methods.

Вградени функции за числа ​

Готови за ползване, без import:

python
print(abs(2 - 5))
print(max(1, 2, 3), min(1, 2, 3))
print(round(2.51), round(2.49))
print(round(8.8349, 2))
print(sum([1044231.30, 651927.30, 644.25]))
print(pow(2, 10))
Променете кода и го изпълнете отново

round() има изненада за хората от SAS и SQL - вижте раздел 14.

Модулът math ​

Още функции има в модула math. Импортирайте го веднъж, в началото на файла:

python
import math

print(math.sqrt(16))
print(math.pi)
print(math.floor(2.9), math.ceil(2.1))     # down, up
print(math.floor(-2.5), math.ceil(-2.5))
print(math.pow(2, 3))                      # always a float (2 ** 3 is an int)
print(math.log(100, 10), math.exp(1))
Променете кода и го изпълнете отново

12. Преобразуване между типове ​

Функциите ​

Името на един тип е и функция, която преобразува стойност към него:

ФункцияДаваПримери
int(x)intint("42") -> 42, int(3.99) -> 3 (отрязва, не закръгля)
float(x)a floatfloat("8.83") -> 8.83, float(5) -> 5.0
str(x)a strstr(1044231.3) -> "1044231.3"
bool(x)a boolbool(0) -> False, bool("no") -> True

Текст към числа ​

Данните от файлове, input(), експорти от Excel и уеб често идват като текст. Един ред от loans.csv, преди всяко преобразуване, е само string:

python
row = "L000002,C0132,investment,EUR,2019-04-16,2029-04-16,1977400.00,651927.30,5.44,35,2"
print(row.split(","))
Променете кода и го изпълнете отново

Всяко парче е str. Не можете да смятате с тях, преди да ги преобразувате:

python
outstanding_text = "651927.30"
rate_text = "5.44"
days_text = "35"

outstanding = float(outstanding_text)
rate = float(rate_text)
days_past_due = int(days_text)

print(outstanding * rate / 100)
print(days_past_due > 30)
Променете кода и го изпълнете отново

Какво приемат int() и float() и какво не:

python
print(int("42"), int(" 42 "), int("0042"), int("-7"), int("1_000"))
print(float("8.83"), float("1e3"), float(" 5 "))
Променете кода и го изпълнете отново
python
print(int("3.5"))       # ValueError: not a whole number - use int(float("3.5"))
Променете кода и го изпълнете отново
python
print(float("1 044 231,30"))     # ValueError: Bulgarian format
Променете кода и го изпълнете отново

Числата, записани по българския начин - интервал между хилядите, запетая пред дробната част - трябва първо да се почистят (още методи на string в занятие 7):

python
text = "1 044 231,30"
clean = text.replace(" ", "").replace(",", ".")
print(clean, float(clean))
Променете кода и го изпълнете отново

SAS преобразува, Python - не

SAS превръща "5" в 5 сам и пише NOTE в log-а. Python никога не превръща текст в числа сам: "5" + 5 е TypeError. Това е "явното е по-добро от неявното" - няма да получите тихо грешно число.

Между числа ​

python
print(float(5))          # 5.0
print(int(3.99))         # 3: int() cuts the fraction
print(int(-3.99))        # -3: towards zero
print(round(3.99))       # 4: round() rounds
print(2 + 3.5)           # int + float: the int becomes a float by itself
Променете кода и го изпълнете отново

Python преобразува автоматично само там, където нищо не се губи: int към float в израз с float, и bool към int (True + 1 е 2).

Числа към текст ​

python
outstanding = 1044231.30
print(str(outstanding))              # the trailing 0 is lost
print("Outstanding: " + str(outstanding))
print(f"Outstanding: {outstanding:.2f}")   # better: an f-string, section 13
Променете кода и го изпълнете отново

Към bool: truthy и falsy ​

bool() дава False за "празни" стойности и True за всичко останало:

False (falsy)True (truthy)
0, 0.0всяко друго число, също и -1
"" (празен string)всеки непразен string, също и "0", "False", " "
None
празни колекции: [], {}непразни колекции
python
print(bool(0), bool(0.0), bool(""), bool(None))
print(bool(-1), bool("0"), bool("False"), bool(" "))
Променете кода и го изпълнете отново

bool("False") е True! За да прочетете "yes" / "no" или "True" / "False" от файл, сравнете текста:

python
restructured_text = "False"
restructured = restructured_text == "True"
print(restructured, type(restructured))
Променете кода и го изпълнете отново

13. Strings и f-strings ​

Съединяването се чете трудно ​

python
client_id = "C0080"
product = "investment"
outstanding = 1044231.30

print("Client " + client_id + ", product " + product + ", outstanding " + str(outstanding) + " EUR")
Променете кода и го изпълнете отново

f-strings ​

f-string има f преди кавичките. В него { } съдържат произволен Python израз; стойността му се поставя в текста:

python
client_id = "C0080"
product = "investment"
outstanding = 1044231.30
rate = 8.83

print(f"Client {client_id}, product {product}, outstanding {outstanding} EUR")
print(f"Yearly interest: {outstanding * rate / 100}")
print(f"{client_id=}")              # name=value, for checking values
Променете кода и го изпълнете отново

Няколко реда, с тройни кавички:

python
loan_id = "L000001"
stage = 1
print(f"""Loan:  {loan_id}
Stage: {stage}
Late:  {stage > 1}""")
Променете кода и го изпълнете отново

Форматиране на стойностите ​

След : в { } идва спецификация на формата (format specification) - като SAS формат:

f-stringРезултатКакво означава
f"{1044231.3:.2f}"1044231.30f = число с фиксирана десетична точка; .2 = 2 цифри след точката (закръглено)
f"{1044231.3:,.2f}"1,044,231.30същото, а , слага запетая между хилядите
f"{0.0883:.2%}"8.83%% умножава по 100 и добавя знака %; 2 цифри след точката
f"{7:03d}"007d = цяло число; 3 = поне 3 знака; 0 = допълва с нули отпред
f"{0.00049:.2e}"4.90e-04e = научен запис: 4.90 x 10 на степен -4
f"{1044231.3:>15,.2f}" 1,044,231.3015 = ширина 15 знака; > = вдясно (интервали отпред)
f"{'EUR':<6}"EUR ширина 6 знака; < = вляво (интервали след текста)
f"{'EUR':^9}" EUR ширина 9 знака; ^ = в средата
f"{'EUR':*^9}"***EUR***същото, но свободните места се запълват с *, а не с интервали

Без <, > или ^ числата отиват вдясно, а текстът - вляво. Твърде малка ширина не отрязва стойността - стойността просто е по-дълга.

python
outstanding = 1044231.3
pd_value = 0.0049
day = 5

print(f"{outstanding:.2f}")
print(f"{outstanding:,.2f}")
print(f"{pd_value:.2%}")
print(f"Day of the month: {day:02d}")
print(f"--->{123:>10}<---")
print(f"--->{123:^10}<---")
print(f"--->{123:*^10}<---")

precision = 3
print(f"{12.34567:.{precision}f}")      # the format from a variable
Променете кода и го изпълнете отново

Шаблонът е {value:[fill][align][width][,][.precision][type]}: подравняване < вляво, > вдясно, ^ в центъра; тип d цяло число, f с фиксирана запетая, % процент, e научен запис. Всички опции: Format Specification Mini-Language.

Българският начин - интервал между хилядите и запетая пред дробната част - е на две замени разстояние:

python
outstanding = 1044231.3
text = f"{outstanding:,.2f}"
print(text.replace(",", " ").replace(".", ","))
Променете кода и го изпълнете отново

Малък отчет ​

Фиксираните ширини правят колони:

python
print(f"|{'=' * 10}|{'=' * 10}|")
print(f"|{1:>10}|{1:<10}|")
print(f"|{23:>10}|{23:<10}|")
print(f"|{456:>10}|{456:<10}|")
print(f"|{'=' * 10}|{'=' * 10}|")
Променете кода и го изпълнете отново

Същото с кредити:

python
print(f"{'loan':<10}{'product':<13}{'outstanding':>15}{'rate':>8}")
print("-" * 46)
print(f"{'L000001':<10}{'investment':<13}{1044231.30:>15,.2f}{0.0883:>8.2%}")
print(f"{'L000002':<10}{'investment':<13}{651927.30:>15,.2f}{0.0544:>8.2%}")
print(f"{'L000003':<10}{'credit_card':<13}{644.25:>15,.2f}{0.0479:>8.2%}")
Променете кода и го изпълнете отново

По-стари начини, които ще срещнете ​

Кодът, писан преди f-strings (Python 3.6, 2016), използва str.format() или %. Четете ги; пишете f-strings.

python
name, year = "Ada Byron", 1852

print("{} died in {}".format(name, year))          # str.format()
print("{1} died in {0}".format(year, name))        # by position
print("{:>10.2f}|".format(3.14159))                # the same format specification

print("%s died in %d" % (name, year))              # %-formatting, the oldest
print("%.2f" % 3.14159)
Променете кода и го изпълнете отново

14. Float, закръгляне и Decimal ​

Защо 0.1 + 0.2 не е 0.3 ​

python
print(0.1 + 0.2)
print(0.1 + 0.2 == 0.3)
print(f"{0.1:.30f}")
Променете кода и го изпълнете отново

float се пази в двоичен вид. Както 1/3 = 0.333... в десетичен вид, 1/10 няма край в двоичен вид: отрязва се след 53 двоични цифри, затова 0.1 в паметта е мъничко повече от 0.1. Обикновено не го виждате, защото print() показва най-краткия текст, който дава същото число. В суми на много стойности малките грешки се натрупват. Още за четене: Floating Point Arithmetic: Issues and Limitations.

SAS има същите float числа и същия ефект - може да го познавате от сравнения, при които трябва ROUND(x, 0.01) или "fuzz".

Сравнявайте float стойности с допуск, а не с ==:

python
import math

print(math.isclose(0.1 + 0.2, 0.3))
print(abs((0.1 + 0.2) - 0.3) < 1e-9)
Променете кода и го изпълнете отново

round() закръгля половинките към четно ​

python
print(round(0.5), round(1.5), round(2.5), round(3.5))
print(round(2.675, 2))
Променете кода и го изпълнете отново
  • round() закръгля 5 към четния съсед: round(2.5) е 2. Това е "банкерското закръгляне" (banker's rounding) - то не тласка сумите нагоре. SAS ROUND и SQL ROUND върху стойности DECIMAL / NUMERIC закръглят 5 далеч от нулата (2.5 -> 3).
  • round(2.675, 2) дава 2.67, защото 2.675 в двоичен вид е мъничко по-малко от 2.675.

За резултати, които трябва да съвпадат до стотинка със SAS, SQL или счетоводната система, използвайте Decimal.

Decimal: точни десетични числа ​

Модулът decimal от стандартната библиотека смята в десетичен вид, като човек на хартия - също като DECIMAL(18, 2) / NUMERIC в SQL.

python
from decimal import Decimal

print(0.1 + 0.2)
print(Decimal("0.1") + Decimal("0.2"))
print(Decimal("0.1") + Decimal("0.2") == Decimal("0.3"))
Променете кода и го изпълнете отново

Създавайте Decimal от string. От float той поема грешката на float - и показва точната стойност, която float всъщност има:

python
from decimal import Decimal

print(Decimal("0.1"))
print(Decimal(0.1))
Променете кода и го изпълнете отново

Закръгляне на пари с quantize ​

quantize() закръгля до знаците на дадената стойност; rounding казва как. ROUND_HALF_UP е закръглянето на SAS, на SQL и от училище:

python
from decimal import Decimal, ROUND_HALF_UP, ROUND_HALF_EVEN

cent = Decimal("0.01")

print(Decimal("2.675").quantize(cent, rounding=ROUND_HALF_UP))     # 2.68
print(round(2.675, 2))                                             # float: 2.67

print(Decimal("2.665").quantize(cent, rounding=ROUND_HALF_UP))     # 2.67: 5 goes up
print(Decimal("2.665").quantize(cent, rounding=ROUND_HALF_EVEN))   # 2.66: 5 goes to even
Променете кода и го изпълнете отново

Годишната лихва на три кредита, до стотинка:

python
from decimal import Decimal, ROUND_HALF_UP

cent = Decimal("0.01")
total = Decimal("0")

for outstanding, rate in [("1044231.30", "8.83"), ("651927.30", "5.44"), ("644.25", "4.79")]:
    interest = Decimal(outstanding) * Decimal(rate) / 100
    interest = interest.quantize(cent, rounding=ROUND_HALF_UP)
    print(interest)
    total += interest

print("Total:", total)
Променете кода и го изпълнете отново

Правила за Decimal:

  • Decimal с int работи; Decimal с float е TypeError - преобразувайте float с Decimal(str(x)).
  • Резултатът от деление има до 28 значещи цифри (precision по подразбиране); закръглете го с quantize(), когато ви трябват стотинки.
  • Decimal е по-бавен от float. Използвайте го за пари, които трябва да се съберат до стотинка: салда, лихви, равнения с главната книга. За лихвени проценти, PD, статистика и модели float е правилният избор.
  • pandas работи с float: там закръглявайте резултатите (занятие 15).
python
from decimal import Decimal

print(Decimal("100.50") * 2)
print(Decimal("100.50") * 1.1)      # TypeError: Decimal and float
Променете кода и го изпълнете отново

15. Упражнения ​

Отворете своето копие на Homework repository във VS Code (първия път: вижте Как да ползвате тези страници; преди занятието: вземете новите задачи) и пуснете задачите от терминала, в основната папка на repository-то:

bash
python 01-intro-syntax-types/practice/task1-first-values.py

Всеки файл е разделен на части. Всяка част има описание, след него редовете your code - пишете кода си между тях - и веднага след тях нейните проверки, които отпечатват OK или FAIL.

ЗадачаФайлКакво правите
1task1-first-values.pyПроменливи и типове за един кредит
2task2-predict-types.pyПредскажете стойността и типа на 14 израза, после проверете
3task3-calculations.pyПродължителността на този курс в часове; дни просрочие в месеци и дни; лихва
4task4-convert-text.pyПреобразувайте текстовите полета на ред от CSV, също и число в български формат
5task5-fstrings.pyФорматирайте суми, проценти и идентификатори; ред от отчет с фиксирани ширини
6task6-decimal.pyЛихва до стотинка с Decimal, закръглена по начина на SAS

В task2-predict-types.py заменете всяко "?" с вашата прогноза, преди да пуснете файла - смисълът е първо да помислите.

Обобщение ​

ТемаЗапомнете
Pythonбезплатен език с общо предназначение; CPython; нова версия всеки октомври; използвате 3.12 или по-нова
Как се изпълнявапроверка на синтаксиса -> bytecode -> виртуалната машина на Python; SyntaxError спира всичко преди първия ред
Подготовка на проектpy -m venv .venv, активиране, pip install -r requirements.txt; по един venv за проект
Пускане на кодpython file.py в терминала; REPL >>>; Jupyter notebooks (kernel-ът пази променливите)
Синтаксиседин statement на ред; блокове чрез отстъп (4 интервала); коментари с #
Типовеint, float, str, bool, None; type(x); всичко е обект
Променливииме, свързано с обект; = свързва; типът принадлежи на обекта; snake_case
Оператори+ - * / // % **; / дава float; == != < <= > >=; and or not
Преобразуванияint(), float(), str(), bool(); текстът никога не става число сам; bool("False") е True
f-stringsf"{x:,.2f}", f"{p:.2%}", f"{n:05d}", f"{s:<10}", f"{x=}"
Париfloat числата са двоични: 0.1 + 0.2 != 0.3; round() закръгля половинките към четно; Decimal("...") + quantize(..., ROUND_HALF_UP)

Домашно ​

  1. 01-intro-syntax-types/homework.py (в homework repository): карта на кредит - преобразувайте текстовите полета на един кредит, изчислете погасения дял, лихвата и месечната вноска и отпечатайте картата. Всяка проверка трябва да отпечата OK.
  2. Задачите за упражнение, които не довършихте в час - препоръчително, следващите задачи надграждат върху тях.
  3. По желание: напишете payment.py, който пита за сумата, годишния лихвен процент и броя години с input() и отпечатва месечната вноска (формулата е в homework.py), форматирана с два знака след запетаята и разделител на хилядите. Пуснете го в терминала.
  4. По желание: създайте notebook 01-practice.ipynb в папката си Homework, прочетете data/loans.csv с pandas (както в началото на тази страница) и покажете loans.head() и loans.describe().
  5. По желание: 01-intro-syntax-types/notebook.ipynb - кратки допълнителни задачи по днешните теми в Jupyter notebook, всяка с клетка за проверка. Отворете го във VS Code и изберете kernel-а .venv.

Още за четене ​

Следващото занятие: условни конструкции и цикли - if / elif / else, версията на Python на CASE WHEN от SQL, и цикли for / while по редовете на файл.

Създаден за