ლექცია 14 · XIV კვირაLecture 14 · Week XIV

კოდის სტილი
და პაკეტები
Code style
and packages

PEP 8 · style checker-ები · PyPI რეპოზიტორი · პარალელი სხვა ენების პაკეტების მენეჯერებთან PEP 8 · style checkers · the PyPI repository · a parallel with other languages' package managers

მოტივაციაMotivation

რატომ ვწუხდებით სტილზეWhy we care about style

კოდი ერთხელ იწერება და ათჯერ იკითხება — შენივე თავის მიერ, სამი თვის შემდეგ. Code is written once and read ten times — by you, three months from now.

def calc(x,y,z=0):
  a=x*y
  if a>100 :
      b = a*0.9
  else :
      b=a
  return b+z
def calculate_total(price, quantity, shipping=0):
    subtotal = price * quantity

    if subtotal > 100:
        subtotal *= 0.9      # 10% discount

    return subtotal + shipping
ორივე ერთნაირად მუშაობსგანსხვავება მხოლოდ ადამიანისთვისაა. და სწორედ ეს არის მთელი აზრი. Both work identicallyThe difference matters only to a human. And that is exactly the point.

კონტექსტიContext

რა არის PEPWhat is a PEP

Python Enhancement Proposal — საჯარო წინადადება ენის განვითარებაზე. ნებისმიერს შეუძლია დაწეროს; საზოგადოება განიხილავს. Python Enhancement Proposal — a public proposal for developing the language. Anyone may write one; the community discusses it.

PEP 8

კოდის სტილის სახელმძღვანელო. დღევანდელი თემა.

The code style guide. Today's topic.

PEP 20

Zen of Python — 19 პრინციპი. სცადე import this

The Zen of Python — 19 principles. Try import this

PEP 257

Docstring-ების კონვენცია

The docstring convention

PEP 484

ტიპების მინიშნებები (type hints)

Type hints

PEP 8 კანონი არააის რეკომენდაციაა. მაგრამ მას თითქმის მთელი Python-ის სამყარო იცავს — ამიტომ სხვისი კოდი ნაცნობი გამოიყურება, შენი კი — პროფესიული. PEP 8 is not a lawIt is a recommendation. But nearly the whole Python world follows it — which is why other people's code looks familiar, and yours looks professional.

PEP 8

განლაგებაLayout

# indentation — 4 spaces (not a tab!)
def function():
    if True:
        print("four spaces per level")

# line length — 79 characters at most
# wrap a long line with parentheses:
total = (first_value + second_value
         + third_value + fourth_value)

# two blank lines between functions
def first():
    pass


def second():
    pass


# one blank line — between logical blocks inside a function
def process(data):
    cleaned = data.strip()

    result = cleaned.upper()
    return result
79 სიმბოლო არქაიკაა?ნაწილობრივ. მაგრამ ვიწრო ხაზი გვერდიგვერდ ორი ფაილის ნახვას აადვილებს და კოდის მიმოხილვას (code review) ამარტივებს. ბევრი გუნდი 88 ან 100-ს იყენებს — მთავარია, ერთი წესი მოქმედებდეს. Is 79 characters archaic?Partly. But a narrow line makes it easy to view two files side by side and simplifies code review. Many teams use 88 or 100 — what matters is that one rule applies to everyone.

PEP 8

სახელდების კონვენციებიNaming conventions

რაWhat სტილიStyle მაგალითიExample
ცვლადი, ფუნქციაVariable, functionsnake_casestudent_name, calculate_total()
კონსტანტაConstantUPPER_CASEMAX_SCORE = 100
კლასიClassPascalCaseclass StudentRecord:
მოდული, ფაილიModule, filelowercasedata_utils.py
„შიდა“ სახელი"Internal" name_leading_internal_helper()
გამოუყენებელიUnused_for _ in range(3):
სახელები, რომლებსაც ვერიდებით ერთი ასო: l, I, O — ციფრებს ჰგავს ჩაშენებულის გადაფარვა: list = [1,2], str = "x", sum = 0 — ფუნქციას „კლავს“ უაზრო: data2, temp, x1 Names we avoid Single letters: l, I, O — they look like digits Shadowing a built-in: list = [1,2], str = "x", sum = 0 — this "kills" the function Meaningless: data2, temp, x1

PEP 8

ჰარეებიWhitespace

x = 5
result = x + y * 2
print(a, b)
def f(a, b=1):
    pass
f(1, b=2)
lst[0]
d["key"]
if x == 1 and y > 2:
x=5
result = x+y * 2
print( a,b )
def f(a, b = 1):
    pass
lst [0]
d ["key"]
if x==1 and y>2 :
ორი წესი, რომელიც ყველაფერს ფარავს 1. ბინარულ ოპერატორს ორივე მხრიდან თითო ჰარე: a + b, x == y 2. ნაგულისხმევ პარამეტრს ჰარეები არ უნდა (თუ ტიპი მითითებული არაა): def f(b=1) Two rules that cover almost everything 1. A binary operator gets one space on each side: a + b, x == y 2. A default parameter gets no spaces (when no type is annotated): def f(b=1)

PEP 8

იმპორტებიImports

# 1. the standard library
import os
import sys
from pathlib import Path

# 2. third-party packages
import requests
import pandas as pd

# 3. your own modules
from utils import clean_text
from models import Student


# ✗ not like this:
import os, sys                # several on one line
from math import *            # importing everything
ავტომატურადVS Code-ში "source.organizeImports" პარამეტრი შენახვისას თავად დაალაგებს (იხ. ლექცია 00). AutomaticallyIn VS Code the "source.organizeImports" setting sorts them on save (see lecture 00).

PEP 20

Zen of Python — import this

  • Beautiful is better than uglyლამაზი სჯობს მახინჯსAesthetics are a real criterion
  • Explicit is better than implicitცხადი სჯობს ნაგულისხმევსSay what you mean; do not rely on hidden behaviour
  • Simple is better than complexმარტივი სჯობს რთულსReach for the simplest thing that works
  • Flat is better than nestedბრტყელი სჯობს ჩადგმულსDeep nesting hides the logic
  • Readability countsწაკითხვადობას მნიშვნელობა აქვსThe whole reason PEP 8 exists
  • Errors should never pass silentlyშეცდომა ჩუმად არ უნდა ჩაიაროს → XII კვირაSee week XII — except: pass
  • In the face of ambiguity, refuse the temptation to guessორაზროვნებისას ნუ გამოიცნობAsk, or raise — do not guess
  • There should be one obvious way to do itუნდა არსებობდეს ერთი ცხადი გზაOne obvious way, ideally only one
  • Now is better than neverახლა სჯობს არასდროსსShip it; then improve it
გაუშვი import this ცოცხლად — 19 სტრიქონი, კარგი დისკუსიის საბაბი. იკითხე: რომელი პრინციპი დაარღვია ბოლო დავალებამ?

ინსტრუმენტებიTooling

Style checker-ებიStyle checkers

ინსტრუმენტიTool ტიპიType რას აკეთებსWhat it does
Rufflinter + formatter ძალიან სწრაფი (Rust-ზეა დაწერილი). ცვლის flake8+isort+black-ს ერთად. რეკომენდებული Very fast (written in Rust). Replaces flake8+isort+black at once. Recommended
Blackformatter „უკომპრომისო“ — თავად წყვეტს ფორმატს. კამათი მთავრდება "Uncompromising" — it decides the format for you. The arguing stops
flake8linter კლასიკური. PEP 8 + ლოგიკური შეცდომების ძებნა The classic one. PEP 8 plus a hunt for logical errors
pylintlinter ყველაზე მკაცრი. ქულას აყენებს კოდს (0–10) The strictest. It scores your code (0–10)
mypytype checker ამოწმებს ტიპების მინიშნებებს Checks your type hints

Linter

ამბობს, რა არასწორია. არ ცვლის კოდს.

Tells you what is wrong. It does not change the code.

Formatter

თავად ასწორებს ფორმატს — წანაცვლებას, ჰარეებს, ხაზის გადატანას.

Fixes the format itself — indentation, whitespace, line wrapping.

პრაქტიკაPractice

Ruff — ერთ წუთშიRuff — in one minute

pip install ruff

ruff check .              # find problems
ruff check . --fix        # fix them automatically
ruff format .             # format the code

# typical output:
main.py:3:1: F401 [*] `os` imported but unused
main.py:7:80: E501 Line too long (94 > 79)
main.py:12:5: E722 Do not use bare `except`
Found 3 errors (2 fixable with `--fix`).
[tool.ruff]
line-length = 88
target-version = "py312"

[tool.ruff.lint]
select = ["E", "F", "I"]   # pycodestyle, pyflakes, isort
ignore = ["E501"]
VS Code-შიდანამატი charliermarsh.ruff + "editor.formatOnSave": true — და კოდი ყოველი შენახვისას თავად სწორდება. ხელით არაფრის კეთება არ გჭირდება. In VS CodeThe charliermarsh.ruff extension + "editor.formatOnSave": true — and the code fixes itself on every save. Nothing to do by hand.

PyPI

რა არის PyPIWhat is PyPI

PyPI (Python Package Index) — pypi.org — ღია რეპოზიტორი, სადაც ~600 000 პაკეტია განთავსებული. PyPI (the Python Package Index) — pypi.org — an open repository hosting roughly 600,000 packages.

requests

HTTP მოთხოვნები

HTTP requests

pandas

ცხრილური მონაცემების ანალიზი

Tabular data analysis

numpy

რიცხვითი გამოთვლები

Numerical computing

matplotlib

გრაფიკები

Plots and charts

flask / django

ვებ-აპლიკაციები

Web applications

pillow

სურათების დამუშავება

Image processing

სტანდარტული ბიბლიოთეკა ≠ PyPImath, random, os, json — Python-თან ერთად მოდის, დაყენება არ სჭირდება („batteries included“). PyPI-ის პაკეტები კი ცალკე ისხმება. The standard library ≠ PyPImath, random, os, json ship with Python and need no installation ("batteries included"). PyPI packages are installed separately.

pip

პაკეტების მართვაManaging packages

pip install requests              # install
pip install requests==2.31.0      # a specific version
pip install "requests>=2.28"      # a minimum version
pip install --upgrade requests    # upgrade
pip uninstall requests            # remove

pip list                          # what is installed
pip show requests                 # details of one package
pip freeze                        # exact versions

# inside a virtual environment (see lecture 00)
python -m venv .venv
.venv\Scripts\activate            # Windows
source .venv/bin/activate         # Linux / macOS
ყოველთვის ვირტუალურ გარემოშიგლობალურად დაყენებული პაკეტები ერთმანეთს ეჯახება. venv თითოეულ პროექტს საკუთარ „სამზარეულოს“ აძლევს. Always inside a virtual environmentGlobally installed packages collide with each other. venv gives every project its own kitchen.

გამეორებადობაReproducibility

requirements.txt

# write the current environment into a file
pip freeze > requirements.txt

# restore the same environment on another machine
pip install -r requirements.txt
requests==2.31.0
pandas==2.1.4
matplotlib==3.8.2
რატომ ღირს„ჩემთან მუშაობს“ — პროგრამირების ყველაზე ცნობილი საბაბი. requirements.txt ზუსტად აღწერს, რა ვერსიები სჭირდება პროექტს, და პრობლემას აქრობს. Why it is worth it"It works on my machine" is programming's most famous excuse. requirements.txt states exactly which versions the project needs, and the excuse disappears.

თანამედროვე ალტერნატივები: pyproject.toml + poetry ან uv — იგივე იდეა, უფრო მოხერხებული ინსტრუმენტებით. Modern alternatives: pyproject.toml with poetry or uv — the same idea, with more convenient tooling.

ცოცხალი მაგალითიA live example

ჩვენი კურსის პაკეტი PyPI-ზეThis course's own package on PyPI

ეს არაა თეორია — კურსს საკუთარი პაკეტი აქვს გამოქვეყნებული. სცადე ახლავე: This is not theory — the course has its own package published. Try it right now:

pip install kapo-mathtools
from kapo_mathtools import statistics, geometry, text_tools, converters

print(statistics.mean([85, 90, 78, 92]))      # 86.25
print(geometry.circle_area(5))                # 78.53981633974483
print(text_tools.is_palindrome("radar"))      # True
print(converters.celsius_to_fahrenheit(25))   # 77.0

help(statistics.mean)      # bilingual docstring

რა არის შიგნითWhat is inside

23 ფუნქცია 4 მოდულში, გარე დამოკიდებულების გარეშე. სულ ~8 კბ.

23 functions in 4 modules, with no external dependencies. About 8 kB in total.

  • statistics — mean, median, variance, std_dev — mean, median, variance, std_dev
  • geometry — წრე, მართკუთხედი, სამკუთხედი — circle, rectangle, triangle
  • text_tools — სიტყვები, პალინდრომი, ხმოვნები — words, palindromes, vowels
  • converters — ტემპერატურა, მანძილი, წონა — temperature, distance, weight

სად ცხოვრობს კოდიWhere the code lives

github.com/kapo-Toolkits/python-course → საქაღალდე library/ → the library/ folder

  • pyproject.toml — პაკეტის აღწერა — the package description
  • tests/ — 26 ტესტი — 26 tests
  • GitHub Actions — ტესტი 3.9/3.11/3.13-ზე, შემდეგ ატვირთვაGitHub Actions — tested on 3.9/3.11/3.13, then published
გახსენი pypi.org/project/kapo-mathtoolsყველაფერი, რაზეც ახლა ვსაუბრობდით, იქ თვალითაც ჩანს: აღწერა, ვერსია, ლიცენზია, ბმულები, ფაილები. Open pypi.org/project/kapo-mathtoolsEverything we just discussed is visible there: the description, the version, the license, the links, the files.
ეს სლაიდი ლექციას აზრს აძლევს — სტუდენტი ხედავს, რომ პაკეტის გამოქვეყნება მისაწვდომია, არა „დიდი კომპანიების საქმე“. სთხოვე აუდიტორიაში დააყენონ და გაუშვან.

კონტექსტიContext

პარალელი სხვა ენებთანA parallel with other languages

ენაLanguage მენეჯერიManager რეპოზიტორიRepository მანიფესტიManifest
PythonpipPyPIrequirements.txt
JavaScriptnpm / yarnnpmjs.compackage.json
Javamaven / gradleMaven Centralpom.xml
C#nugetnuget.org.csproj
Rustcargocrates.ioCargo.toml
PHPcomposerPackagistcomposer.json
იდეა ყველგან ერთიაცენტრალური რეპოზიტორი + ბრძანების ხაზის ინსტრუმენტი + ფაილი, სადაც დამოკიდებულებები წერია. თუ ერთი გაიგე — დანარჩენებიც ნაცნობი გახდება. The idea is the same everywhereA central repository + a command-line tool + a file listing the dependencies. Understand one and the rest will look familiar.

უსაფრთხოებაSecurity

რაზე უნდა იფიქრო პაკეტის დაყენებამდეWhat to think about before installing a package

რეალური შემთხვევები2022–2024 წლებში PyPI-დან ასობით მავნე პაკეტი წაიშალა — ისინი პაროლებსა და კრიპტოსაფულეებს იპარავდნენ. სახელის ერთი ასოთი შეცდომა საკმარისია. Real casesBetween 2022 and 2024, hundreds of malicious packages were removed from PyPI — they stole passwords and crypto wallets. A one-letter typo in the name is enough.

შემაჯამებელიSummary

რა უნდა დაგამახსოვრდესWhat to take away

სახლში1) გაუშვი ruff check ყველა შენს დავალებაზე და გაასწორე. 2) შექმენი venv, დააყენე requests, დაწერე requirements.txt. 3) იპოვე PyPI-ზე პაკეტი, რომელიც შენს ინტერესს ეხება, და მოამზადე 2-წუთიანი პრეზენტაცია. At home1) Run ruff check over all your assignments and fix what it reports. 2) Create a venv, install requests, write a requirements.txt. 3) Find a PyPI package related to your interests and prepare a 2-minute presentation about it.
შემდეგი — ლექცია 15მოდულები და პაკეტები, import/from, ვერსიების კონტროლი (git) + პრაქტიკული დავალება #5. Next — lecture 15Modules and packages, import/from, version control with git + practical assignment #5.