ლექცია 15 · XV კვირაLecture 15 · Week XV

მოდულები,
პაკეტები, git
Modules,
packages, git

import და from · მოდულის მოძებნა და ხელახლა ჩატვირთვა · პაკეტები · ვერსიების კონტროლი · შემაჯამებელი import and from · how a module is found and reloaded · packages · version control · the wrap-up

დღეს ასევე: პრაქტიკული დავალება #5 Also today: practical assignment #5

გამეორება · ლექციები 13–14Review · lectures 13–14

შემოწმება — 8 კითხვაCheck yourself — 8 questions

1. რა სამ ნაბიჯს ასრულებს for ციკლი შიგნით? 1. What three steps does a for loop perform internally?
იძახებს iter()-ს იტერატორის მისაღებად → ყოველ ბიჯზე next()-ს → StopIteration-ის დაჭერისას ჩერდება. It calls iter() to get an iterator → calls next() on every step → stops when it catches StopIteration.
2. რა განსხვავებაა yield-სა და return-ს შორის? 2. What is the difference between yield and return?
return ფუნქციას ამთავრებს; yield მნიშვნელობას აბრუნებს და ფუნქციას „აპაუზებს“ — შემდეგი next() იმავე ადგილიდან განაგრძობს. return ends the function; yield hands back a value and pauses the function — the next next() resumes from the same place.
3. რა განსხვავებაა [x for x in r]-სა და (x for x in r)-ს შორის? 3. What is the difference between [x for x in r] and (x for x in r)?
პირველი სიას ქმნის — ყველა ელემენტი მაშინვე მეხსიერებაშია. მეორე გენერატორია — ელემენტს საჭიროებისას ქმნის, მეხსიერებას თითქმის არ იკავებს. The first builds a list — every element is in memory at once. The second is a generator — it produces each element on demand and uses almost no memory.
4. რატომ აბრუნებს list(it) მეორედ ცარიელ სიას? 4. Why does a second list(it) return an empty list?
იტერატორი ერთჯერადია — გავლის შემდეგ ამოწურულია. ხელახლა გავლისთვის ახალი iter() სჭირდება. An iterator is single-use — once traversed it is exhausted. To traverse again you need a fresh iter().
5. რას ნიშნავს snake_case, UPPER_CASE და PascalCase PEP 8-ში? 5. What do snake_case, UPPER_CASE and PascalCase mean in PEP 8?
ცვლადები და ფუნქციები · კონსტანტები · კლასები. Variables and functions · constants · classes.
6. რა განსხვავებაა linter-სა და formatter-ს შორის? 6. What is the difference between a linter and a formatter?
Linter პრობლემას პოულობს და გაცნობებს; formatter თავად ასწორებს ფორმატირებას. Ruff ორივეს აკეთებს. A linter finds problems and reports them; a formatter fixes the formatting itself. Ruff does both.
7. რას აკეთებს pip freeze > requirements.txt? 7. What does pip freeze > requirements.txt do?
ჩაწერს ფაილში მიმდინარე გარემოს ყველა პაკეტს ზუსტი ვერსიებით. აღდგენა — pip install -r requirements.txt. It writes every package of the current environment, with exact versions, into the file. To restore: pip install -r requirements.txt.
8. რატომ არის სახიფათო უცნობი პაკეტის დაყენება? 8. Why is installing an unfamiliar package risky?
PyPI-ს მოდერაცია არ აქვს, დაყენებისას პაკეტის კოდი შენს კომპიუტერზე სრულდება. სახელის ერთი ასოთი შეცდომა (typosquatting) მავნე პაკეტს გამოიწვევს. PyPI is not moderated, and on installation the package's code runs on your machine. A one-letter typo in the name (typosquatting) can land you a malicious package.

ცნებაThe concept

მოდული — უბრალოდ .py ფაილიA module is just a .py file

ყოველი Python-ის ფაილი უკვე მოდულია. საკმარისია მისი იმპორტი. Every Python file already is a module. All you have to do is import it.

"""მათემატიკური დამხმარე ფუნქციები. / Mathematical helper functions."""

PI = 3.14159


def circle_area(r):
    return PI * r ** 2


def is_prime(n):
    if n < 2:
        return False
    for d in range(2, int(n ** 0.5) + 1):
        if n % d == 0:
            return False
    return True
import mathtools

print(mathtools.PI)
print(mathtools.circle_area(5))
print(mathtools.is_prime(17))
რატომ ვყოფთ ფაილებად500-ხაზიან ერთ ფაილში შეცდომის პოვნა რთულია. ხუთი 100-ხაზიანი ფაილი, თითო თავისი პასუხისმგებლობით — გაცილებით მართვადია. Why we split into filesFinding a bug in one 500-line file is hard. Five 100-line files, each with one responsibility, are far more manageable.

სინტაქსიSyntax

import დაand from

# 1. the whole module — the name is always visible
import mathtools
print(mathtools.circle_area(5))

# 2. specific names
from mathtools import circle_area, PI
print(circle_area(5))

# 3. an alias
import mathtools as mt
print(mt.circle_area(5))

from mathtools import circle_area as area
print(area(5))

# 4. ✗ everything — never
from mathtools import *
რომელი როდის import module — ნაგულისხმევი არჩევანი. კოდში ჩანს, საიდან მოვიდა ფუნქცია from … import x — როცა 1–3 სახელს ხშირად იყენებ import … as — გრძელი სახელისთვის ან მიღებული შემოკლებისთვის (import pandas as pd) Which one when import module — the default choice. The code shows where the function came from from … import x — when you use one to three names often import … as — for a long name or an established abbreviation (import pandas as pd)

მნიშვნელოვანიImportant

if __name__ == "__main__":

def circle_area(r):
    return PI * r ** 2


print("test:", circle_area(1))     # ⚠ this also runs on import!
def circle_area(r):
    return PI * r ** 2


if __name__ == "__main__":
    # runs only when the file is executed directly
    print("test:", circle_area(1))

პირდაპირ გაშვებაRun directly

python mathtools.py
__name__ = "__main__" → ბლოკი შესრულდება

python mathtools.py
__name__ = "__main__" → the block runs

იმპორტიImported

import mathtools
__name__ = "mathtools" → ბლოკი გამოტოვდება

import mathtools
__name__ = "mathtools" → the block is skipped

ეს იდიომა ყველგან შეგხვდებაის მოდულს ორმაგ როლს აძლევს: ბიბლიოთეკაც არის და დამოუკიდებელი პროგრამაც. You will meet this idiom everywhereIt gives a module a double role: it is both a library and a standalone program.

მექანიზმიThe mechanism

სად ეძებს Python მოდულსWhere Python looks for a module

import sys

for path in sys.path:
    print(path)
  1. მიმდინარე საქაღალდე (სკრიპტის ადგილმდებარეობა)The current folder (where the script lives)
  2. გზები, რომლებიც PYTHONPATH გარემოს ცვლადშია მითითებულიThe paths listed in the PYTHONPATH environment variable
  3. სტანდარტული ბიბლიოთეკის საქაღალდეებიThe standard library folders
  4. site-packages — სადაც pip აყენებს პაკეტებსsite-packages — where pip installs packages
ხაფანგი, რომელიც ყველას გადახდენიაფაილს math.py დაარქვი და import math შენს ფაილს იპოვის სტანდარტულის ნაცვლად. იგივე ეხება random.py, string.py, json.py-ს. The trap that catches everyoneName a file math.py and import math will find your file instead of the standard one. The same goes for random.py, string.py and json.py.
import importlib
import mathtools

importlib.reload(mathtools)    # the code changed — read it again

მოდული სესიაზე ერთხელ იტვირთება. ჩვეულებრივ სკრიპტში ეს არ გვაწუხებს, მაგრამ REPL-ში ან Jupyter-ში reload გამოგადგება. A module is loaded once per session. In an ordinary script this never bothers us, but in the REPL or in Jupyter reload comes in handy.

სტრუქტურაStructure

პაკეტი — მოდულების საქაღალდეA package is a folder of modules

myproject/
├── main.py
├── requirements.txt
├── .gitignore
└── tools/
    ├── __init__.py
    ├── mathtools.py
    └── textutils.py
from tools.mathtools import circle_area
from tools import textutils

import tools.mathtools as mt

print(circle_area(5))
print(textutils.clean("  ტექსტი  "))
__init__.pyაღნიშნავს, რომ საქაღალდე პაკეტია. შეიძლება ცარიელი იყოს, ან პაკეტის „ფასადი“ — ხშირად გამოყენებული სახელების ერთად შემოსატანად.
Python 3.3+-ში ტექნიკურად სავალდებულო აღარაა, მაგრამ ცხადობისთვის მაინც ვწერთ.
__init__.pyMarks the folder as a package. It may be empty, or serve as the package's façade — pulling the commonly used names together.
Since Python 3.3 it is no longer technically required, but we still write it for clarity.

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

ნამდვილი პაკეტი, რომელიც შეგიძლია წაიკითხოA real package you can go and read

ზუსტად ის სტრუქტურა, რაზეც ახლა ვსაუბრობდით — ცოცხალ პროექტში: Exactly the structure we just described — in a live project:

library/
├── pyproject.toml            the package description: name, version, license
├── README.md                 this text appears on the PyPI page
├── LICENSE
├── kapo_mathtools/           ← the package itself
│   ├── __init__.py           from . import statistics, geometry, ...
│   ├── statistics.py
│   ├── geometry.py
│   ├── text_tools.py
│   └── converters.py
├── tests/                    26 tests
└── examples/demo.py
__version__ = "0.4.0"

from . import converters, geometry, statistics, text_tools

__all__ = ["statistics", "geometry", "text_tools", "converters", "__version__"]
სცადეpip install kapo-mathtools, შემდეგ from kapo_mathtools import geometry. იგივე პაკეტი — ერთხელ როგორც საქაღალდე GitHub-ზე, ერთხელ როგორც დაყენებული ბიბლიოთეკა შენს კომპიუტერზე. → იხ. ლექცია 14 Try itpip install kapo-mathtools, then from kapo_mathtools import geometry. The same package — once as a folder on GitHub, once as an installed library on your machine. → see lecture 14
კარგი მომენტია დავალება #5-ის დასაკავშირებლად: ზუსტად ამ სტრუქტურას ქმნიან. სთხოვე GitHub-ზე გახსნან library/ და შეადარონ საკუთარს.

ვერსიების კონტროლიVersion control

რა პრობლემას წყვეტს gitWhat problem git solves

git-ის გარეშეWithout git

main.py
main_v2.py
main_v2_final.py
main_v2_final_FIXED.py
main_v2_final_FIXED_ok.py
  • რომელი მუშაობდა?Which one worked?
  • რა შეიცვალა მათ შორის?What changed between them?
  • როგორ დავაბრუნო გუშინდელი?How do I get yesterday's version back?
  • როგორ ვიმუშაოთ ორმა ერთ ფაილზე?How do two people work on one file?

git-ითWith git

  • ისტორიაყოველი ცვლილება ჩაწერილია — ვინ, როდის, რატომ HistoryEvery change is recorded — who, when, why
  • დაბრუნებანებისმიერ წერტილში დაბრუნება ერთი ბრძანებით Going backReturn to any point with a single command
  • განშტოებებიექსპერიმენტი მთავარი ვერსიის დაზიანების გარეშე BranchesExperiment without breaking the main version
  • თანამშრომლობარამდენიმე ადამიანი ერთ პროექტზე CollaborationSeveral people on one project
იკითხე, ვის აქვს „საბოლოო_ვერსია_2“ დოკუმენტი. ყველას აქვს — ესაა ის პრობლემა, რომელსაც git წყვეტს.

git

საბაზისო ბრძანებებიThe basic commands

# once, per machine
git config --global user.name "Firstname Lastname"
git config --global user.email "you@example.com"

# inside a project
git init                    # create the repository
git status                  # what changed

git add main.py             # stage a file
git add .                   # stage everything
git commit -m "add the loops assignment"

git log --oneline           # the history
git diff                    # what changed since the last commit

git checkout main.py        # discard the changes in a file
სამი „ზონა“ Working directory — სადაც რედაქტირებ → git add Staging area — რას ჩავწერ → git commit Repository — ისტორია Three "zones" Working directory — where you edit → git add Staging area — what will go in → git commit Repository — the history

git

განშტოებები და GitHubBranches and GitHub

git branch feature-menu       # a new branch
git switch feature-menu       # move onto it
git switch -c feature-menu    # both at once

git switch main               # back to main
git merge feature-menu        # merge the changes in
git remote add origin https://github.com/user/project.git
git push -u origin main       # upload
git pull                      # download
git clone https://github.com/user/project.git

GitHub / GitLab

ღრუბლოვანი პლატფორმა git-რეპოზიტორებისთვის. სარეზერვო ასლი + თანამშრომლობა + პორტფოლიო

A cloud platform for git repositories. A backup + collaboration + a portfolio

VS Code-შიIn VS Code

Source Control პანელი (Ctrl+Shift+G) — commit, push, diff ტერმინალის გარეშე. + GitLens

The Source Control panel (Ctrl+Shift+G) — commit, push and diff without the terminal. Plus GitLens

git

.gitignoreრას არ ვინახავთwhat we do not keep

# Python
__pycache__/
*.pyc
.venv/
venv/

# environment and secrets
.env
config_secret.py

# editor
.vscode/
.idea/

# operating system
.DS_Store
Thumbs.db

# data
*.log
data/temp/
არასდროს ჩააგდო git-შიპაროლები, API-გასაღებები, ბაზის მონაცემები. ერთხელ ატვირთული საიდუმლო ისტორიაში რჩება მაშინაც კი, თუ შემდეგ წაშალე. Never put these into gitPasswords, API keys, database credentials. A secret committed once stays in the history even if you delete it afterwards.

მზა შაბლონები: github.com/github/gitignore Ready-made templates: github.com/github/gitignore

შეფასებაAssessment

პრაქტიკული დავალება #5Practical assignment #5

8 ქულა · სრულდება აუდიტორიაში, დამოუკიდებლად 8 points · done in class, individually

  1. მოდულად დაშლაწინა დავალება დაშალე: tools/mathtools.py, tools/textutils.py, main.py Split into modulesBreak up your previous assignment: tools/mathtools.py, tools/textutils.py, main.py
  2. __init__.pyშექმენი პაკეტი და გამოიყენე from tools.mathtools import ... __init__.pyMake it a package and use from tools.mathtools import ...
  3. if __name__ == "__main__":თითოეულ მოდულს დაუმატე საკუთარი ტესტ-ბლოკი if __name__ == "__main__":Give every module its own small test block
  4. gitgit init.gitignore → მინიმუმ 3 აზრიანი commit gitgit init.gitignore → at least 3 meaningful commits
  5. ატვირთვაატვირთე GitHub-ზე და დაამატე README.md პროექტის აღწერით PublishPush it to GitHub and add a README.md describing the project
ბონუსიგაუშვი ruff check . და გაასწორე ყველა შენიშვნა commit-ამდე. BonusRun ruff check . and fix every warning before you commit.

შემაჯამებელი ლექციაThe wrap-up

რა ვისწავლეთ სემესტრშიWhat we learned this semester

საფუძვლებიFundamentals

  • სინტაქსი, წანაცვლება
  • ტიპები და კონვერტაცია
  • ოპერატორები
  • Syntax and indentation
  • Types and conversion
  • Operators

მართვის ნაკადიControl flow

  • if / elif / else
  • for და while
  • break / continue
  • if / elif / else
  • for and while
  • break / continue

ფუნქციებიFunctions

  • ჩაშენებული, math, random
  • def, პარამეტრები, return
  • scope, lambda
  • Built-ins, math, random
  • def, parameters, return
  • Scope, lambda

მონაცემებიData

  • str და მისი მეთოდები
  • list, tuple
  • set, dict
  • str and its methods
  • list, tuple
  • set, dict

მდგრადობაRobustness

  • ფაილები, with
  • try / except
  • იტერატორები, yield
  • Files, with
  • try / except
  • Iterators, yield

პროფესიული ჩვევებიProfessional habits

  • PEP 8, Ruff
  • PyPI, pip, venv
  • მოდულები, პაკეტები, git
  • PEP 8, Ruff
  • PyPI, pip, venv
  • Modules, packages, git
მთავარისინტაქსი ინსტრუმენტია. ნამდვილი შედეგი — ალგორითმული აზროვნება: ამოცანის ნაბიჯებად დაშლის უნარი. ის ყველა ენაზე გადადის. The main thingSyntax is a tool. The real result is algorithmic thinking: the ability to break a problem into steps. That transfers to every language.

შეფასებაAssessment

დასკვნითი გამოცდაThe final exam

ფორმატი — 30 ქულაFormat — 30 points

  • 3 პრაქტიკული ამოცანა × 10 ქულა3 practical problems × 10 points
  • მოიცავს მთელ სემესტრის მასალასCovers the whole semester
საბოლოო ქულასემესტრული (70) + დასკვნითი (30). დადებითი შეფასების ზღვარი ჩვეულებრივ 51 ქულაა — ზუსტი წესი შენს კურსში დააზუსტე. The final gradeCoursework (70) + the exam (30). The pass mark is usually 51 points — check the exact rule for your own course.

როგორ მოემზადოHow to prepare

  • ხელახლა დაწერე ხუთივე პრაქტიკული დავალება — არა წაიკითხოRewrite all five practical assignments — do not just read them
  • გაიარე ყველა „შემაჯამებელი“ სლაიდიGo through every "summary" slide
  • გაიმეორე გამეორების კითხვები (ლექციები 03, 05, 07, 08, 11, 13, 15)Redo the review questions (lectures 03, 05, 07, 08, 11, 13, 15)
  • ივარჯიშე ტიპურ ამოცანებზე: ციფრები, სტრიქონები, სიები, ლექსიკონები, ფაილებიPractise the typical problems: numbers, strings, lists, dictionaries, files

გაგრძელებაWhat comes next

სად წავიდეთ აქედანWhere to go from here

ობიექტზე ორიენტირებულიObject-oriented

კლასები, მემკვიდრეობა, ინკაფსულაცია — შემდეგი ბუნებრივი ნაბიჯი

Classes, inheritance, encapsulation — the natural next step

მონაცემთა ანალიზიData analysis

pandas, numpy, matplotlib — Python-ის ყველაზე ძლიერი სფერო

pandas, numpy, matplotlib — Python's strongest field

ვებიThe web

flask, fastapi, django — სერვისები და API

flask, fastapi, django — services and APIs

ავტომატიზაციაAutomation

ფაილები, Excel, ვებ-სკრეიპინგი — ყოველდღიური რუტინის შემცირება

Files, Excel, web scraping — cutting down the daily routine

ტესტირებაTesting

pytest — როგორ დავრწმუნდეთ, რომ კოდი მართლა მუშაობს

pytest — how to be sure the code really works

ალგორითმებიAlgorithms

დახარისხება, ძებნა, სირთულე — ინტერვიუებისთვის აუცილებელი

Sorting, searching, complexity — essential for interviews

ერთადერთი რჩევააირჩიე საკუთარი პატარა პროექტი და დაწერე. კურსი საფუძველს გაძლევს — უნარი პრაქტიკიდან მოდის. 20 ხაზი დღეში სამ თვეში სრულიად სხვა დონეზე გაგიყვანს. The one piece of advicePick a small project of your own and write it. The course gives you the foundation — the skill comes from practice. Twenty lines a day will put you on a completely different level in three months.
დაასრულე პოზიტიურად. სთხოვე თითოეულს ერთი წინადადებით თქვას, რა პროექტს დაწერდა — ეს ხშირად ნამდვილ მოტივაციას ბადებს.