Home »
Blog »
AI/ML Engineer সিরিজ » Series 02 » Episode 03
Functions, Modules, Packages: কোড যখন notebook থেকে বড় হয়
flagship project-এর প্রথম কাঠামো তৈরি (Series 02, Episode 03)
🟢 BEGINNER
Series 02 — AI Engineer-দের জন্য Python
Episode 03 / 09
📑 এই পর্বে যা যা আছে
- ১. গল্প: Rahim-এর copy-paste দুর্দশা
- ২. আসল সমস্যা: একই কোড বারবার
- ৩. function কেন — DRY নীতি
- ৪. তিন লেভেলে বোঝা: function, module, package
- ৫. function লেখা: argument, default, return
- ৬. Visual: notebook থেকে package-এ যাত্রা
- ৭. module: কোড আলাদা file-এ ভাগ করা
- ৮. package: folder + __init__.py
- ৯. Code: flagship V1-এর প্রথম কাঠামো
- ১০. Experiment: import ও reuse
- ১১. AI Engineer-এর দৃষ্টিকোণ
- ১২. Boss Question
- ১৩. Job Requirement Decoder
- ১৪. সাধারণ ভুল
- ১৫. Interview Prep
- ১৬. হাতে-কলমে (Mini Exercise)
- ১৭. Project Connection
- ১৮. সারসংক্ষেপ ও পরবর্তী পর্ব
🧩 ১. গল্প: Rahim-এর copy-paste দুর্দশা
Rahim তার job-analyzer script-এ একই "skill খোঁজার" কোড ৫ জায়গায় copy-paste করেছে। এখন
skill খোঁজার নিয়ম একটু বদলাতে গিয়ে তাকে ৫ জায়গায় বদলাতে হচ্ছে — একটা জায়গা মিস করলে বাগ।
Arif (ML engineer) দেখে বলল:
"এই সমস্যাটা প্রতিটা junior-এর হয়। Notebook-এ সব একসাথে লিখলে প্রথমে দ্রুত মনে হয়, কিন্তু
project বড় হলে maintain করা দুঃস্বপ্ন। সমাধান তিনটা শব্দে: function, module, package। এগুলোই
code-কে notebook থেকে software-এ রূপান্তর করে।"
❓ ২. আসল সমস্যা: একই কোড বারবার
AI/ML-এ একটা কাজ বারবার লাগে — data পরিষ্কার করা, skill বের করা, metric হিসাব করা। প্রতিবার
নতুন করে লিখলে: (১) সময় নষ্ট, (২) bug ছড়ায়, (৩) কোড পড়া কঠিন। এর সমাধান — একবার লিখে বারবার
ব্যবহার করা, অর্থাৎ function।
♻️ ৩. function কেন — DRY নীতি
DRY = Don't Repeat Yourself। একটা কাজ একবার function-এ লিখুন, তারপর যতবার লাগে
call করুন। নিয়ম বদলালে একটাই জায়গা বদলাবেন।
function হলো একটা নামওয়ালা কাজের ব্লক: কিছু input (argument) নেয়, কিছু কাজ করে, একটা output
(return) দেয়। ML pipeline আসলে ছোট ছোট function-এর একটা chain।
🎯 ৪. তিন লেভেলে বোঝা: function, module, package
Level 1 — সহজ intuition:
function = একটা রেসিপি (একটা কাজ)। module = একটা রেসিপি বই (এক file-এ কয়েকটা রেসিপি)।
package = একটা রান্নার লাইব্রেরি (কয়েকটা বই একসাথে ফোল্ডারে)।
Level 2 — technical ভাবে:
function = def দিয়ে সংজ্ঞায়িত reusable block। module = একটা .py file, যেখানে
অনেক function/class থাকে। package = এমন একটা folder যাতে module থাকে (এবং সাধারণত __init__.py)।
Level 3 — AI Engineer-এর দৃষ্টিকোণ:
production project-এ কোড আলাদা module-এ ভাগ থাকে: data.py (data load),
features.py (feature বানানো), model.py (model), api.py (serving)।
scikit-learn, PyTorch নিজেরাও বিশাল package — আপনি রোজ from sklearn.linear_model import ... লেখেন।
🔧 ৫. function লেখা: argument, default, return
def count_skill(job_descriptions, skill):
"""একটা skill কতটি job-এ আছে তা গোনে।"""
count = 0
for jd in job_descriptions:
if skill.lower() in jd.lower():
count += 1
return count
def skill_share(job_descriptions, skill, as_percent=True):
"""skill কত অংশ job-এ আছে। as_percent=False দিলে ভগ্নাংশ।"""
n = len(job_descriptions)
if n == 0:
return 0.0
share = count_skill(job_descriptions, skill) / n
return share * 100 if as_percent else share
jds = [
"Python and ML required",
"Python, FastAPI backend",
"SQL data analyst",
]
print(count_skill(jds, "python")) # 2
print(skill_share(jds, "python")) # 66.66...
print(skill_share(jds, "python", False)) # 0.666...
যা লক্ষ্য করবেন: as_percent=True হলো default argument — না দিলে
percent আসে। একটা function আরেকটাকে call করছে (skill_share ভেতরে count_skill) —
এভাবেই ছোট function জোড়া দিয়ে বড় কাজ হয়।
🖼️ ৬. Visual: notebook থেকে package-এ যাত্রা
পর্যায় ১: সব এক file-এ (notebook style)
analyzer.py → data + skill + report সব একসাথে (messy)
পর্যায় ২: function-এ ভাগ
analyzer.py → load_jobs(), count_skill(), make_report()
পর্যায় ৩: module-এ ভাগ (একাধিক file)
data.py → load_jobs()
skills.py → count_skill(), skill_share()
report.py → make_report()
পর্যায় ৪: package (folder)
career_assistant/
__init__.py
data.py
skills.py
report.py
📄 ৭. module: কোড আলাদা file-এ ভাগ করা
# file: skills.py
def count_skill(job_descriptions, skill):
return sum(skill.lower() in jd.lower() for jd in job_descriptions)
# file: main.py (অন্য file থেকে import)
from skills import count_skill
jds = ["Python ML", "SQL only", "Python FastAPI"]
print(count_skill(jds, "python")) # 2
কেন module? একই file হাজার লাইন হলে কেউ পড়তে পারে না। বিষয় অনুযায়ী file-এ ভাগ
করলে team-এর সবাই দ্রুত খুঁজে পায়, আর একটা অংশ বদলালে বাকিটা নিরাপদ থাকে।
📦 ৮. package: folder + __init__.py
অনেকগুলো module একটা folder-এ রাখলে সেটা package হয়। folder-এ একটা (খালি হলেও চলে)
__init__.py থাকলে Python বোঝে এটা একটা package।
career_assistant/
__init__.py # folder-কে package বানায় (খালি হলেও চলে)
data.py # def load_jobs(path): ...
skills.py # def count_skill(...), skill_share(...)
report.py # def make_report(...)
# ব্যবহার (project root থেকে):
# from career_assistant.skills import count_skill
মনে রাখুন: import path সবসময় আপনি কোথা থেকে Python চালাচ্ছেন তার ওপর নির্ভর করে।
junior-দের সবচেয়ে বড় বিভ্রান্তি এখানেই — তাই project root থেকে চালানোর অভ্যাস করুন।
💻 ৯. Code: flagship V1-এর প্রথম কাঠামো
এবার আমরা Bangladesh Tech Career Assistant-এর V1 কাঠামো বানাই।
# career_assistant/data.py
def load_jobs():
"""আপাতত hard-coded; পরে file/DB থেকে আসবে (E06)।"""
return [
{"title": "ML Engineer", "text": "Python, ML, SQL"},
{"title": "Backend Dev", "text": "Python, FastAPI"},
{"title": "Data Analyst", "text": "SQL, Excel"},
]
# career_assistant/skills.py
def count_skill(jobs, skill):
return sum(skill.lower() in j["text"].lower() for j in jobs)
# main.py
from career_assistant.data import load_jobs
from career_assistant.skills import count_skill
def main():
jobs = load_jobs()
for skill in ["python", "sql", "fastapi"]:
c = count_skill(jobs, skill)
print(f"{skill:10s}: {c}/{len(jobs)} jobs")
if __name__ == "__main__":
main()
if __name__ == "__main__": মানে — এই file সরাসরি চালালে main() চলবে,
কিন্তু import করলে চলবে না। এটা Python-এর একটা গুরুত্বপূর্ণ অভ্যাস।
🧪 ১০. Experiment: import ও reuse
উপরের কাঠামো বানিয়ে python3 main.py চালান। তারপর skills.py-তে একটা নতুন
function top_skill(jobs, candidates) যোগ করুন যা সবচেয়ে বেশিবার আসা skill ফেরত দেয় —
এবং main.py-তে import করে ব্যবহার করুন। লক্ষ্য করুন: data.py একটুও বদলাতে হলো না।
👷 ১১. AI Engineer-এর দৃষ্টিকোণ
- ML pipeline = ছোট function-এর chain (load → clean → feature → train → evaluate)।
- ভালো ভাগ করা কোড = সহজ test (Series 02 E08), সহজ debug, সহজ reuse।
- Notebook experiment ঠিক আছে, কিন্তু production কোড সবসময় module/package-এ যায়।
💼 ১২. Boss Question
Boss: "একটা কাজ তো হয়েই গেছে, আবার function-module-package-এ ভাগ করে সময় নষ্ট কেন?"
উত্তর: কারণ ৩ মাস পরে যখন নতুন feature বা bug fix লাগবে, ভালো-ভাগ করা কোডে সেটা
ঘণ্টার কাজ; জগাখিচুড়ি কোডে সপ্তাহের কাজ। ভালো structure = দ্রুত পরিবর্তন, কম bug, নতুন developer
দ্রুত যোগ দিতে পারে — সব সরাসরি খরচ ও সময় বাঁচায়।
🔎 ১৩. Job Requirement Decoder: "Clean, modular, maintainable Python code"
| প্রশ্ন | উত্তর |
| এর মানে কী? | কোড function/module-এ ভাগ করা, DRY, পড়ার মতো — এলোমেলো এক-file script নয়। |
| কোম্পানি কেন চায়? | team-এ অনেকে একসাথে কাজ করে; maintainable কোড ছাড়া project টিকে না। |
| কোন সমস্যা সমাধান করে? | copy-paste bug, বড় file, কঠিন debug, ধীর onboarding। |
| junior-এর কী জানা লাগে? | function লেখা, module-এ ভাগ, import, __main__ guard। |
| এখনই কী master লাগে না? | packaging/publish (PyPI), entry points, namespace package internals। |
| GitHub-এ কীভাবে দেখাবেন? | flagship project-এর পরিষ্কার folder structure + ছোট function। |
| Interview-তে কী? | "module vs package?", "__name__ == '__main__' কেন?", "DRY মানে?" |
⚠️ ১৪. সাধারণ ভুল
ভুল ১: সব কোড এক file-এ — ঠিক: বিষয় অনুযায়ী module-এ ভাগ।
ভুল ২: function-এ mutable default (def f(x=[])) — ঠিক: def f(x=None), ভেতরে x = x or []।
ভুল ৩: একটা function-এ ১০টা কাজ — ঠিক: এক function = এক দায়িত্ব।
ভুল ৪: from module import * — ঠিক: স্পষ্টভাবে যা লাগে তাই import করুন।
🎤 ১৫. Interview Prep
প্রশ্ন ১: module আর package-এর পার্থক্য?
উত্তর: module একটা .py file; package একটা folder যাতে module থাকে (__init__.py সহ)।
প্রশ্ন ২: if __name__ == "__main__": কেন লাগে?
উত্তর: যাতে file সরাসরি চালালে code চলে, কিন্তু import করলে না চলে।
প্রশ্ন ৩: mutable default argument সমস্যা কী?
উত্তর: default একবারই তৈরি হয়, তাই সব call একই object share করে — bug হয়।
প্রশ্ন ৪: DRY মানে?
উত্তর: Don't Repeat Yourself — একই logic বারবার না লিখে function-এ রাখা।
✍️ ১৬. হাতে-কলমে (Mini Exercise)
১. career_assistant/ package বানান data.py, skills.py সহ।
২. skills.py-তে most_common_skill(jobs, candidates) function লিখুন।
৩. main.py থেকে import করে চালান।
৪. একই function-কে দুবার call করে দেখান — কোড repeat করলেন না, শুধু call করলেন।
🚀 ১৭. Project Connection
আজ আমরা flagship V1-এর কঙ্কাল বানালাম: career_assistant package,
ভেতরে data ও skills module। পরের episode-গুলোতে এই package-এ
OOP (E04), file/JSON loading (E06), testing (E08) যোগ হবে, আর E09-তে GitHub-এ publish হবে।
📌 ১৮. সারসংক্ষেপ ও পরবর্তী পর্ব
✓ function = reusable কাজ; DRY নীতি bug কমায়
✓ module = এক .py file; package = module-ভরা folder (__init__.py)
✓ __main__ guard দিয়ে file চালানো vs import আলাদা করা যায়
✓ flagship V1-এর প্রথম package structure দাঁড়াল
পরবর্তী Episode (S02E04): "OOP for ML: Class দিয়ে কেন model, dataset, pipeline লেখা হয়" —
কেন scikit-learn আর PyTorch পুরোটাই class-based, আর আমরা কীভাবে একটা JobPost class বানাব।