অধ্যায় 6 · অনুশীলন ও ক্যাপস্টোন
ক্যাপস্টোন প্রজেক্ট, চিট শিট আর এরপর কী
- পৃষ্ঠা 22 / 22
- 11 মিনিট পড়া
AI সিস্টেমে ডেটা নিয়ে কাজের পুরো স্তরটাই আপনি পেরিয়ে এসেছেন: অ্যাডভান্সড কোয়েরি, মজবুত ডিজাইন, ট্রানজ্যাকশন আর পারফরম্যান্স, ডেটাবেস ঘিরে Python আর pandas, পরিষ্কার ও যাচাই করা ডেটা, পাইপলাইন, ML-এর উপযোগী ডেটাসেট, LLM অ্যাপের ডেটা লেয়ার, আর তাদের চারপাশের অ্যানালিটিক্যাল সিস্টেম। জ্ঞান দক্ষতা হয়ে ওঠে তখনই, যখন শুরু থেকে শেষ পর্যন্ত কিছু একটা বানান — আসল সিদ্ধান্ত আর আসল ভুলসহ। এই শেষ পাতা ঠিক সেজন্য চারটা ক্যাপস্টোন প্রজেক্ট দেয়, অ্যাডভান্সড টিউটোরিয়ালের এক পাতার একটা চিট শিট দেয়, আর দেখায় AI পথে সামনে কী।
যা শিখবেন
- চারটা ক্যাপস্টোন ব্রিফ — ডেটা পরিষ্কার, ETL পাইপলাইন, ML ডেটাসেট বিল্ডার, অ্যানালিটিক্স ওয়্যারহাউস — চাহিদা, ধাপ (মাইলস্টোন) আর চেকলিস্টসহ
- একটা ডেটা প্রজেক্টকে পোর্টফোলিওর উপযোগী করে কী
- অ্যাডভান্সড টিউটোরিয়ালের সিনট্যাক্স আর প্যাটার্নের একটা চিট শিট
- SQL আর ডেটা হ্যান্ডলিং এরপর কোথায় নিয়ে যায়: API, প্রম্পট ইঞ্জিনিয়ারিং, এমবেডিং, ভেক্টর ডেটাবেস আর RAG
ক্যাপস্টোনগুলো কীভাবে করবেন
একটা বা দুটো বেছে নিন; প্রতিটায় কয়েক সন্ধ্যা লাগে। একটা Git রিপোজিটরিতে README.md-সহ কাজ করুন, গোপন তথ্য এনভায়রনমেন্ট ভেরিয়েবলে রাখুন, আর প্রতিটা রান পুনরুৎপাদনযোগ্য রাখুন: একটা কমান্ডেই কাঁচা ইনপুট থেকে সবকিছু আবার তৈরি হবে। শুরু করুন SQLite দিয়ে; প্রজেক্টের দরকার হলে PostgreSQL-এ (Docker) যান। প্রতিটা ব্রিফে কোন পাতাগুলো আবার দেখবেন তা লেখা আছে। (প্রজেক্ট ১ ছিল বিগিনার টিউটোরিয়ালের শেষে প্রজেক্ট: BitByte Shop-এর বিক্রয় বিশ্লেষণ রিপোর্ট, তাই এখানে নম্বর শুরু ২ থেকে।)
প্রজেক্ট ২: অগোছালো ডেটার ক্লিনার
লক্ষ্য: একটা অগোছালো এক্সপোর্টকে পরিষ্কার, যাচাই করা টেবিল আর একটা ডেটা-মানের রিপোর্টে বদলানো। আবার দেখুন: ডেটা হ্যান্ডলিংয়ের মূল কথা: ফরম্যাট, মান আর উৎস, pandas দিয়ে ডেটা পরিষ্কার, ইমপোর্ট ও এক্সপোর্ট: CSV, JSON, Excel আর Parquet।
- ইনপুট: ১,০০০+ অর্ডারের একটা CSV, যা আপনি seed দিয়ে জেনারেট করে তারপর ইচ্ছে করে নষ্ট করবেন: মিশ্র তারিখের ফরম্যাট, "৳" আর কমাসহ লেখা হিসেবে দাম, ডুপ্লিকেট সারি, শহরের নামের অসংগত বানান ("Dhaka", "dhaka ", "DHK"), মিসিং ভ্যালু, অসম্ভব পরিমাণ, UTF-8-এ বাংলা নাম।
- চাহিদা: পুনর্ব্যবহারযোগ্য একটা
clean(df)ফাংশন; একটা নিয়মের ফাইল (অনুমোদিত শহর, মানের সীমা); বাতিল সারি কারণসহ একটা কোয়ারেন্টাইন ফাইলে; আউটপুট Parquet-এ আর কনস্ট্রেইন্টসহ একটা SQLite টেবিলে; প্রতিটা নিয়মের আগে/পরের সংখ্যার একটা রিপোর্ট। - ধাপ: (১) জেনারেটর আর প্রোফাইলিং, (২) টেস্টসহ পরিষ্কারের নিয়ম, (৩) কোয়ারেন্টাইন আর রিপোর্ট, (৪) ডেটাবেসে লোড আর কনস্ট্রেইন্ট টিকে আছে তার প্রমাণ।
প্রজেক্ট ৩: একটা আইডেমপোটেন্ট ETL পাইপলাইন
লক্ষ্য: একটা অপারেশনাল ডেটাবেস আর একটা "API" থেকে ডেটা নিরাপদে আর বারবার একই ফলে একটা অ্যানালিটিক্স ডেটাবেসে নেওয়া। আবার দেখুন: ETL ও ELT: নির্ভরযোগ্য ডেটা পাইপলাইন বানানো, Python ও ডেটাবেস: কানেকশন, প্যারামিটার আর ট্রানজ্যাকশন, ট্রানজ্যাকশন, ACID, আইসোলেশন আর লকিং।
- ইনপুট: শপের ডেটাবেস (বা জেনারেট করা বড় একটা), সাথে পেমেন্ট API-এর বদলি হিসেবে JSON ফাইলের একটা ফোল্ডার।
- চাহিদা: extract, transform আর load আলাদা ফাংশনে; একটা ওয়াটারমার্ক টেবিল দিয়ে ইনক্রিমেন্টাল লোড; আপসার্ট, যাতে দ্বিতীয় রানে কিছুই না বদলায়; প্রতিটা লোড একটা ট্রানজ্যাকশনে; সারির সংখ্যাসহ লগ; "API"-এর চারপাশে ব্যাকঅফসহ রিট্রাই; একটা মিলিয়ে দেখার ধাপ (উৎস বনাম গন্তব্যের count আর sum), যা না মিললে রানটা ব্যর্থ করে।
- ধাপ: (১) পূর্ণ লোড, (২) ওয়াটারমার্কসহ ইনক্রিমেন্টাল লোড, (৩) আইডেমপোটেন্সির টেস্ট: দুবার চালিয়ে তুলনা, (৪) ব্যর্থতার টেস্ট: মাঝপথে বন্ধ করে আবার চালান, কিছুই ডুপ্লিকেট হবে না।
প্রজেক্ট ৪: একটা ML ডেটাসেট বিল্ডার
লক্ষ্য: এমন একটা কমান্ড, যা লিকমুক্ত, ভার্সন করা একটা ট্রেনিং সেট বানায় আর একটা বেসলাইন মডেল ট্রেন করে। আবার দেখুন: SQL ও pandas দিয়ে ML-এর উপযোগী ডেটা তৈরি, উইন্ডো ফাংশন ২: LAG, LEAD, রানিং টোটাল আর ফ্রেম, pandas ও SQLAlchemy: SQL থেকে DataFrame, DataFrame থেকে SQL।
- ইনপুট: seed দিয়ে জেনারেট করা গ্রাহক/অ্যাক্টিভিটির একটা ডেটাবেস (গ্রাহক, অর্ডার, সাপোর্ট টিকিট, অ্যাপ সেশন)।
- চাহিদা: কাটঅফ তারিখের প্যারামিটারসহ ফিচার SQL; স্পষ্ট পপুলেশন আর লেবেল উইন্ডো; দুই বা ততোধিক উৎস থেকে অন্তত দশটা ফিচার; কয়েকটা কাটঅফের স্ন্যাপশট Parquet-এ, একটা ম্যানিফেস্টসহ (seed, কোয়েরির ভার্সন, সারির সংখ্যা, কনটেন্টের হ্যাশ); স্বয়ংক্রিয় পয়েন্ট-ইন-টাইম চেক; সময় ধরে ভাগ; ইমপিউটেশন, স্কেলিং আর এনকোডিংসহ একটা scikit-learn পাইপলাইন; সংখ্যাগরিষ্ঠ বেসলাইনের পাশে মেট্রিকের রিপোর্ট; README-তে লেখা একটা ইচ্ছাকৃত লিকের পরীক্ষা।
- ধাপ: (১) জেনারেটর, (২) টেস্টসহ একটা সঠিক স্ন্যাপশট, (৩) একাধিক স্ন্যাপশট আর ম্যানিফেস্ট, (৪) মডেল আর রিপোর্ট।
প্রজেক্ট ৫: ছোট একটা অ্যানালিটিক্স ওয়্যারহাউস
লক্ষ্য: ইতিহাসসহ একটা স্টার স্কিমা, একটা পাইপলাইন যা লোড করে, আর যা ব্যবসার প্রশ্নের উত্তর দ্রুত দেয়। আবার দেখুন: ওয়্যারহাউস, লেক, স্ট্রিম আর স্কেল, ইনডেক্স: কীভাবে কাজ করে আর কখন কাজে লাগে, EXPLAIN আর কোয়েরি অপ্টিমাইজেশন, ভিউ, স্টোরড প্রসিডিওর, ফাংশন আর ট্রিগার।
- ইনপুট: প্রজেক্ট ৩-এর আউটপুট, বা শপ আর জেনারেট করা এক বছরের অর্ডার।
- চাহিদা: ঘোষিত গ্রেইন; জেনারেট করা তারিখের ডাইমেনশন; পয়েন্ট-ইন-টাইম ফ্যাক্ট লোডসহ টাইপ ২ গ্রাহক ডাইমেনশন; ভিউ হিসেবে রাখা অন্তত আটটা রিপোর্ট কোয়েরি (মাসিক আয় আর গ্রোথ, কোহর্ট রিটেনশন, প্রতি ক্যাটাগরিতে সেরা N, পেমেন্টের মিশ্রণ…);
EXPLAINপ্ল্যান দিয়ে যুক্তি দেখানো ইনডেক্স; PostgreSQL-এ একটা পার্টিশন করা ফ্যাক্ট টেবিল আর ড্যাশবোর্ডের জন্য একটা ম্যাটেরিয়ালাইজড ভিউ; অ্যানালিস্টদের জন্য শুধু পড়ার (read-only) একটা রোল। - ধাপ: (১) ডাইমেনশনাল মডেলের ডায়াগ্রাম, (২) SCD টাইপ ২-সহ লোডিং, (৩) উৎসের সাথে মিলিয়ে দেখা রিপোর্ট ভিউ, (৪) পারফরম্যান্স আর নিরাপত্তার পর্ব।
পোর্টফোলিওর চেকলিস্ট
| দিক | সম্পন্ন যখন… |
|---|---|
| পুনরুৎপাদনযোগ্য | একটা কমান্ড কাঁচা ইনপুট থেকে আউটপুট আবার বানায়; র্যান্ডম জেনারেটরে seed দেওয়া; ভার্সন পিন করা (requirements.txt) |
| সঠিক | টোটাল উৎসের সাথে মেলে; টেস্টে NULL, ডুপ্লিকেট, ফাঁকা ইনপুট আর দ্বিতীয়বার চালানোর ক্ষেত্র ধরা আছে |
| নিরাপদ | সব জায়গায় প্যারামিটার (স্ট্রিং জুড়ে SQL নয়); ক্রেডেনশিয়াল শুধু এনভায়রনমেন্ট ভেরিয়েবলে; PII মাস্ক করা বা বাদ |
| ব্যাখ্যা করা | README-তে সমস্যা, স্কিমার ডায়াগ্রাম, কীভাবে চালাবেন, ফলাফল আর ট্রেড-অফ; কমেন্ট বলে কেন, কী নয় |
| মাপা | সারির সংখ্যা আর সময় লগ করা; ধীর কোয়েরি EXPLAIN দিয়ে দেখা |
অ্যাডভান্সড চিট শিট
কোয়েরি
| প্যাটার্ন | সিনট্যাক্স |
|---|---|
| CTE | WITH t AS (SELECT …) SELECT … FROM t |
| রিকার্সিভ CTE | WITH RECURSIVE n(x) AS (SELECT 1 UNION ALL SELECT x + 1 FROM n WHERE x < 10) … |
| র্যাঙ্কিং | ROW_NUMBER() / RANK() / DENSE_RANK() OVER (PARTITION BY g ORDER BY v DESC) |
| প্রতি দলে সেরা N | CTE-তে র্যাঙ্ক, তারপর বাইরে WHERE rn <= N |
| আগের / পরের সারি | LAG(v) OVER (ORDER BY d), LEAD(v, 1, 0) OVER (…) |
| রানিং টোটাল / মুভিং অ্যাভারেজ | SUM(v) OVER (ORDER BY d), AVG(v) OVER (ORDER BY d ROWS BETWEEN 6 PRECEDING AND CURRENT ROW) |
| মোটের অংশ | 100.0 * v / SUM(v) OVER (PARTITION BY g) |
| গ্যাপ আর আইল্যান্ড | গ্রুপের কি হিসেবে julianday(d) - ROW_NUMBER() OVER (PARTITION BY u ORDER BY d) |
| অ্যান্টি-জয়েন | WHERE NOT EXISTS (SELECT 1 FROM b WHERE b.k = a.k) |
| ফ্যান-আউট এড়ানো | প্রতিটা চাইল্ড টেবিল একটা CTE-তে কি ধরে অ্যাগ্রিগেট, তারপর জয়েন |
ডিজাইন, শুদ্ধতা আর পারফরম্যান্স
| কাজ | সিনট্যাক্স |
|---|---|
| ট্রানজ্যাকশন | BEGIN; … COMMIT; / ROLLBACK;, SAVEPOINT s; ROLLBACK TO s; |
| নিরাপদে কমানো | UPDATE products SET stock = stock - 1 WHERE product_id = ? AND stock > 0 |
| সারি লক | SELECT … FOR UPDATE (PostgreSQL, MySQL) |
| আপসার্ট | INSERT … ON CONFLICT (k) DO UPDATE SET v = excluded.v; MySQL: ON DUPLICATE KEY UPDATE |
| ইনডেক্স | CREATE INDEX idx ON t (a, b) — বাঁ দিকের কলাম আগে; নিয়মের জন্য UNIQUE |
| প্ল্যান | EXPLAIN QUERY PLAN … (SQLite), EXPLAIN ANALYZE … (PostgreSQL, MySQL 8) |
| sargable তারিখের ফিল্টার | d >= '2026-03-01' AND d < '2026-04-01', কলামের ওপর কখনো ফাংশন নয় |
| ভিউ / ম্যাটেরিয়ালাইজড ভিউ | CREATE VIEW v AS …; CREATE MATERIALIZED VIEW mv AS …; REFRESH MATERIALIZED VIEW mv; |
| ট্রিগার | CREATE TRIGGER t AFTER UPDATE ON x FOR EACH ROW BEGIN … END; (SQLite) |
| ন্যূনতম অধিকার | GRANT SELECT ON v TO analyst;, REVOKE … |
| পার্টিশনিং | CREATE TABLE t (…) PARTITION BY RANGE (d); + PARTITION OF t FOR VALUES FROM … TO … |
Python, ডেটা আর AI
| কাজ | সিনট্যাক্স |
|---|---|
| প্যারামিটার | cur.execute("… WHERE id = ?", (x,)) (sqlite3), %s (psycopg2, psycopg 3, PyMySQL) |
| একসাথে অনেক INSERT | cur.executemany(sql, rows); PostgreSQL COPY, MySQL LOAD DATA |
| pandas | pd.read_sql(sql, con, params=…), df.to_sql("t", con, if_exists="append", index=False) |
| SQLAlchemy | engine = create_engine(url); with engine.begin() as c: c.execute(text(sql), {"k": v}) |
| পয়েন্ট-ইন-টাইম ফিচার | প্রতিটা উৎস < :cutoff দিয়ে ফিল্টার; লেবেল [cutoff, cutoff + window) থেকে |
| SCD টাইপ ২ জয়েন | ON d.id = f.id AND f.date >= d.valid_from AND f.date < d.valid_to |
| JSON | SQLite json_extract(j, '$.k'), json_each; PostgreSQL j ->> 'k', j @> '{"k": 1}' |
| ফুল-টেক্সট সার্চ | SQLite CREATE VIRTUAL TABLE f USING fts5(body); WHERE f MATCH 'word' ORDER BY rank (BM25, যত কম তত ভালো); PostgreSQL to_tsvector('english', body) @@ plainto_tsquery('english', 'word'), ts_rank, GIN ইনডেক্স |
| pgvector | CREATE EXTENSION vector; embedding vector(768); ORDER BY embedding <=> :q LIMIT 5 (কোসাইন; <-> L2, <#> ঋণাত্মক ইনার প্রোডাক্ট); USING hnsw (embedding vector_cosine_ops); রিকলের জন্য SET hnsw.ef_search |
| টেক্সট-টু-SQL গার্ড | শুধু পড়ার (read-only) রোল, অনুমোদিত টেবিল/ভিউ, একটাই স্টেটমেন্ট, সারির সীমা, statement_timeout, লগ |
AI পথে এরপর কী
এই বিষয় দিয়ে Level 0-এর ডেটার ভিত্তি শেষ হলো। এরপর যা আসে, তা সরাসরি এর ওপর দাঁড়ায়:
Level 0 (এখন) এরপর পথ ১: AI ইঞ্জিনিয়ার
AI কীভাবে কাজ করে · Python · ──▶ API: ডিজাইন আর ব্যবহার ──▶ এমবেডিং → ভেক্টর ডেটাবেস
গণিত · SQL ও ডেটা প্রম্পট ইঞ্জিনিয়ারিং (pgvector ও অন্যরা) → RAG
→ মূল্যায়ন আর মনিটরিং- API: আপনার SQL আর pandas-এর কাজ হয়ে উঠবে একটা সার্ভিস (ডেটাবেসের ওপর FastAPI), এখানে শেখা প্যারামিটার, ট্রানজ্যাকশন আর নিরাপত্তাসহ।
- প্রম্পট ইঞ্জিনিয়ারিং: AI অ্যাপের জন্য SQL: এমবেডিং, pgvector আর RAG মেটাডেটা-র কথোপকথন আর খরচের লগ হয়ে উঠবে প্রম্পট তুলনার মূল্যায়ন সেট।
- পথ ১: এমবেডিং, ভেক্টর ডেটাবেস আর RAG
documents/chunksটেবিল আর হাইব্রিড সার্চকে অনেক দূর নিয়ে যায় — চাঙ্কিং কৌশল, রির্যাঙ্কার, মূল্যায়ন — ঠিক সেই PostgreSQL আর pgvector-এর ভিত্তিতেই, যা আপনি ব্যবহার করেছেন।
প্রতি সপ্তাহে SQL চর্চা চালিয়ে যান: ইন্টারভিউয়ের সমস্যাগুলো PostgreSQL বা MySQL-এ আবার সমাধান করুন, পাবলিক ডেটাসেট (সরকারি খোলা ডেটা, Kaggle) DuckDB বা PostgreSQL-এ চেষ্টা করুন, আর ধীর সবকিছুর কোয়েরি প্ল্যান পড়ুন।
সাধারণ ভুল
- যে প্রজেক্ট শুধু আপনার ল্যাপটপেই চলে। হার্ড-কোড করা পাথ আর পাসওয়ার্ড, seed ছাড়া জেনারেটর। সমাধান: এনভায়রনমেন্ট ভেরিয়েবল, আপেক্ষিক পাথ, seed আর এক কমান্ডের রান স্ক্রিপ্ট।
- শুধু সব ঠিকঠাক চলার পথ (happy path)। পরিষ্কার ডেটায় একবার পরখ করা পাইপলাইন। সমাধান: ফাঁকা ইনপুট, ডুপ্লিকেট, NULL, আবার চালানো আর মাঝপথে ক্র্যাশের টেস্ট।
- যে ফলাফল কেউ যাচাই করতে পারে না। মিলিয়ে দেখা ছাড়া ড্যাশবোর্ডের একটা সংখ্যা। সমাধান: প্রতিটা আউটপুটকে উৎসের একটা সাধারণ count বা sum-এর সাথে মিলিয়ে প্রিন্ট করুন।
- খুব তাড়াতাড়ি খুব বড়। ১০,০০০ সারির জন্য Spark আর Kafka। সমাধান: মাপা কোনো সীমা বাধ্য না করা পর্যন্ত SQLite বা DuckDB।
নিজে চেষ্টা করুন
- সহজ:
ROW_NUMBERদিয়ে প্রত্যেক গ্রাহকের সবচেয়ে সাম্প্রতিক অর্ডার (ID আর তারিখ) দেখান। - মাঝারি: প্রতিটা ক্যাপস্টোনে যে মিলিয়ে দেখার চেক লাগে, তা লিখুন: delivered আর shipped অর্ডারের
order_items-এর মোট দাম তাদের পেমেন্টের মোটের সাথে তুলনা করুন, আরOKবা পার্থক্যটা প্রিন্ট করুন। - কঠিন:
manifest_for(df, name, seed)লিখুন: এটা একটা ডিকশনারি ফেরত দেবে, যাতে থাকবে নাম, সারির সংখ্যা, কলামের নাম, seed, আর DataFrame-এর CSV লেখার SHA-256 হ্যাশের প্রথম ১৬টা অক্ষর।pd.read_sqlদিয়ে পড়া delivered অর্ডারে পরখ করে JSON হিসেবে প্রিন্ট করুন।
উত্তর
-- ১.
WITH ranked AS (
SELECT customer_id, order_id, order_date,
ROW_NUMBER() OVER (PARTITION BY customer_id ORDER BY order_date DESC, order_id DESC) AS rn
FROM orders
)
SELECT customer_id, order_id, order_date
FROM ranked
WHERE rn = 1
ORDER BY customer_id;+-------------+----------+------------+
| customer_id | order_id | order_date |
+-------------+----------+------------+
| 1 | 10 | 2026-04-19 |
| 2 | 12 | 2026-05-21 |
| 3 | 14 | 2026-06-09 |
| 4 | 5 | 2026-02-25 |
| 5 | 7 | 2026-03-15 |
| 6 | 13 | 2026-06-02 |
| 7 | 11 | 2026-05-06 |
+-------------+----------+------------+# ২ আর ৩.
import hashlib
import json
import pandas as pd
from sqlhelp import con
items, paid = con.execute("""
SELECT (SELECT SUM(oi.quantity * oi.unit_price)
FROM order_items AS oi JOIN orders AS o ON o.order_id = oi.order_id
WHERE o.status IN ('delivered', 'shipped')),
(SELECT SUM(p.amount)
FROM payments AS p JOIN orders AS o ON o.order_id = p.order_id
WHERE o.status IN ('delivered', 'shipped'))
""").fetchone()
print("OK" if items == paid else f"difference: {items - paid}")
def manifest_for(df, name, seed):
digest = hashlib.sha256(df.to_csv(index=False).encode()).hexdigest()[:16]
return {"name": name, "rows": len(df), "columns": list(df.columns), "seed": seed, "sha256_16": digest}
delivered = pd.read_sql("SELECT * FROM orders WHERE status = 'delivered' ORDER BY order_id", con)
print(json.dumps(manifest_for(delivered, "delivered_orders", seed=None)))OK
{"name": "delivered_orders", "rows": 11, "columns": ["order_id", "customer_id", "order_date", "status"], "seed": null, "sha256_16": "af73a7877a5c2153"}সারসংক্ষেপ
- চারটা ক্যাপস্টোন — ক্লিনার, ETL পাইপলাইন, ML ডেটাসেট বিল্ডার, ওয়্যারহাউস — অ্যাডভান্সড টিউটোরিয়ালকে পোর্টফোলিওর কাজে রূপ দেয়।
- পোর্টফোলিওর উপযোগী মানে পুনরুৎপাদনযোগ্য, সঠিক (মিলিয়ে দেখা আর টেস্ট করা), নিরাপদ, ব্যাখ্যা করা আর মাপা।
- চিট শিটে প্যাটার্নগুলো একসাথে: CTE আর উইন্ডো, ট্রানজ্যাকশন আর ইনডেক্স, প্যারামিটার আর pandas, পয়েন্ট-ইন-টাইম ফিচার, JSON, ফুল-টেক্সট আর ভেক্টর সার্চ।
- AI পথ চলতে থাকে API আর প্রম্পট ইঞ্জিনিয়ারিং দিয়ে, তারপর এমবেডিং, ভেক্টর ডেটাবেস আর RAG — সবই এই বিষয়ের ডেটার দক্ষতার ওপর দাঁড়িয়ে।
এরপর: এখানেই AI-এর জন্য SQL ও ডেটা হ্যান্ডলিং: অ্যাডভান্সড শেষ। নিজেকে যাচাই করতে কোর্সের পরীক্ষা দিন, একটা ক্যাপস্টোন বেছে নিন, আর AI পথে এগিয়ে যান API আর প্রম্পট ইঞ্জিনিয়ারিং দিয়ে।