Функсияи statusLine файлро ҳамон тавр тасвир мекунад, ки git status. Аммо як ҳолатро намедонад: файл аллакай дар индекс аст (staged), ва пас аз git add он боз як бор тағйир ёфт (changedAfterAdd: true). Барои он сатри staged, but changed again: ном лозим аст. Шартро анҷом диҳед.
git branch # список веток, звёздочка у текущей
git switch -c feature/filters # создать ветку и перейти на неё
# ...правим файлы, git add, git commit...
git log --oneline --graph --all # история в виде дерева
git switch main # вернуться на main
git merge feature/filters # влить ветку в main
git branch -d feature/filters # удалить ветку, она больше не нужна
Шохаҳоро чӣ тавр номгузорӣ кардан
Дар фармонҳо шохаро аз рӯи қолаби навъ/тавсифи-кӯтоҳ меноманд: feature/order-filters, fix/wrong-total, docs/readme-tajik. Калимаҳои англисӣ, ҳарфҳои хурд, бе фосила, калимаҳо бо дефис. Аз рӯи ном фавран намоён аст, ки дар шоха чӣ ҳаст ва барои чӣ.
Хатогиҳои маъмул
Бевосита дар main кор кардан. Он гоҳ аз чӣ PR сохтан намешавад, ва ҳангоми мушкил бозгашт кардан ҷое нест. Одат: аввал git switch -c, баъд код.
Шохаро бо таҳрирҳои нигоҳнадошта иваз кардан. Git ё онҳоро мебарад, ё рад мекунад. Беҳтараш аввал commit кунед.
Шохаҳо — графи commit-ҳо ҳастанд, ва мо онро бо код гашта метавонем. Аз оддӣ оғоз мекунем: занҷири «падар → падар»-ро мегузарем, чунон ки git log мекунад.
Амал: мустаҳкам мекунем
ВАЗИФАИ 2.1
Таърихи шоха
осон
Ҳар commit «падар»-и худро ба ёд дорад. Шоха — танҳо ишоратгар ба commit-и охирин аст. history(branch)-ро анҷом диҳед: аз охири шоха бо занҷири parent гузаред ва массиви паёмҳоро аз нав ба кӯҳна баргардонед — git log ҳамин тавр кор мекунад.
let id = branches[branch] ва давраи while (id !== null) эълон кунед. Дар бадана: commit-и byId[id]-ро гиред, message-и онро нигоҳ доред, ба parent гузаред.
git remote add origin https://github.com/ВАШ_ЛОГИН/chaykhona-site.git
git push -u origin main # первая отправка, -u запоминает связь веток
git push # дальше достаточно просто push
git clone https://github.com/ВАШ_ЛОГИН/chaykhona-site.git # скачать чужой репозиторий
git pull # забрать новые коммиты с GitHub
git fetch # только скачать информацию, ничего не менять
Тавсифи хуби PR вақти ревьюерро сарфа мекунад. buildPr(pr)-ро анҷом диҳед: функсия як сатр бо формати «Натиҷаи интизоршаванда»-ро бармегардонад: сарлавҳаи «Что сделано» бо рӯйхати нишонадор, сатри холӣ, «Зачем», сатри холӣ, «Как проверить» бо рӯйхати рақамгузорӣшуда.
Таҳрир кардан мумкин аст · Ctrl + Enter
functionbuildPr(pr) {
// сатрро баргардонед; массиви сатрҳоро ҷамъ кунед ва join("\n")-ро даъват намоед
}
const pr = {
what: ["добавлен фильтр заказов по статусу", "фильтр запоминается в localStorage"],
why: "Менеджер хочет быстро находить неоплаченные заказы.",
check: ["Откройте страницу заказов", "Выберите статус «Не оплачен»", "Обновите страницу: фильтр остался"],
};
console.log(buildPr(pr));
Натиҷаи интизоршаванда
## Что сделано
- добавлен фильтр заказов по статусу
- фильтр запоминается в localStorage
## Зачем
Менеджер хочет быстро находить неоплаченные заказы.
## Как проверить
1. Откройте страницу заказов
2. Выберите статус «Не оплачен»
3. Обновите страницу: фильтр остался
Ишора 1
Аз массиви const lines = ["## Что сделано"] оғоз кунед. Бандҳоро бо forEach илова кунед: lines.push(`- ${w}`). Сатри холӣ дар массив — ин танҳо "" аст.
Git метавонад тағйиротро худкор ҷамъ кунад, агар шумо ва ҳамкор ҷойҳои гуногунро таҳрир карда бошед. Аммо агар шумо ҳарду як сатри ягонаро гуногун тағйир диҳед, Git намедонад, версияи кӣ дуруст аст, ва аз одам хоҳиш мекунад, ки ҳал кунад. Ин низоъ (conflict) аст. Он вайроншавӣ нест, балки қисми оддии кор: дар ҳар гурӯҳ низоъҳо ҳар ҳафта рух медиҳанд.
Фарз кунем, ки шумо бо ҳамкор файли rate.js-ро таҳрир кардед. Ҳамкор шохаи худро аллакай ба main даровард, ва шумо дар шохаи худ git pull origin main кардед:
Терминал
git switch feature/rate
git pull origin main
# Auto-merging rate.js
# CONFLICT (content): Merge conflict in rate.js
# Automatic merge failed; fix conflicts and then commit the result.
Git истод ва дар файл маркерҳои низоъ-ро сабт кард:
Охири низоъ ва номи шохае, ки версияи дуюм аз он омадааст.
Низоъро чӣ тавр ҳал кардан
Файлро кушоед бо калимаи CONFLICT. Дар VS Code болои блок тугмаҳо пайдо мешаванд: Accept Current (аз они ман), Accept Incoming (аз они бегона), Accept Both (ҳарду) ва Compare.
Аз рӯи маъно ҳал кунед, ки чӣ бояд бимонад. Гоҳо бояд порчаҳоро аз ҳарду версия гирифт — ва коди ниҳоиро бо даст навишт. Бо муаллифи таҳрири дуюм мувофиқа кунед.
git add rate.js
git commit -m "merge main into feature/rate"
git push
Агар ошуфтед
Фармони git merge --abort (ё git rebase --abort) ҷамъкуниро бекор мекунад ва ҳама чизро ба ҳолати пеш аз он бармегардонад. Низоъро дар шохаи худ пеш аз merge ҳал мекунанд: он гоҳ ба main натиҷаи тоза мерасад.
Хатои хатарнок
Файлеро commit кардан, ки дар он сатрҳои <<<<<<< мондаанд. Чунин код иҷро намешавад. Пеш аз git add дар лоиҳа <<<<<<<-ро ҷустуҷӯ кунед (Ctrl+Shift+F дар VS Code).
Маркерҳо — матни оддӣ ҳастанд, ва онҳоро бо код таҳлил кардан мумкин аст. Вазифаи аввалро шумо бо даст, мисли низои ҳақиқӣ ҳал мекунед. Дар дуюмӣ «ҳалли худкор»-ро менависед, чунон ки муҳаррирҳо мекунанд.
Амал: мустаҳкам мекунем
ВАЗИФАИ 4.1
Низоъро бо даст ҳал мекунем
миёна
Пас аз merge-и ноком файл мисли дар тағйирёбандаи conflicted менамояд. Гурӯҳ қарор дод: номи функсияро аз main (toSomoni) мемонем, ва формула-ро аз шохаи feature/rate мегирем: параметри rate бо қимати пешфарзии 10.9 ва мудаввар кардан. Дар resolved матни ниҳоии файлро нависед: бе маркерҳо ва бо як сатри код. Чор санҷиши зер бояд false / true / true / true диҳанд.
Таҳрир кардан мумкин аст · Ctrl + Enter
const conflicted = `// курс обмена
<<<<<<< HEAD
const toSomoni = (usd) => usd * 11;
=======
const convertUsd = (usd, rate = 10.9) => Math.round(usd * rate);
>>>>>>> feature/rate
`;
const resolved = `// курс обмена
`; // сатри ниҳоии кодро анҷом диҳед
console.log("маркеры остались:", /<<<<<<<|=======|>>>>>>>/.test(resolved));
console.log("имя из main:", resolved.includes("const toSomoni ="));
console.log("формула из feature:", resolved.includes("rate = 10.9") && resolved.includes("Math.round(usd * rate)"));
console.log("лишнее убрано:", !resolved.includes("convertUsd") && !resolved.includes("usd * 11"));
Натиҷаи интизоршаванда
маркеры остались: false
имя из main: true
формула из feature: true
лишнее убрано: true
resolveAll(text, side)-ро нависед, ки маркерҳои низоъро хориҷ мекунад. side = "ours" версияро аз HEAD (то =======) мемонад, "theirs" — версияро аз шохаи бегона (пас аз =======), "both" — ҳарду пай дар пай. Сатрҳои берун аз низоъ чунон ки ҳастанд, нигоҳ дошта мешаванд. Аз рӯи сатрҳо гузаред ва дар ёд доред, ки ҳоло дар кадом қисми блок ҳастед.
Таҳрир кардан мумкин аст · Ctrl + Enter
const conflicted = [
"<h1>MakeFirstStep</h1>",
"<<<<<<< HEAD",
"<p>Курсы программирования</p>",
"=======",
"<p>Курсы Frontend и ИИ</p>",
">>>>>>> feature/text",
"<footer>Душанбе</footer>",
].join("\n");
functionresolveAll(text, side) {
const out = [];
let part = "none"; // none | ours | theirsfor (const line of text.split("\n")) {
// коди шумо
}
return out.join("\n");
}
for (const side of ["ours", "theirs", "both"]) {
console.log(side + ": " + resolveAll(conflicted, side).split("\n").join(" / "));
}
fix: wrong total in cart, feat(ui): add dark theme. Феъл дар шакли амр («add», «fix»), ҳарфҳои хурд, то 50 аломат, бе нуқта, як андеша барои як commit.
Барои мустаҳкам кардан мебинем, ки таснифи паёмҳо дар код чӣ гуна менамояд. Мисолро иҷро кунед ва паёмҳоро тағйир диҳед:
Навъи commit аз рӯи паём · Ctrl + Enter
const messages = ["feat: add filters", "fix(cart): sum", "update", "docs: readme"];
for (const m of messages) {
const match = m.match(/^([a-z]+)(\([^)]*\))?: /);
console.log(m.padEnd(20), "->", match ? match[1] : "нет типа");
}
Дар формати Conventional Commits паём бо навъ оғоз мешавад: feat: …, fix(cart): …. commitType(msg)-ро анҷом диҳед: он навъро (калима то дунуқта ё то қавс) ё "other"-ро, агар паём аз рӯи формат нест, бармегардонад. Ҳисоб ва чоп аллакай омодаанд.
Таҳрир кардан мумкин аст · Ctrl + Enter
const messages = [
"feat: add order filters",
"fix: wrong total in cart",
"docs: update readme",
"fix(cart): off-by-one in loop",
"update",
"feat(ui): dark theme",
"fix: crash on empty order",
"Changes",
];
functioncommitType(msg) {
// регулярка: калима дар аввал, (соҳа)-и ихтиёрӣ, дунуқта ва фосилаreturn"other";
}
const counts = {};
for (const m of messages) {
const type = commitType(m);
counts[type] = (counts[type] ||0) + 1;
}
console.log(JSON.stringify(counts));
const m = msg.match(regex); return m ? m[1] : "other";
ВАЗИФАИ 5.3
Линтери commit-ҳо
душвор
lintCommit(msg)-ро нависед — массиви мушкилот. Қоидаҳо: (1) паём бояд бо feat|fix|docs|style|refactor|test|chore, (соҳа)-и ихтиёрӣ ва : оғоз шавад; вагарна як мушкили «нет типа вида feat: …» — минбаъд санҷидан лозим нест; (2) «тема длиннее 50 символов» (мавзӯъ — матни пас аз : ); (3) «тема с заглавной буквы»; (4) «точка в конце». Массиви холӣ маънои «ҳама хуб»-ро дорад.
Таҳрир кардан мумкин аст · Ctrl + Enter
functionlintCommit(msg) {
const problems = [];
return problems;
}
const list = [
"feat: add order filters",
"Fixed bug.",
"fix(cart): Wrong total.",
"docs: describe in the readme how to install dependencies and run the project",
];
for (const m of list) {
const p = lintCommit(m);
console.log(`${m.slice(0, 24)} -> ${p.length ? p.join("; ") : "ok"}`);
}
Натиҷаи интизоршаванда
feat: add order filters -> ok
Fixed bug. -> нет типа вида feat: …
fix(cart): Wrong total. -> тема с заглавной буквы; точка в конце
docs: describe in the re -> тема длиннее 50 символов
Ишора 1
Як регулярка бо се гурӯҳ: /^(feat|fix|docs|style|refactor|test|chore)(\([^)]*\))?: (.+)$/. Мавзӯъ — ин m[3] аст.
Ишора 2
Агар matchnull баргардонд — фавран return ["нет типа вида feat: …"]. Санҷишҳои боқӣ — се if-и мустақил бо push.
Гоҳо хаторо худатон бояд эҷод кунед. Масалан, функсия аз корбар миқдори манфӣ гирифт. throw функсияи ҷориро қатъ мекунад ва хаторо ба боло — то наздиктарин catch «мепартояд». Объекти хато-ро партоед (new Error("матн")), на танҳо сатр: объект стек дорад.
throw new Error · Ctrl + Enter
functionsetQuantity(qty) {
if (!Number.isInteger(qty)) thrownewTypeError("Количество должно быть целым числом");
if (qty < 1) thrownewRangeError("Количество не может быть меньше 1");
return qty;
}
for (const value of [3, 0, 2.5]) {
try {
console.log("ок:", setQuantity(value));
} catch (e) {
console.log(`${e.name}: ${e.message}`);
}
}
Хатои маъмул: catch-и холӣ
catch (e) {}-и холӣ хаторо «фурӯ мебарад»: барнома хомӯш аст ва ғайриодатӣ рафтор мекунад, ва сабабро ёфтан намешавад. Ҳадди ақал — хаторо ба консол бароред ё ба корбар паём нишон диҳед. Ва танҳо он хатоҳоеро бигиред, ки коркард карда метавонед: боқиро тавассути throw e ба пеш гузаронед (вазифаи 6.5).
Ин код хато медиҳад · Ctrl + Enter
functionrisky() {
thrownewError("что-то пошло не так");
}
risky(); // хато гирифта нашуд: иҷро қатъ шуд
console.log("до этой строки мы уже не дойдём");
Сатри холӣ ҳам JSON-и нодуруст аст, барои ҳамин барои даъвати сеюм catch ҳам кор мекунад ва массиви холӣ бармегардонад.
ВАЗИФАИ 6.4
Хатоҳои худӣ тавассути throw
миёна
withdraw(balance, amount)-ро анҷом диҳед — гирифтани сомонӣ. Агар amount аз сифр зиёд набошад, new RangeError("Сумма должна быть больше нуля")-ро партоед. Агар amount аз баланс зиёд бошад — new Error("Недостаточно сомони"). Вагарна боқимондаро баргардонед. Тартиби санҷишҳо — чунон ки дар шарт.
Таҳрир кардан мумкин аст · Ctrl + Enter
functionwithdraw(balance, amount) {
// ду санҷиш бо throw, баъд return
}
for (const amount of [200, 0, 5000, -10]) {
try {
console.log("остаток:", withdraw(1000, amount));
} catch (e) {
console.log(`${e.name}: ${e.message}`);
} finally {
console.log("— операция завершена —");
}
}
Натиҷаи интизоршаванда
остаток: 800
— операция завершена —
RangeError: Сумма должна быть больше нуля
— операция завершена —
Error: Недостаточно сомони
— операция завершена —
RangeError: Сумма должна быть больше нуля
— операция завершена —
Ишора 1
throw функсияро фавран қатъ мекунад, барои ҳамин пас аз он else лозим нест: if (amount <= 0) throw new RangeError("…");.
Ишора 2
Блоки finally дар давра пас аз ҳар амал иҷро мешавад — ҳам муваффақ, ҳам ноком.
ВАЗИФАИ 6.5
Танҳо хатоҳои худро мегирем
душвор
catch-и хуб танҳо хатоҳоеро коркард мекунад, ки интизор аст, ва бегонаро ба пеш мегузаронад: throw e. validate(order)-ро анҷом диҳед: агар дар фармоиш name набошад, fail("name", "укажите имя")-ро даъват кунед; агар qty аз 1 камтар бошад — fail("qty", "минимум 1 штука"). Функсияи ёрирасони fail аллакай ҳаст. Даъвати process(null) бояд бо TypeError-и ҳақиқӣ биафтад, ки process онро фурӯ намебарад.
Донишҷӯ аз куратор мепурсад, куратор — аз муаллим, муаллим — аз методист, ва дар охир маълум мешавад, ки дар ҷадвал хато ҳаст. Стек — ин сабти он аст, ки кӣ аз кӣ пурсид. Барои ёфтани он, ки хато аз куҷост, занҷирро аз поён ба боло мегузарем, аммо ба даъвати болоӣ менигарем: маҳз он «натавонист».
Бе DevTools «ба дохили» давра нигоҳ кардан тавассути console.log мумкин аст. Ба давра як сатри логро тавре илова кунед, ки пас аз коркарди ҳар рақам n=…, sum=… (қиматҳо дар ин лаҳза) чоп шавад. Қимати ниҳоиро функсия худаш чоп мекунад.
Таҳрир кардан мумкин аст · Ctrl + Enter
functionsumPositive(numbers) {
let sum = 0;
for (const n of numbers) {
if (n > 0) sum += n;
// дар ин ҷо console.log илова кунед
}
return sum;
}
console.log(sumPositive([5, -3, 10, 0, 7]));
Аввал кодро ба ҳамин ҳол иҷро кунед ва бубинед, ки чӣ чоп мекунад — бо натиҷаи интизоршаванда муқоиса кунед. Ишораи «аломат»-ро дар шарт бихонед. Фарзия пешниҳод кунед, як ҷойро ислоҳ намоед ва боз иҷро кунед. Ишораҳоро танҳо пас аз кӯшиши худатон кушоед.
Мисоли таҳлил
Инак хато ва ислоҳи он «бо суханон». Иҷро кунед:
Чӣ чоп мешавад? · Ctrl + Enter
const scores = [70, 85, 90];
functionaverage(list) {
let sum = 0;
for (let i = 0; i < list.length; i++) {
sum += list[i];
}
return sum / list.length + 1;
}
console.log(average(scores));
Рӯйхати донишҷӯёни курс ба ҳар саҳифа 3 нафар нишон дода мешавад. Саҳифаи якум бояд аз «Алишер» оғоз шавад, аммо чизи дигар чоп мешавад. getPage-ро ислоҳ кунед, то саҳифаҳои 1, 2, 3 гурӯҳҳои даркориро чоп кунанд.
Дар label як аломати = — ин таъинот аст: нарх ҳангоми ҳар даъват 0 мешавад. Муқоисаи === лозим аст.
Тартиби коди ғайримуттаҳид
ВАЗИФАИ 8.5
Хато: forEach ва await
миёна
Се таом пай дар пай пухта мешаванд, ва «Все блюда готовы!» бояд пас аз се сатри «… готов» пайдо шавад. Ҳоло сатри ниҳоӣ аввал чоп мешавад. Кодро ислоҳ кунед: forEach колбэкҳои async-ро интизор шуда наметавонад. Онро бо давраи интизоршаванда иваз кунед.
плов готов
самбуса готов
лагман готов
Все блюда готовы!
Ишора 1
forEach колбэкҳоро оғоз мекунад ва натиҷаи онҳоро интизор намешавад, барои ҳамин main фавран ба пеш меравад. Давраи for…of дар дохили функсияи async ҳар await-ро интизор мешавад.
Ишора 2
for (const d of dishes) { console.log(await cook(d)); }
ВАЗИФАИ 8.6
Хато: await-ро фаромӯш кардем
миёна
Бояд Итого: 80 (30 + 50) чоп шавад. Ба ҷои он матн бо «Promise» ҳосил мешавад. Функсияи getPrice ғайримуттаҳид аст. showTotal-ро ислоҳ кунед.
Таҳрир кардан мумкин аст · Ctrl + Enter
const getPrice = (id) =>newPromise((resolve) =>setTimeout(() =>resolve(id * 10), 20));
asyncfunctionshowTotal() {
const a = getPrice(3);
const b = getPrice(5);
console.log("Итого:", a + b);
}
showTotal();
Натиҷаи интизоршаванда
Итого: 80
Ишора 1
Бе await дар тағйирёбанда худи промис меистад, на рақам. Ҷамъи ду промис онҳоро ба сатр табдил медиҳад.
Ишора 2
await-ро пеш аз ҳар getPrice(...) гузоред. Ё Promise.all-ро истифода баред, агар мехоҳед ҳарду нархро якбора гиред.
ВАЗИФАИ 8.7
Хато: таймерҳо дар давра
осон
Се таймер бояд таймер 1, таймер 2, таймер 3-ро чоп кунанд. Аммо онҳо як рақамро чоп мекунанд. Эълони тағйирёбандаи давраро ислоҳ кунед — як калимаро тағйир додан лозим аст.
Таҳрир кардан мумкин аст · Ctrl + Enter
for (var i = 1; i <= 3; i++) {
setTimeout(() => console.log("таймер", i), i * 10);
}
Натиҷаи интизоршаванда
таймер 1
таймер 2
таймер 3
Ишора 1
Тағйирёбандаи var барои тамоми давра як аст, ва то лаҳзаи кори таймерҳо давра аллакай тамом шудааст (i 4 шуд).
Ишора 2
Бо let дар ҳар давр тағйирёбандаи худии i эҷод мешавад.
Ду хато бо як сабаб — якчанд «тағйирёбанда» ба як массиви ягона менигаранд. (1) Тӯри аз се сатр: пас аз илова кардани «A1» ба аввалӣ ва «C1» ба сеюм дарозиҳо бояд 1,0,1 бошанд. (2) Нусхаи ҳолат copy набояд ба state таъсир расонад: тегҳо дар он бояд js бимонанд. Ҳарду қисмро ислоҳ кунед.
new Array(3).fill([]) дар се ячейка як ва ҳамон массивро мегузорад. Се массиви гуногунро эҷод кардан лозим аст: Array.from({ length: 3 }, () => []) — функсия барои ҳар ячейка аз нав даъват мешавад.
Бонус: то шумо кодро содда мекардед, аксар вақт худатон хаторо меёбед. Ин муқаррарӣ ва хеле қиматнок аст. Усул «мурғобича» (rubber duck) ном дорад: мушкилро бо овози баланд чунон возеҳ шарҳ додан, ки ҷавоб худаш пайдо шавад.
Бо фарзияҳо чӣ тавр кор накардан лозим
ЗС се фарзия дод. Онҳоро пай дар пай, аз эҳтимолтарин месанҷед, ва пас аз ҳар кадом — иҷро. Агар якбора се «ислоҳ»-ро гузоред, намефаҳмед, кадомаш кор кард, ва ёд намегиред, ки ин хаторо дафъаи оянда пай бурдан лозим аст. Ҳамчунин ЗС гоҳо методҳои вуҷуднадоштаро бо боварӣ маслиҳат медиҳад: номи ношиносро дар MDN санҷед.
Ба варақаи кӯмакии промптҳо ду сатри ин дарсро илова кунед — «Commit-ҳо ва pull request» ва «Хато ба ҷои „кор намекунад“». Ҳарду маҳоратро бо код машқ мекунем.
Амал: мустаҳкам мекунем
ВАЗИФАИ 9.1
Промпт бо мисоли ҳадди ақал
миёна
bugPrompt(bug)-ро анҷом диҳед: он аз тавсифи хато промпти тайёр барои ЗС-ро аз рӯи формати курс ҷамъ мекунад — чор сатр (код аз сатри дуюм меояд). Агар дар консол хато набошад (bug.error муайян нашудааст), дар сатри хато нет менависем.
Таҳрир кардан мумкин аст · Ctrl + Enter
functionbugPrompt(bug) {
// сатрро аз сатрҳо баргардонед:// Баг: ожидаю «…», получаю «…».// Минимальный код:// <код>// Ошибка в консоли: …// Дай 3 гипотезы причины по вероятности.
}
console.log(bugPrompt({
expected: "45",
actual: "NaN",
code: "const prices = [20, 25];\nlet sum = 0;\nfor (let i = 0; i <= prices.length; i++) sum += prices[i];\nconsole.log(sum);",
}));
console.log("---");
console.log(bugPrompt({ expected: "Привет, Али", actual: "Привет, undefined", code: "greet({ nam: 'Али' })", error: "ошибки нет" }));
Натиҷаи интизоршаванда
Баг: ожидаю «45», получаю «NaN».
Минимальный код:
const prices = [20, 25];
let sum = 0;
for (let i = 0; i <= prices.length; i++) sum += prices[i];
console.log(sum);
Ошибка в консоли: нет
Дай 3 гипотезы причины по вероятности.
---
Баг: ожидаю «Привет, Али», получаю «Привет, undefined».
Минимальный код:
greet({ nam: 'Али' })
Ошибка в консоли: ошибки нет
Дай 3 гипотезы причины по вероятности.
Ревью: PR-и ҳамкорро аз рӯи чек-листи қисми 3 бихонед. Ҳадди аққал ду шарҳ ба сатрҳои мушаххас гузоред: яке бо савол, яке бо пешниҳод. Коди шохаро иҷро кунед.
Муаллиф ба шарҳҳо ҷавоб медиҳад ва кодро бо commit-ҳои нав дар ҳамон шоха ислоҳ мекунад. Ревьюер Approve-ро пахш мекунад.
git switch main
git pull
git branch -d feature/calc-total
Қисми 3. Низои қасдӣ (10 дақиқа)
Ҳарду шохаҳои навро аз main-и тоза эҷод мекунанд ва як сатри ягонаро дар README (масалан, сарлавҳа) — гуногун тағйир медиҳанд.
А PR-и худро аввал медарорад. Б дар шохаи худ git pull origin main мекунад — низоъ пайдо мешавад.
Б низоъро якҷоя бо А ҳал мекунад (дар бораи матни ниҳоӣ мувофиқа мекунанд), git add, git commit, git push мекунад. PR-и Б навсозӣ шуд ва дигар низоъ надорад.
Қисми 4. Се хатои ҷойгузоршуда (25 дақиқа)
Ҳар кас пинҳонӣ ба лоиҳаи худ се хатои навъҳои гуногун (аз харитаи қисми 8) ворид мекунад ва ба шохаи нави bugs/номҳо push мекунад. Ҳамкор онҳоро бо усули қисми 7 ислоҳ мекунад: такрор кардан, хаторо хондан, breakpoint ё логро гузоштан, ислоҳро бо commit-и алоҳидаи fix: … бо сабаб анҷом додан. Версияи тамринии чунин лоиҳа — вазифаи зер: онро ҳамчун ревьюи коди бегона бихонед.
Амал: мустаҳкам мекунем
ВАЗИФАИ 10.1
Се хато дар лоиҳаи бегона
душвор
Ҳамкор сабади мағозаи MakeFirstStep-ро навишт ва аз шумо ревью металабад. Тахфифи 10% аз 500 сомонӣ аз ҷумла амал мекунад, интиқол 15 сомонӣ аст ва танҳо ба нусхаи сабад илова мешавад. Дар код се хатои навъҳои гуногун пинҳон шудааст. Онҳоро ёбед, ислоҳ кунед ва дар шарҳ болои ҳар ислоҳ сабабро бо як сатр нависед. Рақамҳои интизоршаванда дар зер — ҷавобҳои дурустанд.
Се хато: (1) давра аз i = 1 оғоз мешавад ва маҳсулоти якумро мегузарад; (2) дар priceWithDiscount ба ҷои >= аломати > меистад — дақиқан 500 тахфиф намегирад; (3) push сабади аслиро тағйир медиҳад.
Ишора 2
Худро бо рақамҳо санҷед: маҷмӯи сабад 550, бо тахфиф 495, сабад барои дақиқан 500 — 450, бо интиқол 565, пас аз ин дар сабади аслӣ ҳамоно 3 маҳсулот.
Чек-листи ҷуфт дар охир
Дар репозиторий: се ва зиёда commit бо паёмҳои бомаъно, як PR-и даровардашуда бо тавсиф ва шарҳҳои ревью, як низои ҳалшуда, се commit-и fix: бо тавсифи сабаб. Агар чизе нест, дар хона анҷом диҳед: ин ба вазифаи хонагӣ дохил мешавад.
11 Вазифаи хонагӣ
Репозиторийро тавре ороиш диҳед, ки нишон додани он ба корфармо шармовар набошад, ва се хаторо бо таҳлили сабаб ёбед. Метавонед лоиҳаи яке аз дарсҳои гузашта (масалан, лоиҳаи хурди №1) ё лоиҳаи ҷуфтро гиред.
Қисми 1. Репозиторий
Репозиторий дар GitHub оммавӣ аст, номи бомаъно ва тавсиф дорад.
Дар таърих ҳадди аққал 10 commit-и бомаъно аз рӯи Conventional Commits: ҳар кадом — як андеша, ягон «update», «fix», «final» нест. Таърихро бо фармони git log --oneline санҷед.
Ҳадди аққал як шоха ба ҷуз main ва pull request-и даровардашуда бо тавсиф (чӣ анҷом шуд, барои чӣ, чӣ тавр санҷидан) ҳаст. Агар танҳо кор кунед, PR-ро аз шохаи худ ба main кушоед ва diff-ро мисли ревьюер худатон бинед.
# Название проекта
Одно предложение: что это и для кого.
## Что умеет
- функция 1
- функция 2
## Как запустить
1. Склонируйте репозиторий
2. Откройте index.html в браузере (или npm install && npm run dev)
## Скриншот

## Что я использовал
HTML, CSS, JavaScript, Git/GitHub
## Автор
Имя, группа курса
Қисми 2. Се хато
Дар лоиҳаи худ ё бегона се хатои воқеии навъҳои гуногун-ро ёбед: масалан, off-by-one, муқоисаи нодуруст, мутатсия, хатои тартиби коди ғайримуттаҳид. Агар наёфтед — онҳоро худатон ба нусхаи лоиҳа ворид кунед ва аз шахси шинос хоҳиш кунед, ки ёбад.
Барои ҳар хато commit-и алоҳидаиfix: … бо ислоҳ созед.
Дар репозиторий файли BUGS.md-ро эҷод кунед ва ҳар хаторо аз рӯи қолаби зер тасвир намоед.
Яке аз се таҳлилро бо промпт ба ЗС дар формати «мисоли ҳадди ақали такроршаванда» ҳамроҳ кунед ва ҷавоби ЗС-ро якҷоя бо баҳои худатон ба файл гузоред: чӣ бо иҷро тасдиқ шуд, ва чӣ нодуруст баромад.
BUGS.md — қолаб
## Баг 1: итоговая сумма корзины меньше правильной
- **Симптом:** ожидал 550, получил 530.
- **Как воспроизвести:** добавить три товара и посмотреть сумму.
- **Причина:** цикл начинался с i = 1 и пропускал первый товар (off-by-one).
- **Как нашёл:** поставил breakpoint в calcTotal, увидел, что цикл идёт с индекса 1.
- **Исправление:** коммит `a1b2c3d` — `fix: count first item in total`.
- **Как не допустить снова:** проверять границы цикла на массиве из 1 и 0 элементов.
Чӣ супурдан лозим
Истинод ба репозиторийи оммавии GitHub.
Истинод ба pull request-и даровардашуда.
Дар репозиторий: README.md, .gitignore, BUGS.md.
Чӣ тавр баҳо медиҳем (0–10)
Чӣ
Холҳо
10+ commit-и бомаъно аз рӯи формат, «update» ва «fix» бе шарҳ нест
3
Шоха, pull request бо тавсиф, ба main дароварда шудааст
2
.gitignore ва README.md аз рӯи қолаб ороиш дода шудаанд, файлҳои партов нестанд
2
Се хатои навъҳои гуногун бо commit-ҳои алоҳидаи fix:
2
Дар BUGS.md сабаб ва чӣ тавр ёфтан фаҳмост; як таҳлил бо ЗС ва санҷиш бо иҷро
1
Пеш аз супурдан
Репозиторийро дар тирезаи хусусии браузер кушоед: оё ҳама чиз бе вуруд намоён аст? git log --oneline-ро санҷед: паёмҳоро мисли шахси ношинос бихонед. Агар ЗС бо код ё таҳлил кумак кард, шумо бояд дар ҳимоя ҳар сатрро шарҳ дода тавонед.
✓ Варақаи кӯмакии дарс
Се минтақа: папкаи корӣ → индекс (git add) → репозиторий (git commit); GitHub — нусха дар шабака (git push / git pull). Пеш аз add ҳамеша git status.