Ачааллж байна...
Энэ бол сургалтын эцсийн удирдлагатай бүтээл, жижиг хэмжээний төгсөлтийн ажил. Өмнөх гурван бүтээлд бид өмнөх сургалтын зарлагын бүртгэлийг алхам алхмаар сайжруулсан: Git-д оруулсан, нийтэлсэн, тест нэмсэн. Энэ удаад бид хоосон фолдероос эхэлнэ. Цоо шинэ жижиг хэрэгсэл, нууц үг үүсгэгчийг эхний мөрөөс эхлээд GitHub дээр нийтлэгдсэн, тестэд хамгаалагдсан, баримтжсан, хувилбартай төсөл болтол бүтээнэ. Энэ сургалтын бүх дадал нэг ажилд нийлнэ: repository ба .gitignore, issue, салаа, тестийг эхэлж бичих, цэвэр функц ба нимгэн бүрхүүл, ruff ба black, docstring, README, pull request, лиценз, release.
Шинэ мэдлэг бараг байхгүй. Python-ий хоёр стандарт модуль, secrets ба string, мөн command line-аас аргумент унших sys.argv гэсэн цөөн шинэ зүйлийг товч тайлбарлана. Бусад бүх алхам танил: хичээл бүрт аль хичээлийн дадал болохыг заана. Ажлын хугацаа 90-120 минут орчим. Шалгах цэгүүд, эцэст нь бүх алхмын дараалал бий. Энэ бүтээлийн үр дүн таны GitHub дээрх хоёр дахь мэргэжлийн төсөл болно.
Эхлэхээс өмнө юу бүтээхээ тодорхой болгоё. Энэ бол 6.1 дүгээр хичээлийн issue-ийн сэтгэлгээ: ажлыг эхлэхээс өмнө гэрээг бич.
Нууц үг үүсгэгч command line-аас ажиллана: python main.py нь 12 тэмдэгттэй нууц үг хэвлэнэ, python main.py 16 нь 16 тэмдэгттэйг. Нууц үг үсэг ба тоонуудаас бүрдэнэ бөгөөд үргэлж дор хаяж нэг жижиг үсэг, нэг том үсэг, нэг тоо агуулна. Урт 8-аас бага байж болохгүй. Буруу аргумент өгвөл, жишээ нь “abc” эсвэл “5”, программ traceback биш, найрсаг мессеж хэвлэнэ.
Бүтэц 9.2 дугаар хичээлийн санааг дагана: passwords.py-д цэвэр цөм, үүсгэх логик; main.py-д нимгэн бүрхүүл, command line унших ба хэвлэх.
Алхам 1: Фолдер, repository, venv
VS Code-ийн terminal-д хэрэглэгчийн фолдертоо, ямар ч repository-оос гадуур, шинэ фолдер үүсгэнэ үү. 4.3 дугаар хичээлийн дүрэм: pwd-ээр байршлаа шалгана.
Command:
cd ~
mkdir password-generator
cd password-generator
git init
python -m venv venv
code .Гаралт (git init-ийн мөр):
Initialized empty Git repository in C:/Users/Bat/password-generator/.git/Шинэ VS Code цонхонд venv-ээ идэвхжүүлж, хөгжүүлэлтийн хэрэгслүүдээ суулгана уу.
Command:
.\venv\Scripts\Activate.ps1
pip install pytest black ruffШалгах цэг: Repository үүссэн, мөрийн эхэнд “(venv)”, гурван хэрэгсэл суусан.
Алхам 2: Төслийн араг яс
Анхны commit-оос өмнө бүх тохиргооны файлыг бэлдэнэ. 2.4 дүгээр хичээлийн дүрэм: .gitignore анхны commit-оос өмнө. Файл бүрийг VS Code-д үүсгэнэ үү.
.gitignore:
# Python cache
__pycache__/
*.pyc
.pytest_cache/
# Virtual environments
venv/
.venv/
# Secrets
.env
# Logs
*.log
# Windows
Thumbs.db
desktop.inirequirements-dev.txt, 9.3 дугаар хичээлийн хөгжүүлэлтийн хамаарал:
pytest
black
ruffpytest.ini, 8.1 дүгээр хичээлийн тохиргоо:
ini
[pytest]
pythonpath = .
testpaths = testspyproject.toml, 11.2 дугаар хичээлийн ruff-ийн тохиргоо:
toml
[tool.ruff]
output-format = "concise"
[tool.ruff.lint]
select = ["E", "F", "B", "I"]README.md, эхний хувилбар. 5.1 дүгээр хичээлийн дадлаар README эхнээсээ байна, бид түүнийг ажлын явцад өргөтгөнө.
markdown
# Password Generator
A small command-line tool that generates random passwords.Мөн tests нэртэй хоосон фолдер үүсгэнэ үү.
Алхам 3: Анхны commit
Command:
git statusГаралт:
On branch main
No commits yet
Untracked files:
(use "git add <file>..." to include in what will be committed)
.gitignore
README.md
pyproject.toml
pytest.ini
requirements-dev.txt
nothing added to commit but untracked files present (use "git add" to track)venv харагдахгүй, хоосон tests фолдер харагдахгүй: 2.4 ба 2.1 дүгээр хичээлүүдийн дүрэм. Жагсаалт зөвхөн цомогт орох ёстой файлуудтай.
Command:
git add .
git commit -m "Initial project setup"Гаралт:
[main (root-commit) 1c4e9b2] Initial project setup
5 files changed, 30 insertions(+)
create mode 100644 .gitignore
create mode 100644 README.md
create mode 100644 pyproject.toml
create mode 100644 pytest.ini
create mode 100644 requirements-dev.txtТаны мөрийн тоо, hash өөр байна.
Шалгах цэг: “(root-commit)” бүхий анхны commit.
Алхам 4: GitHub руу гаргах
4.2 дугаар хичээлийн аргаар GitHub дээр password-generator нэртэй хоосон repository үүсгэнэ үү: README, .gitignore, license сонгохгүй. Тайлбарт “Command-line password generator in Python” гэж бичиж болно. Public эсвэл private-ийг өөрөө шийдээрэй.
Command:
git remote add origin https://github.com/bat-dorj/password-generator.git
git push -u origin mainГаралт (сүүлийн мөрүүд):
To https://github.com/bat-dorj/password-generator.git
* [new branch] main -> main
branch 'main' set up to track 'origin/main'.Хаягийг өөрийн username-ээр солиорой.
Шалгах цэг: GitHub хуудсанд таван файл болон README-ийн хоёр мөр харагдаж байна.
Алхам 5: Issue
GitHub дээр Issues табд 9.3 дугаар хичээлийн хайрцагтай жагсаалттай issue нээнэ үү.
Гарчиг:
Generate passwordsТайлбар:
markdown
Add `generate_password(length)` in `passwords.py`.
- [ ] At least one lowercase letter, one uppercase letter and one digit
- [ ] Only letters and digits
- [ ] Length below 8 raises ValueError
- [ ] Secure random generator by default, seedable for testsШошго: enhancement. Энэ бол шинэ repository тул issue #1 болно.
Алхам 6: Салаа
Command:
git switch -c password-coreШинэ хоёр модуль: string ба secrets
Тест бичихээсээ өмнө хоёр стандарт модулийг товч танилцуулъя. string модуль бэлэн тэмдэгтийн цуглуулгууд агуулдаг: string.ascii_lowercase бол “abcdefghijklmnopqrstuvwxyz”, string.ascii_uppercase том үсгүүд, string.digits бол “0123456789”, string.ascii_letters жижиг ба том үсгүүд хамтдаа. Тэдгээрийг гараар бичихээс илүү найдвартай.
secrets модуль бол санамсаргүй утга үүсгэх аюулгүй хэрэгсэл. Өмнөх сургалтаас та random модулийг мэдэж байж магадгүй. Тэр нь тоглоом, симуляц, тестэд тохиромжтой боловч нууц үгэнд аюултай: random-ийн гаргасан дарааллыг хангалттай олон утга харсан хүн урьдчилан таамаглах боломжтой. secrets нь үйлдлийн системийн аюулгүй санамсаргүй эх үүсвэрийг ашигладаг тул нууц үг, түлхүүр зэрэгт зориулагдсан. Энэ бол шударга, чухал ялгаа: нууц үг үүсгэгчид random биш, secrets.
Гэхдээ санамсаргүй функцийг хэрхэн тестлэх вэ? Үр дүн нь ажиллуулах бүрт өөр. 9.2 дугаар хичээлийн date.today()-ийн асуудалтай ижил: нуугдмал оролт. Шийдэл нь ч ижил: нуугдмал оролтыг параметр болго. Функц санамсаргүй тоо үүсгэгчийг rng параметрээр авна. Программ ажиллахдаа secrets-ийн аюулгүй үүсгэгчийг хэрэглэнэ. Тест харин random.Random(42) гэх мэт seed буюу үрээр эхлүүлсэн үүсгэгч өгнө: ижил үртэй үүсгэгч үргэлж ижил дараалал гаргадаг тул тест давтагдахуйц болно.
Алхам 7: Тестүүдийг эхэлж бичих
9.3 дугаар хичээлийн дараалал: эхлээд тест. tests фолдерт test_passwords.py үүсгэнэ үү.
python
import random
import string
import pytest
from passwords import MIN_LENGTH, generate_password
@pytest.fixture
def rng():
return random.Random(42)
@pytest.mark.parametrize("length", [MIN_LENGTH, 12, 32])
def test_password_has_requested_length(length, rng):
assert len(generate_password(length, rng)) == length
def test_password_uses_only_letters_and_digits(rng):
password = generate_password(64, rng)
assert all(c in string.ascii_letters + string.digits for c in password)
@pytest.mark.parametrize("seed", range(20))
def test_password_has_lower_upper_and_digit(seed):
password = generate_password(MIN_LENGTH, random.Random(seed))
assert any(c.islower() for c in password)
assert any(c.isupper() for c in password)
assert any(c.isdigit() for c in password)
def test_same_seed_gives_same_password():
first = generate_password(12, random.Random(7))
second = generate_password(12, random.Random(7))
assert first == second
def test_default_generator_gives_different_passwords():
assert generate_password() != generate_password()
@pytest.mark.parametrize("length", [0, 3, MIN_LENGTH - 1])
def test_too_short_length_raises(length):
with pytest.raises(ValueError, match="at least"):
generate_password(length)Эдгээр тестүүд өмнөхүүдээс нэг чухал зүйлээрээ ялгаатай: тэд нууц үгийн яг утгыг огт шалгадаггүй. Санамсаргүй үр дүнгийн яг утгыг урьдчилан бодох боломжгүй, тиймээс тестүүд шинж чанарыг шалгадаг: урт зөв үү, зөвшөөрөгдсөн тэмдэгтүүд л байна уу, гурван төрлийн тэмдэгт бий юу, ижил үр ижил үр дүн өгөх үү. Энэ бол санамсаргүй кодыг тестлэх гол арга.
Тест бүрийг товч уншъя. rng fixture бол 8.2 дугаар хичээлийн fixture: тест бүрт шинэ, үр 42-оор эхэлсэн үүсгэгч. Уртын тест 8.3 дугаар хичээлийн parametrize-оор хамгийн бага урт, ердийн урт, урт нууц үгийг шалгана. Тэмдэгтийн тест all()-ээр нууц үгийн тэмдэгт бүр зөвшөөрөгдсөн эсэхийг шалгана, урт нууц үг илүү олон тэмдэгт шалгадаг тул 64. Гурван төрлийн тэмдэгтийн тест хорин өөр үрээр, хамгийн богино уртаар ажилладаг: богино нууц үгэнд гурван төрлийн нэг нь санамсаргүйгээр дутах магадлал хамгийн их тул энэ бол хил дээрх тохиолдол. Энэ тест гурван assert-тэй боловч нэг санааг шалгадаг: "бүрэлдэхүүн зөв", 7.3 дугаар хичээлийн дүрэм. Ижил үрийн тест давтагдах байдлыг, эсрэг тест аюулгүй анхдагч үүсгэгч ажиллаж байгааг шалгана. Сүүлийнх нь 8.4 дүгээр хичээлийн pytest.raises: хилийн яг доорх утга 7 болон илт буруу утгууд.
test_default_generator_gives_different_passwords-ийн тухай нэг шударга тэмдэглэл: онолын хувьд хоёр санамсаргүй нууц үг санамсаргүйгээр ижил гарах боломжтой. 12 тэмдэгттэй нууц үгийн хувьд тэр магадлал маш бага тул практикт хэзээ ч тохиолдохгүй. Гэхдээ санамсаргүй байдалд тулгуурласан тест бол заримдаа үндэслэлгүйгээр унадаг “flaky” буюу тогтворгүй тестийн нэг хэлбэр гэдгийг санаарай: ийм тестийг цөөн, магадлал нь бодитоор тэг байх үед л бич.
Command:
pytestГаралт (гол хэсэг):
E ModuleNotFoundError: No module named 'passwords'
=========================== short test summary info ===========================
ERROR tests/test_passwords.py
!!!!!!!!!!!!!!!!!!!! Interrupted: 1 error during collection !!!!!!!!!!!!!!!!!!!!Хүлээгдэж буй улаан.
Шалгах цэг: Тестүүд бичигдсэн, модуль байхгүй тул ERROR.
Алхам 8: Цөмийг бичих
Үндсэн фолдерт passwords.py үүсгэнэ үү.
python
"""Generate random passwords that are hard to guess."""
import secrets
import string
MIN_LENGTH = 8
ALPHABET = string.ascii_letters + string.digits
def generate_password(length=12, rng=None):
"""Return a random password of the given length.
The password always contains at least one lowercase letter,
one uppercase letter and one digit.
Args:
length: Number of characters, at least MIN_LENGTH.
rng: Random number generator. Defaults to a secure system
generator; tests pass a seeded random.Random instead.
Returns:
The password as a string.
Raises:
ValueError: If length is less than MIN_LENGTH.
"""
if length < MIN_LENGTH:
raise ValueError(f"Length must be at least {MIN_LENGTH}, got {length}")
if rng is None:
rng = secrets.SystemRandom()
chars = [
rng.choice(string.ascii_lowercase),
rng.choice(string.ascii_uppercase),
rng.choice(string.digits),
]
chars += [rng.choice(ALPHABET) for _ in range(length - 3)]
rng.shuffle(chars)
return "".join(chars)Энэ сургалтын дадлууд хаана хэрэглэгдсэнийг харцгаая. Модулийн docstring 11.4 дүгээр хичээлээс. MIN_LENGTH ба ALPHABET бол 11.3 дугаар хичээлийн нэртэй тогтмолууд, ид шидийн тоо биш. Функцийн docstring Args, Returns, Raises хэсгүүдтэй. Хамгийн эхний шалгалт 8.4 дүгээр хичээлийн зарчмаар буруу оролтыг тэр дороо, тодорхой мессежтэй эсэргүүцнэ. rng=None ба функцийн доторх шалгалт 11.2 дугаар хичээлийн B006 урхиас зайлсхийнэ: анхдагч утга нь хуваалцагдах объект биш, None. secrets.SystemRandom() бол secrets модулийн аюулгүй үүсгэгч бөгөөд random.Random-тэй ижил choice ба shuffle аргуудтай, тиймээс тест болон программ нэг кодыг хэрэглэнэ.
Алгоритм энгийн: эхлээд гурван төрөл тус бүрээс нэг тэмдэгт сонгоно, энэ нь шаардлагыг баталгаажуулна. Үлдсэн тэмдэгтүүдийг бүх зөвшөөрөгдсөн тэмдэгтээс сонгоно. Эцэст нь бүгдийг холино, эс бөгөөс нууц үг үргэлж жижиг үсэг, том үсэг, тоогоор эхэлж, таамаглахад хялбар болох байсан. _ бол 11.2 дугаар хичээлийн "санаатайгаар хэрэглэдэггүй хувьсагч" заншил.
Command:
pytestГаралт (сүүлийн мөр):
============================= 29 passed in 0.06s ==============================Хорин есөн тест: гурван урт, нэг тэмдэгтийн, хорин бүрэлдэхүүний, хоёр үүсгэгчийн, гурван алдааны.
Шалгах цэг: 29 тест давсан.
Алхам 9: Чанар, хянах, commit
12.1 дүгээр хичээлийн давталт.
Command:
ruff check --fix .
black .
pytestГаралт:
All checks passed!
All done!
2 files left unchanged.
...
============================= 29 passed in 0.06s ==============================Хэрвээ ruff эсвэл black ямар нэг юм засвал энэ нь хэвийн: бичих явцад гарсан жижиг зөрүүг тэд цэгцэлсэн. Дараа нь git status ба git diff-ээр 12.1 дүгээр хичээлийн аргаар өөрийгөө хянана уу.
Command:
git add passwords.py tests\test_passwords.py
git commit -m "Add password generator core"README-д “Requirements” хэсэг нэмнэ үү.
markdown
Every password contains at least one lowercase letter, one uppercase
letter and one digit.
## Requirements
- Python 3.10 or newer
- No external packagesCommand:
git add README.md
git commit -m "Describe password rules in README"Шалгах цэг: Салаа хоёр commit-тэй.
Алхам 10: Pull request ба merge
Command:
git push -u origin password-coreGitHub дээр pull request нээнэ үү. Гарчиг: “Generate passwords”. Тайлбар:
markdown
Adds `generate_password()` with a secure default generator.
- At least one lowercase letter, one uppercase letter and one digit
- Length below 8 raises ValueError
- Seedable generator parameter for repeatable tests
- 29 tests
Closes #16.2 дугаар хичээлийн аргаар Files changed табд өөрийгөө хянаад, merge хийж, салааг устгана уу. Дараа нь local-ыг шинэчилнэ.
Command:
git switch main
git pull
git branch -d password-core
git fetch --prune
pytestШалгах цэг: Pull request #2 нэгтгэгдсэн, issue #1 хаагдсан, main дээр 29 тест давсан.
Алхам 11: Issue ба салаа
Шинэ issue нээнэ үү. Гарчиг: “Command-line interface”. Тайлбар: “python main.py [length] prints a password. Default length 12. Invalid input prints a friendly message instead of a traceback.” Энэ issue #3 болно.
Command:
git switch -c clisys.argv: command line-ийн аргументууд
python main.py 16 гэж бичихэд 16-г программ хэрхэн мэдэх вэ? Python-ий sys модульд argv гэсэн жагсаалт бий: түүний эхний элемент script-ийн нэр, үлдсэн нь command line-д бичигдсэн аргументууд, бүгд текст. python main.py 16-д sys.argv нь [‘main.py’, ‘16’]. Бид script-ийн нэрийг хэрэглэхгүй тул sys.argv[1:]-ийг, өөрөөр хэлбэл зөвхөн аргументуудыг, функцэд дамжуулна.
9.2 дугаар хичээлийн санаа энд ч хэрэглэгдэнэ: аргументуудыг функцийн доторх sys.argv-аас унших биш, параметрээр авбал функцийг тестэд ямар ч аргументтай дуудаж болно. Мөн функц хэвлэсний дараа амжилт эсвэл алдааны код буцаана: 0 амжилт, 1 алдаа, command line-ийн программуудын тогтсон заншил.
Алхам 12: Тестүүдийг эхэлж бичих
tests фолдерт test_main.py үүсгэнэ үү.
python
from main import main
def test_main_prints_password_of_given_length(capsys):
assert main(["16"]) == 0
assert len(capsys.readouterr().out.strip()) == 16
def test_main_uses_default_length(capsys):
assert main([]) == 0
assert len(capsys.readouterr().out.strip()) == 12
def test_main_rejects_text(capsys):
assert main(["abc"]) == 1
assert "бүхэл тоо" in capsys.readouterr().out
def test_main_rejects_short_length(capsys):
assert main(["5"]) == 1
assert "бүхэл тоо" in capsys.readouterr().out9.2 дугаар хичээлийн capsys энд яг тохирох газартаа: бүрхүүлийн ажил бол хэвлэх, тиймээс хэвлэлтийг шалгана. strip() нь print-ийн нэмдэг шинэ мөрийн тэмдэгтийг арилгана. Хэрэглэгчид зориулсан мессеж монголоор: 11.3 дугаар хичээлийн дүрмээр кодын нэрс англи, программын гаралт хэрэглэгчийн хэлээр.
Command:
pytestГаралт (гол хэсэг):
E ModuleNotFoundError: No module named 'main'Хүлээгдэж буй улаан.
Алхам 13: Бүрхүүлийг бичих
Үндсэн фолдерт main.py үүсгэнэ үү.
python
"""Command-line entry point. Usage: python main.py [length]."""
import sys
from passwords import MIN_LENGTH, generate_password
def main(args):
"""Print a password for the given command-line arguments."""
try:
length = int(args[0]) if args else 12
print(generate_password(length))
except ValueError:
print(f"Нууц үгийн урт {MIN_LENGTH}-аас багагүй бүхэл тоо байх ёстой.")
return 1
return 0
if __name__ == "__main__":
sys.exit(main(sys.argv[1:]))main функц нимгэн: аргументыг тоо болгож, цөмийг дуудаж, хэвлэнэ. Хоёр төрлийн буруу оролт хоёулаа ValueError өгдөг: int(“abc”) ба generate_password(5). Нэг except хоёуланг нь барьж, 10.4 дүгээр хичээлийн "хэрэглэгчид найрсаг мессеж" хэв маягаар хариулна.
Хамгийн доод хоёр мөр шинэ. if __name__ == "__main__": нь "энэ файлыг шууд ажиллуулсан бол" гэсэн утгатай. 10.4 дүгээр хичээлд __name__ нь шууд ажиллуулсан файлд “main” болдгийг харсан. Тест main.py-г import хийхэд __name__ нь “main” болох тул энэ блок ажиллахгүй, тест main() функцийг өөрөө дуудна. Харин python main.py ажиллуулахад блок ажиллаж, sys.exit() функцийн буцаасан кодоор программыг дуусгана.
Command:
pytestГаралт (сүүлийн мөр):
============================= 33 passed in 0.07s ==============================Одоо жинхэнэ хэрэглэгч шиг ажиллуулъя.
Command:
python main.py
python main.py 16
python main.py 5
python main.py abcГаралт:
q7RmT2xKbW9a
Lp4vNw8QzRt2Ekc9
Нууц үгийн урт 8-аас багагүй бүхэл тоо байх ёстой.
Нууц үгийн урт 8-аас багагүй бүхэл тоо байх ёстой.Таны нууц үгс мэдээж өөр байна: тэд санамсаргүй. Эхний нууц үг 12, хоёр дахь нь 16 тэмдэгттэй. Буруу оролтод traceback-гүй, ойлгомжтой мессеж.
Шалгах цэг: 33 тест давсан, программ дөрвөн тохиолдолд зөв хариулсан.
Алхам 14: README, чанар, commit
README-д “How to run”, “Running tests”, “Project structure” хэсгүүдийг нэмнэ үү.
markdown
## How to run
```powershell
git clone https://github.com/bat-dorj/password-generator.git
cd password-generator
python main.py
python main.py 16
```
The optional number is the password length (at least 8, default 12).
## Running tests
```powershell
pip install -r requirements-dev.txt
pytest
```
## Project structure
- `passwords.py` — password generation
- `main.py` — command-line entry point
- `tests/` — pytest test suiteCommand:
ruff check --fix .
black .
pytest
git add main.py tests\test_main.py
git commit -m "Add command-line interface"
git add README.md
git commit -m "Document usage and tests in README"
git push -u origin cliPull request нээж, тайлбарт “Closes #3” бичээд, өөрийгөө хянаад, merge хийж, салааг устгаад, local-ыг Алхам 10-ын аргаар шинэчилнэ үү.
Шалгах цэг: Pull request #4 нэгтгэгдсэн, issue #3 хаагдсан, main дээр 33 тест давсан.
Алхам 15: Лиценз
5.2 дугаар хичээлийн аргаар GitHub дээр “Add file”, “Create new file”, нэр нь LICENSE, “Choose a license template”, MIT, commit. Дараа нь local дээр pull хийгээд, README-ийн төгсгөлд нэмнэ үү.
markdown
## License
MIT. See the `LICENSE` file for details.Энэ бол жижиг баримт бичгийн өөрчлөлт тул 12.1 дүгээр хичээлийн "жижиг засвар шууд main руу" сонголтыг хэрэглэж болно.
Command:
git pull
git add README.md
git commit -m "Add license section to README"
git pushАлхам 16: Нүүр хуудас ба хувилбар
5.4 дүгээр хичээлийн шалгуураар repository-гоо шалгана уу: About хэсэгт тайлбар ба topics, жишээ нь python, cli, password-generator. Дараа нь 5.3 дугаар хичээлийн аргаар анхны release-ээ гаргана уу: tag v1.0.0, гарчиг “Version 1.0.0”, “Generate release notes” дарахад таны хоёр pull request автоматаар жагсагдана. Publish.
Command:
git pull
git tagГаралт:
From https://github.com/bat-dorj/password-generator
* [new tag] v1.0.0 -> v1.0.0
Already up to date.
v1.0.0Алхам 17: Танихгүй хүний нүдээр
Repository public бол 5.4 дүгээр хичээлийн аргаар профайлдаа онцлоод, incognito цонхоор хараарай. Танихгүй reviewer юуг харах вэ? Тодорхой README, ажиллуулах ба тестлэх заавартай. Цэвэр бүтэц. MIT лиценз. v1.0.0 release. Хоёр хаагдсан issue, тус бүр нь pull request-тэйгээ холбоостой. Commit-ын түүх: тохиргоо, цөм, түүний баримт, бүрхүүл, түүний баримт, лиценз. Кодонд docstring, нэртэй тогтмол, тодорхой нэрс. Тест 33. Энэ бол жижиг төсөл, хоёр жижиг файл. Гэхдээ түүнийг нээсэн хүн бүр нэг зүйлийг тодорхой харна: энэ хүн мэргэжлийн хэв маягаар ажилладаг.
Шалгах цэг: Incognito цонхонд repository бүрэн, цэгцтэй, итгэл төрүүлэхүйц харагдаж байна.
# --- А. Эхлүүлэх ---
cd ~
mkdir password-generator
cd password-generator
git init
python -m venv venv
.\venv\Scripts\Activate.ps1
pip install pytest black ruff
# .gitignore, requirements-dev.txt, pytest.ini, pyproject.toml, README.md, tests\
git status
git add .
git commit -m "Initial project setup"
# GitHub: хоосон repository
git remote add origin <хаяг>
git push -u origin main
# --- Б, В. Боломж бүрт (12.1-ийн давталт) ---
# GitHub: issue
git switch -c салааны-нэр
# тест → pytest (улаан) → код → pytest (ногоон)
python main.py ...
# README
ruff check --fix .
black .
pytest
git status
git diff
git add ... ; git commit -m "..."
git push -u origin салааны-нэр
# GitHub: pull request "Closes #N", хянах, merge, delete branch
git switch main
git pull
git branch -d салааны-нэр
git fetch --prune
# --- Г. Нийтлэх ---
# GitHub: LICENSE загвар
git pull
# README-д License хэсэг, commit, push
# GitHub: About, topics, release v1.0.0, pin
git pull
git tag
# incognito шалгалтДоорх санаанууд бүгд сонголт. Хүсвэл, сонирхвол туршаад үзээрэй.
Тусгай тэмдэгт. Нууц үгэнд “!”, “@”, “#” зэрэг тусгай тэмдэгт оруулах сонголт нэмээрэй, жишээ нь python main.py 16 --symbols. Давталтыг бүтнээр нь хийгээрэй: issue, салаа, эхлээд тест, дараа нь код, README, pull request. Хоёр шинэ шийдвэр гаргах хэрэгтэй болно: аль тэмдэгтүүдийг зөвшөөрөх, тусгай тэмдэгт үргэлж байх уу. Тэдгээрийг issue-д бичээрэй. Дараа нь шинэ боломж тул v1.1.0 release гаргаарай.
Хоёр дахь компьютерийн шалгалт. Repository-гоо өөр фолдерт clone хийж, зөвхөн README-г дагаж, шинэ venv үүсгэн тестүүдийг ажиллуулаарай. 9.3 дугаар хичээлийн нэмэлт боломжийн нэгэн адил энэ нь README тань үнэхээр бүрэн гэдгийн хамгийн шударга шалгалт.
CI-тэй танилцах. 12.1 дүгээр хичээлд CI-г зөвхөн нэрлэсэн. Сонирхвол GitHub-ийн албан ёсны баримт бичгээс GitHub Actions-ийн Python-д зориулсан эхлэлийн зааврыг уншиж, энэ жижиг repository-д ruff, black --check, pytest-ийг ажиллуулдаг workflow нэмж үзээрэй. Энэ нь энэ сургалтын хүрээнээс гадуурх ажил тул алдаа гарвал энэ сургалтын debugging-ийн аргачлалаар, мессеж бүрийг тайван уншиж шийдээрэй.
from main import main ажиллахгүй байх. Хэрвээ test_main.py “cannot import name ‘main’” алдаагаар унавал main.py-д main нэртэй функц байгаа эсэх, нэр нь яг таарч байгаа эсэхийг шалгаарай. Модулийн нэр ба функцийн нэр ижил байх нь Python-д хэвийн: эхний “main” бол файл, хоёр дахь нь доторх функц.
Программ ажиллуулахад юу ч хэвлэхгүй байх. Хэрвээ python main.py юу ч хэвлэхгүй дуусвал хамгийн доод if __name__ == "__main__": блок байхгүй, эсвэл нэр буруу бичигдсэн: жишээ нь доогуур зураасны тоо. Энэ нь хоёр талдаа хоёр хоёр доогуур зураастай байх ёстой.
Тест санамсаргүйгээр унах. Хэрвээ test_password_has_lower_upper_and_digit хааяа, гэхдээ үргэлж биш, унаж байвал generate_password гурван төрлийн тэмдэгтийг баталгаажуулах алхмыг алгасаж байна: жишээ нь бүх тэмдэгтийг ALPHABET-ээс сонгодог. Хорин өөр үр яг ийм алдааг барих зорилготой. Хааяа унадаг тест таны кодын хааяа гардаг алдааг илтгэж байгаа: 10.1 дүгээр хичээлийн "давтаж гарга" алхмаар унасан үрийг тайлангаас, ID-аас олж, түүгээр алдааг давтаж, засаарай.
random-ийг secrets-ийн оронд хэрэглэх. Хэрвээ анхдагч үүсгэгчийг random.Random() болговол бүх тест давна, учир нь тест хоёуланд ижил ажилладаг. Гэхдээ нууц үг аюулгүй биш болно. Энэ бол тестийн хүрэхгүй алдаа: 7.1 дүгээр хичээлийн "тест кодын зөвийг баталдаггүй" үнэний жишээ. Тиймээс шийдвэрийг docstring-д бичсэн бөгөөд pull request-ийн хянах үед анхаарах ёстой.
Нэг том pull request. Цөм ба бүрхүүлийг нэг салаа, нэг pull request болгох уруу таталт төрж магадгүй, учир нь хоёулаа жижиг. Гэхдээ тус тусдаа issue, тус тусдаа pull request түүхийг ойлгомжтой болгож, release-ийн автомат тэмдэглэлийг утга бүхий болгодог. 12.1 дүгээр хичээлийн "жижиг давталтууд" зарчим.
Энэ удирдлагатай бүтээлд та хоосон фолдероос эхлэн GitHub дээр нийтлэгдсэн, хувилбартай, мэргэжлийн төсөл бүтээж, энэ сургалтын бараг бүх дадлыг нэг ажилд хэрэглэсэн. Ажлыг эхлэхээс өмнө гэрээг тодорхойлсон. Repository, venv, .gitignore, хөгжүүлэлтийн хамаарал, pytest ба ruff-ийн тохиргоо, README-ийн эхлэлийг анхны commit-оос өмнө бэлдсэн. Хоёр боломжийг тус бүр issue, салаа, тестийг эхэлж бичих, код, чанарын шалгалт, жижиг commit-ууд, “Closes #N” бүхий pull request-ээр 12.1 дүгээр хичээлийн давталтаар бүтээсэн. Санамсаргүй кодыг rng параметрээр тестлэх боломжтой болгож, яг утга биш, шинж чанарыг шалгасан. Нууц үгэнд random биш, secrets-ийн аюулгүй үүсгэгчийг хэрэглэсэн. Цэвэр цөм passwords.py ба нимгэн бүрхүүл main.py-г салгаж, бүрхүүлийг sys.argv-ийг параметрээр авч, capsys-ээр тестэлсэн. Нэртэй тогтмол, docstring, найрсаг алдааны мессеж, MIT лиценз, About, v1.0.0 release, эцэст нь incognito шалгалт.
Дараагийн хичээл бол энэ сургалтын эцсийн хичээл. Бид юу өөрчлөгдсөнийг эргэн харж, таны GitHub одоо ажил олгогч, reviewer-т юу харуулж байгааг дүгнэж, гэрчилгээний тухай ярьж, цувралын дараагийн сургалт руу гүүр тавина.
Бүртгэлтэй болсноор энэ сургалтын бүх хичээлд хандах эрх авна.