Български
Тема
Български
Тема
Днес ще се научите да:
pip и requirements.txt;print();int, float, str, bool, None;math;Decimal и ги закръгляте така, както го правят SAS и SQL.От SQL към Python - един и същ въпрос, по два начина:
SELECT SUM(outstanding) FROM loans WHERE stage = 3;import pandas as pd
loans = pd.read_csv("data/loans.csv")
print(loans.loc[loans["stage"] == 3, "outstanding"].sum())import pandas as pd
loans = pd.read_csv("data/loans.csv")
print(loans.loc[loans["stage"] == 3, "outstanding"].sum())До занятие 16 ще пишете такъв код всеки ден. Днес започваме от частите, от които е направен: стойности, типове, променливи и оператори.
Ива Попова - 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 - 16 | NumPy и pandas: версията на Python за вашата работа в SQL и SAS; финалният проект |
OK или FAIL, и домашно. Разглеждаме домашното в началото на следващото занятие.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 |
| Анимации стъпка по стъпка | Анимации |
| Финалният проект | Финален проект |
Python е език за програмиране с общо предназначение: безплатен, с отворен код и един от най-използваните езици в света. Използва се за:
За един анализатор основната причина са библиотеките: pandas и NumPy за таблици и числа, matplotlib за графики, statsmodels и scikit-learn за модели, openpyxl за Excel, SQLAlchemy за бази данни. Всички са безплатни.
| SQL | SAS | Python | |
|---|---|---|---|
| Какво е | език за заявки на базата данни | комерсиална система за данни и статистика | език с общо предназначение, с библиотеки за данни |
| Къде са данните | в базата данни | SAS data sets (.sas7bdat), библиотеки | в паметта: lists, dictionaries, pandas DataFrames; файлове и бази данни |
| Типична работа | select, join, групиране, филтриране | DATA step, PROCs, формати, макроси | всичко изброено, плюс автоматизация, графики, модели |
| Цена | част от базата данни | лиценз | безплатен |
Няма да спрете да ползвате SQL. Най-доброто място за филтриране и съединяване на големи таблици все още е базата данни; Python изпраща SQL заявката и работи с резултата (занятие 13). Python заменя най-вече SAS частта от работата - и добавя това, което нито SQL, нито SAS правят добре.
Как идеите от SAS се пренасят в Python (повечето идват в следващите занятия):
| SAS | Python |
|---|---|
| DATA step | цикъл по редовете (занятия 2 - 6) или pandas (занятия 14 - 16) |
PROC SORT | sorted(), DataFrame.sort_values() |
PROC MEANS, PROC SUMMARY | sum(), statistics, DataFrame.groupby().agg() |
PROC FREQ | collections.Counter, value_counts(), pd.crosstab() |
PROC TRANSPOSE | DataFrame.pivot(), melt() |
формати (COMMA12.2, PERCENT8.2) | f-strings: f"{x:,.2f}", f"{x:.2%}" - раздел 13 |
макроси, %LET | функции (занятие 4), променливи |
LIBNAME | пътища до файлове, връзки към бази данни |
| SAS log-ът | изходът в терминала; съобщенията за грешки (tracebacks) |
| проект в Enterprise Guide | Jupyter notebook - раздел 7 |
Python идва с голяма стандартна библиотека: модули за файлове, CSV, JSON, дати, точни десетични числа, регулярни изрази, бази данни SQLite, статистика и много други. Само ги импортирате с import. Всичко останало е в PyPI, Python Package Index (https://pypi.org): стотици хиляди безплатни пакети, които се инсталират с pip (раздел 4).
import statistics
rates = [8.83, 5.44, 4.79, 8.35]
print(statistics.mean(rates))
print(statistics.median(rates))import statistics
rates = [8.83, 5.44, 4.79, 8.35]
print(statistics.mean(rates))
print(statistics.median(rates))Правилата, по които е създаден езикът, написани от Tim Peters. Пуснете import this, за да видите всичките 19:
import thisimport thisТези, които най-много ще усетите в този курс:
"5" в 5 вместо вас (SAS го прави, с бележка в log-а) - вие казвате какво искате (раздел 12).print "hello" без скоби), той е стар.Python е език; програмата, която изпълнява Python код, е реализация (implementation):
| Реализация | Какво е |
|---|---|
| CPython | стандартната, написана на C - Python-ът, който инсталирате от python.org. Когато се каже "Python", се има предвид CPython |
| PyPy | по-бърза реализация с JIT компилатор, за дълго работещ код на чист Python |
| Pyodide | CPython, компилиран за браузъра (WebAssembly) - той изпълнява примерите на този сайт |
| MicroPython | малък Python за микроконтролери |
| Cython | не е реализация, а компилатор: код, подобен на Python, към C, за бързи разширения. Части от pandas са написани на него |
По-стари имена, които още може да срещнете: Jython (Python върху Java) и IronPython (Python върху .NET) днес рядко се използват.
Процесорът разбира само машинен код: много прости инструкции в двоичен вид. Програма на "човешки" език трябва първо да се преведе. Има два класически начина:
.exe). Като преводач, който превежда цялата книга, и след това вие я четете. Езици: C, C++, Rust; Java и C# се компилират до bytecode за виртуална машина..exe. Като преводач на среща, изречение по изречение. Езици: Python, JavaScript, PHP, Ruby. SAS работи по подобен начин: компилира и изпълнява по една DATA step или PROC наведнъж.Python е интерпретируем език, с малък компилатор вътре:
SyntaxError спира всичко тук, преди да се изпълни първият ред;__pycache__ с файлове .pyc - ще видите такава в Homework repository);Можете да видите bytecode-а с модула dis (инструкциите се различават малко между версиите на Python):
import dis
dis.dis("interest = outstanding * rate / 100")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.
Инсталирахте инструментите преди курса - вижте Инсталиране на Python на вашия компютър. Този раздел обяснява какво прави всяка стъпка, за да можете да я повторите за нов проект.
C:\Users\<you>\AppData\Local\Programs\Python\Python3xx\.Проверете го в терминал:
py --version # the Python launcher
python --version # if Python is in PATHpython3 --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.
Можете да имате няколко версии една до друга. На Windows Python launcher py избира една от тях:
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.
Пакетът (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 е активен.
Защо. Всеки проект има нужда от свои пакети, често в определена версия: миналогодишният отчет иска pandas 2.2, новият модел - pandas 3. Ако всички проекти инсталират в единствения Python на компютъра, нова инсталация може да счупи стар проект (това се нарича dependency hell).
Какво. Виртуалната среда (venv) е папка в проекта - обикновено .venv - със собствено копие на python и собствени пакети. Пакетите, инсталирани докато тя е активна, отиват там, и само там.
Модулът venv идва с Python. Веднъж за всеки проект, в папката на проекта:
py -m venv .venvpython3 -m venv .venvВсеки път, когато работите по проекта, я активирайте:
.venv\Scripts\activate # PowerShell and cmd
source .venv/Scripts/activate # only in Git Bashsource .venv/bin/activateПромптът започва с (.venv). Сега python и pip са тези от .venv:
where.exe python # the first line must end with .venv\Scripts\python.exe
deactivate # leave the virtual environmentwhich python # must end with .venv/bin/python
deactivate # leave the virtual environmentPowerShell: "running scripts is disabled on this system"
PowerShell може да откаже да изпълни Activate.ps1. Разрешете го само за текущия терминал, след което активирайте отново:
Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope Process
.venv\Scripts\activateИли използвайте Command Prompt (cmd): във VS Code стрелката v до + на панела с терминала отваря нов терминал от друг вид.
requirements.txt: списъкът с пакети Проектът изброява пакетите си в requirements.txt, така че всеки да може да изгради същата среда. Homework repository има такъв файл:
jupyterlab>=4.2
ipykernel>=6.29
numpy>=2.0
pandas>=2.2
openpyxl>=3.1
sqlalchemy>=2.0
matplotlib>=3.9pip install -r requirements.txt # install all of them
pip freeze > requirements.txt # or: write down the exact versions you have nowpip 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, ipykernel | Jupyter notebooks, в браузъра и във VS Code | всички |
openpyxl | четене и запис на Excel файлове | 9, 14 - 16 |
sqlalchemy | връзка на pandas с база данни | 13, 16 |
seaborn (по-хубави статистически графики, върху matplotlib) не е в списъка - инсталирайте го с pip, ако искате да го пробвате.
Скрипт, който има нужда от пакет, който не е инсталиран, спира на import:
> 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, който е безплатен за всички.
| Част | Къде | За какво |
|---|---|---|
| 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:
Следващите лекции работят с файлове с данни. Тези разширения ви помагат да ги разглеждате, без да излизате от VS Code:
.xlsx във VS Code.Не е нужно да ги търсите едно по едно: папката Homework ги изброява всички в .vscode/extensions.json и VS Code предлага да ги инсталира, когато отворите папката. Как става и как да използвате същия списък във ваши проекти: Разширения на VS Code.
Цветова тема: Ctrl+K Ctrl+T (Themes).
Винаги отваряйте папката на проекта, а не отделни файлове: 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?
За този курс папките са:
course/
Python-Data-Analysts-UniCredit-Homework/ your work: tasks and homework
Python-Data-Analysts-UniCredit-Labs/ the code from the lessons (only git pull)Ctrl+Shift+P > Python: Select Interpreter > този в .venv. След това VS Code изпълнява файловете ви с него, а новите терминали активират venv-а сами.
В Explorer направете десен клик върху папката > New File и го наречете hello.py.
Напишете:
my_name = "Iva" # put your name
print("Hello, " + my_name)Пуснете го по един от тези начини:
python hello.py;Изходът се появява в панела Terminal.
| Клавиши | Действие |
|---|---|
Ctrl+Shift+P | Command 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.
Изгледът Source Control (Ctrl+Shift+G) показва променените файлове; напишете съобщение, Commit, след това Sync (push). Командите за Homework repository са в Как да ползвате тези страници; самият Git е темата на занятие 10.
Скриптът е файл .py. Пуснете го от терминал, в папката на проекта:
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 modulepython (или py) без файл стартира интерактивния Python - REPL (read, evaluate, print, loop - чете, изчислява, отпечатва, повтаря). Напишете ред, натиснете Enter и вижте резултата. Промптът е >>>; ... означава "продължете statement-а":
>>> 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.
Notebook (файл .ipynb) е документ от клетки (cells). Клетката с код се изпълнява и резултатът ѝ - число, таблица, графика - се появява точно под нея. Текстовите клетки обясняват работата. Това е най-близкото в Python до проект в Enterprise Guide или SQL worksheet: идеално за изследване на данни и показване на резултати.

На картинката (JupyterLab в браузъра):
data;[1] - клетка с код и резултатът ѝ, таблица; синята лента показва избраната клетка;[2] - клетка с код, чийто резултат е графика;Python 3 (ipykernel), Python-ът, който изпълнява кода; Idle в лентата на състоянието значи, че чака работа.Project Jupyter е безплатният проект с отворен код зад notebooks. Името идва от три езика: Julia, Python и R - notebook може да изпълнява и други езици, но ние използваме само Python.
Notebook-ът е файлът; няколко програми могат да отворят един и същ .ipynb:
| Програма | Къде работи |
|---|---|
| JupyterLab | в браузъра, стартиран от вашия компютър (jupyter lab) |
| VS Code | в редактора - това използваме в курса |
| облачни платформи за данни (например Google Colab, Databricks) | на сървър, отваря се в браузъра |
Файлът .ipynb е текст (JSON), който пази кода, текста и последните резултати. Затова notebook-ът запазва таблиците и графиките си, когато го затворите, а GitHub го показва като страница, с резултатите, без да го изпълнява.
Notebooks не са подходящи за задача, която се изпълнява всеки месец без човек, или за код, който много отчети ползват общо - за това пишете скрипт или модул (вижте "Скрипт или notebook?" в края на тази секция и лекция 10).
Пробвайте без инсталиране
jupyter.org/try отваря JupyterLab в браузъра, без нищо за инсталиране. Използвайте го само с измислени данни, никога с данните на банката.
| Вид клетка | Какво съдържа |
|---|---|
| Код (Code) | Python код; изходът се показва под клетката |
| Markdown | текст със заглавия, списъци, таблици, връзки (Markdown syntax); HTML също работи |
| Raw | текст, който не се изпълнява и не се форматира |
Kernel-ът е Python процесът зад notebook-а. Той пази променливите между клетките: една клетка може да използва променлива от клетка над нея. (На този сайт всеки пример работи самостоятелно - в notebook не е така.)
[3] до клетката е редът, в който са изпълнени клетките.Notebook-ът има нужда от два пакета във venv-а на проекта: ipykernel (изпълнява notebook-а с Python-а на venv-а) и jupyterlab (notebooks в браузъра). И двата са в requirements.txt (раздел 4) - ако сте го инсталирали, ги имате. В нов проект, с активен venv:
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.
Ctrl+Shift+P > Create: New Jupyter Notebook (или нов файл analysis.ipynb)..venv на проекта.Shift+Enter я изпълнява и минава към следващата клетка.Или в браузъра: jupyter lab в терминала (с активен venv) отваря JupyterLab.
Клетка с графика - същото работи и в notebook:
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()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).
Редовете, които започват с % (един ред) или %% (цялата клетка), са команди на notebook-а, а не Python (IPython magics):
| Magic | Какво прави |
|---|---|
%pip install seaborn | инсталира пакет в средата на kernel-а |
%timeit sum(range(1000)) | измерва колко време отнема един ред |
%%time | измерва цялата клетка |
%%html | клетката е HTML (например вградено видео) |
!dir (Windows), !ls | изпълнява команда на системата |
| Notebook | Скрипт (.py) |
|---|---|
| изследване на данни, пробване на идеи | задача, която се пуска отново и отново |
| резултати с таблици и графики до кода | пуска се от терминала или от планировчик |
| споделяне на анализ с текст | лесен за преглед и за версии в Git |
Често и двете: изследвайте в notebook, после преместете готовия код в скрипт.
Програмата е поредица от statements (инструкции), които се изпълняват отгоре надолу. В Python:
; като в SQL и SAS (можете да сложите ; между два statements на един ред, но никой не го прави);(, [ или { (или след \ в края на реда - избягвайте го);42, rate, outstanding * rate / 100.outstanding = 1044231.30
rate = 8.83
yearly_interest = (outstanding
* rate
/ 100)
print(yearly_interest)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:
data _null_;
total = 0;
product = 1;
do i = 1 to 4;
total = total + i;
product = product * i;
end;
put total= product=;
run;numbers = [1, 2, 3, 4]
product = 1
for i in numbers:
product = product * i # inside the loop: indented
total = sum(numbers)
print(total, product)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.
Правила:
Tab във файл .py;TabError: inconsistent use of tabs and spaces in indentation.Отстъп там, където не се очаква:
loan_id = "L000001"
stage = 1
print(loan_id, stage)loan_id = "L000001"
stage = 1
print(loan_id, stage)IndentationError: unexpected indent - и нищо не се изпълнява, дори първият ред (синтаксисът се проверява преди програмата да започне, раздел 3).
Грешен отстъп може и да не даде никаква грешка - само грешен резултат. Намерете бъга:
days_past_due = 120
if days_past_due > 90:
print("*" * 5)
print("Non-performing")
else:
print("-" * 5)
print("Performing")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 го пренебрегва.
# 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)# 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(): показване на стойности print() записва стойности на екрана, разделени с интервали, и завършва с нов ред. Две опции променят това: sep (разделителят) и end (какво идва накрая).
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")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):
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. В аналитичната работа рядко ви трябва: данните идват от файлове и бази данни.
В string обратната наклонена черта \ започва escape sequence - символ, който не можете да въведете директно:
| Последователност | Резултат |
|---|---|
\n | нов ред |
\t | табулация (tab) |
\' | ' |
\" | " |
\\ | една \ |
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")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"...", в който \ е просто символ:
print("C:\new\table.csv") # wrong
print(r"C:\new\table.csv") # right: a raw string
print("C:/new/table.csv") # right: forward slashesprint("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.
Всяка стойност в Python има тип. Типът решава какво може да прави стойността: 1 + 2 събира числа, "1" + "2" съединява текстове.
print(1 + 2)
print("1" + "2")
print(3 * 4)
print(3 * "4")
print(True + True)print(1 + 2)
print("1" + "2")
print(3 * 4)
print(3 * "4")
print(True + True)Основните типове:
| Тип | Стойности | SQL | SAS |
|---|---|---|---|
int | цели числа: 42, -7, 1_000_000 | INTEGER, BIGINT | числов (numeric) |
float | числа с дробна част: 8.83, 0.0005, 1.5e-3 | FLOAT, DOUBLE | числов (той е float) |
str | текст: "EUR", 'L000001' | VARCHAR, CHAR | символен (character) |
bool | True, False | BOOLEAN, BIT | 1 / 0 |
NoneType | None - "няма стойност" | NULL | липсваща стойност (., " ") |
type() дава типа на една стойност:
for value in [42, 8.83, "EUR", True, None]:
print(repr(value), type(value).__name__)for value in [42, 8.83, "EUR", True, None]:
print(repr(value), type(value).__name__)В Python всяка стойност - число, текст, True, дори функция - е обект: парче памет, което знае своя тип и своята стойност. Затова стойностите имат методи (функции, които им принадлежат):
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())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 - цели числа print(42, +42, -42)
print(1_000_000 + 2_000_000) # _ only makes long numbers readable
print(2 ** 100) # no limit on the sizeprint(42, +42, -42)
print(1_000_000 + 2_000_000) # _ only makes long numbers readable
print(2 ** 100) # no limit on the sizeint в Python няма максимум: расте, колкото е нужно. (В SQL INTEGER спира около 2.1 милиарда, BIGINT - при 9.2 * 10**18.)
float - числа с дробна част 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 keptprint(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 keptfloat е двоично число с плаваща запетая от 64 бита (IEEE 754 "double") - точно същото като числова стойност в SAS. Има около 15 - 17 значещи цифри. Повечето десетични дроби не могат да се запазят точно - раздел 14 показва какво означава това за парите.
Python има и комплексни числа complex (3 + 4j), за инженерни и научни задачи; няма да ви трябват в този курс.
str - текст String-ът е поредица от символи (Unicode - кирилицата също работи), в единични или двойни кавички - няма разлика. Тройните кавички """...""" или '''...''' позволяват няколко реда:
product = "investment"
region = 'Пловдив'
note = """The loan was restructured
in March 2026."""
print(product, region)
print(note)
print(len(region)) # the number of charactersproduct = "investment"
region = 'Пловдив'
note = """The loan was restructured
in March 2026."""
print(product, region)
print(note)
print(len(region)) # the number of charactersString в единични кавички не може да продължи на следващия ред:
note = 'The loan was restructured
in March 2026.'note = 'The loan was restructured
in March 2026.'bool - True и False Резултатът от сравнение е bool. Обърнете внимание на главните букви: True, False.
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))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:
print(True + True + False)
print(sum([120 > 90, 35 > 90, 200 > 90])) # how many are over 90print(True + True + False)
print(sum([120 > 90, 35 > 90, 200 > 90])) # how many are over 90None - няма стойност None означава "няма стойност (засега)" - като NULL в SQL и липсваща стойност в SAS.
industry = None # retail clients have no industry code
print(industry)
print(industry is None) # the right way to test for None
print(type(industry))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.)
Променливата е име за стойност. Присвояването = изчислява израза отдясно и дава име на резултата:
loan_id = "L000001"
outstanding = 1044231.30
rate = 8.83
interest = outstanding * rate / 100
print(loan_id, interest)loan_id = "L000001"
outstanding = 1044231.30
rate = 8.83
interest = outstanding * rate / 100
print(loan_id, interest)LENGTH в SAS или DECLARE в SQL).outstanding = 1044231.30
print(outstandng)outstanding = 1044231.30
print(outstandng)В много езици променливата е кутия, която съдържа стойност. В Python е по-точно да се каже: стойността е обект в паметта, а променливата е име (етикет), свързано с този обект. Присвояването свързва име с обект; id() дава идентичността на обекта (в CPython - адреса му в паметта):
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))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-а - никога не освобождавате памет сами.
Анимация
Имена и обекти: 1. Име и обект, 2. Нова стойност, 3. Две имена, един обект
Типът принадлежи на обекта, а не на името. Едно и също име може да е свързано с int сега и със str по-късно:
value = 42
print(type(value))
value = "42"
print(type(value))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.
_; без интервали, без -;if, for, class, None, True, ...);rate, Rate и RATE са три различни имена - не както в SAS и SQL, където това няма значение.import keyword
print(keyword.kwlist) # the words you cannot use as namesimport keyword
print(keyword.kwlist) # the words you cannot use as namesfirst_name = "Ada"
print(first_Name) # NameError: a different namefirst_name = "Ada"
print(first_Name) # NameError: a different namesur-name = "Byron" # SyntaxError: "-" is minussur-name = "Byron" # SyntaxError: "-" is minusPEP 8 е ръководството за стил на Python. За имената:
| Какво | Стил | Пример |
|---|---|---|
| променливи, функции | snake_case: малки букви, думите свързани с _ | days_past_due, client_since |
| константи (стойности, които не се променят) | UPPER_SNAKE_CASE | REPORT_DATE = "2026-09-30" |
| класове (занятие 11) | CapWords | Loan, RatingScale |
outstanding, а не x или data2.is_late, has_collateral.camelCase (daysPastDue) се използва само в стар код, който вече го има.UPPER_CASE само казва на другите хора "не променяйте това".# 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)# 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 += 100 | total = total + 100 |
total -= 100 | total = total - 100 |
total *= 2 | total = total * 2 |
total /= 2 | total = total / 2 |
total //= 2, total %= 2, total **= 2 | същото с //, %, ** |
total = 0
total += 1044231.30
total += 651927.30
total += 644.25
print(total)total = 0
total += 1044231.30
total += 651927.30
total += 644.25
print(total)del name премахва едно име (обектът изчезва, когато никое име не сочи към него):
temp = 42
del temp
print(temp) # NameErrortemp = 42
del temp
print(temp) # NameErrorАнимация
Имена и обекти: 4. x = x + 1, 6. Няколко имена наведнъж, 7. is и == (за напреднали)
| Оператор | Значение | Пример | Резултат |
|---|---|---|---|
+ | събиране | 7 + 2 | 9 |
- | изваждане | 7 - 2 | 5 |
* | умножение | 7 * 2 | 14 |
/ | деление - винаги float | 7 / 2 | 3.5 |
// | целочислено деление: цялата част, закръглена надолу | 7 // 2 | 3 |
% | остатък от деление (modulo) | 7 % 2 | 1 |
** | степенуване | 7 ** 2 | 49 |
-x | минус | -7 | -7 |
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 floatprint(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 дни и колко дни отгоре?
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 oncedays_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. При отрицателни стойности проверете кое ви трябва.
print(-7 // 2, -7 % 2, int(-7 / 2))print(-7 // 2, -7 % 2, int(-7 / 2))Както в математиката и в SQL:
| Приоритет | Оператори |
|---|---|
| 1 (първи) | ( ) |
| 2 | ** |
| 3 | -x (минус) |
| 4 | *, /, //, % |
| 5 | +, - |
| 6 | сравнения: ==, !=, <, <=, >, >= |
| 7 | not |
| 8 | and |
| 9 (последен) | or |
Операторите с еднакъв приоритет се изпълняват отляво надясно - освен **, който се изпълнява отдясно наляво. Когато се съмнявате, сложете скоби: така и кодът се чете по-лесно.
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 firstprint(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. // и %
| Python | SQL | SAS | Значение |
|---|---|---|---|
== | = | =, EQ | равно |
!= | <>, != | ^=, NE | различно |
<, <= | <, <= | <, <= (LT, LE) | по-малко (или равно) |
>, >= | >, >= | >, >= (GT, GE) | по-голямо (или равно) |
= дава име, == сравнява. Резултатът е bool. Сравненията могат да се свързват във верига - като BETWEEN в SQL:
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 mattersdays_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 mattersand, or и not комбинират условия - с малки букви, като думи:
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)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 (като || в SQL и SAS), а * повтаря string:
print("ala" + "bala")
print("1" + "2")
print("-" * 30)
print("ab" * 3)print("ala" + "bala")
print("1" + "2")
print("-" * 30)
print("ab" * 3)Python не смесва типовете вместо вас - "ябълки с круши" е грешка:
print("Stage " + 3)print("Stage " + 3)print("ab" * "3")print("ab" * "3")Решението е явно преобразуване, "Stage " + str(3) (раздел 12), или f-string (раздел 13).
Анимация
Как се изчислява израз: 7. Смесени типове
Strings имат много методи - функции, които извиквате с точка след стойността. Няколко, за първи поглед (в занятие 7 са всички):
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())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:
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))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. Импортирайте го веднъж, в началото на файла:
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))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))Името на един тип е и функция, която преобразува стойност към него:
| Функция | Дава | Примери |
|---|---|---|
int(x) | int | int("42") -> 42, int(3.99) -> 3 (отрязва, не закръгля) |
float(x) | a float | float("8.83") -> 8.83, float(5) -> 5.0 |
str(x) | a str | str(1044231.3) -> "1044231.3" |
bool(x) | a bool | bool(0) -> False, bool("no") -> True |
Данните от файлове, input(), експорти от Excel и уеб често идват като текст. Един ред от loans.csv, преди всяко преобразуване, е само string:
row = "L000002,C0132,investment,EUR,2019-04-16,2029-04-16,1977400.00,651927.30,5.44,35,2"
print(row.split(","))row = "L000002,C0132,investment,EUR,2019-04-16,2029-04-16,1977400.00,651927.30,5.44,35,2"
print(row.split(","))Всяко парче е str. Не можете да смятате с тях, преди да ги преобразувате:
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)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() и какво не:
print(int("42"), int(" 42 "), int("0042"), int("-7"), int("1_000"))
print(float("8.83"), float("1e3"), float(" 5 "))print(int("42"), int(" 42 "), int("0042"), int("-7"), int("1_000"))
print(float("8.83"), float("1e3"), float(" 5 "))print(int("3.5")) # ValueError: not a whole number - use int(float("3.5"))print(int("3.5")) # ValueError: not a whole number - use int(float("3.5"))print(float("1 044 231,30")) # ValueError: Bulgarian formatprint(float("1 044 231,30")) # ValueError: Bulgarian formatЧислата, записани по българския начин - интервал между хилядите, запетая пред дробната част - трябва първо да се почистят (още методи на string в занятие 7):
text = "1 044 231,30"
clean = text.replace(" ", "").replace(",", ".")
print(clean, float(clean))text = "1 044 231,30"
clean = text.replace(" ", "").replace(",", ".")
print(clean, float(clean))SAS преобразува, Python - не
SAS превръща "5" в 5 сам и пише NOTE в log-а. Python никога не превръща текст в числа сам: "5" + 5 е TypeError. Това е "явното е по-добро от неявното" - няма да получите тихо грешно число.
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 itselfprint(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 itselfPython преобразува автоматично само там, където нищо не се губи: int към float в израз с float, и bool към int (True + 1 е 2).
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 13outstanding = 1044231.30
print(str(outstanding)) # the trailing 0 is lost
print("Outstanding: " + str(outstanding))
print(f"Outstanding: {outstanding:.2f}") # better: an f-string, section 13bool: truthy и falsy bool() дава False за "празни" стойности и True за всичко останало:
False (falsy) | True (truthy) |
|---|---|
0, 0.0 | всяко друго число, също и -1 |
"" (празен string) | всеки непразен string, също и "0", "False", " " |
None | |
празни колекции: [], {} | непразни колекции |
print(bool(0), bool(0.0), bool(""), bool(None))
print(bool(-1), bool("0"), bool("False"), bool(" "))print(bool(0), bool(0.0), bool(""), bool(None))
print(bool(-1), bool("0"), bool("False"), bool(" "))bool("False") е True! За да прочетете "yes" / "no" или "True" / "False" от файл, сравнете текста:
restructured_text = "False"
restructured = restructured_text == "True"
print(restructured, type(restructured))restructured_text = "False"
restructured = restructured_text == "True"
print(restructured, type(restructured))client_id = "C0080"
product = "investment"
outstanding = 1044231.30
print("Client " + client_id + ", product " + product + ", outstanding " + str(outstanding) + " EUR")client_id = "C0080"
product = "investment"
outstanding = 1044231.30
print("Client " + client_id + ", product " + product + ", outstanding " + str(outstanding) + " EUR")f-string има f преди кавичките. В него { } съдържат произволен 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 valuesclient_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Няколко реда, с тройни кавички:
loan_id = "L000001"
stage = 1
print(f"""Loan: {loan_id}
Stage: {stage}
Late: {stage > 1}""")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.30 | f = число с фиксирана десетична точка; .2 = 2 цифри след точката (закръглено) |
f"{1044231.3:,.2f}" | 1,044,231.30 | същото, а , слага запетая между хилядите |
f"{0.0883:.2%}" | 8.83% | % умножава по 100 и добавя знака %; 2 цифри след точката |
f"{7:03d}" | 007 | d = цяло число; 3 = поне 3 знака; 0 = допълва с нули отпред |
f"{0.00049:.2e}" | 4.90e-04 | e = научен запис: 4.90 x 10 на степен -4 |
f"{1044231.3:>15,.2f}" | 1,044,231.30 | 15 = ширина 15 знака; > = вдясно (интервали отпред) |
f"{'EUR':<6}" | EUR | ширина 6 знака; < = вляво (интервали след текста) |
f"{'EUR':^9}" | EUR | ширина 9 знака; ^ = в средата |
f"{'EUR':*^9}" | ***EUR*** | същото, но свободните места се запълват с *, а не с интервали |
Без <, > или ^ числата отиват вдясно, а текстът - вляво. Твърде малка ширина не отрязва стойността - стойността просто е по-дълга.
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 variableoutstanding = 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.
Българският начин - интервал между хилядите и запетая пред дробната част - е на две замени разстояние:
outstanding = 1044231.3
text = f"{outstanding:,.2f}"
print(text.replace(",", " ").replace(".", ","))outstanding = 1044231.3
text = f"{outstanding:,.2f}"
print(text.replace(",", " ").replace(".", ","))Фиксираните ширини правят колони:
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}|")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}|")Същото с кредити:
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%}")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.
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)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)Decimal 0.1 + 0.2 не е 0.3 print(0.1 + 0.2)
print(0.1 + 0.2 == 0.3)
print(f"{0.1:.30f}")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 стойности с допуск, а не с ==:
import math
print(math.isclose(0.1 + 0.2, 0.3))
print(abs((0.1 + 0.2) - 0.3) < 1e-9)import math
print(math.isclose(0.1 + 0.2, 0.3))
print(abs((0.1 + 0.2) - 0.3) < 1e-9)round() закръгля половинките към четно print(round(0.5), round(1.5), round(2.5), round(3.5))
print(round(2.675, 2))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.
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"))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 всъщност има:
from decimal import Decimal
print(Decimal("0.1"))
print(Decimal(0.1))from decimal import Decimal
print(Decimal("0.1"))
print(Decimal(0.1))quantize quantize() закръгля до знаците на дадената стойност; rounding казва как. ROUND_HALF_UP е закръглянето на SAS, на SQL и от училище:
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 evenfrom 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Годишната лихва на три кредита, до стотинка:
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)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)).quantize(), когато ви трябват стотинки.Decimal е по-бавен от float. Използвайте го за пари, които трябва да се съберат до стотинка: салда, лихви, равнения с главната книга. За лихвени проценти, PD, статистика и модели float е правилният избор.float: там закръглявайте резултатите (занятие 15).from decimal import Decimal
print(Decimal("100.50") * 2)
print(Decimal("100.50") * 1.1) # TypeError: Decimal and floatfrom decimal import Decimal
print(Decimal("100.50") * 2)
print(Decimal("100.50") * 1.1) # TypeError: Decimal and floatОтворете своето копие на Homework repository във VS Code (първия път: вижте Как да ползвате тези страници; преди занятието: вземете новите задачи) и пуснете задачите от терминала, в основната папка на repository-то:
python 01-intro-syntax-types/practice/task1-first-values.pyВсеки файл е разделен на части. Всяка част има описание, след него редовете your code - пишете кода си между тях - и веднага след тях нейните проверки, които отпечатват OK или FAIL.
| Задача | Файл | Какво правите |
|---|---|---|
| 1 | task1-first-values.py | Променливи и типове за един кредит |
| 2 | task2-predict-types.py | Предскажете стойността и типа на 14 израза, после проверете |
| 3 | task3-calculations.py | Продължителността на този курс в часове; дни просрочие в месеци и дни; лихва |
| 4 | task4-convert-text.py | Преобразувайте текстовите полета на ред от CSV, също и число в български формат |
| 5 | task5-fstrings.py | Форматирайте суми, проценти и идентификатори; ред от отчет с фиксирани ширини |
| 6 | task6-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-strings | f"{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) |
01-intro-syntax-types/homework.py (в homework repository): карта на кредит - преобразувайте текстовите полета на един кредит, изчислете погасения дял, лихвата и месечната вноска и отпечатайте картата. Всяка проверка трябва да отпечата OK.payment.py, който пита за сумата, годишния лихвен процент и броя години с input() и отпечатва месечната вноска (формулата е в homework.py), форматирана с два знака след запетаята и разделител на хилядите. Пуснете го в терминала.01-practice.ipynb в папката си Homework, прочетете data/loans.csv с pandas (както в началото на тази страница) и покажете loans.head() и loans.describe().01-intro-syntax-types/notebook.ipynb - кратки допълнителни задачи по днешните теми в Jupyter notebook, всяка с клетка за проверка. Отворете го във VS Code и изберете kernel-а .venv.Следващото занятие: условни конструкции и цикли - if / elif / else, версията на Python на CASE WHEN от SQL, и цикли for / while по редовете на файл.