এই পর্বে যা পাবেন
- মডিউল ১১-এর পাঁচটি পাতা কীভাবে একসাথে কাজ করে, আর বিশ্ববিদ্যালয়, চাকরির লিখিত পরীক্ষা ও ইন্টারভিউর জন্য আলাদা পড়ার পথ
- Software engineering-এর প্রতিটি ধরনের numerical-এর সূত্র, নিয়ম আর সাধারণ ফাঁদ — এক জায়গায়, কোর্সের পর্বগুলোর ধ্রুবক আর রীতির সাথে মিলিয়ে
- CPM-এর forward-backward pass, PERT-এর সম্ভাবনা আর crashing-এর টেবিল এমনভাবে লেখার অভ্যাস, যাতে পরীক্ষক প্রতিটি ধাপ মেলাতে পারেন
- উল্টো দিকের প্রশ্ন সামলানো: “৬০ person-month-এ কত বড় software?”, “৯৫% নিশ্চয়তার তারিখ কবে?”, “কত মিনিটের MTTR লাগবে?”
- ছোট প্রোগ্রাম আর আসল Git দিয়ে নিজের উত্তর যাচাই, আর AI-এর দেওয়া হিসাব সন্দেহের চোখে দেখা
১ · মডিউল ১১-এর শুরু — পাঁচটি অনুশীলন পর্ব, এই পাতার নিয়ম আর খাতার কৌশল
মডিউল ১১-এ স্বাগতম। প্রথম ৬৫টি পর্বে আপনি দেখেছেন software কীভাবে পরিকল্পনা, নকশা, test আর release হয়, আর Git দিয়ে একটি দল কীভাবে একসাথে কাজ করে। শেষ পাঁচটি পর্ব নতুন কিছু শেখায় না — সেই জ্ঞান পরীক্ষার খাতায়, MCQ-এর ঘড়ির সামনে আর ইন্টারভিউর টেবিলে কাজে লাগানোর অনুশীলন করায়। বাড়ি বানানো শেষ হলে যেমন রাজমিস্ত্রি নকশার সাথে প্রতিটি দেয়াল মিলিয়ে দেখেন, এই মডিউলও তেমন — প্রতিটি অধ্যায় একবার করে মিলিয়ে দেখা।
পাঁচটি পাতার কাজ আলাদা, তবে একটি অন্যটির পরিপূরক:
| পর্ব | পাতা | কী আছে | কোন দক্ষতা তৈরি করে |
|---|---|---|---|
| ৬৬ | এই পাতা — Numerical | FP, COCOMO, CPM-PERT, earned value, risk, metric, coverage, DORA আর Git-এর গোনাগুনি, পূর্ণ সমাধানসহ | সূত্র বেছে নেওয়া, নিয়ম ঘোষণা, ধাপে ধাপে হিসাব, উল্টো চেক |
| ৬৭ | MCQ প্রশ্নব্যাংক | পুরো কোর্সের বহুনির্বাচনি প্রশ্ন, মডিউল ধরে, প্রতিটি অপশনের ব্যাখ্যাসহ | দ্রুত চেনা, ফাঁদের অপশন বাদ দেওয়া, সময় সামলানো |
| ৬৮ | লিখিত ও মৌখিক প্রশ্ন | Process, requirement, design, testing আর management-এর বর্ণনামূলক প্রশ্ন আর ভাইভার উত্তরের কাঠামো | সংজ্ঞা, তুলনা, ছবি আঁকা আর গুছিয়ে লেখা |
| ৬৯ | Git ইন্টারভিউ | Git-এর ধারণা, পরিস্থিতিভিত্তিক সমস্যা আর command-এর অনুশীলন | “এখন কী করবেন” ধরনের প্রশ্নে নিরাপদ, যাচাই করা উত্তর |
| ৭০ | Software engineering ইন্টারভিউ | SOLID, design pattern, testing, code review আর আচরণগত প্রশ্ন | নকশার যুক্তি মুখে বলা, অভিজ্ঞতার গল্প সাজানো |
কোন পরীক্ষার জন্য কোন পথে
🎓 বিশ্ববিদ্যালয়ের লিখিত পরীক্ষা
Software Engineering বা Software Project Management কোর্সে numerical প্রায় নিশ্চিত নম্বর। প্রথমে এই পাতার ভাগ ২ আর ৩ (COCOMO, FP, CPM-PERT) — এগুলো খাতায় পুরো লিখে অনুশীলন করুন; তারপর ভাগ ৬ (testing-এর গোনা); তারপর পর্ব ৬৮-এর বর্ণনামূলক উত্তর; শেষে পর্ব ৬৭ দিয়ে নিজেকে যাচাই।
📝 চাকরির লিখিত পরীক্ষা
IT অফিসার বা assistant programmer পদের লিখিত পরীক্ষায় software engineering অংশ প্রায়ই ছোট থাকে — MCQ আর এক-দুই লাইনের হিসাব। তাই আগে পর্ব ৬৭, তারপর এই পাতার ছোট অঙ্কগুলো (VAF, cost slope, V(G), RE, DRE, MTBF, n(n − ১) ÷ ২), যেগুলো দুই মিনিটে করা যায়।
কোন ভাগে কী, কোন পর্ব ঝালাবেন
| ভাগ | কী আছে | মূল পর্ব |
|---|---|---|
| ২ | Function point (UFP, VAF, AFP), Basic ও Intermediate COCOMO, COCOMO II, তিন-বিন্দু অনুমান, velocity থেকে পরিসর | ০৫, ৬০ |
| ৩ | CPM-এর forward-backward pass, float, critical path, PERT-এর Z আর সম্ভাবনা, crashing, earned value | ৬১ |
| ৪ | Risk exposure, RRL, EMV-এর decision tree, MTBF-MTTR আর availability, defect density, DRE, control chart | ০৩, ০৪, ৬২ |
| ৫ | Ca, Ce, instability, abstractness, distance, LCOM4, যোগাযোগের পথ, bus factor | ২৫, ৬০, ৬৩ |
| ৬ | Equivalence class আর boundary value-এর সংখ্যা, decision table, pairwise, V(G) তিনভাবে, statement-branch-MC/DC-এর ন্যূনতম test, mutation score, exhaustive test | ৪৫, ৪৭, ৫০ |
| ৭ | Little-এর সূত্র, flow efficiency, percentile forecast, DORA, Kano, RICE আর WSJF | ০৬, ২৪, ৫৯ |
| ৮ | Bisect-এর ⌈log2 n⌉, A..B range-এ কোন commit, ahead/behind | ০৯, ১৪, ১৫, ৫৫ |
এই পাতার নিয়ম (convention) — প্রশ্নে অন্য কিছু না বললে
| বিষয় | নিয়ম |
|---|---|
| Function point | IFPUG-ধাঁচের weight: EI 3/4/6, EO 4/5/7, EQ 3/4/6, ILF 7/10/15, EIF 5/7/10 (low/avg/high); VAF = 0.65 + 0.01 × ΣGSC, ১৪টি GSC প্রতিটি ০–৫ (পর্ব ৬০) |
| COCOMO 81 | Basic: organic 2.4/1.05/0.38, semi-detached 3.0/1.12/0.35, embedded 3.6/1.20/0.32 (a/b/d), c = 2.5. Intermediate-এ a বদলে 3.2/3.0/2.8, b আর d একই, সাথে EAF |
| COCOMO II.2000 | A = 2.94, B = 0.91, C = 3.67, D = 0.28; PM = A × SizeE × ΠEM, E = B + 0.01 × ΣSF, TDEV = C × PMF, F = D + 0.2 × (E − B) |
| CPM | Activity-on-node; দিন ০ থেকে শুরু, তাই ES = পূর্বসূরিদের EF-এর সর্বোচ্চ, EF = ES + সময়; TF = LS − ES, FF = উত্তরসূরিদের সর্বনিম্ন ES − EF (পর্ব ৬১) |
| PERT | te = (a + 4m + b) ÷ ৬, σ² = ((b − a) ÷ ৬)²; activity-গুলো স্বাধীন, তাই পথের variance যোগ হয়, σ নয়; Φ(z) = ½(১ + erf(z/√২)), টেবিল থেকে পড়লে দুই দশমিকে গোল করা Z |
| Earned value | SV = EV − PV, CV = EV − AC, SPI = EV ÷ PV, CPI = EV ÷ AC; EAC-এর মূল রূপ BAC ÷ CPI; ঋণাত্মক বা ১-এর কম = খারাপ |
| Reliability | MTBF মানে দুটি failure-এর মাঝে চলার গড় সময় (মেরামত বাদ), তাই A = MTBF ÷ (MTBF + MTTR); বছর = ৮৭৬০ ঘণ্টা (পর্ব ০৩) |
| Control chart | কেন্দ্র = গড়, সীমা = গড় ± ৩σ, σ নমুনার (n − ১ দিয়ে ভাগ); LCL ঋণাত্মক হলে ০ (পর্ব ৬২) |
| Package metric | Ca আর Ce গোনা হয় package ধরে (class নয়); Ca + Ce = ০ হলে I = ০; D = |A + I − ১|, D ≥ ০.৫ হলে zone of pain বা uselessness (পর্ব ২৫) |
| BVA | ISTQB-এর ২-মান (সীমা + অন্য পাশের নিকটতম মান) আর ৩-মান (সীমা + দুই পাশের প্রতিবেশী); integer ইনপুট (পর্ব ৪৭) |
| Percentile ও median | Nearest-rank: সাজানো তালিকার ⌈q × n⌉-তম মান — DORA-র median-ও এভাবে (পর্ব ০৬, ৫৯) |
| Bisect | n = সন্দেহভাজন commit (জানা ভালো commit বাদ, জানা খারাপটি সহ); skip না থাকলে ⌈log2 n⌉টি পরীক্ষা (পর্ব ৫৫) |
১. দেওয়া তথ্য আর একক এক লাইনে। “Size = 50 KLOC, mode = organic, effort person-month-এ, সময় মাসে” — এক লাইনেই অর্ধেক কাজ, আর KLOC বনাম LOC-এর ভুল সেখানেই ধরা পড়ে।
২. নিয়ম ঘোষণা করুন। “ধরে নিলাম COCOMO 81-এর Basic রূপ; activity-গুলো স্বাধীন; দিন ০ থেকে শুরু।” প্রশ্নে স্পষ্ট না থাকলে এটাই আপনার রক্ষাকবচ — পরীক্ষক অন্য নিয়ম ধরলেও যুক্তি দেখে নম্বর দেন।
৩. সূত্র আগে, মান পরে। “E = a × KLOCb” লিখে তারপর সংখ্যা বসান। গণনায় ভুল হলেও সূত্রের নম্বর থাকে।
৪. টেবিলে উত্তর দিন। FP-এর পাঁচ সারি, CPM-এর ES-EF-LS-LF-TF, crashing-এর ধাপ, decision table, MC/DC-এর জোড়া — সবই টেবিলের অঙ্ক। কলামের নাম আগে লিখুন।
৫. একটি sanity check দিন। VAF ০.৬৫–১.৩৫-এর মধ্যে? Critical path-এর দৈর্ঘ্য = project-এর সময়? সম্ভাবনা ০ আর ১-এর মধ্যে? V(G) তিন পদ্ধতিতে একই? এক লাইনের এই চেক অনেক ভুল ধরে।
৬. শেষ উত্তর আলাদা করুন, এক লাইনের মন্তব্যসহ। “E ≈ ১৪৫.৯ PM; দল গড়ে ৯ জন — মানে ১৭ মাসের project” — তুলনা বা সিদ্ধান্তের প্রশ্নে এই এক লাইন প্রায়ই পূর্ণ নম্বর আনে।
২ · Estimation — function point, COCOMO 81, COCOMO II আর velocity
ঝালিয়ে নিন: পর্ব ৬০ · Software estimation (FP, COCOMO, three-point), পর্ব ০৫ · Agile আর Scrum (velocity আর forecast).
Function point: UFP = Σ (সংখ্যা × weight); VAF = 0.65 + 0.01 × ΣGSC (০.৬৫–১.৩৫); AFP = UFP × VAF. Backfiring: KLOC ≈ AFP × (LOC/FP) ÷ ১০০০ — মোটা দাগের অনুমান।
COCOMO 81: E = a × KLOCb person-month, D = 2.5 × Ed মাস, দল = E ÷ D; Intermediate-এ E গুণ EAF (১৫টি cost driver-এর গুণফল)।
COCOMO II: E = 0.91 + 0.01 × ΣSF; PM = 2.94 × SizeE × ΠEM; F = 0.28 + 0.2 × (E − 0.91); TDEV = 3.67 × PMF.
তিন-বিন্দু অনুমান: te = (O + 4M + P) ÷ ৬, σ = (P − O) ÷ ৬; কয়েকটি কাজ যোগে variance যোগ। Velocity: সেরা = ⌈কম backlog ÷ সর্বোচ্চ velocity⌉, খারাপ = ⌈বেশি backlog ÷ সর্বনিম্ন velocity⌉.
Function point
২.১(সহজ) একটি কাল্পনিক পাড়ার লাইব্রেরি অ্যাপে ৫টি EI, ৪টি EO, ৩টি EQ, ২টি ILF আর ১টি EIF — সবগুলোর জটিলতা average. ১৪টি GSC-র যোগফল ৪২. UFP, VAF আর AFP কত? (ঝালিয়ে নিন: পর্ব ৬০)
average weights: EI 4, EO 5, EQ 4, ILF 10, EIF 7
UFP = 5x4 + 4x5 + 3x4 + 2x10 + 1x7 = 20 + 20 + 12 + 20 + 7 = 79
VAF = 0.65 + 0.01 x 42 = 1.07
AFP = 79 x 1.07 = 84.53
Sanity check: VAF ০.৬৫ আর ১.৩৫-এর মধ্যে, আর ΣGSC ৩৫-এর বেশি বলে VAF ১-এর একটু বেশি — আকার ৭% বাড়ল। সবচেয়ে সাধারণ ভুল EQ-কে EO-র weight (৫) দেওয়া; EQ কোনো হিসাব ছাড়া হুবহু ফেরত দেয়, তাই তার weight কম। UFP = ৭৯, VAF = ১.০৭, AFP ≈ ৮৪.৫৩.
২.২(মাঝারি) একটি কাল্পনিক ক্লিনিকের appointment অ্যাপ: EI — low ৩, average ২, high ২; EO — low ১, average ২, high ১; EQ — low ২, average ১; ILF — average ৩, high ১; EIF — low ২. ১৪টি GSC-র দশটির রেটিং ৩, চারটির ৫. ভাষার জন্য ধরা হলো ৫০ LOC/FP (একটি অনুমান, মানদণ্ড নয়)। UFP, AFP আর আনুমানিক KLOC কত?
EI : 3x3 + 2x4 + 2x6 = 9 + 8 + 12 = 29
EO : 1x4 + 2x5 + 1x7 = 4 + 10 + 7 = 21
EQ : 2x3 + 1x4 + 0x6 = 6 + 4 = 10
ILF: 0x7 + 3x10 + 1x15 = 30 + 15 = 45
EIF: 2x5 + 0x7 + 0x10 = 10 = 10
UFP = 29 + 21 + 10 + 45 + 10 = 115
sum GSC = 10x3 + 4x5 = 50 -> VAF = 0.65 + 0.50 = 1.15
AFP = 115 x 1.15 = 132.25 -> size ~ 132.25 x 50 / 1000 = 6.61 KLOC
খেয়াল করুন, ILF একাই ৪৫ — মোটের প্রায় ৩৯%. Data function-এর weight বেশি, কারণ ফাইল রক্ষণাবেক্ষণে কাজ বেশি। Sanity check: ΣGSC ৫০ ≤ ৭০ আর VAF ১.১৫ ≤ ১.৩৫. Backfiring-এর ফল (৬.৬১ KLOC) খুব মোটা দাগের — ভাষা আর দলভেদে LOC/FP অনেক বদলায়। UFP = ১১৫, AFP ≈ ১৩২.২৫, আকার প্রায় ৬.৬ KLOC.
# Function point calculator (IFPUG-style weights, VAF = 0.65 + 0.01 x sum of 14 GSC).
WEIGHTS = {"EI": (3, 4, 6), "EO": (4, 5, 7), "EQ": (3, 4, 6),
"ILF": (7, 10, 15), "EIF": (5, 7, 10)} # low, average, high
def function_points(counts, gsc_sum, loc_per_fp=None):
ufp = 0
for kind, (lo, av, hi) in counts.items():
w = WEIGHTS[kind]
sub = lo * w[0] + av * w[1] + hi * w[2]
ufp += sub
print(f" {kind:3}: {lo}x{w[0]} + {av}x{w[1]} + {hi}x{w[2]} = {sub}")
assert 0 <= gsc_sum <= 70, "14 GSC ratings, each 0..5"
vaf = 0.65 + 0.01 * gsc_sum
afp = ufp * vaf
print(f" UFP = {ufp}, VAF = 0.65 + 0.01 x {gsc_sum} = {vaf:.2f}, AFP = {afp:.2f}")
if loc_per_fp: # backfiring (rough!)
print(f" size ~ {afp:.2f} x {loc_per_fp} LOC/FP = {afp * loc_per_fp / 1000:.2f} KLOC")
return afp
print("2.1 library app (all average)")
function_points({"EI": (0, 5, 0), "EO": (0, 4, 0), "EQ": (0, 3, 0),
"ILF": (0, 2, 0), "EIF": (0, 1, 0)}, 42)
print("2.2 clinic app (mixed complexity)")
function_points({"EI": (3, 2, 2), "EO": (1, 2, 1), "EQ": (2, 1, 0),
"ILF": (0, 3, 1), "EIF": (2, 0, 0)}, 10 * 3 + 4 * 5, loc_per_fp=50)আউটপুট:
2.1 library app (all average)
EI : 0x3 + 5x4 + 0x6 = 20
EO : 0x4 + 4x5 + 0x7 = 20
EQ : 0x3 + 3x4 + 0x6 = 12
ILF: 0x7 + 2x10 + 0x15 = 20
EIF: 0x5 + 1x7 + 0x10 = 7
UFP = 79, VAF = 0.65 + 0.01 x 42 = 1.07, AFP = 84.53
2.2 clinic app (mixed complexity)
EI : 3x3 + 2x4 + 2x6 = 29
EO : 1x4 + 2x5 + 1x7 = 21
EQ : 2x3 + 1x4 + 0x6 = 10
ILF: 0x7 + 3x10 + 1x15 = 45
EIF: 2x5 + 0x7 + 0x10 = 10
UFP = 115, VAF = 0.65 + 0.01 x 50 = 1.15, AFP = 132.25
size ~ 132.25 x 50 LOC/FP = 6.61 KLOC
দুটি লাইনই ২.১ আর ২.২-এর হাতের হিসাবের সাথে হুবহু মেলে: ৭৯ → ৮৪.৫৩, আর ১১৫ → ১৩২.২৫ → ৬.৬১ KLOC. assert লাইনটি একটি sanity check — ১৪টি GSC-র যোগফল ০ থেকে ৭০-এর বাইরে গেলে প্রোগ্রাম থেমে যাবে। নিজের বইয়ের অঙ্ক বসাতে counts-এর পাঁচটি tuple (low, average, high) আর GSC-র যোগফল বদলান।
COCOMO 81 আর COCOMO II
২.৩(সহজ) ১০ KLOC-এর একটি organic project. Basic COCOMO দিয়ে effort, সময় আর গড় দলের আকার বের করুন।
organic: a = 2.4, b = 1.05, c = 2.5, d = 0.38
10^1.05 = 11.22
E = 2.4 x 11.22 = 26.9 person-months
D = 2.5 x 26.9^0.38 = 2.5 x 3.50 = 8.7 months
team = 26.9 / 8.7 = 3.1 people (productivity 10000 / 26.9 = 371 LOC/PM)
Sanity check: E ≈ ২৭ PM মানে একজন মানুষের সোয়া দুই বছর; তিনজনে প্রায় নয় মাস — বাস্তবসম্মত। ক্যালকুলেটরে xy না থাকলে log দিয়ে: ১০১.০৫ = e১.০৫ × ln ১০. E ≈ ২৬.৯ PM, D ≈ ৮.৭ মাস, দল প্রায় ৩ জন।
২.৪(মাঝারি) একই ৫০ KLOC-এর project তিনটি mode-এ (organic, semi-detached, embedded) Basic COCOMO দিয়ে তুলনা করুন। কোন সংখ্যা সবচেয়ে বেশি বদলায়, কোনটি প্রায় একই থাকে?
mode E (PM) D (months) team LOC/PM
organic 145.9 16.6 8.8 343
semi-detached 239.9 17.0 14.1 208
embedded 393.6 16.9 23.3 127
Effort প্রায় ২.৭ গুণ বাড়ে (১৪৫.৯ থেকে ৩৯৩.৬), কিন্তু সময় প্রায় একই (১৬.৬–১৭.০ মাস) — বাড়তি কাজ আসে বড় দল থেকে। কারণ সময়ের exponent d ছোট আর mode-ভেদে কমে (০.৩৮ → ০.৩২); তাই embedded-এর সময় (১৬.৯) semi-detached-এর (১৭.০) চেয়ে সামান্য কমও আসে। উৎপাদনশীলতা ৩৪৩ থেকে ১২৭ লাইনে নামে — কঠোর শর্তে প্রতিটি লাইনের পেছনে বেশি যাচাই। Effort আর দল সবচেয়ে বেশি বদলায়; সময় প্রায় স্থির।
২.৫(মাঝারি) ৪০ KLOC-এর semi-detached project, Intermediate COCOMO. Cost driver: RELY very high (১.৪০), DATA high (১.০৮), ACAP high (০.৮৬), TOOL low (১.১০); বাকি ১১টি nominal (১.০০)। EAF, effort আর সময় কত?
EAF = 1.40 x 1.08 x 0.86 x 1.10 = 1.4304
Intermediate semi-detached: a = 3.0, b = 1.12, d = 0.35
40^1.12 = 62.27 ; nominal E = 3.0 x 62.27 = 186.8 PM
E = 186.8 x 1.4304 = 267.2 PM
D = 2.5 x 267.2^0.35 = 2.5 x 7.07 = 17.7 months ; team = 15.1
Semi-detached-এ Intermediate-এর a (৩.০) Basic-এর মতোই; organic (৩.২) আর embedded (২.৮)-এ আলাদা — এটি পরীক্ষার প্রিয় ফাঁদ। দক্ষ analyst (০.৮৬) effort কমালেও খুব উঁচু নির্ভরযোগ্যতা আর দুর্বল tool মিলে মোট ৪৩% বাড়িয়েছে। Sanity check: EAF ১-এর বেশি, তাই E nominal-এর চেয়ে বেশি হওয়ারই কথা। EAF ≈ ১.৪৩০, E ≈ ২৬৭.২ PM, D ≈ ১৭.৭ মাস।
২.৬(কঠিন) COCOMO II.2000, আকার ৫০ KSLOC. Scale factor: PREC high (২.৪৮), FLEX nominal (৩.০৪), RESL high (২.৮৩), TEAM very high (১.১০), PMAT nominal (৪.৬৮)। Effort multiplier: RELY high (১.১০), CPLX high (১.১৭), PCAP high (০.৮৮), TOOL high (০.৯০); বাকি ১৩টি ১.০০. Exponent, PM, TDEV আর দল কত? আকার দ্বিগুণ হলে PM কত গুণ হবে?
sum SF = 2.48 + 3.04 + 2.83 + 1.10 + 4.68 = 14.13
E = 0.91 + 0.01 x 14.13 = 1.0513
Pi EM = 1.10 x 1.17 x 0.88 x 0.90 = 1.0193
50^1.0513 = 61.11
PM = 2.94 x 61.11 x 1.0193 = 183.1 person-months
F = 0.28 + 0.2 x (1.0513 - 0.91) = 0.3083
TDEV = 3.67 x 183.1^0.3083 = 3.67 x 4.98 = 18.3 months ; team = 10.0
doubling the size: PM x 2^1.0513 = x 2.072
সব scale factor nominal হলে ΣSF হতো ১৮.৯৭ আর E ≈ ১.১০; এখানে অভিজ্ঞতা, দলের সমন্বয় আর আগেভাগে ঝুঁকি মীমাংসা exponent কমিয়ে ১.০৫-এ এনেছে। দ্বিগুণ আকারে PM ২.০৭২ গুণ — দ্বিগুণের সামান্য বেশি, অর্থাৎ diseconomy of scale এখনো আছে, তবে কম। সাধারণ ভুল: scale factor-কে EM-এর মতো গুণ করা — SF বসে exponent-এ, EM বসে গুণফলে। E = ১.০৫১৩, PM ≈ ১৮৩.১, TDEV ≈ ১৮.৩ মাস, দল প্রায় ১০ জন।
২.৭(কঠিন) উল্টো প্রশ্ন: একটি organic project-এর বাজেট সর্বোচ্চ ৬০ person-month. Basic COCOMO অনুযায়ী সর্বোচ্চ কত KLOC-এর software এই বাজেটে বানানো যায়, আর nominal সময় কত?
E = 2.4 x KLOC^1.05 -> KLOC = (E / 2.4)^(1 / 1.05)
KLOC = (60 / 2.4)^(0.9524) = 25^0.9524 = 21.45
check: 2.4 x 21.45^1.05 = 60.0 PM
D = 2.5 x 60^0.38 = 11.8 months
উল্টো প্রশ্নে ঘাতকে উল্টাতে হয়: ১ ÷ ১.০৫ ≈ ০.৯৫২৪. Sanity check: ৬০ ÷ ২.৪ = ২৫, আর exponent ১-এর একটু কম বলে উত্তর ২৫-এর একটু কম — মেলে। উত্তর বসিয়ে আবার effort বের করা (৬০.০) সবচেয়ে ভালো উল্টো চেক। প্রায় ২১.৪৫ KLOC, সময় প্রায় ১১.৮ মাস।
// COCOMO 81 (Basic + Intermediate) and COCOMO II.2000 in one calculator.
const BASIC = { organic: [2.4, 1.05, 0.38], semidetached: [3.0, 1.12, 0.35], embedded: [3.6, 1.20, 0.32] };
const INTER_A = { organic: 3.2, semidetached: 3.0, embedded: 2.8 }; // same b and d as Basic
const prod = xs => xs.reduce((p, x) => p * x, 1);
function cocomo81(kloc, mode, eaf = 1, intermediate = false) {
const [a, b, d] = BASIC[mode];
const E = (intermediate ? INTER_A[mode] : a) * kloc ** b * eaf; // person-months
const D = 2.5 * E ** d; // months
return `E=${E.toFixed(1)} PM D=${D.toFixed(1)} mo team=${(E / D).toFixed(1)} LOC/PM=${(kloc * 1000 / E).toFixed(0)}`;
}
function cocomo2(ksloc, sf, em) {
const E = 0.91 + 0.01 * sf.reduce((s, x) => s + x, 0);
const PM = 2.94 * ksloc ** E * prod(em);
const F = 0.28 + 0.2 * (E - 0.91);
const T = 3.67 * PM ** F;
return `E=${E.toFixed(4)} PiEM=${prod(em).toFixed(4)} PM=${PM.toFixed(1)} F=${F.toFixed(4)} TDEV=${T.toFixed(1)} team=${(PM / T).toFixed(1)}`;
}
console.log("2.3 organic 10 KLOC:", cocomo81(10, "organic"));
for (const m of Object.keys(BASIC)) console.log("2.4 " + m.padEnd(12) + " 50 KLOC:", cocomo81(50, m));
const eaf = prod([1.40, 1.08, 0.86, 1.10]); // RELY VH, DATA H, ACAP H, TOOL L
console.log("2.5 EAF =", eaf.toFixed(4), "->", cocomo81(40, "semidetached", eaf, true));
// scale factors PREC H, FLEX N, RESL H, TEAM VH, PMAT N; EMs RELY H, CPLX H, PCAP H, TOOL H
console.log("2.6", cocomo2(50, [2.48, 3.04, 2.83, 1.10, 4.68], [1.10, 1.17, 0.88, 0.90]));
console.log("2.6 doubling size multiplies PM by 2^E =", (2 ** 1.0513).toFixed(3));
const k = (60 / 2.4) ** (1 / 1.05); // inverse: organic, 60 PM budget
console.log("2.7 max size for 60 PM:", k.toFixed(2), "KLOC; D =", (2.5 * 60 ** 0.38).toFixed(1), "months");আউটপুট:
2.3 organic 10 KLOC: E=26.9 PM D=8.7 mo team=3.1 LOC/PM=371
2.4 organic 50 KLOC: E=145.9 PM D=16.6 mo team=8.8 LOC/PM=343
2.4 semidetached 50 KLOC: E=239.9 PM D=17.0 mo team=14.1 LOC/PM=208
2.4 embedded 50 KLOC: E=393.6 PM D=16.9 mo team=23.3 LOC/PM=127
2.5 EAF = 1.4304 -> E=267.2 PM D=17.7 mo team=15.1 LOC/PM=150
2.6 E=1.0513 PiEM=1.0193 PM=183.1 F=0.3083 TDEV=18.3 team=10.0
2.6 doubling size multiplies PM by 2^E = 2.072
2.7 max size for 60 PM: 21.45 KLOC; D = 11.8 months
প্রথম লাইন ২.৩ (২৬.৯ PM, ৮.৭ মাস), পরের তিন লাইন ২.৪-এর টেবিল, তারপর ২.৫-এর EAF ১.৪৩০৪ আর ২৬৭.২ PM, ২.৬-এর COCOMO II (E = ১.০৫১৩, PM ১৮৩.১, TDEV ১৮.৩) আর ২.০৭২ গুণ, শেষে ২.৭-এর উল্টো প্রশ্ন (২১.৪৫ KLOC). intermediate চিহ্ন দিলে a বদলে INTER_A থেকে আসে — Basic আর Intermediate-এর একমাত্র পার্থক্য সেখানেই, b আর d একই।
তিন-বিন্দু অনুমান আর velocity
২.৮(সহজ) চারটি স্বাধীন কাজের (O, M, P) দিনে: login (২, ৪, ৮), search (৩, ৫, ৯), payment (৪, ৭, ১৬), report (১, ২, ৩)। প্রতিটির te আর σ, মোট প্রত্যাশিত সময় আর মোট σ বের করুন।
task te = (O + 4M + P)/6 sigma = (P - O)/6 variance
login (2 + 16 + 8)/6 = 4.33 1.00 1.00
search (3 + 20 + 9)/6 = 5.33 1.00 1.00
payment (4 + 28 + 16)/6 = 8.00 2.00 4.00
report (1 + 8 + 3)/6 = 2.00 0.33 0.11
total mean = 19.67 days ; total variance = 6.11 ; total sigma = sqrt(6.11) = 2.47
ফাঁদ: σ-গুলো সরাসরি যোগ করলে ৪.৩৩ আসে — ভুল। স্বাধীন কাজে variance যোগ হয়, তারপর বর্গমূল। payment-এর গড় (৮) M (৭)-এর চেয়ে বেশি, কারণ দেরির দিকের লেজ লম্বা। Normal ধরে মোটামুটি ৮৪% সম্ভাবনায় ১৯.৬৭ + ২.৪৭ ≈ ২২.১ দিনের মধ্যে — সেই হিসাবের পূর্ণ রূপ ভাগ ৩-এ। মোট ≈ ১৯.৬৭ দিন, σ ≈ ২.৪৭ দিন।
২.৯(মাঝারি) একটি দলের শেষ পাঁচটি Sprint-এর velocity: ২১, ১৮, ২৪, ১৯, ২৩ point. বাকি backlog ১৬০ থেকে ১৯০ point-এর মধ্যে, Sprint দুই সপ্তাহের। কত Sprint আর কত সপ্তাহ লাগবে — একটি পরিসর হিসেবে বলুন।
average velocity = (21 + 18 + 24 + 19 + 23) / 5 = 105 / 5 = 21
best = ceil(160 / 24) = ceil(6.67) = 7 sprints
mid = ceil(175 / 21) = ceil(8.33) = 9 sprints
worst = ceil(190 / 18) = ceil(10.56) = 11 sprints
range: 7 to 11 sprints = 14 to 22 weeks
Sprint অর্ধেক হয় না, তাই প্রতিটিতে ওপরের দিকে গোল (⌈ ⌉)। সেরা ক্ষেত্রে সবচেয়ে কম কাজ ভাগ সর্বোচ্চ velocity, খারাপ ক্ষেত্রে সবচেয়ে বেশি কাজ ভাগ সর্বনিম্ন velocity — পর্ব ০৫-এর নিয়মেই। একটি সংখ্যা (৯) না বলে পরিসর বলাই সৎ forecast. ৭ থেকে ১১ Sprint, অর্থাৎ ১৪ থেকে ২২ সপ্তাহ; মাঝামাঝি অনুমান ৯ Sprint.
(সহজ) Function point গণনায় ১৪টি general system characteristic-এর রেটিংয়ের যোগফল ৫৫ হলে VAF কত?
- 1.55
- 1.20
- 0.55
- 1.35
(মাঝারি) Basic COCOMO-তে ২০ KLOC-এর একটি organic project-এর effort প্রায় কত? (a = 2.4, b = 1.05)
- 48.0 PM
- 86.0 PM
- 11.5 PM
- 55.8 PM
(সহজ) COCOMO II.2000-এ পাঁচটি scale factor-এর যোগফল ২০ হলে size exponent E কত?
- 1.11
- 1.20
- 0.91
- 1.0997
(সহজ) একটি কাজের তিন-বিন্দু অনুমান: O = ৪, M = ৬, P = ১৪ দিন। PERT-এর প্রত্যাশিত সময় আর standard deviation কত?
- 6 দিন, σ = 1.67
- 8 দিন, σ = 3.33
- 7 দিন, σ = 1.67
- 7 দিন, σ = 2.78
৩ · Scheduling — CPM, PERT-এর সম্ভাবনা, crashing আর earned value
ঝালিয়ে নিন: পর্ব ৬১ · Project planning (CPM, PERT, crashing, earned value), পর্ব ৬০ (তিন-বিন্দু অনুমান)।
CPM: forward pass-এ ES = max(পূর্বসূরির EF), EF = ES + সময়; backward pass-এ LF = min(উত্তরসূরির LS), LS = LF − সময়। TF = LS − ES; FF = min(উত্তরসূরির ES) − EF. TF = ০-এর শিকল = critical path.
PERT: μ = পথের Σte, σ = √(পথের Σσ²); Z = (T − μ) ÷ σ, P(≤ T) = Φ(Z); উল্টো প্রশ্নে T = μ + Z × σ (৯০% → Z ≈ ১.২৮২, ৯৫% → ১.৬৪৫, ৯৯% → ২.৩২৬)।
Crashing: cost slope = (crash খরচ − normal খরচ) ÷ (normal সময় − crash সময়); প্রতিবার সব critical path কাটে এমন সবচেয়ে সস্তা activity-সেট এক দিন কমান; slope দৈনিক পরোক্ষ খরচের চেয়ে বেশি হলে থামুন।
Earned value: SV = EV − PV, CV = EV − AC, SPI = EV ÷ PV, CPI = EV ÷ AC, EAC = BAC ÷ CPI, ETC = EAC − AC, VAC = BAC − EAC.
একটি পূর্ণ CPM + PERT উত্তর
একটি কাল্পনিক পাড়ার লাইব্রেরি অ্যাপের আটটি activity (দিনে)। প্রতিটির সময় CPM-এর জন্য, আর বন্ধনীতে (a, m, b) PERT-এর জন্য — এমনভাবে নেওয়া যে te ঠিক CPM-এর সময়ের সমান: A requirement ৩ (২, ৩, ৪) · B API ৫, A-র পরে (৩, ৫, ৭) · C UI নকশা ৪, A-র পরে (২, ৪, ৬) · D database ৬, B-র পরে (৩, ৬, ৯) · E login ৩, B আর C-র পরে (১, ৩, ৫) · F UI কোড ৫, C-র পরে (৩, ৫, ৭) · G integration ৪, D আর E-র পরে (২, ৩, ১০) · H test ও release ২, F আর G-র পরে (১, ২, ৩)।
লাইব্রেরি অ্যাপের AON network — critical path লাল
Each box: ES · duration · EF on top, LS · float · LF below
act dur pred (a, m, b)
A 3 - (2, 3, 4)
B 5 A (3, 5, 7)
C 4 A (2, 4, 6)
D 6 B (3, 6, 9)
E 3 B,C (1, 3, 5)
F 5 C (3, 5, 7)
G 4 D,E (2, 3, 10)
H 2 F,G (1, 2, 3)
AON · day 0 · independent tasks
A: ES 0 EF 3 B: ES 3 EF 8 C: ES 3 EF 7 D: ES 8 EF 14 E: ES max(8, 7) = 8 EF 11 F: ES 7 EF 12 G: ES max(14, 11) = 14 EF 18 H: ES max(12, 18) = 18 EF 20 project duration T = 20 days
H: LF 20 LS 18 G: LF 18 LS 14 F: LF 18 LS 13 E: LF 14 LS 11 D: LF 14 LS 8 C: LF min(11, 13) = 11 LS 7 B: LF min(8, 11) = 8 LS 3 A: LF min(3, 7) = 3 LS 0
act TF FF = min ES(succ) - EF A 0 0 B 0 0 C 4 min(8, 7) - 7 = 0 D 0 0 E 3 14 - 11 = 3 F 6 18 - 12 = 6 G 0 0 H 0 0 CP: A-B-D-G-H = 3+5+6+4+2 = 20
on the critical path only:
act te = (a+4m+b)/6 var
A (2+12+4)/6 = 3 0.111
B (3+20+7)/6 = 5 0.444
D (3+24+9)/6 = 6 1.000
G (2+12+10)/6 = 4 1.778
H (1+8+3)/6 = 2 0.111
mu=20 var=3.444 sigma=1.856
P(T<=22): Z = 2 / 1.856 = 1.078
table Z = 1.08 -> 0.8599
exact (erf) -> 0.8594
P(T<=18): Z = -1.078
-> 1 - 0.8594 = 0.1406
about 86% by day 22, 14% by 18
95%: T = mu + 1.645 x sigma
= 20 + 1.645 x 1.856
= 23.05 days
near-critical A-B-E-G-H:
mu 17, var 2.889, P(<=22) 0.998
check: CP length = last EF = 20
check: P(<=18) + P(<=22) = 1
20 days · A-B-D-G-H · P(22)~0.86
- তথ্য আর নিয়ম। প্রথম লাইনে টেবিলটি কপি করুন আর নিয়ম লিখুন: activity-on-node, দিন ০ থেকে শুরু, activity-গুলো পরস্পর স্বাধীন। (a, m, b) এমনভাবে দেওয়া যে প্রতিটির te ঠিক CPM-এর সময়ের সমান।
- Forward pass. শুরুর A-র ES ০, EF ৩. যেখানে একাধিক পূর্বসূরি, সেখানে সবচেয়ে বড় EF: E-র ES = max(৮, ৭) = ৮, G-র ES = max(১৪, ১১) = ১৪, H-এর ES = max(১২, ১৮) = ১৮. শেষ EF ২০ — project-এর ন্যূনতম সময়।
- Backward pass. শেষের H-এর LF = ২০, LS = ১৮. একাধিক উত্তরসূরি হলে সবচেয়ে ছোট LS: C-র LF = min(E-র ১১, F-এর ১৩) = ১১, B-র LF = min(D-র ৮, E-র ১১) = ৮, A-র LF = min(৩, ৭) = ৩, তাই LS ০ — শুরুতে ফিরে শূন্য মিলল, হিসাব ঠিক।
- Float আর critical path. TF শূন্য: A, B, D, G, H — যোগফল ৩ + ৫ + ৬ + ৪ + ২ = ২০ দিন। C-র TF ৪ কিন্তু FF ০, কারণ C-র EF ৭ আর উত্তরসূরি F-এর ES-ও ৭; E-র দুটিই ৩, F-এর দুটিই ৬.
- PERT-এর μ আর σ. শুধু critical path-এর পাঁচটি activity. te-এর যোগ ২০; variance-এর যোগ ৩.৪৪৪, যার অর্ধেকের বেশি (১.৭৭৮) G-র লম্বা লেজ থেকে। σ = √৩.৪৪৪ ≈ ১.৮৫৬ — σ-গুলো যোগ নয়।
- Z আর সম্ভাবনা। ২২ দিনে Z ≈ ১.০৭৮; টেবিলে ১.০৮ পড়লে ০.৮৫৯৯, erf দিয়ে হুবহু ০.৮৫৯৪. ১৮ দিন গড় থেকে একই দূরত্বে উল্টো দিকে, তাই ১ − ০.৮৫৯৪ = ০.১৪০৬.
- উল্টো প্রশ্ন আর যাচাই। ৯৫%-এর জন্য Z = ১.৬৪৫, তাই ২০ + ১.৬৪৫ × ১.৮৫৬ ≈ ২৩.০৫ দিন। Near-critical A-B-E-G-H-এর গড় ১৭ — ২২ দিনে ৯৯.৮% সম্ভাবনায় শেষ, তাই merge bias সামান্য। শেষ লাইনে উত্তর এক বাক্যে।
৩.১(মাঝারি) ওপরের আট activity-র network-এ ES, EF, LS, LF, total float আর free float-এর টেবিল বানান। Critical path আর project-এর সময় কত? কোন activity-র total float আর free float আলাদা, আর কেন?
act dur ES EF LS LF TF FF
A 3 0 3 0 3 0 0
B 5 3 8 3 8 0 0
C 4 3 7 7 11 4 0
D 6 8 14 8 14 0 0
E 3 8 11 11 14 3 3
F 5 7 12 13 18 6 6
G 4 14 18 14 18 0 0
H 2 18 20 18 20 0 0
paths: A-B-D-G-H = 20, A-B-E-G-H = 17, A-C-E-G-H = 16, A-C-F-H = 14
E-র ES = max(B-র EF ৮, C-র EF ৭) = ৮ — “সামনে বড়টি”। C-র LF = min(E-র LS ১১, F-এর LS ১৩) = ১১ — “পেছনে ছোটটি”। C-র TF ৪ হলেও FF ০, কারণ C-র EF ৭ আর তার উত্তরসূরি F-এর ES-ও ৭: C এক দিন দেরি করলে F-কেও পিছাতে হয় — float-টি C, E আর F ভাগ করে নেয়। Sanity check: critical path-এর দৈর্ঘ্য (২০) = সবচেয়ে বড় EF (২০), আর সব পথের মধ্যে এটিই দীর্ঘতম। Critical path A-B-D-G-H, ২০ দিন।
৩.২(মাঝারি) একই network-এ (a, m, b) দেওয়া আছে ওপরে। Project ২২ দিনের মধ্যে আর ১৮ দিনের মধ্যে শেষ হওয়ার সম্ভাবনা কত? ৯৫% নিশ্চয়তার তারিখ কোনটি? Near-critical পথটি কি চিন্তার কারণ?
critical path A-B-D-G-H:
te : 3 + 5 + 6 + 4 + 2 = 20 days
var : 0.111 + 0.444 + 1.000 + 1.778 + 0.111 = 3.444 ; sigma = 1.856
P(T <= 22): Z = (22 - 20) / 1.856 = 1.078 ~ 1.08 -> Phi = 0.8599 (exact 0.8594)
P(T <= 18): Z = -1.078 -> 1 - 0.8594 = 0.1406
95% date : 20 + 1.645 x 1.856 = 23.05 days
near-critical A-B-E-G-H: mu = 17, var = 2.889 -> P(<= 22) = 0.998
G-র অনুমান (২, ৩, ১০) ডান দিকে লম্বা — মোট variance-এর অর্ধেকের বেশি (১.৭৭৮ ÷ ৩.৪৪৪) শুধু এখান থেকে। টেবিল থেকে Z = ১.০৮ পড়লে ০.৮৫৯৯, দশমিক না কেটে ০.৮৫৯৪ — দুটোই পূর্ণ নম্বর পাওয়ার মতো, কোনটি নিলেন তা লিখুন। Sanity check: P(≤ ১৮) + P(≤ ২২) = ১, কারণ দুটি T গড় থেকে সমান দূরে, দুই দিকে। Near-critical পথটি ২২ দিনে প্রায় নিশ্চিত শেষ, তাই এখানে merge bias সামান্য। প্রায় ৮৬% আর ১৪%; ৯৫%-এর তারিখ প্রায় ২৩.০৫ দিন।
৩.৩(মাঝারি) ওপরের network-এ C (UI নকশা) যদি ৩ দিন দেরি করে, project-এর শেষ তারিখ বদলাবে? আর ৫ দিন দেরি করলে?
C: TF = 4, FF = 0
C late 3 days: C = 7 days, EF = 10 -> E starts 10, F starts 10; T stays 20
C late 5 days: C = 9 days, EF = 12 -> path A-C-E-G-H = 3 + 9 + 3 + 4 + 2 = 21
new critical path A-C-E-G-H, T = 21 (1 day late)
Total float ৪ মানে চার দিন পর্যন্ত দেরি project-কে ছোঁয় না — কিন্তু free float ০ বলে প্রথম দিন থেকেই E আর F-এর শুরু পিছায়, তাদের নিজের float খেয়ে। পাঁচ দিনে float শেষ হয়ে এক দিন বেশি, আর critical path বদলে যায়। ৩ দিনে কোনো প্রভাব নেই (২০ দিন); ৫ দিনে project ২১ দিন, নতুন critical path A-C-E-G-H.
// CPM: forward pass, backward pass, total/free float and every critical path.
// activity: [duration in days, predecessors]; listed in a valid topological order.
function cpm(acts, table = true) {
const ids = Object.keys(acts), ES = {}, EF = {}, LS = {}, LF = {};
const succ = Object.fromEntries(ids.map(k => [k, ids.filter(s => acts[s][1].includes(k))]));
for (const k of ids) { ES[k] = Math.max(0, ...[...acts[k][1]].map(p => EF[p])); EF[k] = ES[k] + acts[k][0]; }
const T = Math.max(...ids.map(k => EF[k]));
for (const k of [...ids].reverse()) { LF[k] = Math.min(T, ...succ[k].map(s => LS[s])); LS[k] = LF[k] - acts[k][0]; }
if (table) console.log("act dur ES EF LS LF TF FF");
for (const k of ids) {
if (!table) break;
const FF = Math.min(T, ...succ[k].map(s => ES[s])) - EF[k];
console.log([k, acts[k][0], ES[k], EF[k], LS[k], LF[k], LS[k] - ES[k], FF].map((v, i) => String(v).padStart(i ? 4 : 3)).join(""));
}
const crit = k => LS[k] === ES[k];
const walk = (k, p) => succ[k].length ? succ[k].filter(s => crit(s) && ES[s] === EF[k]).flatMap(s => walk(s, p + "-" + s)) : [p];
const cps = ids.filter(k => !acts[k][1].length && crit(k)).flatMap(k => walk(k, k));
console.log("project =", T, "days; critical path(s):", cps.join(", "));
return T;
}
const lib = { A: [3, ""], B: [5, "A"], C: [4, "A"], D: [6, "B"], E: [3, "BC"],
F: [5, "C"], G: [4, "DE"], H: [2, "FG"] };
cpm(lib);
console.log("3.3 C late by 3 days ->"); cpm({ ...lib, C: [7, "A"] }, false);
console.log("3.3 C late by 5 days ->"); cpm({ ...lib, C: [9, "A"] }, false);আউটপুট:
act dur ES EF LS LF TF FF
A 3 0 3 0 3 0 0
B 5 3 8 3 8 0 0
C 4 3 7 7 11 4 0
D 6 8 14 8 14 0 0
E 3 8 11 11 14 3 3
F 5 7 12 13 18 6 6
G 4 14 18 14 18 0 0
H 2 18 20 18 20 0 0
project = 20 days; critical path(s): A-B-D-G-H
3.3 C late by 3 days ->
project = 20 days; critical path(s): A-B-D-G-H
3.3 C late by 5 days ->
project = 21 days; critical path(s): A-C-E-G-H
টেবিলটি ৩.১-এর উত্তর আর stepper-এর ধাপ ২–৪-এর সাথে মেলে। শেষ চার লাইন ৩.৩: C তিন দিন দেরিতে project ২০ দিনই, পাঁচ দিনে ২১ আর critical path বদলে A-C-E-G-H. walk একাধিক critical path থাকলে সবগুলো ছাপে; activity-গুলো এমন ক্রমে লিখতে হবে যাতে প্রতিটির পূর্বসূরি আগে আসে (topological order).
৩.৪(মাঝারি) একটি project-এর critical path-এর μ = ৪০ দিন, variance = ১৬. (ক) ৪৫ দিনের মধ্যে শেষ হওয়ার সম্ভাবনা, (খ) ৩৬ থেকে ৪৪ দিনের মধ্যে শেষ হওয়ার সম্ভাবনা, (গ) ৪৮ দিনের বেশি লাগার সম্ভাবনা, (ঘ) ৯৯% নিশ্চয়তার তারিখ বের করুন।
sigma = sqrt(16) = 4
(a) Z = (45 - 40) / 4 = 1.25 P = Phi(1.25) = 0.8944
(b) Z = -1 .. +1 P = Phi(1) - Phi(-1) = 0.8413 - 0.1587 = 0.6827
(c) Z = (48 - 40) / 4 = 2 P = 1 - Phi(2) = 1 - 0.9772 = 0.0228
(d) Z = 2.326 T = 40 + 2.326 x 4 = 49.30 days
ফাঁদ: variance ১৬-কে σ ধরে Z = ৫ ÷ ১৬ লেখা। আগে বর্গমূল নিন। “বেশি লাগার” প্রশ্নে ১ − Φ, আর “মাঝে” প্রশ্নে দুই Φ-এর বিয়োগ। Sanity check: (খ)-তে ±১σ, তাই প্রায় ৬৮% — normal বণ্টনের চেনা মান। (ক) ≈ ০.৮৯৪৪, (খ) ≈ ০.৬৮২৭, (গ) ≈ ০.০২২৮, (ঘ) ≈ ৪৯.৩ দিন।
# Three-point (PERT) estimates per task, path probability with Z and the normal CDF.
import math
def pert(a, m, b):
return (a + 4 * m + b) / 6, ((b - a) / 6) ** 2 # expected time, variance
Phi = lambda z: 0.5 * (1 + math.erf(z / math.sqrt(2))) # standard normal CDF
def path(name, tasks, targets=(), sure=()):
mu = var = 0.0
for k, (a, m, b) in tasks.items():
te, v = pert(a, m, b)
mu += te
var += v # variances add, sigmas do not
print(f" {k:8} a={a} m={m} b={b} te={te:.3f} var={v:.3f}")
sd = math.sqrt(var)
print(f"{name}: mu={mu:.3f} var={var:.3f} sigma={sd:.3f}")
for T in targets:
z = (T - mu) / sd
print(f" P(T <= {T}) : Z = {z:+.4f} p = {Phi(z):.4f}")
for p, z in sure: # z read from the normal table
print(f" {p:.0%} sure by mu + {z} x sigma = {mu + z * sd:.2f}")
path("2.8 four tasks", {"login": (2, 4, 8), "search": (3, 5, 9),
"payment": (4, 7, 16), "report": (1, 2, 3)})
path("3.2 critical path A-B-D-G-H", {"A": (2, 3, 4), "B": (3, 5, 7), "D": (3, 6, 9),
"G": (2, 3, 10), "H": (1, 2, 3)},
targets=(18, 22), sure=((0.90, 1.2816), (0.95, 1.645)))
print("3.4 mu=40 sigma=4:", f"P(<=45)={Phi(1.25):.4f}", f"P(36..44)={Phi(1) - Phi(-1):.4f}",
f"P(>48)={1 - Phi(2):.4f}", f"99% by {40 + 2.326 * 4:.2f}")আউটপুট:
login a=2 m=4 b=8 te=4.333 var=1.000
search a=3 m=5 b=9 te=5.333 var=1.000
payment a=4 m=7 b=16 te=8.000 var=4.000
report a=1 m=2 b=3 te=2.000 var=0.111
2.8 four tasks: mu=19.667 var=6.111 sigma=2.472
A a=2 m=3 b=4 te=3.000 var=0.111
B a=3 m=5 b=7 te=5.000 var=0.444
D a=3 m=6 b=9 te=6.000 var=1.000
G a=2 m=3 b=10 te=4.000 var=1.778
H a=1 m=2 b=3 te=2.000 var=0.111
3.2 critical path A-B-D-G-H: mu=20.000 var=3.444 sigma=1.856
P(T <= 18) : Z = -1.0776 p = 0.1406
P(T <= 22) : Z = +1.0776 p = 0.8594
90% sure by mu + 1.2816 x sigma = 22.38
95% sure by mu + 1.645 x sigma = 23.05
3.4 mu=40 sigma=4: P(<=45)=0.8944 P(36..44)=0.6827 P(>48)=0.0228 99% by 49.30
প্রথম অংশ ২.৮-এর চারটি কাজ: মোট ১৯.৬৬৭ দিন, σ ২.৪৭২. দ্বিতীয় অংশ ৩.২ আর stepper-এর ধাপ ৫–৭: μ = ২০, σ ≈ ১.৮৫৬, P(≤ ২২) = ০.৮৫৯৪, ৯৫%-এর তারিখ ২৩.০৫. শেষ লাইন ৩.৪-এর চারটি উত্তর। sure-এ Z-এর মান টেবিল থেকে হাতে দেওয়া (১.২৮১৬, ১.৬৪৫), যেমন পরীক্ষায় করবেন।
Crashing
৩.৫(কঠিন) ছয়টি activity (হাজার টাকা): P normal ৪ দিন, crash ৩, slope ৯; Q (P-র পরে) ৬ → ৪, slope ৫; R (P-র পরে) ৫ → ৪, slope ৩; S (Q-র পরে) ৩ → ২, slope ১০; T (R-এর পরে) ৩ → ২, slope ৬; U (S আর T-র পরে) ২, কমানো যায় না। Normal-এ সরাসরি খরচ মোট ২০০, পরোক্ষ খরচ দিনে ১২. (ক) একটি activity normal ৮ দিনে ৪০ হাজার, crash ৫ দিনে ৬১ হাজার হলে তার slope কত? (খ) ওপরের project সবচেয়ে কম মোট খরচে কত দিনে শেষ করা উচিত?
(a) slope = (61 - 40) / (8 - 5) = 21 / 3 = 7 thousand taka per day
(b) paths: P-Q-S-U = 4+6+3+2 = 15 ; P-R-T-U = 4+5+3+2 = 14
T critical cheapest cut direct indirect total
15 PQSU - 200 180 380
14 PQSU Q (5) 205 168 373
13 PQSU, PRTU Q+R (5+3 = 8) 213 156 369
12 PQSU, PRTU P (9) 222 144 366 <- minimum
11 PQSU, PRTU S+T (10+6 = 16 > 12) 238 132 370
প্রথম ধাপে শুধু P-Q-S-U critical; সেখানে সবচেয়ে সস্তা Q (৫)। R-এর slope (৩) কম হলেও তখন R critical নয় — কমালে টাকা নষ্ট। ১৪ দিনে দুটি পথই critical, তাই দুটিকেই কাটতে হয়: সাধারণ activity P (৯) বনাম প্রতিটি পথ থেকে একটি করে Q+R (৮) — Q+R সস্তা। Q তখন crash সীমায় (৪), R-ও (৪)। এরপর P (৯) — দুই পথেই আছে। শেষ বিকল্প S+T (১৬) দৈনিক পরোক্ষ খরচ ১২-র বেশি, তাই মোট খরচ বাড়ে। (ক) দিনে ৭ হাজার টাকা; (খ) ১২ দিনে, মোট খরচ ৩৬৬ হাজার টাকা।
// Crashing: shorten one day at a time by the cheapest set that cuts EVERY critical path.
// activity: [normal days, crash days, cost slope in thousand taka per day]
const A = { P: [4, 3, 9], Q: [6, 4, 5], R: [5, 4, 3], S: [3, 2, 10], T: [3, 2, 6], U: [2, 2, 0] };
const paths = ["PQSU", "PRTU"], INDIRECT = 12; // overhead: 12 thousand taka per day
const dur = Object.fromEntries(Object.entries(A).map(([k, v]) => [k, v[0]]));
const len = p => [...p].reduce((s, k) => s + dur[k], 0);
let direct = 200, T = Math.max(...paths.map(len)); // direct cost at normal durations
const show = () => console.log(`T=${T} paths ${paths.map(p => p + "=" + len(p)).join(" ")} direct=${direct} total=${direct + INDIRECT * T}`);
show();
for (;;) {
const crit = paths.filter(p => len(p) === T);
const can = Object.keys(A).filter(k => dur[k] > A[k][1]);
let best = null;
for (let mask = 1; mask < 1 << can.length; mask++) {
const set = can.filter((_, i) => (mask >> i) & 1);
if (!crit.every(p => set.some(k => p.includes(k)))) continue;
const cost = set.reduce((s, k) => s + A[k][2], 0);
if (!best || cost < best.cost || (cost === best.cost && set.length < best.set.length)) best = { set, cost };
}
if (!best) { console.log("cannot crash further"); break; }
const verdict = best.cost < INDIRECT ? "saves money" : "costs more than it saves";
console.log(` crash ${best.set.join("+")} (+${best.cost}/day) -> ${verdict}`);
best.set.forEach(k => dur[k]--); direct += best.cost; T = Math.max(...paths.map(len));
show();
}আউটপুট:
T=15 paths PQSU=15 PRTU=14 direct=200 total=380
crash Q (+5/day) -> saves money
T=14 paths PQSU=14 PRTU=14 direct=205 total=373
crash Q+R (+8/day) -> saves money
T=13 paths PQSU=13 PRTU=13 direct=213 total=369
crash P (+9/day) -> saves money
T=12 paths PQSU=12 PRTU=12 direct=222 total=366
crash S+T (+16/day) -> costs more than it saves
T=11 paths PQSU=11 PRTU=11 direct=238 total=370
cannot crash further
প্রতিটি ধাপ ৩.৫-এর টেবিলের সারি: Q (+৫), Q+R (+৮), P (+৯) — তিনটিই দৈনিক পরোক্ষ খরচ ১২-র কম, তাই মোট খরচ কমে ৩৬৬-তে নামে। শেষ ধাপ S+T (+১৬) মোট খরচ বাড়িয়ে ৩৭০ করে, আর তারপর আর কমানো যায় না। প্রোগ্রামটি প্রতিটি ধাপে সব সম্ভাব্য activity-সেট (bitmask) পরীক্ষা করে — ছোট network-এ এটিই সবচেয়ে নিরাপদ।
Earned value
৩.৬(মাঝারি) একটি project-এর মোট বাজেট (BAC) ৫০০ হাজার টাকা। ৬ সপ্তাহ শেষে: PV = ২৪০, EV = ২০০, AC = ২৩০. SV, CV, SPI, CPI, EAC (BAC ÷ CPI), ETC আর VAC বের করুন। Project-এর অবস্থা এক বাক্যে লিখুন।
SV = EV - PV = 200 - 240 = -40 SPI = 200 / 240 = 0.833
CV = EV - AC = 200 - 230 = -30 CPI = 200 / 230 = 0.870
EAC = BAC / CPI = 500 / 0.870 = 575.0
ETC = EAC - AC = 575 - 230 = 345.0 ; VAC = BAC - EAC = -75.0
other EAC forms: AC + (BAC - EV) = 530.0 ; AC + (BAC - EV)/(CPI x SPI) = 644.0
TCPI = (BAC - EV) / (BAC - AC) = 300 / 270 = 1.111
SPI আর CPI দুটিই ১-এর কম: পরিকল্পনার চেয়ে পিছিয়ে, আর যতটুকু কাজ হয়েছে তাতেও বেশি খরচ — প্রতি ১ টাকায় ০.৮৭ টাকার কাজ। এখনকার হারে চললে শেষে ৫৭৫, অর্থাৎ ৭৫ হাজার বেশি। কোন EAC নেবেন তা নির্ভর করে বাড়তি খরচ কেন হলো তার ওপর: একবারের ঘটনা হলে ৫৩০, দেরি আর খরচ দুটিই চলতে থাকলে ৬৪৪. TCPI (কিছু বইয়ে থাকে) বলে বাজেটে শেষ করতে বাকি কাজে ১.১১১ দক্ষতা লাগবে — এখনকার ০.৮৭ থেকে যা অবাস্তব লাফ। SV −৪০, CV −৩০, SPI ০.৮৩৩, CPI ০.৮৭০, EAC ৫৭৫, ETC ৩৪৫, VAC −৭৫ — পিছিয়ে এবং বাজেট ছাড়িয়ে।
৩.৭(মাঝারি) চারটি work package-এর বাজেট ৪০, ৬০, ৮০ আর ২০ হাজার টাকা। আজ পর্যন্ত পরিকল্পনা: প্রথম তিনটি শেষ আর চতুর্থটির অর্ধেক। বাস্তবে প্রথম দুটি শেষ, তৃতীয়টি শুরু হয়েছে (developer বলছেন “৬০% শেষ”), চতুর্থটি শুরু হয়নি। খরচ হয়েছে ১৫০. 50/50 নিয়মে আর 0/100 নিয়মে EV, SPI আর CPI কত?
PV = 40 + 60 + 80 + 0.5 x 20 = 190
50/50 rule: started = 50%, finished = 100%
EV = 40 + 60 + 0.5 x 80 + 0 = 140 SPI = 140/190 = 0.737 CPI = 140/150 = 0.933
0/100 rule: only finished work counts
EV = 40 + 60 + 0 + 0 = 100 SPI = 100/190 = 0.526 CPI = 100/150 = 0.667
দুই নিয়মের কোনোটিই “৬০% শেষ” দাবি গোনে না — software-এ “৯০% শেষ” সমস্যা এড়াতেই এগুলোর জন্ম (পর্ব ৬১)। 0/100 সবচেয়ে রক্ষণশীল; তাই একই অবস্থায় SPI অনেক খারাপ দেখায়। Sanity check: EV কখনো BAC (২০০)-এর বেশি হতে পারে না। 50/50: EV ১৪০, SPI ০.৭৩৭, CPI ০.৯৩৩; 0/100: EV ১০০, SPI ০.৫২৬, CPI ০.৬৬৭.
# Earned value: SV, CV, SPI, CPI and three common EAC forms (amounts in thousand taka).
def earned_value(name, BAC, PV, EV, AC):
SV, CV, SPI, CPI = EV - PV, EV - AC, EV / PV, EV / AC
print(f"{name}: BAC={BAC} PV={PV} EV={EV} AC={AC}")
print(f" SV={SV:+} CV={CV:+} SPI={SPI:.3f} CPI={CPI:.3f}")
eacs = {"BAC/CPI": BAC / CPI, "AC+(BAC-EV)": AC + (BAC - EV),
"AC+(BAC-EV)/(CPI*SPI)": AC + (BAC - EV) / (CPI * SPI)}
for form, eac in eacs.items():
print(f" EAC {form:22} = {eac:7.1f} VAC = {BAC - eac:+.1f}")
print(f" ETC (BAC/CPI - AC) = {BAC / CPI - AC:.1f} TCPI = {(BAC - EV) / (BAC - AC):.3f}")
earned_value("3.6 week 6", BAC=500, PV=240, EV=200, AC=230)
# 3.7: EV from work packages under two progress rules
packages = [ # (budget, planned % by today, actual % done, started?)
(40, 100, 100, True), (60, 100, 100, True), (80, 100, 60, True), (20, 50, 0, False)]
PV = sum(b * p / 100 for b, p, _, _ in packages)
AC = 150
for rule in ("50/50", "0/100"):
EV = 0
for b, _, done, started in packages:
if done == 100:
EV += b # finished: full budget earned
elif started and rule == "50/50":
EV += b / 2 # started: half, whatever the "% done"
print(f"3.7 rule {rule}: PV={PV:.0f} EV={EV:.0f} AC={AC} SPI={EV / PV:.3f} CPI={EV / AC:.3f}")আউটপুট:
3.6 week 6: BAC=500 PV=240 EV=200 AC=230
SV=-40 CV=-30 SPI=0.833 CPI=0.870
EAC BAC/CPI = 575.0 VAC = -75.0
EAC AC+(BAC-EV) = 530.0 VAC = -30.0
EAC AC+(BAC-EV)/(CPI*SPI) = 644.0 VAC = -144.0
ETC (BAC/CPI - AC) = 345.0 TCPI = 1.111
3.7 rule 50/50: PV=190 EV=140 AC=150 SPI=0.737 CPI=0.933
3.7 rule 0/100: PV=190 EV=100 AC=150 SPI=0.526 CPI=0.667
প্রথম অংশ ৩.৬: SV −৪০, CV −৩০, SPI ০.৮৩৩, CPI ০.৮৭০, তিন রূপের EAC ৫৭৫, ৫৩০ আর ৬৪৪, ETC ৩৪৫, TCPI ১.১১১. শেষ দুই লাইন ৩.৭-এর দুই নিয়ম — একই কাজের অবস্থায় 0/100 নিয়মে SPI ০.৫২৬, 50/50-এ ০.৭৩৭. “৬০% শেষ” তথ্যটি কোড ইচ্ছা করে ব্যবহার করে না।
(সহজ) একটি activity-র সময় ৪ দিন, আর তার তিনটি পূর্বসূরির EF যথাক্রমে ৯, ১২ আর ৭. Forward pass-এ এর ES আর EF কত?
- ES 7, EF 11
- ES 28, EF 32
- ES 12, EF 16
- ES 9, EF 13
(মাঝারি) একটি activity-র ES = ৫, EF = ৯, LS = ৮; তার উত্তরসূরিদের সবচেয়ে ছোট ES = ১০. Total float আর free float কত?
- TF 3, FF 1
- TF 1, FF 3
- TF 3, FF 3
- TF 3, FF 5
(মাঝারি) PERT-এ critical path-এর প্রত্যাশিত সময় ৩০ দিন আর σ = ২ দিন। Normal বণ্টন ধরে project ৩৩ দিনের মধ্যে শেষ হওয়ার সম্ভাবনা প্রায় কত?
- 0.5000
- 0.8413
- 0.9987
- 0.9332
(মাঝারি) একটি project-এ PV = ১০০, EV = ৯০, AC = ১২০ (হাজার টাকা)। কোন বিবরণটি ঠিক?
- SPI 0.90, CPI 1.33 — পিছিয়ে কিন্তু বাজেটের নিচে
- SPI 0.90, CPI 0.75 — পিছিয়ে এবং বাজেট ছাড়িয়ে
- SPI 1.11, CPI 1.33 — এগিয়ে এবং বাজেটের নিচে
- AC > PV, তাই শুধু বাজেট ছাড়িয়েছে, সময়মতো আছে
৪ · Risk আর quality — RE, RRL, EMV, availability, DRE আর control chart
ঝালিয়ে নিন: পর্ব ০৩ · Software quality (MTBF, availability, DRE), পর্ব ০৪ · SDLC আর process model (spiral-এর risk exposure), পর্ব ৬২ · Risk আর quality management (RRL, EMV, control chart).
Risk exposure: RE = P × L (প্রত্যাশিত ক্ষতি); RRL = (REআগে − REপরে) ÷ প্রতিকারের খরচ — ১-এর বেশি মানে লাভজনক।
EMV: chance node-এ Σ(p × মূল্য), decision node-এ সবচেয়ে বড় (EMV − খরচ) — decision tree ভেতর থেকে বাইরে হিসাব।
Availability: A = MTBF ÷ (MTBF + MTTR); বছরে বন্ধ = (১ − A) × ৮৭৬০ ঘণ্টা; লক্ষ্য A-র জন্য MTTR = MTBF × (১ − A) ÷ A.
Defect: defect density = defect ÷ KLOC; DRE = আগে পাওয়া ÷ (আগে + পরে পাওয়া)। Control chart: গড় ± ৩σ, LCL ঋণাত্মক হলে ০.
৪.১(সহজ) একটি কাল্পনিক অনলাইন বাজার অ্যাপের চারটি ঝুঁকি (ক্ষতি লাখ টাকায়): R1 payment gateway বদল — P ০.৩, L ২০; R2 মূল developer চলে যাওয়া — P ০.৬, L ৫; R3 ঈদের ভিড়ে server বসে যাওয়া — P ০.১, L ৫০; R4 নতুন আইনে data নিয়ম বদল — P ০.২৫, L ১৬. প্রতিটির RE, অগ্রাধিকারের ক্রম আর মোট RE বের করুন।
R1: 0.3 x 20 = 6.0
R2: 0.6 x 5 = 3.0
R3: 0.1 x 50 = 5.0
R4: 0.25 x 16 = 4.0
order by RE: R1 (6) > R3 (5) > R4 (4) > R2 (3) ; total RE = 18.0 lakh
সম্ভাবনায় সবচেয়ে বড় (R2, ০.৬) তালিকার শেষে, আর ক্ষতিতে সবচেয়ে বড় (R3, ৫০) দ্বিতীয় — RE দুটিকে একসাথে দেখে বলেই এটি দরকারি। তবে R3-এর মতো “কম সম্ভাবনা, বিশাল ক্ষতি” ঝুঁকি শুধু RE দেখে নিচে নামানো বিপজ্জনক হতে পারে; পর্ব ৬২-এ দেখেছেন, ছোট প্রতিষ্ঠানের জন্য একটি খারাপ ফলই যথেষ্ট। ক্রম R1, R3, R4, R2; মোট RE ১৮ লাখ।
৪.২(মাঝারি) ৪.১-এর R1 (RE ৬ লাখ) কমানোর দুটি প্রস্তাব: M1 — দুটি gateway-র জন্য একটি adapter স্তর, খরচ ১.৫ লাখ, P নামবে ০.১-এ, ক্ষতি একই; M2 — নিজস্ব payment module, খরচ ৩ লাখ, P ০.০৫ আর ক্ষতি ১২ লাখে নামবে। কোনটি ভালো বিনিয়োগ?
M1: RE after = 0.1 x 20 = 2.0 RRL = (6 - 2.0) / 1.5 = 2.67
M2: RE after = 0.05 x 12 = 0.6 RRL = (6 - 0.6) / 3 = 1.80
cost + residual RE: M1 = 1.5 + 2.0 = 3.5 ; M2 = 3 + 0.6 = 3.6 ; do nothing = 6
দুটিরই RRL ১-এর বেশি, অর্থাৎ দুটিই খরচের চেয়ে বেশি প্রত্যাশিত ক্ষতি কমায়। প্রতি টাকায় M1 বেশি কাজ করে (২.৬৭ বনাম ১.৮০), আর “খরচ + বাকি ঝুঁকি”-র মোটেও M1 সামান্য কম। M2-এর residual ঝুঁকি কম — ঝুঁকি একেবারেই সইতে না পারলে সেটিও যুক্তিসঙ্গত। M1 (RRL ≈ ২.৬৭) ভালো বিনিয়োগ।
৪.৩(কঠিন) Build বনাম buy (লাখ টাকা)। Build: খরচ ৩০; সফল হওয়ার সম্ভাবনা ০.৭ হলে মূল্য ১০০, ব্যর্থ (০.৩) হলে ৪০. Buy: খরচ ৪৫; ভালো মিল (০.৯) হলে ১০০, দুর্বল মিল (০.১) হলে ৬০. EMV দিয়ে সিদ্ধান্ত নিন, আর build-এর সাফল্যের সম্ভাবনা কত হলে দুটি সমান হয়?
build: 0.7 x 100 + 0.3 x 40 = 70 + 12 = 82 ; 82 - 30 = 52
buy : 0.9 x 100 + 0.1 x 60 = 90 + 6 = 96 ; 96 - 45 = 51
decision: build (52 > 51)
tie: 100p + 40(1 - p) - 30 = 51 -> 60p = 41 -> p = 0.683
পার্থক্য মাত্র ১ লাখ, আর সমতার বিন্দু ০.৬৮৩ — দলের ০.৭ অনুমান একটু আশাবাদী হলেই সিদ্ধান্ত উল্টে যায়। এমন ক্ষেত্রে sensitivity লিখে দেওয়াই পূর্ণ উত্তর। Build-এর খারাপ ফল (৪০ − ৩০ = ১০) buy-এর খারাপ ফলের (৬০ − ৪৫ = ১৫) চেয়েও খারাপ — ঝুঁকি এড়াতে চাইলে buy. EMV-তে build (৫২ বনাম ৫১); সম্ভাবনা ০.৬৮৩-এর নিচে নামলে buy.
৪.৪(মাঝারি) (ক) একটি ফলাফল পোর্টালের MTBF ৫০০ ঘণ্টা, MTTR ২ ঘণ্টা। Availability আর বছরে প্রত্যাশিত বন্ধ সময় কত? ৯৯.৯% পেতে MTTR কত হওয়া দরকার (MTBF একই)? (খ) আরেকটি system ৩০ দিন (৭২০ ঘণ্টা) পর্যবেক্ষণে ৪বার বসে গেছে, মোট মেরামতে লেগেছে ৬ ঘণ্টা। MTBF, MTTR আর availability কত?
(a) A = 500 / (500 + 2) = 0.99602 = 99.602%
downtime = (1 - 0.99602) x 8760 = 34.9 hours per year
target 99.9%: MTTR = 500 x 0.001 / 0.999 = 0.5005 h = 30.0 minutes
(b) uptime = 720 - 6 = 714 h ; MTBF = 714 / 4 = 178.5 h ; MTTR = 6 / 4 = 1.5 h
A = 178.5 / (178.5 + 1.5) = 99.167% (check: 714 / 720 = 99.167%)
(খ)-তে MTBF মানে চলার গড় সময়, তাই মেরামতের ৬ ঘণ্টা বাদ দিয়ে ভাগ — ৭২০ ÷ ৪ = ১৮০ নিলে MTBF আর MTTR যোগ হয়ে যায় (কিছু বই একে MTTF-এর সাথে মিলিয়ে বলে, পর্ব ০৩ দেখুন)। Sanity check: দীর্ঘ সময়ের availability = চলা সময় ÷ মোট সময় = ৭১৪ ÷ ৭২০ — একই উত্তর। (ক)-এর শিক্ষা: availability বাড়াতে failure কমানো ছাড়াও দ্রুত ফেরা (MTTR ২ ঘণ্টা থেকে ৩০ মিনিট) সমান কার্যকর। (ক) ৯৯.৬০২%, বছরে প্রায় ৩৪.৯ ঘণ্টা, MTTR ৩০ মিনিট; (খ) MTBF ১৭৮.৫ ঘণ্টা, MTTR ১.৫ ঘণ্টা, A ≈ ৯৯.১৬৭%.
৪.৫(সহজ) ২৫ KLOC-এর একটি release-এ review-তে ৬০টি আর test-এ ৯০টি defect ধরা পড়েছে; release-এর পরের ৯০ দিনে ব্যবহারকারীরা আরও ৩০টি জানিয়েছেন। DRE, মোট defect density আর release-পরবর্তী defect density কত?
before release = 60 + 90 = 150 ; after = 30 ; total = 180
DRE = 150 / 180 = 0.833 = 83.3%
density (all) = 180 / 25 = 7.20 per KLOC
density (post-release) = 30 / 25 = 1.20 per KLOC
DRE সবসময় “এখন পর্যন্ত জানা” defect-এর ওপর — ৯০ দিনের পরে আরও বেরোলে DRE কমবে। দুটি density দুটি ভিন্ন প্রশ্নের উত্তর দেয়, তাই রিপোর্টে কোনটি দিচ্ছেন স্পষ্ট লিখুন। Sanity check: DRE ১-এর বেশি হতে পারে না, আর আগে-পরে যোগ মোটের সমান। DRE ≈ ৮৩.৩%, ৭.২০ আর ১.২০ প্রতি KLOC.
৪.৬(মাঝারি) একটি দলের দশ সপ্তাহের defect সংখ্যা: ১২, ১৫, ১১, ১৪, ১৩, ১৬, ১২, ১০, ১৪, ১৩. নমুনার σ দিয়ে control limit বের করুন। এগারোতম সপ্তাহে ২১টি defect এলে কী বলবেন?
mean = 130 / 10 = 13.0
squared deviations: 1, 4, 4, 1, 0, 9, 1, 9, 1, 0 -> sum = 30
sample sigma = sqrt(30 / 9) = sqrt(3.333) = 1.826
UCL = 13 + 3 x 1.826 = 18.48 ; LCL = 13 - 3 x 1.826 = 7.52
week 11: 21 > 18.48 -> outside the limits: look for a special cause
সীমার ভেতরের ওঠানামা (যেমন ১৬) স্বাভাবিক — একে নিয়ে তদন্ত করলে সময় নষ্ট। ২১ সীমার বাইরে, তাই কোনো বিশেষ কারণ খুঁজুন (একটি তাড়াহুড়োর release, নতুন module). পর্ব ৬২-এর মতো এখানে সরলতার জন্য নমুনার σ; আনুষ্ঠানিক XmR chart-এ moving range থেকে σ আসে, তাতে সংখ্যা সামান্য বদলায়। Population σ (১০ দিয়ে ভাগ, ১.৭৩২) নিলে UCL ১৮.২০ — প্রশ্নে কোনটি চাওয়া, দেখে নিন। UCL ≈ ১৮.৪৮, LCL ≈ ৭.৫২; ২১ out of control.
// Risk and quality numbers: RE, RRL, EMV, availability, DRE, control limits.
const f = (x, d = 2) => x.toFixed(d);
const risks = { R1: [0.3, 20], R2: [0.6, 5], R3: [0.1, 50], R4: [0.25, 16] }; // [P, loss in lakh taka]
const re = Object.entries(risks).map(([id, [p, L]]) => [id, p * L]).sort((a, b) => b[1] - a[1]);
console.log("4.1 RE ranking:", re.map(([id, v]) => `${id}=${f(v, 1)}`).join(" "),
" total =", f(re.reduce((s, r) => s + r[1], 0), 1));
const rrl = (before, after, cost) => (before - after) / cost; // Boehm's RRL
console.log("4.2 M1 RRL =", f(rrl(6, 0.1 * 20, 1.5)), " M2 RRL =", f(rrl(6, 0.05 * 12, 3)));
// EMV: chance node = sum(p x payoff); decision = best (EMV - cost)
const chance = branches => branches.reduce((s, [p, v]) => s + p * v, 0);
const build = chance([[0.7, 100], [0.3, 40]]) - 30, buy = chance([[0.9, 100], [0.1, 60]]) - 45;
console.log("4.3 EMV build =", f(build, 1), " buy =", f(buy, 1), " ->", build > buy ? "build" : "buy",
" tie at P(success) =", f((buy + 30 - 40) / 60, 3));
const avail = (mtbf, mttr) => mtbf / (mtbf + mttr);
const A = avail(500, 2);
console.log("4.4 A =", f(100 * A, 3) + "%", " downtime/year =", f((1 - A) * 8760, 1), "h",
" MTTR for 99.9% =", f(500 * (1 - 0.999) / 0.999 * 60, 1), "min");
const up = 720 - 6, n = 4; // 30 days, 4 failures, 6 h of repair
console.log("4.4b MTBF =", f(up / n, 1), "h MTTR =", f(6 / n, 1), "h A =", f(100 * avail(up / n, 6 / n), 3) + "%");
const pre = 60 + 90, post = 30, kloc = 25;
console.log("4.5 DRE =", f(100 * pre / (pre + post), 1) + "%", " density total =", f((pre + post) / kloc),
"/KLOC post-release =", f(post / kloc), "/KLOC");
const wk = [12, 15, 11, 14, 13, 16, 12, 10, 14, 13];
const m = wk.reduce((s, x) => s + x, 0) / wk.length;
const sd = Math.sqrt(wk.reduce((s, x) => s + (x - m) ** 2, 0) / (wk.length - 1)); // sample sigma
console.log("4.6 mean =", f(m), " sigma =", f(sd, 3), " UCL =", f(m + 3 * sd), " LCL =", f(Math.max(0, m - 3 * sd)));আউটপুট:
4.1 RE ranking: R1=6.0 R3=5.0 R4=4.0 R2=3.0 total = 18.0
4.2 M1 RRL = 2.67 M2 RRL = 1.80
4.3 EMV build = 52.0 buy = 51.0 -> build tie at P(success) = 0.683
4.4 A = 99.602% downtime/year = 34.9 h MTTR for 99.9% = 30.0 min
4.4b MTBF = 178.5 h MTTR = 1.5 h A = 99.167%
4.5 DRE = 83.3% density total = 7.20 /KLOC post-release = 1.20 /KLOC
4.6 mean = 13.00 sigma = 1.826 UCL = 18.48 LCL = 7.52
প্রতিটি লাইন ভাগ ৪-এর একটি প্রশ্নের উত্তর: RE-র ক্রম আর মোট ১৮, RRL ২.৬৭ আর ১.৮০, EMV ৫২ বনাম ৫১ আর সমতার বিন্দু ০.৬৮৩, availability ৯৯.৬০২% আর ৩০ মিনিটের MTTR, log থেকে MTBF ১৭৮.৫, DRE ৮৩.৩%, আর control limit ১৮.৪৮ ও ৭.৫২. σ-এর হিসাবে wk.length - 1 দিয়ে ভাগ — নমুনার σ; wk.length দিলে population σ হতো।
(সহজ) একটি ঝুঁকির ঘটার সম্ভাবনা ০.৪ আর ঘটলে ক্ষতি ১৫ লাখ টাকা। Risk exposure কত?
- ৬ লাখ টাকা
- ১৫ লাখ টাকা
- ৩৭.৫ লাখ টাকা
- ৯ লাখ টাকা
(মাঝারি) একটি প্রতিকারে খরচ ৪ লাখ; এতে একটি ঝুঁকির RE ১০ লাখ থেকে ২ লাখে নামে। Risk reduction leverage কত, আর প্রতিকারটি কেমন?
- 2.5 — লাভজনক
- 0.5 — অলাভজনক
- 2.0 — লাভজনক
- 8.0 — খুব লাভজনক
(সহজ) MTBF ৯৯৯ ঘণ্টা আর MTTR ১ ঘণ্টা হলে availability আর বছরে প্রত্যাশিত বন্ধ সময় প্রায় কত?
- 99.99%, প্রায় ৫৩ মিনিট
- 99.9%, প্রায় ৮.৭৬ ঘণ্টা
- 99%, প্রায় ৮৭.৬ ঘণ্টা
- 99.9%, ১ ঘণ্টা
(সহজ) Release-এর আগে review আর test-এ ৪৫টি defect ধরা পড়েছে, release-এর পরে ব্যবহারকারীরা ৫টি পেয়েছেন। Defect removal efficiency কত?
- 11.1%
- 88.9%
- 10%
- 90%
৫ · Design metric — coupling, LCOM4, যোগাযোগের পথ আর bus factor
ঝালিয়ে নিন: পর্ব ২৫ · Modularity, coupling আর cohesion (Ca, Ce, I, A, D, LCOM4), পর্ব ৬০ (Brooks আর যোগাযোগের পথ), পর্ব ৬৩ · দলগত কাজ আর open source (bus factor).
Package: Ca = কতজন আমার ওপর নির্ভর করে, Ce = আমি কতজনের ওপর; I = Ce ÷ (Ca + Ce); A = abstract ÷ মোট class; D = |A + I − ১| — main sequence থেকে দূরত্ব; D ≥ ০.৫ আর A + I < ১ হলে zone of pain, A + I > ১ হলে zone of uselessness.
LCOM4: method-গুলোর graph-এ connected component-এর সংখ্যা (দুটি method যুক্ত, যদি একটি attribute ভাগ করে বা একটি অন্যটিকে ডাকে); ১ = cohesive. যোগাযোগের পথ: n(n − ১) ÷ ২. Bus factor: সবচেয়ে কম কয়জন সরে গেলে অর্ধেকের বেশি ফাইল “অনাথ”।
৫.১(সহজ) একটি package-এর ওপর বাইরের ৩টি package নির্ভর করে, আর এটি নিজে ১টির ওপর নির্ভর করে। এর ৮টি class-এর ৬টি interface বা abstract. I, A আর D কত? Package-টি কোথায় দাঁড়িয়ে?
Ca = 3, Ce = 1
I = Ce / (Ca + Ce) = 1 / 4 = 0.25
A = 6 / 8 = 0.75
D = |0.75 + 0.25 - 1| = 0.00
Stable (অনেকে নির্ভর করে) আর abstract (বেশিরভাগ interface) — ঠিক main sequence-এর ওপর। এটিই Martin-এর stable abstractions principle-এর আদর্শ: যাকে অনেকে ব্যবহার করে, তাকে বদলানো কঠিন, তাই তার ভেতরে interface রাখুন যাতে বাড়ানো যায়। I = ০.২৫, A = ০.৭৫, D = ০ — ভারসাম্যপূর্ণ।
৫.২(মাঝারি) একটি কাল্পনিক অনলাইন বাজারের সাতটি package (তীর = “নির্ভর করে”; বন্ধনীতে মোট class / abstract): app → orders, payment, report (৫/০); orders → domain, db (৬/১); payment → domain, gateway (৪/১); report → domain, db (৩/০); db → domain (৪/৩); gateway → কেউ নয় (২/০); domain → কেউ নয় (৮/০)। প্রতিটির Ca, Ce, I, A, D বের করে সমস্যার package চিহ্নিত করুন।
package Ca Ce I A D
app 0 3 1.00 0.00 0.00
orders 1 2 0.67 0.17 0.17
payment 1 2 0.67 0.25 0.08
report 1 2 0.67 0.00 0.33
db 2 1 0.33 0.75 0.08
gateway 1 0 0.00 0.00 1.00 zone of pain
domain 4 0 0.00 0.00 1.00 zone of pain
Ca গুনতে প্রতিটি package-এর দিকে আসা তীর গুনুন: domain-এর দিকে orders, payment, report আর db — ৪টি। domain পুরো stable (I = ০) অথচ পুরো concrete (A = ০) — বদলানো কঠিন, বাড়ানোর জায়গাও নেই: zone of pain. Domain model-এর ক্ষেত্রে এটি প্রায়ই মেনে নেওয়া হয়, যদি domain খুব কম বদলায়; gateway-র ক্ষেত্রে বেশি চিন্তার — বাইরের payment সেবা বদলালে payment-কেও বদলাতে হবে, তাই একটি PaymentGateway interface রাখাই ভালো। domain আর gateway, দুটিই D = ১.০০.
৫.৩(মাঝারি) ResultService class-এর method আর তারা কোন attribute ছোঁয়: addMarks {marks}, totalMarks {marks}, gpa {scale}, exportCsv {marks}, sendEmail {mailer}, formatEmail {template}, logAccess {logfile}. gpa ডাকে totalMarks-কে, sendEmail ডাকে formatEmail-কে। LCOM4 কত, আর class-টি কীভাবে ভাঙবেন?
shared attribute: addMarks - totalMarks - exportCsv (marks)
call links : gpa -> totalMarks ; sendEmail -> formatEmail
components:
1. addMarks, totalMarks, gpa, exportCsv
2. sendEmail, formatEmail
3. logAccess
LCOM4 = 3
gpa নিজে marks ছোঁয় না, কিন্তু totalMarks-কে ডাকে — তাই LCOM4-এ সে প্রথম দলে। sendEmail আর formatEmail কোনো attribute ভাগ করে না, তবু ডাকার সম্পর্কে এক দল। তিনটি টুকরো মানে তিনটি দায়িত্ব: ফল হিসাব (ResultCalculator), নোটিশ (Notifier) আর logging — SRP-র (পর্ব ২৭) সংখ্যাগত ইঙ্গিত। LCOM4 = ৩; তিনটি class-এ ভাঙা যায়।
// Martin's package metrics (Ca, Ce, I, A, D), LCOM4 and communication paths.
// Counting PACKAGES (not classes) for Ca and Ce, as in the coupling lesson.
const pkgs = { app: [["orders", "payment", "report"], 5, 0], orders: [["domain", "db"], 6, 1],
payment: [["domain", "gateway"], 4, 1], report: [["domain", "db"], 3, 0],
db: [["domain"], 4, 3], gateway: [[], 2, 0], domain: [[], 8, 0] }; // [deps, classes, abstract]
const ca = Object.fromEntries(Object.keys(pkgs).map(p => [p, 0]));
for (const [deps] of Object.values(pkgs)) deps.forEach(d => ca[d]++);
console.log("package Ca Ce I A D");
for (const [p, [deps, n, abs]] of Object.entries(pkgs)) {
const Ce = deps.length, Ca = ca[p], I = Ca + Ce ? Ce / (Ca + Ce) : 0, A = abs / n, D = Math.abs(A + I - 1);
const zone = D >= 0.5 ? (A + I < 1 ? " zone of pain" : " zone of uselessness") : "";
console.log(p.padEnd(8), String(Ca).padStart(2), String(Ce).padStart(2), ...[I, A, D].map(x => x.toFixed(2).padStart(4)), zone);
}
// LCOM4: methods linked if they share an attribute or one calls the other
const uses = { addMarks: ["marks"], totalMarks: ["marks"], gpa: ["scale"], exportCsv: ["marks"],
sendEmail: ["mailer"], formatEmail: ["template"], logAccess: ["logfile"] };
const calls = [["gpa", "totalMarks"], ["sendEmail", "formatEmail"]];
const link = Object.fromEntries(Object.keys(uses).map(m => [m, m]));
const root = m => link[m] === m ? m : root(link[m]);
const ms = Object.keys(uses);
ms.forEach((a, i) => ms.slice(i + 1).forEach(b => { if (uses[a].some(x => uses[b].includes(x))) link[root(a)] = root(b); }));
calls.forEach(([a, b]) => { link[root(a)] = root(b); });
const groups = {}; ms.forEach(m => (groups[root(m)] ||= []).push(m));
console.log("LCOM4 =", Object.keys(groups).length, "->", Object.values(groups).map(g => g.join(",")).join(" | "));
const paths = n => n * (n - 1) / 2;
console.log("communication paths: 6 people =", paths(6), " 9 people =", paths(9), " added =", paths(9) - paths(6));আউটপুট:
package Ca Ce I A D
app 0 3 1.00 0.00 0.00
orders 1 2 0.67 0.17 0.17
payment 1 2 0.67 0.25 0.08
report 1 2 0.67 0.00 0.33
db 2 1 0.33 0.75 0.08
gateway 1 0 0.00 0.00 1.00 zone of pain
domain 4 0 0.00 0.00 1.00 zone of pain
LCOM4 = 3 -> addMarks,totalMarks,gpa,exportCsv | sendEmail,formatEmail | logAccess
communication paths: 6 people = 15 9 people = 36 added = 21
টেবিলটি ৫.২-এর উত্তর: domain আর gateway দুটিই zone of pain-এ (D = ১.০০)। LCOM4-এর লাইন ৫.৩ — তিনটি দল; শেষ লাইন ৫.৪-এর ১৫, ৩৬ আর ২১. LCOM4 বের করা হয়েছে union-find দিয়ে: যুক্ত দুটি method-এর “মূল” এক করে দেওয়া, শেষে কয়টি আলাদা মূল থাকল তা গোনা।
৫.৪(সহজ) ৬ জনের একটি দলে কতগুলো যোগাযোগের পথ? দেরি হওয়া project-এ আরও ৩ জন যোগ করলে কতগুলো নতুন পথ তৈরি হয়?
paths(n) = n(n - 1) / 2
paths(6) = 6 x 5 / 2 = 15
paths(9) = 9 x 8 / 2 = 36
new paths = 36 - 15 = 21
লোক ৫০% বাড়ল (৬ → ৯), কিন্তু যোগাযোগের পথ বাড়ল ১৪০% (১৫ → ৩৬)। সাথে নতুনদের শেখানোর সময় — এটাই Brooks-এর সূত্রের (১৯৭৫) পেছনের হিসাব: দেরি হওয়া project-এ লোক যোগ করলে তা আরও দেরি করে। ছোট দল আর পরিষ্কার interface এই সংখ্যা কমায়। ১৫টি পথ; নতুন ২১টি, মোট ৩৬.
৫.৫(কঠিন) আটটি ফাইলের commit-সংখ্যা: auth.py — Rafi ১২, Mitu ৩; cart.py — Rafi ৭, Tanvir ৫; pay.py — Rafi ৯; search.py — Mitu ১০, Rafi ১; ui.js — Sumi ৮, Mitu ৪; form.js — Sumi ৬; deploy.yml — Rafi ৪, Tanvir ১; README.md — Sumi ২, Rafi ২, Tanvir ১. সরল নিয়ম: কোনো লেখক একটি ফাইল “জানেন” যদি তার অন্তত ২৫% commit তাঁর; প্রতিবার যিনি সবচেয়ে বেশি ফাইল জানেন তাঁকে সরান (সমান হলে বর্ণক্রমে আগে), অর্ধেকের বেশি ফাইল অনাথ হলে থামুন। Bus factor কত?
knows (>= 25%):
auth: Rafi (12/15 = 0.80; Mitu 0.20) cart: Rafi 0.58, Tanvir 0.42
pay: Rafi search: Mitu (Rafi 0.09)
ui: Sumi 0.67, Mitu 0.33 form: Sumi
deploy: Rafi (Tanvir 0.20) README: Sumi 0.40, Rafi 0.40 (Tanvir 0.20)
files known: Rafi 5, Sumi 3, Mitu 2, Tanvir 1
remove Rafi -> orphans: auth, pay, deploy = 3/8 (not more than half)
recount: Sumi 3, Mitu 2, Tanvir 1 -> remove Sumi
-> orphans: auth, pay, deploy, form, README = 5/8 > 4 stop
bus factor = 2
দুজন (Rafi আর Sumi) হঠাৎ না থাকলে আটটির পাঁচটি ফাইল কেউ জানেন না। ২৫%-এর সীমায় Tanvir README জানেন না (২০%) — সীমা বদলালে উত্তরও বদলায়, আর গবেষণার আসল পদ্ধতি (পর্ব ৬৩-এ উল্লেখিত Avelino ও সহকর্মীদের ২০১৬ সালের কাজ) আরও সূক্ষ্ম। তাই উত্তরে নিয়মটি লিখে দিন। প্রতিকার: pairing আর review-তে auth ও pay-এ দ্বিতীয় একজনকে যুক্ত করা। Bus factor = ২.
# Bus (truck) factor, simplified: an author "knows" a file if they made >= 25% of
# its commits; remove the author who knows most files until > half the files are orphaned.
commits = {
"src/auth.py": {"Rafi": 12, "Mitu": 3},
"src/cart.py": {"Rafi": 7, "Tanvir": 5},
"src/pay.py": {"Rafi": 9},
"src/search.py": {"Mitu": 10, "Rafi": 1},
"web/ui.js": {"Sumi": 8, "Mitu": 4},
"web/form.js": {"Sumi": 6},
"ops/deploy.yml": {"Rafi": 4, "Tanvir": 1},
"docs/README.md": {"Sumi": 2, "Rafi": 2, "Tanvir": 1},
}
SHARE = 0.25
knows = {f: {a for a, c in m.items() if c / sum(m.values()) >= SHARE} for f, m in commits.items()}
for f, who in knows.items():
print(f"{f:15} known by {', '.join(sorted(who))}")
removed, n = [], len(knows)
while True:
left = {f: who - set(removed) for f, who in knows.items()}
orphans = sorted(f for f, who in left.items() if not who)
print(f"removed {removed or '-'} -> orphans {len(orphans)}/{n} {orphans}")
if len(orphans) > n / 2:
break
count = {}
for who in left.values():
for a in who:
count[a] = count.get(a, 0) + 1
removed.append(max(sorted(count), key=count.get)) # ties: alphabetical first
print("bus factor =", len(removed))আউটপুট:
src/auth.py known by Rafi
src/cart.py known by Rafi, Tanvir
src/pay.py known by Rafi
src/search.py known by Mitu
web/ui.js known by Mitu, Sumi
web/form.js known by Sumi
ops/deploy.yml known by Rafi
docs/README.md known by Rafi, Sumi
removed - -> orphans 0/8 []
removed ['Rafi'] -> orphans 3/8 ['ops/deploy.yml', 'src/auth.py', 'src/pay.py']
removed ['Rafi', 'Sumi'] -> orphans 5/8 ['docs/README.md', 'ops/deploy.yml', 'src/auth.py', 'src/pay.py', 'web/form.js']
bus factor = 2
৫.৫-এর হাতের হিসাবের সাথে মেলে: প্রথমে Rafi (৫টি ফাইল জানেন) সরলে ৩টি অনাথ, তারপর Sumi সরলে ৫টি — আটটির অর্ধেকের বেশি, তাই bus factor ২. SHARE ০.২০ করলে Tanvir README আর deploy.yml-ও “জানেন”, উত্তর বদলায় কি না দেখুন — নিয়মই উত্তর ঠিক করে।
(সহজ) একটি package-এর ওপর ৬টি package নির্ভর করে, আর এটি ২টির ওপর নির্ভর করে। Martin-এর instability I কত?
- 0.75
- 3.00
- 0.33
- 0.25
(সহজ) ৮ জনের একটি দলে দুজন-দুজন করে মোট কতগুলো যোগাযোগের পথ?
- 64
- 28
- 56
- 7
(মাঝারি) একটি package-এর abstractness A = ০.২ আর instability I = ০.৩. Main sequence থেকে দূরত্ব D কত, আর এটি কোন দিকে?
- 0.5 — zone of pain-এর দিকে
- 0.5 — zone of uselessness-এর দিকে
- 0.1 — main sequence-এর কাছে
- 0.5 — ঠিক main sequence-এর ওপর
৬ · Testing — partition, boundary, decision table, pairwise, V(G), coverage আর mutation
ঝালিয়ে নিন: পর্ব ৪৫ · Testing-এর মৌলিক (exhaustive testing কেন অসম্ভব), পর্ব ৪৭ · Test case নকশা (EP, BVA, decision table, pairwise), পর্ব ৫০ · Coverage আর complexity (V(G), MC/DC, mutation).
EP ও BVA: k-টি valid range পাশাপাশি থাকলে partition k + ২ (দুই পাশে invalid); ২-মান BVA-তে ২k + ২টি আর ৩-মান BVA-তে ৪k + ২টি মান (integer, পুনরাবৃত্তি বাদে)। এক range-এ: EP ৩, ২-মান ৪, ৩-মান ৬.
Decision table: n-টি Y/N শর্তে 2nটি rule; একই কাজ আর এক শর্তে পার্থক্য হলে দুটি rule মিশে “−”। Pairwise: ন্যূনতম suite ≥ দুটি সবচেয়ে বড় মান-সংখ্যার গুণফল।
V(G): E − N + ২P = decision + ১ = region-এর সংখ্যা (planar graph). MC/DC: n-টি শর্তের and/or-এ সাধারণত n + ১টি test; multiple-condition 2n. Mutation score = killed ÷ (মোট − equivalent).
Black-box: partition, boundary, decision table আর pairwise
৬.১(সহজ) একটি অর্ডার ফর্মে “পরিমাণ” integer, বৈধ ১ থেকে ৫০. Equivalence class কয়টি, আর ২-মান ও ৩-মান BVA-তে কোন মানগুলো test করবেন?
classes: invalid low (<= 0) | valid 1..50 | invalid high (>= 51) -> 3
2-value BVA: 0, 1, 50, 51 -> 4 values
3-value BVA: 0, 1, 2, 49, 50, 51 -> 6 values
২-মানে প্রতিটি সীমা আর অন্য পাশের নিকটতম মান; ৩-মানে সীমার দুই প্রতিবেশীও। ৩-মানের ২ এমন ভুল ধরে, যেখানে কোডে qty >= 1-এর বদলে qty == 1 লেখা — ২-মানের ০ আর ১ তা ধরতে পারে না; ৪৯ ওপরের সীমায় একই কাজ করে। খালি ঘর, অক্ষর বা দশমিকের মতো ধরনের দিক থেকে invalid partition আলাদা গুনতে হবে, যদি প্রশ্ন চায়। ৩টি class; ২-মানে ৪টি, ৩-মানে ৬টি মান।
৬.২(মাঝারি) বাসের ভাড়ায় বয়স (integer) অনুযায়ী তিন দল: শিশু ০–১২, প্রাপ্তবয়স্ক ১৩–৫৯, প্রবীণ ৬০–১২০. সংখ্যার দিকে partition কয়টি? ২-মান আর ৩-মান BVA-র মানগুলোর তালিকা আর সংখ্যা দিন।
partitions: <0 | 0-12 | 13-59 | 60-120 | >120 -> 5
2-value: -1, 0, 12, 13, 59, 60, 120, 121 -> 8
3-value: -1, 0, 1, 11, 12, 13, 14, 58, 59, 60, 61,
119, 120, 121 -> 14
পাশাপাশি দুটি partition-এর সীমা (১২ আর ১৩, ৫৯ আর ৬০) একে অপরের off point, তাই ২-মানে বাড়তি মান লাগে শুধু দুই প্রান্তে (−১, ১২১)। ৩-মানে পুনরাবৃত্তি বাদ দিতে ভুলবেন না — ১২-র প্রতিবেশী ১৩ আর ১৩-র প্রতিবেশী ১২ একই মান। সূত্রে মিলিয়ে দেখুন: k = ৩ হলে ২k + ২ = ৮ আর ৪k + ২ = ১৪. ৫টি partition; ৮টি আর ১৪টি মান।
৬.৩(মাঝারি) একটি কাল্পনিক বৃত্তির নিয়ম: GPA ≥ ৩.৫ আর পারিবারিক আয় সীমার নিচে হলে ১০০%; GPA ≥ ৩.৫ কিন্তু আয় বেশি হলে ৫০%; GPA ৩.৫-এর কম হলে খেলোয়াড় কোটায় ২৫%, নইলে ০. তিনটি শর্ত (C1 GPA ≥ ৩.৫, C2 আয় কম, C3 খেলোয়াড়)। পূর্ণ decision table-এ কয়টি rule, আর ছোট করার পরে কয়টি?
full table: 2^3 = 8 rules
C1 GPA>=3.5 Y Y Y Y N N N N
C2 low income Y Y N N Y Y N N
C3 sports Y N Y N Y N Y N
waiver % 100 100 50 50 25 0 25 0
collapsed:
C1 Y Y N N
C2 Y N - -
C3 - - Y N
waiver % 100 50 25 0 -> 4 rules (4 tests)
YYY আর YYN-এর কাজ একই (১০০) আর শুধু C3-এ পার্থক্য, তাই মিশে YY−। একইভাবে YN−, আর N-এর দিকে C2-র প্রভাব নেই বলে NYY ও NNY মিশে N−Y, NYN ও NNN মিশে N−N. প্রতিটি “−” একটি দাবি — কোডে সত্যিই প্রভাব নেই কি না, ঝুঁকি থাকলে একটি বাড়তি test দিয়ে দেখা ভালো। ৮টি rule; ছোট করে ৪টি।
৬.৪(মাঝারি) (ক) তিনটি parameter — browser (৩টি মান), ভাষা (৩টি), ভূমিকা (২টি)। সব মিলনে কয়টি test, আর pairwise suite-এ সবচেয়ে কম কয়টি? (খ) পাঁচটি on/off setting-এর ক্ষেত্রে একই প্রশ্ন।
(a) all combinations = 3 x 3 x 2 = 18
lower bound = 3 x 3 = 9 (every browser-language pair must appear once)
a 9-test suite covering all pairs exists -> minimum = 9
(b) all combinations = 2^5 = 32
lower bound = 2 x 2 = 4, but the true minimum is 6
(exhaustive search: no 5-row suite covers all 40 pairs)
দুটি বড় parameter-এর সব জোড়া অন্তত একবার আসতেই হবে — তাই গুণফলটি নিম্নসীমা। (ক)-তে এই সীমা পূরণ করা যায়: প্রতিটি browser-ভাষা জোড়ার সাথে ভূমিকা এমনভাবে বসানো যে প্রতিটি browser আর প্রতিটি ভাষার সাথে দুই ভূমিকাই আসে। (খ) ফাঁদ: নিম্নসীমা ৪ হলেও পাঁচটি binary parameter-এ ৬টির কমে হয় না — এটি একটি স্ক্রিপ্টে সব ৫-সারির সমন্বয় পরীক্ষা করে যাচাই করা (চারটি parameter হলে ৫টিই যথেষ্ট)। পরীক্ষায় সাধারণত নিম্নসীমা আর একটি বাস্তব suite চাওয়া হয়। (ক) ১৮ বনাম ৯; (খ) ৩২ বনাম ৬.
White-box: V(G), coverage আর MC/DC
৬.৫(মাঝারি) একটি লাইব্রেরির জরিমানার function: fine = 0; for d = 1..days: if d <= 7: continue; fine += member ? 5 : 10; শেষে if fine > 500: fine = 500; return fine. CFG-র node: ১ শুরু, ২ loop-এর শর্ত, ৩ d <= 7, ৪ member?, ৫ +৫, ৬ +১০, ৭ d বাড়ানো, ৮ fine > 500, ৯ ৫০০-তে আটকানো, ১০ return. Edge: ১→২, ২→৩, ২→৮, ৩→৭, ৩→৪, ৪→৫, ৪→৬, ৫→৭, ৬→৭, ৭→২, ৮→৯, ৮→১০, ৯→১০. V(G) তিন পদ্ধতিতে বের করুন।
(1) E - N + 2P = 13 - 10 + 2 x 1 = 5
(2) decision nodes (2 outgoing edges): 2 (loop), 3 (if), 4 (?:), 8 (if) = 4 -> 4 + 1 = 5
(3) regions (planar drawing, outer one included) = E - N + 2 = 5
basis path testing -> 5 independent paths to test
Ternary ?:-ও একটি দুই-মুখী decision — অনেকে এটি বাদ দিয়ে ৪ লেখেন। tool-ভেদে ?: আর &&-কে গোনার নিয়ম আলাদা (পর্ব ৫০), তাই খাতায় নিয়মটি লিখুন। Sanity check: তিনটি হিসাব একই। Loop থাকায় basis-এর কিছু পথ হুবহু চালানো যায় না (যেমন শূন্যবার loop-এ fine > ৫০০ অসম্ভব) — তখন পর্ব ৫০-এর নিয়মে কাছাকাছি একটি সম্ভব পথ বেছে নিতে হয়। V(G) = ৫.
৬.৬(সহজ) def ship(w, express): cost = 50; if w > 5: cost += 20; if express: cost *= 2; return cost. ১০০% statement coverage, ১০০% branch coverage আর ১০০% path coverage-এর জন্য সবচেয়ে কম কয়টি test লাগে? প্রতিটির একটি উদাহরণ দিন।
statement: 1 test ship(6, True) -> 140 (both if-bodies run)
branch : 2 tests ship(6, True) -> 140 ; ship(3, False) -> 50
path : 4 tests (T,T) (T,F) (F,T) (F,F): e.g. 140, 70, 100, 50
MC/DC : 2 tests here (each decision has a single condition = branch)
else ছাড়া if-এ statement আর branch-এর পার্থক্য সবচেয়ে স্পষ্ট: একটি test-এ দুটি body-ই চলে, কিন্তু দুটি F শাখা একবারও নেওয়া হয় না। দুটি স্বাধীন if পরপর থাকায় path ২ × ২ = ৪. Sanity check: branch coverage statement-কে subsume করে, তাই branch-এর suite (২) কখনো statement-এর (১)-এর চেয়ে ছোট হয় না। ১, ২ আর ৪টি test.
৬.৭(কঠিন) Decision (a || b) && c. সত্যসারণির আটটি সারি (a, b, c) ক্রমে T1 = 000 থেকে T8 = 111. প্রতিটি শর্তের independence pair খুঁজে MC/DC-এর ন্যূনতম test-সেট বের করুন। Multiple-condition coverage-এ কয়টি লাগত?
row a b c out independence pairs (only one condition differs, outcome differs)
T1 0 0 0 0 a : (T2, T6) 001 -> 0, 101 -> 1
T2 0 0 1 0 b : (T2, T4) 001 -> 0, 011 -> 1
T3 0 1 0 0 c : (T3, T4), (T5, T6), (T7, T8)
T4 0 1 1 1
T5 1 0 0 0 a and b each have ONE pair, both use T2
T6 1 0 1 1 -> must take T2, T4, T6; add one c pair that reuses them:
T7 1 1 0 0 (T3, T4) or (T5, T6)
T8 1 1 1 1 minimum MC/DC = 4 tests: {T2, T3, T4, T6} or {T2, T4, T5, T6}
multiple-condition coverage = 2^3 = 8 tests
a-র প্রভাব দেখাতে b = ০ আর c = ১ রাখতেই হয় (b = ১ হলে a || b এমনিতেই সত্য, c = ০ হলে পুরোটা এমনিতেই মিথ্যা) — তাই একটিমাত্র জোড়া। ন্যূনতম সংখ্যা n + ১ = ৪, যা and/or-এর decision-এ সাধারণ ফল। Sanity check: সেটে প্রতিটি শর্ত T আর F দুটিই পেয়েছে, আর decision-ও দুই ফল দিয়েছে। ৪টি test (যেমন T2, T3, T4, T6); MCC-তে ৮টি।
# V(G) three ways from an edge list, and a brute-force minimum MC/DC test-set finder.
from itertools import product, combinations
edges = [(1, 2), (2, 3), (2, 8), (3, 7), (3, 4), (4, 5), (4, 6), (5, 7), (6, 7),
(7, 2), (8, 9), (8, 10), (9, 10)] # CFG of fine(days, member)
nodes = {x for e in edges for x in e}
out = {}
for a, _ in edges:
out[a] = out.get(a, 0) + 1
decisions = sum(1 for k in out.values() if k == 2)
print(f"6.5 E={len(edges)} N={len(nodes)} -> V(G) = E - N + 2 = {len(edges) - len(nodes) + 2}; "
f"decisions + 1 = {decisions + 1}")
def mcdc(name, n, decision):
rows = list(product([0, 1], repeat=n))
res = {r: int(bool(decision(*r))) for r in rows}
pairs = {k: [(i + 1, j + 1) for (i, r), (j, s) in combinations(enumerate(rows), 2)
if [x != y for x, y in zip(r, s)].count(True) == 1 and r[k] != s[k] and res[r] != res[s]]
for k in range(n)}
for k, p in pairs.items():
print(f" condition {k + 1} independence pairs (row numbers): {p}")
for size in range(1, len(rows) + 1):
best = [t for t in combinations(range(1, len(rows) + 1), size)
if all(any(a in t and b in t for a, b in pairs[k]) for k in range(n))]
if best:
print(f"{name}: minimum MC/DC = {size} tests (n + 1 = {n + 1}); sets: {best}")
return
mcdc("6.7 (a or b) and c", 3, lambda a, b, c: (a or b) and c)
mcdc("a and b and c", 3, lambda a, b, c: a and b and c)আউটপুট:
6.5 E=13 N=10 -> V(G) = E - N + 2 = 5; decisions + 1 = 5
condition 1 independence pairs (row numbers): [(2, 6)]
condition 2 independence pairs (row numbers): [(2, 4)]
condition 3 independence pairs (row numbers): [(3, 4), (5, 6), (7, 8)]
6.7 (a or b) and c: minimum MC/DC = 4 tests (n + 1 = 4); sets: [(2, 3, 4, 6), (2, 4, 5, 6)]
condition 1 independence pairs (row numbers): [(4, 8)]
condition 2 independence pairs (row numbers): [(6, 8)]
condition 3 independence pairs (row numbers): [(7, 8)]
a and b and c: minimum MC/DC = 4 tests (n + 1 = 4); sets: [(4, 6, 7, 8)]
প্রথম লাইন ৬.৫: E − N + ২ = ৫ আর decision + ১ = ৫. তারপর ৬.৭-এর independence pair — a-র একটিই (T2, T6), b-র একটিই (T2, T4) — আর ন্যূনতম দুটি সেট {২, ৩, ৪, ৬} ও {২, ৪, ৫, ৬}. শেষ অংশ a and b and c: সব-T (T8) আর প্রতিটি শর্ত একবার F — ৪টি, যা MCQ-এর উত্তরও। প্রোগ্রামটি ছোট থেকে বড় সব সেট পরীক্ষা করে, তাই যা ছাপে তা সত্যিই ন্যূনতম।
Mutation আর exhaustive testing
৬.৮(মাঝারি) একটি mutation tool ৪০টি mutant বানিয়েছে। Test suite ২৮টি মেরেছে, ১২টি টিকে আছে; পরীক্ষা করে দেখা গেল টিকে থাকাদের ৪টি equivalent. Mutation score কত? নতুন test আরও ৫টি mutant মারলে score কত হবে?
score = killed / (total - equivalent) = 28 / (40 - 4) = 28 / 36 = 77.8%
naive (wrong): 28 / 40 = 70.0%
after 5 more kills: 33 / 36 = 91.7% (3 non-equivalent survivors left)
Equivalent mutant কোনো test-ই মারতে পারে না, তাই হর থেকে বাদ — নইলে ১০০% কখনো সম্ভব নয়। কোনটি equivalent তা সাধারণভাবে যন্ত্রে নির্ধারণ করা যায় না, মানুষকে দেখতে হয়। বাকি ৩টি টিকে থাকা mutant-ই এখন সবচেয়ে দামি তথ্য: কোন ভুল আপনার test ধরে না। ৭৭.৮%; পরে ৯১.৭%.
৬.৯(সহজ) (ক) একটি function দুটি 16-bit integer নেয়। সব ইনপুট-মিলন test করতে কয়টি test, আর সেকেন্ডে ১০ লাখ test চালালে কত সময়? (খ) একটি ফর্মে চারটি drop-down, মান-সংখ্যা ৩, ৪, ৫ আর ২ — সব মিলন কয়টি?
(a) 2^16 x 2^16 = 2^32 = 4,294,967,296 cases
4,294,967,296 / 10^6 per second = 4295 s = 71.6 minutes
three 32-bit inputs: 2^96 ~ 7.9 x 10^28 -> about 2.5 x 10^15 years at the same speed
(b) 3 x 4 x 5 x 2 = 120 combinations
দুটি ছোট integer-এই এক ঘণ্টার বেশি, তিনটি 32-bit-এ মহাবিশ্বের বয়সের চেয়ে অনেক বেশি — এটাই “exhaustive testing অসম্ভব” নীতির সংখ্যাগত রূপ (পর্ব ৪৫), আর EP, BVA আর pairwise-এর কারণ। (ক) ২৩২ ≈ ৪২৯ কোটি test, প্রায় ৭১.৬ মিনিট; (খ) ১২০টি।
// Mutation score = killed / (all mutants - equivalent mutants), on a tiny real function.
const ORIGINAL = `if (weight <= 0) return -1;
let cost = weight > 5 ? 80 : 50;
if (express) cost = cost * 2;
return cost;`;
const MUTANTS = [["M1", "weight > 5", "weight >= 5"], ["M2", "weight <= 0", "weight < 0"],
["M3", "cost * 2", "cost + 2"], ["M4", "? 80", "? 81"], ["M5", "cost * 2", "cost + cost"],
["M6", "if (express)", "if (!express)"]];
const EQUIVALENT = new Set(["M5"]); // a human decided: no input tells M5 apart
const make = body => new Function("weight", "express", body);
const fee = make(ORIGINAL);
const WEAK = [[3, false, 50], [8, true, 160]];
const STRONG = [...WEAK, [5, false, 50], [0, false, -1]];
function score(name, suite) {
suite.forEach(([w, e, want]) => { if (fee(w, e) !== want) throw new Error("bad test"); });
let killed = 0;
for (const [id, find, repl] of MUTANTS) {
const m = make(ORIGINAL.replace(find, repl));
const hit = suite.find(([w, e, want]) => m(w, e) !== want);
if (hit) killed++;
console.log(` ${id} ${(find + " -> " + repl).padEnd(28)} ${hit ? "killed by (" + hit.slice(0, 2) + ")" : EQUIVALENT.has(id) ? "survived (equivalent)" : "SURVIVED"}`);
}
const s = killed / (MUTANTS.length - EQUIVALENT.size);
console.log(`${name}: killed ${killed} of ${MUTANTS.length - EQUIVALENT.size} -> score ${(100 * s).toFixed(1)}%`);
}
score("weak suite", WEAK);
score("strong suite", STRONG);
console.log("6.8 score =", (100 * 28 / (40 - 4)).toFixed(1) + "%, after 5 more kills =", (100 * 33 / 36).toFixed(1) + "%");
console.log("6.9 two 16-bit inputs:", 2 ** 32, "cases =", (2 ** 32 / 1e6 / 60).toFixed(1), "min at 1e6 tests/s");আউটপুট:
M1 weight > 5 -> weight >= 5 SURVIVED
M2 weight <= 0 -> weight < 0 SURVIVED
M3 cost * 2 -> cost + 2 killed by (8,true)
M4 ? 80 -> ? 81 killed by (8,true)
M5 cost * 2 -> cost + cost survived (equivalent)
M6 if (express) -> if (!express) killed by (3,false)
weak suite: killed 3 of 5 -> score 60.0%
M1 weight > 5 -> weight >= 5 killed by (5,false)
M2 weight <= 0 -> weight < 0 killed by (0,false)
M3 cost * 2 -> cost + 2 killed by (8,true)
M4 ? 80 -> ? 81 killed by (8,true)
M5 cost * 2 -> cost + cost survived (equivalent)
M6 if (express) -> if (!express) killed by (3,false)
strong suite: killed 5 of 5 -> score 100.0%
6.8 score = 77.8%, after 5 more kills = 91.7%
6.9 two 16-bit inputs: 4294967296 cases = 71.6 min at 1e6 tests/s
দুর্বল suite (৩, false) আর (৮, true)-এর branch coverage পূর্ণ, তবু M1 আর M2 টিকে যায় — দুটিই সীমার ভুল (>= বনাম >), আর কোনো test সীমায় নেই। Score ৩ ÷ ৫ = ৬০%. (৫, false) আর (০, false) যোগ করলে দুটিই মরে, score ১০০%. M5 (cost + cost) equivalent — কোনো ইনপুটেই আলাদা ফল দেয় না, তাই হরে নেই। শেষ দুই লাইন ৬.৮ আর ৬.৯-এর সংখ্যা।
(সহজ) একটি function-এর control-flow graph-এ ১৫টি edge আর ১২টি node (একটিই connected অংশ)। Cyclomatic complexity কত?
- 3
- 27
- 5
- 4
(সহজ) একটি integer ঘরের বৈধ পরিসর ১০ থেকে ২০ (একটিই range). ৩-মান boundary value analysis-এ কয়টি মান test করবেন?
- 6
- 4
- 3
- 11
(মাঝারি) Decision a && b && c-এর জন্য MC/DC পূরণ করতে সবচেয়ে কম কয়টি test লাগে?
- 8
- 2
- 3
- 4
(মাঝারি) ৫০টি mutant-এর মধ্যে ৫টি equivalent, আর test suite ৩৬টি মেরেছে। Mutation score কত?
- 72%
- 80%
- 82%
- 90%
৭ · Process আর flow — Little-এর সূত্র, flow efficiency, DORA আর অগ্রাধিকার
ঝালিয়ে নিন: পর্ব ০৬ · Kanban আর lean (Little, flow efficiency, percentile), পর্ব ২৪ · Requirement management (Kano, RICE, WSJF), পর্ব ৫৯ · Continuous delivery আর DevOps (DORA).
Little: গড় cycle time = গড় WIP ÷ গড় throughput — স্থিতিশীল ব্যবস্থায়, তিনটিই একই সীমানায় মাপা। Flow efficiency = সক্রিয় কাজের সময় ÷ lead time. Percentile = সাজানো তালিকার ⌈q × n⌉-তম মান।
DORA: deployment frequency = সফল deploy ÷ দিন; lead time for changes = commit থেকে production, median; change failure rate = সমস্যা ঘটানো deploy ÷ মোট; time to restore = incident-এর median.
অগ্রাধিকার: RICE = Reach × Impact × Confidence ÷ Effort; WSJF = (business value + time criticality + risk reduction) ÷ job size = cost of delay ÷ size; Kano-তে প্রতিটি উত্তর-জোড়া টেবিল থেকে শ্রেণি, সবচেয়ে বেশিবার আসা শ্রেণিই উত্তর।
৭.১(সহজ) একটি দলের Kanban board-এ গড়ে ২৪টি card চলমান, আর দল সপ্তাহে গড়ে ৬টি card শেষ করে। গড় cycle time কত? Throughput একই রেখে cycle time ২ সপ্তাহে নামাতে WIP কত রাখতে হবে? আর আরেকটি দলে cycle time ৫ দিন, throughput দিনে ৩ — গড় WIP কত?
cycle time = WIP / throughput = 24 / 6 = 4 weeks
target 2 weeks: WIP = cycle time x throughput = 2 x 6 = 12 cards
second team: WIP = 5 days x 3 per day = 15 cards
সূত্রটি গড়ের, আর স্থিতিশীল ব্যবস্থার — যত card ঢোকে প্রায় তত বেরোয়। প্রতি সপ্তাহে backlog বাড়তে থাকলে (আগমন > throughput) পুরো ব্যবস্থায় এটি খাটে না। তিনটি সংখ্যাই একই “শুরু” আর “শেষ” বিন্দু দিয়ে মাপতে হবে। ৪ সপ্তাহ; WIP ১২; দ্বিতীয় দলে গড়ে ১৫টি card.
৭.২(মাঝারি) একটি card-এর যাত্রা (ঘণ্টায়): ready-তে অপেক্ষা ২০, development ৬, review-এর অপেক্ষা ১৪, review ১, test-এর অপেক্ষা ২২, test ৩, deploy-এর অপেক্ষা ৬. Lead time আর flow efficiency কত? সবচেয়ে বড় অপচয় কোথায়?
active = 6 + 1 + 3 = 10 h
waiting = 20 + 14 + 22 + 6 = 62 h
lead time = 10 + 62 = 72 h
flow efficiency = 10 / 72 = 13.9%
কাজের সময়ের প্রায় ছয় গুণ সময় card অপেক্ষায়। সবচেয়ে বড় অপেক্ষা test-এর আগে (২২ ঘণ্টা) — tester-দের WIP বা automated test বাড়ানো সবচেয়ে বেশি লাভ দেবে। developer-কে আরও দ্রুত কোড লেখানো (৬ ঘণ্টা কমানো) প্রায় কিছুই বদলাবে না। Lead time ৭২ ঘণ্টা, flow efficiency প্রায় ১৩.৯%.
৭.৩(মাঝারি) ১৪ দিনে ৮টি production deploy. প্রতিটির commit-গুলোর lead time (ঘণ্টা) আর ফল: D1 — ৩, ২৬; D2 — ৫, সমস্যা, ২৫ মিনিটে স্বাভাবিক; D3 — ২, ৮, ৪; D4 — ৩০; D5 — ৬, ১, সমস্যা, ৯০ মিনিট; D6 — ৭; D7 — ১২; D8 — ৩, সমস্যা, ৪০ মিনিট। Nearest-rank median ধরে DORA-র চারটি metric বের করুন।
deployment frequency = 8 / 14 = 0.57 per day (about 4 per week)
lead times sorted (12 commits): 1 2 3 3 4 5 6 7 8 12 26 30
median = ceil(0.5 x 12) = 6th value = 5 h (mean 8.92 h)
change failure rate = 3 / 8 = 37.5%
restore times sorted: 25 40 90 -> ceil(0.5 x 3) = 2nd = 40 min
Lead time প্রতিটি commit-এর জন্য একটি মান — deploy-এর জন্য নয়। গড় (৮.৯২) দুটি দীর্ঘ commit (২৬, ৩০) টেনে তোলে, median নয়; তাই DORA median নেয়। ছোট নমুনায় একটি deploy এদিক-ওদিক হলেই CFR ১২.৫ শতাংশ-বিন্দু বদলায় — সংখ্যার পাশে নমুনার আকারও লিখুন। পড়ার কথা: গতি ভালো, কিন্তু প্রায় তিনটির একটি deploy সমস্যা ঘটাচ্ছে। ০.৫৭/দিন, ৫ ঘণ্টা, ৩৭.৫%, ৪০ মিনিট।
# DORA's four metrics from a small log, plus Little's law, flow efficiency and p85.
from math import ceil
def nearest_rank(xs, q): # the q-th percentile, nearest-rank method
s = sorted(xs)
return s[ceil(q * len(s)) - 1]
DAYS = 14
deploys = [ # (lead time of each commit in hours, caused a failure?, minutes to restore)
([3, 26], False, None), ([5], True, 25), ([2, 8, 4], False, None), ([30], False, None),
([6, 1], True, 90), ([7], False, None), ([12], False, None), ([3], True, 40)]
leads = [h for d in deploys for h in d[0]]
fails = [d for d in deploys if d[1]]
print(f"7.3 deploys {len(deploys)} in {DAYS} days -> frequency {len(deploys) / DAYS:.2f}/day")
print(f" lead time median = {nearest_rank(leads, 0.5)} h of {len(leads)} commits"
f" (mean {sum(leads) / len(leads):.2f} h)")
print(f" change failure rate = {sum(d[1] for d in deploys)}/{len(deploys)}"
f" = {100 * sum(d[1] for d in deploys) / len(deploys):.1f}%")
restores = [d[2] for d in fails]
print(f" time to restore median = {nearest_rank(restores, 0.5)} min over {len(restores)} incidents")
wip, thru = 24, 6
print(f"7.1 cycle time = WIP / throughput = {wip}/{thru} = {wip / thru:.1f} weeks;"
f" for 2 weeks keep WIP at {2 * thru}")
active, waits = [6, 1, 3], [20, 14, 22, 6]
lead = sum(active) + sum(waits)
print(f"7.2 flow efficiency = {sum(active)}/{lead} = {100 * sum(active) / lead:.1f}%")
cycle = [2, 3, 1, 5, 2, 8, 4, 3, 2, 6, 3, 1, 12, 4, 2, 3, 7, 5, 2, 9]
print(f"7.5 p50={nearest_rank(cycle, 0.5)} p85={nearest_rank(cycle, 0.85)} "
f"p95={nearest_rank(cycle, 0.95)} mean={sum(cycle) / len(cycle):.2f} days")আউটপুট:
7.3 deploys 8 in 14 days -> frequency 0.57/day
lead time median = 5 h of 12 commits (mean 8.92 h)
change failure rate = 3/8 = 37.5%
time to restore median = 40 min over 3 incidents
7.1 cycle time = WIP / throughput = 24/6 = 4.0 weeks; for 2 weeks keep WIP at 12
7.2 flow efficiency = 10/72 = 13.9%
7.5 p50=3 p85=7 p95=9 mean=4.20 days
প্রথম চার লাইন ৭.৩: দিনে ০.৫৭টি deploy, lead time-এর median ৫ ঘণ্টা (১২টি commit-এর ৬ষ্ঠ মান), CFR ৩৭.৫%, আর restore-এর median ৪০ মিনিট। তারপর ৭.১-এর ৪ সপ্তাহ ও WIP ১২, ৭.২-এর ১৩.৯%, আর ৭.৫-এর p50 ৩, p85 ৭, p95 ৯. nearest_rank একটি ফাংশনেই DORA-র median আর Kanban-এর percentile দুটোই হয় — একই নিয়ম।
৭.৪(মাঝারি) তিনটি কাল্পনিক feature. RICE-এর জন্য (reach/quarter, impact, confidence, effort person-month): F1 ডিজিটাল wallet-এ পেমেন্ট (২০০০, ২, ৮০%, ৪); F2 বাংলায় পণ্য খোঁজা (৫০০০, ১, ১০০%, ২); F3 ভর্তি-মৌসুমের বিশেষ delivery slot (৮০০, ৩, ৫০%, ১)। WSJF-এর জন্য (business value, time criticality, risk reduction, job size): F1 (৮, ৩, ২, ৮); F2 (৫, ২, ১, ৩); F3 (৬, ১৩, ৩, ২)। দুই পদ্ধতিতে ক্রম বের করে পার্থক্য ব্যাখ্যা করুন।
RICE = R x I x C / E
F1: 2000 x 2 x 0.8 / 4 = 800
F2: 5000 x 1 x 1.0 / 2 = 2500
F3: 800 x 3 x 0.5 / 1 = 1200 order: F2 > F3 > F1
WSJF = (BV + TC + RR) / size
F1: (8 + 3 + 2) / 8 = 1.63
F2: (5 + 2 + 1) / 3 = 2.67
F3: (6 + 13 + 3) / 2 = 11.00 order: F3 > F2 > F1
RICE-এ বেশি মানুষের কাছে পৌঁছানো F2 এগিয়ে; WSJF-এ সময়ের চাপ (time criticality ১৩) F3-কে এক নম্বরে তোলে — মৌসুম পেরিয়ে গেলে এর মূল্য অনেক কমে, যা RICE-এ ধরা পড়ে না। দুটিতেই F1 শেষে: বড় effort বা বড় job size. সংখ্যাগুলো অনুমান — সূত্র অনুমানকে সাজায়, সত্য বানায় না (পর্ব ২৪)। RICE: F2, F3, F1; WSJF: F3, F2, F1.
৭.৫(মাঝারি) শেষ ২০টি শেষ হওয়া card-এর cycle time (দিন): ২, ৩, ১, ৫, ২, ৮, ৪, ৩, ২, ৬, ৩, ১, ১২, ৪, ২, ৩, ৭, ৫, ২, ৯. Nearest-rank-এ p50, p85 আর p95 বের করুন। আজ শুরু হওয়া একটি card সম্পর্কে ৮৫% নিশ্চয়তায় কী বলবেন?
sorted: 1 1 2 2 2 2 2 3 3 3 3 4 4 5 5 6 7 8 9 12
p50 = ceil(0.50 x 20) = 10th = 3 days
p85 = ceil(0.85 x 20) = 17th = 7 days
p95 = ceil(0.95 x 20) = 19th = 9 days (mean = 84 / 20 = 4.2 days)
সৎ উত্তর: “৮৫% সম্ভাবনায় ৭ দিনের মধ্যে, ৯৫% সম্ভাবনায় ৯ দিনের মধ্যে।” গড় ৪.২ দিন বললে প্রায় অর্ধেক card-ই দেরিতে মনে হবে, কারণ লম্বা লেজ (১২) গড়কে টানে। Percentile-এর অন্য পদ্ধতিতে (interpolation) সংখ্যা সামান্য বদলাতে পারে, তাই পদ্ধতির নাম লিখুন। p50 = ৩, p85 = ৭, p95 = ৯ দিন।
৭.৬(সহজ) “অর্ডারের live tracking” feature নিয়ে ৮ জনের Kano উত্তর-জোড়া (functional, dysfunctional; ১ পছন্দ, ২ প্রত্যাশিত, ৩ নিরপেক্ষ, ৪ মেনে নেব, ৫ অপছন্দ): ১৫, ২৫, ১৫, ১৪, ১৫, ২৫, ১৩, ১৫. পর্ব ২৪-এর মূল্যায়ন টেবিল ধরে feature-টির শ্রেণি কী?
table (row = functional, column = dysfunctional):
row 1: Q A A A O rows 2-4: R I I I M row 5: R R R R Q
15 -> O (one-dimensional) x4
25 -> M (must-be) x2
14 -> A (attractive) x1
13 -> A (attractive) x1
majority: O = 4 of 8 -> one-dimensional (performance) feature
“থাকলে পছন্দ, না থাকলে অপছন্দ” (১৫) মানে যত ভালো, তত খুশি — performance বা one-dimensional. দুজনের কাছে এটি ইতিমধ্যে must-be (২৫) — সময়ের সাথে আনন্দদায়ক feature মৌলিক হয়ে যায়, Kano-র একটি পরিচিত পর্যবেক্ষণ। Sanity check: ৪ + ২ + ১ + ১ = ৮. One-dimensional (performance).
(সহজ) একটি স্থিতিশীল Kanban ব্যবস্থায় গড় WIP ১৮টি card আর throughput দিনে ৩টি। Little-এর সূত্রে গড় cycle time কত?
- ৫৪ দিন
- ৬ দিন
- ০.১৭ দিন
- ২১ দিন
(সহজ) একটি card-এর lead time ৬৪ ঘণ্টা, যার মধ্যে কেউ সক্রিয়ভাবে কাজ করেছেন মাত্র ৮ ঘণ্টা। Flow efficiency কত?
- 87.5%
- 800%
- 14.3%
- 12.5%
(মাঝারি) একটি feature-এর reach প্রতি quarter-এ ১০০০ জন, impact ২, confidence ৫০%, effort ২ person-month. RICE score কত?
- 2000
- 1000
- 500
- 250
(সহজ) এক মাসে ২০টি production deploy-এর ৩টির পরে rollback বা hotfix লেগেছে। Change failure rate কত?
- 15%
- 85%
- 3
- 17.6%
৮ · Git-এর গোনাগুনি — bisect-এর ধাপ, range আর ahead/behind
ঝালিয়ে নিন: পর্ব ০৯ · History আর পার্থক্য দেখা (A..B range), পর্ব ১৪ · Remote repository (ahead/behind), পর্ব ১৫ · Rebase, পর্ব ৫৫ · Git দিয়ে bug খোঁজা (bisect).
Bisect: n টি সন্দেহভাজন commit-এ skip ছাড়া ⌈log2 n⌉টি পরীক্ষা; প্রতিটি skip একটি বাড়তি চালানো।
Range: A..B = B থেকে reachable কিন্তু A থেকে নয় এমন commit; A...B = যেকোনো একটি থেকে reachable কিন্তু দুটি থেকেই নয় (symmetric difference). Merge commit-এর মাধ্যমে যা reachable, তা-ও গোনা হয়।
Ahead/behind: ahead = upstream..local-এর সংখ্যা, behind = local..upstream-এর সংখ্যা; একসাথে git rev-list --left-right --count local...upstream.
৮.১(সহজ) v2.0 tag-এ software ঠিক ছিল, HEAD-এ ভাঙা। v2.0-র পরে HEAD পর্যন্ত (HEAD-সহ) commit আছে (ক) ৩০০টি, (খ) ১০২৪টি, (গ) ১০২৫টি। কোনো commit skip না হলে git bisect-এ সবচেয়ে বেশি কয়টি পরীক্ষা লাগবে? একে একে দেখলে খারাপ ক্ষেত্রে কয়টি?
n = suspects = commits after the good one, up to and including the bad one
(a) n = 300 : 2^8 = 256 < 300 <= 512 = 2^9 -> ceil(log2 300) = 9 tests
(b) n = 1024 : 2^10 = 1024 exactly -> ceil(log2 1024) = 10 tests
(c) n = 1025 : just above 2^10 -> ceil(log2 1025) = 11 tests
one by one, worst case: n - 1 tests (299, 1023, 1024) - the last one needs no test
প্রতিটি পরীক্ষা সন্দেহের তালিকা অর্ধেক করে, তাই k টি পরীক্ষায় ২kটি সম্ভাবনা আলাদা করা যায়। ফাঁদ: জানা ভালো commit-টিকেও n-এ গোনা — সেটি সন্দেহভাজন নয়। জানা খারাপটি গোনা হয়, কারণ সেটিই প্রথম খারাপ হতে পারে (পর্ব ৫৫)। একে একে দেখার খারাপ ক্ষেত্রে n − ১টি, কারণ বাকি একটি থাকলে সেটিই উত্তর। Skip করা commit থাকলে সংখ্যা বাড়ে। (ক) ৯, (খ) ১০, (গ) ১১.
৮.২(মাঝারি) main-এ c1 → c2 → c3; c3 থেকে feature branch-এ f1 → f2; তারপর main-এ c4 → c5. (ক) git log main..feature আর git log feature..main কোন commit দেখাবে? (খ) main...feature-এ কয়টি? (গ) feature-এ বসে git rebase main কয়টি commit নতুন করে বসাবে?
একটি scratch repository-তে ঠিক এই ইতিহাস বানিয়ে Git ২.৫৩-এ চালানো হয়েছে (hash আপনার repository-তে আলাদা হবে):
$ git log --oneline --graph --all
* 026020c c5
* 8af12f3 c4
| * b286ca6 f2
| * f4c41e8 f1
|/
* 8e33805 c3
* 632d184 c2
* bf0d89c c1
$ git log --oneline main..feature
b286ca6 f2
f4c41e8 f1
$ git log --oneline feature..main
026020c c5
8af12f3 c4
$ git rev-list --count main...feature
4
$ git rev-list --left-right --count main...feature
2 2
$ git log --oneline -1 $(git merge-base main feature)
8e33805 c3main..feature মানে “feature থেকে পৌঁছানো যায়, main থেকে নয়” — f1, f2. উল্টো দিকে c4, c5. তিন বিন্দুতে দুই দিকের যোগ, ২ + ২ = ৪; --left-right --count দুটিকে আলাদা করে দেখায় (বাঁয়ে main-এর ২, ডানে feature-এর ২)। merge base c3, তাই rebase ঠিক main..feature-এর commit-গুলো — f1 আর f2 — c5-এর ওপর নতুন hash-এ বসাবে। (ক) f2, f1 আর c5, c4; (খ) ৪; (গ) ২টি।
* ee82f0c c4 <- main * bde15bc M: merge feature |\ * | 4db7579 c3 | | * 5754fdd f3 <- feature | |/ | * dc70ad0 f2 | * 1ca1ffb f1 |/ * 42181b9 c2 * 569c0d6 c1
from feature (f3), follow parents:
f3 -> f2 -> f1 -> c2 -> c1
R(feature) = {f3,f2,f1,c2,c1} (5)
from main (c4):
c4 -> M; M has 2 parents: c3, f2
c3 -> c2 -> c1 f2 -> f1 -> c2
R(main) = {c4,M,c3,f2,f1,c2,c1} (7)
first-parent: c4,M,c3,c2,c1 (5)
main..feature = R(feature) - R(main) = {f3} (1) feature..main = R(main) - R(feature) = {c4, M, c3} (3) --left-right --count main...feature 3 1
- ইতিহাস। c2 থেকে feature-এ f1, f2; main-এ c3; তারপর M-এ feature main-এ merge হয়েছে। এরপর feature-এ f3 আর main-এ c4. Hash-গুলো একটি scratch repository-তে Git ২.৫৩-এ বানানো আসল ইতিহাসের।
- feature থেকে কোথায় পৌঁছানো যায়। f3 থেকে parent ধরে পেছনে: f2, f1, c2, c1 — মোট ৫টি commit. এদের কোনোটি থেকে M বা c3-এ যাওয়া যায় না, কারণ তীর শুধু parent-এর দিকে।
- main থেকে কোথায় পৌঁছানো যায়। c4 থেকে M; M-এর দুটি parent — c3 আর f2. তাই f2 আর f1-ও main থেকে reachable — মোট ৭টি। শুধু প্রথম parent ধরলে (--first-parent) f1, f2 বাদ, থাকে ৫টি।
- বিয়োগ। main..feature-এ থাকে শুধু f3 — অনেকে ভুল করে তিনটি লেখেন। feature..main-এ c4, M আর c3.
--left-right --countএকসাথে দেখায় ৩ আর ১ — main ৩টি এগিয়ে, feature ১টি।
৮.৩(কঠিন) main-এ c1 → c2; c2 থেকে feature-এ f1 → f2; main-এ c3, তারপর feature-কে main-এ merge করে merge commit M; এরপর feature-এ f3 আর main-এ c4. main..feature আর feature..main-এ কয়টি করে commit? main থেকে মোট কয়টি commit reachable, আর --first-parent ধরে কয়টি?
$ git log --oneline --graph --all
* ee82f0c c4
* bde15bc M: merge feature
|\
* | 4db7579 c3
| | * 5754fdd f3
| |/
| * dc70ad0 f2
| * 1ca1ffb f1
|/
* 42181b9 c2
* 569c0d6 c1
$ git log --oneline main..feature
5754fdd f3
$ git log --oneline feature..main
ee82f0c c4
bde15bc M: merge feature
4db7579 c3
$ git rev-list --count main
7
$ git rev-list --count --first-parent main
5
$ git log --oneline -1 $(git merge-base main feature)
dc70ad0 f2বহু উত্তরদাতা main..feature-এ f1, f2, f3 — তিনটি লেখেন। কিন্তু M-এর দ্বিতীয় parent f2, তাই f1 আর f2 এখন main থেকেও reachable; বাকি থাকে শুধু f3. উল্টো দিকে c3, M আর c4 — merge commit-ও একটি commit, গোনা হয়। main থেকে reachable: c1, c2, c3, f1, f2, M, c4 = ৭; প্রথম parent ধরে হাঁটলে f1 আর f2 বাদ, তাই ৫. Merge base এখন f2 (dc70ad0), c2 নয়। ১ আর ৩; reachable ৭, first-parent ৫.
৮.৪(মাঝারি) রাফি আর নীলা একই remote-এ কাজ করেন। দুটি commit-এর পরে নীলা ৩টি commit push করেছেন, আর রাফি নিজের কম্পিউটারে ২টি commit করেছেন (push করেননি)। রাফি git fetch করার পরে git status কী বলবে? তারপর git rebase origin/main (বা git pull --rebase) করলে, কোনো conflict না হলে, ahead/behind কত হবে?
$ git fetch
From ../origin
bf4ebf7..2312357 main -> origin/main
$ git status -sb
## main...origin/main [ahead 2, behind 3]
$ git status
On branch main
Your branch and 'origin/main' have diverged,
and have 2 and 3 different commits each, respectively.
(use "git pull" if you want to integrate the remote branch with yours)
…
$ git rev-list --left-right --count main...origin/main
2 3
$ git rebase origin/main
Successfully rebased and updated refs/heads/main.
$ git status -sb
## main...origin/main [ahead 2]
$ git log --oneline --graph
* db41281 r2
* d447b78 r1
* 2312357 n3
* 4e31114 n2
* f894430 n1
* bf4ebf7 c2
* b23e050 c1Fetch শুধু origin/main সরায়, রাফির main-কে ছোঁয় না — তাই “diverged”: রাফির ২টি commit remote-এ নেই (ahead ২), নীলার ৩টি রাফির কাছে নেই (behind ৩)। Rebase রাফির ২টি commit নীলার ৩টির ওপরে নতুন করে বসায়; এখন রাফির main origin/main-এর সব commit ধারণ করে (behind ০), আর নিজের ২টি এখনো push হয়নি (ahead ২)। এরপর সাধারণ git push-ই যথেষ্ট, force লাগে না। Fetch-এর পরে ahead ২, behind ৩; rebase-এর পরে ahead ২, behind ০.
(সহজ) git bisect-এ জানা ভালো আর জানা খারাপ commit-এর মাঝে ৫০০টি সন্দেহভাজন commit (খারাপটি সহ)। কোনো skip না হলে সবচেয়ে বেশি কয়টি পরীক্ষা লাগবে?
- 9
- 8
- 250
- 10
(মাঝারি) main-এ c1 → c2 → c3 → c4. c2 থেকে feature branch-এ f1 → f2 → f3; কোনো merge হয়নি। git rev-list --count main..feature কত দেখাবে?
- 2
- 5
- 3
- 7
(মাঝারি) git fetch-এর পরে git status -sb দেখাল ## main...origin/main [ahead 2, behind 3]. কোনো conflict ছাড়া git pull --rebase হলে অবস্থা কী হবে?
- ahead 0, behind 0
- ahead 5, behind 0
- ahead 2, behind 3
- ahead 2, behind 0
৯ · শেষ মুহূর্তের সূত্র-তালিকা
পরীক্ষার আগের রাতে বা হলে ঢোকার আগে এই এক টেবিলই যথেষ্ট। প্রতিটি সারির শেষ কলামে সবচেয়ে সাধারণ ফাঁদ — সূত্রের চেয়ে ওটা মনে রাখাই বেশি কাজের।
| বিষয় | সূত্র | ফাঁদ |
|---|---|---|
| Function point | UFP = Σ সংখ্যা × weight; VAF = 0.65 + 0.01ΣGSC; AFP = UFP × VAF | EQ-কে EO-র weight; VAF ১.৩৫-এর বেশি |
| Basic COCOMO | E = a·KLOCb; D = 2.5·Ed; দল = E/D (organic 2.4/1.05/0.38, semi 3.0/1.12/0.35, embedded 3.6/1.20/0.32) | KLOC-এর বদলে LOC; D-তে KLOC বসানো |
| Intermediate | E = ai·KLOCb·EAF, ai = 3.2/3.0/2.8 | Basic-এর a দিয়ে EAF গুণ |
| COCOMO II | E = 0.91 + 0.01ΣSF; PM = 2.94·SizeE·ΠEM; TDEV = 3.67·PM0.28 + 0.2(E − 0.91) | SF-কে গুণ করা; COCOMO 81-এর ধ্রুবক মেশানো |
| তিন-বিন্দু | te = (O + 4M + P)/6; σ = (P − O)/6; Σvariance | σ যোগ করা |
| Velocity | ⌈কম backlog ÷ max v⌉ থেকে ⌈বেশি backlog ÷ min v⌉ | একটি সংখ্যা বলা; নিচে গোল করা |
| CPM | ES = max EFpred; LF = min LSsucc; TF = LS − ES; FF = min ESsucc − EF | TF আর FF গুলিয়ে ফেলা |
| PERT | Z = (T − μ)/σ; P = Φ(Z); T = μ + Zσ (৯০% 1.282, ৯৫% 1.645, ৯৯% 2.326) | variance-কে σ ধরা; “বেশি লাগার” প্রশ্নে ১ − Φ ভুলে যাওয়া |
| Crashing | slope = ΔC/ΔT; সব critical path কাটে এমন সবচেয়ে সস্তা সেট; slope > দৈনিক পরোক্ষ খরচ হলে থামা | non-critical activity কমানো |
| Earned value | SV = EV − PV; CV = EV − AC; SPI = EV/PV; CPI = EV/AC; EAC = BAC/CPI; VAC = BAC − EAC | PV আর AC সরাসরি তুলনা |
| Risk | RE = P × L; RRL = ΔRE ÷ খরচ; EMV = Σp·মূল্য − খরচ | RRL-এর লবে RE-এর পুরো মান |
| Reliability | A = MTBF/(MTBF + MTTR); বন্ধ = (১ − A)·৮৭৬০ h | MTBF-এ মেরামতের সময় ঢুকে যাওয়া |
| Defect | density = defect/KLOC; DRE = আগে ÷ (আগে + পরে) | কোন density দিচ্ছেন না লেখা |
| Control chart | গড় ± ৩σ (নমুনা σ), LCL ≥ ০ | ±২σ বা population σ না বলে নেওয়া |
| Package metric | I = Ce/(Ca + Ce); A = Na/Nc; D = |A + I − ১| | Ca আর Ce উল্টে ফেলা |
| দল | পথ = n(n − ১)/২; LCOM4 = component-এর সংখ্যা | n² বা n(n − ১) লেখা |
| BVA | এক range: EP ৩, ২-মান ৪, ৩-মান ৬; k পাশাপাশি range: ২k + ২ আর ৪k + ২ | পুনরাবৃত্তি বাদ না দেওয়া |
| Decision table ও pairwise | 2n rule; pairwise ≥ দুই বড় মান-সংখ্যার গুণফল | নিম্নসীমাকেই সবসময় উত্তর ধরা |
| V(G) | E − N + 2P = decision + ১ = region | ?: আর && গোনার নিয়ম না বলা |
| Coverage | statement ≤ branch ≤ MC/DC (n + ১) ≤ MCC (2n) | condition coverage-কে branch-এর চেয়ে শক্ত ভাবা |
| Mutation | score = killed ÷ (মোট − equivalent) | হরে equivalent রাখা |
| Flow | CT = WIP ÷ throughput; FE = সক্রিয় ÷ lead time; pq = ⌈qn⌉-তম মান | অস্থিতিশীল ব্যবস্থায় Little খাটানো |
| DORA | deploy/দিন; lead time median (commit ধরে); CFR = সমস্যা ÷ deploy; restore median | deploy ধরে lead time; গড় নেওয়া |
| অগ্রাধিকার | RICE = R·I·C/E; WSJF = (BV + TC + RR)/size | confidence শতাংশে রেখে গুণ |
| Git | bisect ⌈log2 n⌉; A..B = B-এর reachable − A-এর reachable; ahead = up..local | merge-এর মাধ্যমে reachable commit ভুলে যাওয়া |
১০ · AI-এর যুগে — numerical-এর উত্তর যাচাই
AI-কে একটি COCOMO বা CPM-এর অঙ্ক দিলে উত্তর আসে পরিষ্কার টেবিলে, আত্মবিশ্বাসী গলায় — আর বেশ প্রায়ই ভুল। ভুলের ধরনগুলো চেনা: COCOMO 81-এর organic ধ্রুবকের সাথে COCOMO II-এর ২.৯৪ মিশিয়ে ফেলা, PERT-এ σ-গুলো সরাসরি যোগ করা, crashing-এ non-critical কিন্তু সস্তা activity কমানো, DRE-তে হর ভুল নেওয়া, mutation score-এ equivalent mutant রেখে দেওয়া, আর Git-এ merge-এর মাধ্যমে reachable commit-গুলো A..B-তে গুনে ফেলা। AI কখনো মনগড়া “standard” মানও বলে (যেমন “IEEE অনুযায়ী V(G) ৭-এর বেশি হলে অবৈধ”) — এমন কোনো নিয়ম নেই।
AI সাধারণত যেখানে ভুল করে
| AI-এর ভুল | পরিণাম | কীভাবে ধরবেন |
|---|---|---|
| COCOMO-র দুই সংস্করণের ধ্রুবক মেশানো; Intermediate-এ Basic-এর a | Effort ২০–৩০% ভুল | পর্ব ৬০-এর টেবিল বা মূল model manual-এর সাথে মেলান |
| PERT-এ σ যোগ, বা variance-কে σ ধরে Z | সম্ভাবনা অনেক কম বা বেশি | Σvariance-এর বর্গমূল আলাদা লাইনে দেখতে চান |
| CPM-এর backward pass-এ “বড়টি” নেওয়া; FF-কে TF ধরা | ভুল critical path | Critical path-এর দৈর্ঘ্য = শেষ EF কি না দেখুন |
| Crashing-এ শুধু সবচেয়ে কম slope দেখা | টাকা নষ্ট, সময় কমে না | প্রতিটি ধাপে সব পথের দৈর্ঘ্য আবার লিখুন |
Bisect-এ জানা ভালো commit-কেও গোনা; A..B-তে merge উপেক্ষা | এক ধাপ বেশি; ভুল commit-তালিকা | একটি throwaway repository-তে git rev-list --count চালান |
| মনগড়া মানদণ্ড, বছর বা “গবেষণায় প্রমাণিত” শতাংশ | ভুল তথ্য উদ্ধৃতি | মূল বই, standard বা প্রবন্ধ খুঁজে দেখুন |
AI-কে উত্তরদাতা নয়, যাচাইকারী আর প্রশ্ন-বানানোর সহকারী হিসেবে ব্যবহার করুন:
যাচাইয়ের চেকলিস্ট
নিজেকে যাচাই করুন
প্রতিটি প্রশ্নে খাতায় হিসাব করে তবে উত্তর বাছুন। ভুল হলে কারণসহ ব্যাখ্যা পাবেন। ওপরের ভাগগুলোর ২৬টি প্রশ্নের সাথে এগুলো মিলিয়ে মোট ৩২টি।
ক্রমপরীক্ষার খাতায় একটি পূর্ণ CPM + PERT উত্তরের ধাপগুলো সঠিক ক্রমে সাজান (▲▼ চেপে সরান)
- Activity, সময় আর পূর্বসূরির টেবিল থেকে network আঁকা
- Forward pass — প্রতিটির ES আর EF
- Backward pass — প্রতিটির LF আর LS
- Total float আর free float, তারপর critical path আর project-এর সময়
- Critical path-এর te আর variance যোগ করে μ আর σ
- Z = (T − μ) ÷ σ, normal table থেকে সম্ভাবনা, আর এক লাইনের সিদ্ধান্ত
(মাঝারি) চারটি parameter, প্রতিটির ৩টি মান। সব মিলন কয়টি, আর pairwise suite-এর ন্যূনতম আকার কত?
- 12 আর 6
- 81 আর 9
- 27 আর 9
- 81 আর 3
(মাঝারি) Critical path A-C-E-তে cost slope (হাজার টাকা/দিন): A ১০, C ৪, E ৭; non-critical B-র slope ২. Project এক দিন ছোট করতে প্রথমে কোনটি crash করবেন?
- B
- A
- E
- C
(সহজ) BAC ৮০০ হাজার টাকা আর বর্তমান CPI ০.৮. এখনকার খরচের হার চললে EAC = BAC ÷ CPI কত?
- 1000
- 640
- 800
- 960
(সহজ) চারটি স্বাধীন Y/N শর্তের পূর্ণ decision table-এ (ছোট করার আগে) কয়টি rule?
- 8
- 4
- 16
- 32
(সহজ) সাপ্তাহিক defect-এর গড় ৫০ আর নমুনার σ ৪. প্রচলিত ৩σ নিয়মে control limit কত?
- UCL 58, LCL 42
- UCL 62, LCL 38
- UCL 54, LCL 46
- UCL 53, LCL 47
(মাঝারি) একটি বিকল্পে খরচ ৩০; সম্ভাবনা ০.৬-এ মূল্য ৮০, আর ০.৪-এ মূল্য ২০ (লাখ টাকা)। এর EMV (খরচ বাদে) কত?
- 56
- 20
- 26
- 50
শব্দকোষ
লেখার মধ্যে ডটেড দাগ দেওয়া শব্দে মাউস রাখুন বা চাপুন — অর্থ দেখাবে। এই পর্বে আসা শব্দগুলো এখানে একসাথে:
মনে রাখুন
- নিয়ম আর একক আগে: COCOMO-র সংস্করণ, দিন ০ থেকে না ১ থেকে, sample না population σ, nearest-rank, ২-মান না ৩-মান BVA — উত্তরের প্রথম লাইনে লিখুন; নিয়ম বদলালে উত্তর বদলায়।
- Estimation: VAF ০.৬৫–১.৩৫; COCOMO-র exponent ১-এর বেশি, তাই আকার দ্বিগুণে কাজ দ্বিগুণের বেশি, অথচ সময় প্রায় একই থাকে; SF exponent-এ, EM গুণফলে; velocity থেকে সবসময় পরিসর।
- Schedule: সামনে বড়টি, পেছনে ছোটটি; TF ≥ FF; PERT-এ variance যোগ হয়; crashing-এ সব critical path একসাথে কাটুন আর slope পরোক্ষ খরচ ছাড়ালে থামুন; SPI ও CPI ১-এর কম মানে খারাপ।
- Risk, quality আর design: RE = P × L, RRL > ১ লাভজনক; A = MTBF ÷ (MTBF + MTTR); DRE-র হরে মোট defect; I = Ce ÷ (Ca + Ce), D = |A + I − ১|; পথ n(n − ১) ÷ ২.
- Testing, flow আর Git: V(G) তিন পদ্ধতিতে একই; MC/DC n + ১; mutation-এর হর থেকে equivalent বাদ; Little = WIP ÷ throughput; DORA-র median commit ধরে; bisect ⌈log2 n⌉;
A..B-তে merge-এর মাধ্যমে reachable commit বাদ যায়।
আরও পড়ুন · ABCL TECH-এ আপনার পরবর্তী পদক্ষেপ
- পর্ব ৬৭ · MCQ প্রশ্নব্যাংক — software engineering ও Gitপরবর্তী পর্বপুরো কোর্সের বহুনির্বাচনি প্রশ্ন, মডিউল ধরে।
- পর্ব ৬৮ · লিখিত ও মৌখিক (ভাইভা) প্রশ্নএই মডিউলেProcess, requirement, design, testing আর management-এর বর্ণনামূলক উত্তর।
- পর্ব ৬১ · Project planning — WBS, Gantt chart, CPM আর PERTগভীরে যানMerge bias, Monte Carlo আর resource levelling-সহ পূর্ণ যুক্তি।
- পর্ব ৫০ · Coverage আর complexityগভীরে যানSubsumption-এর সিঁড়ি, basis path আর mutation testing-এর বিস্তার।
- সফটওয়্যার ইঞ্জিনিয়ারিং ও Git · কোর্স হোম৭০টি পর্বপুরো কোর্সের রোডম্যাপ — এগারোটি মডিউল।
- System Design · Estimation-এর অনুশীলনপাশের ট্র্যাকQPS, storage আর bandwidth-এর অঙ্ক — একই খাতা-সাজানোর কৌশলে।
- অপারেটিং সিস্টেম · Numerical সমস্যাপাশের ট্র্যাকScheduling, paging আর disk-এর অঙ্ক, পূর্ণ সমাধানসহ।