Free tutorials & notes in Hindi & English · Clean code examples 🧰 मुफ़्त PDF और फ़ोटो टूल्स →
🏆 Major Project – Churn Prediction  ·  दिन 60

दिन 60: Project 5: App Deploy और Final Report

⏱ 4 hours📶 Major project · Part 5 of 5 🎓🎯 100% self-study
दिन 60 / 60

✅ आज आप सीखेंगे

  • सारे data पर final model फिर train करना
  • कारणों और actions के साथ monthly call list बनाना
  • Streamlit app और JSON API देना
  • Final report और model card लिखना
  • 10 slides और 2 मिनट में project present करना

🏢 असली दुनिया में

Budget मंज़ूर! अगले महीने से retention team आपके model से चुने 600 customers को call करेगी। आज आप इसे ship करेंगे: model file, हर महीने की 1 तारीख़ को चलने वाली scoring script, agents के लिए app, CRM के लिए API, और management को सब समझाने वाली report।

हम क्या ship कर रहे हैं

Customer database (महीने की 1 तारीख़)score_customers.py + churn_model_v1.joblibrisk_list_this_month.csvAgents के लिए Streamlit app · CRM के लिए /score APICalls → नतीजे → monitoring → retrain
Production loop

Step 1: final model और model card

Python – train_final.py
import numpy as np
import pandas as pd

def load_churn(path="telecom_churn.csv"):
    # "None" means no internet plan – stop pandas from turning it into NaN
    df = pd.read_csv(path, keep_default_na=False, na_values=[""])
    df["total_charges"] = df["total_charges"].fillna(df["monthly_charges"] * df["tenure_months"])
    df["churned"] = (df["churn"] == "Yes").astype(int)
    return df

def add_features(df):
    df = df.copy()
    df["tenure_band"] = pd.cut(df["tenure_months"], [0, 6, 12, 24, 48, 72], labels=["0-6", "7-12", "13-24", "25-48", "49-72"]).astype(str)
    df["is_new"] = (df["tenure_months"] <= 6).astype(int)
    df["has_complaint"] = (df["complaints"] > 0).astype(int)
    df["charge_per_gb"] = (df["monthly_charges"] / df["data_usage_gb"].clip(lower=1)).round(2)
    df["avg_monthly_paid"] = (df["total_charges"] / df["tenure_months"]).round(1)
    df["monthly_no_support"] = ((df["contract"] == "Monthly") & (df["tech_support"] == "No")).astype(int)
    return df

# original columns – the champion model uses these
NUM = ["senior_citizen", "tenure_months", "monthly_charges", "total_charges", "complaints", "data_usage_gb"]
CAT = ["gender", "contract", "internet_service", "tech_support", "payment_method"]
# original + engineered columns (tested on Day 58)
NUM_ALL = NUM + ["is_new", "has_complaint", "charge_per_gb", "avg_monthly_paid", "monthly_no_support"]
CAT_ALL = CAT + ["tenure_band"]

import json
import joblib
import sklearn
from sklearn.compose import ColumnTransformer
from sklearn.preprocessing import OneHotEncoder, StandardScaler
from sklearn.pipeline import Pipeline
from sklearn.linear_model import LogisticRegression
from sklearn.model_selection import cross_val_score, StratifiedKFold

df = load_churn()
X, y = df[NUM + CAT], df["churned"]
model = Pipeline([("prep", ColumnTransformer([("num", StandardScaler(), NUM), ("cat", OneHotEncoder(handle_unknown="ignore"), CAT)])),
                  ("clf", LogisticRegression(C=0.1, max_iter=5000))])
cv_auc = cross_val_score(model, X, y, cv=StratifiedKFold(5, shuffle=True, random_state=0), scoring="roc_auc")
model.fit(X, y)                                    # final model uses ALL 3,000 customers
joblib.dump(model, "churn_model_v1.joblib")
card = {"name": "TeleOne churn model", "version": "1.0.0", "algorithm": "logistic regression (C=0.1)",
        "trained_on": f"{len(X)} customers", "features": NUM + CAT,
        "cv_roc_auc": f"{cv_auc.mean():.3f} ± {cv_auc.std():.3f}", "locked_test_roc_auc_day59": 0.832,
        "intended_use": "rank customers for retention calls; not for pricing or credit decisions",
        "monitoring": "monthly PSI on inputs, quarterly AUC on new outcomes, retrain if AUC < 0.78",
        "sklearn_version": sklearn.__version__}
json.dump(card, open("model_card.json", "w", encoding="utf-8"), indent=2, ensure_ascii=False)
print(json.dumps(card, indent=2, ensure_ascii=False))
{ "name": "TeleOne churn model", "version": "1.0.0", "algorithm": "logistic regression (C=0.1)", "trained_on": "3000 customers", "features": [ "senior_citizen", "tenure_months", "monthly_charges", "total_charges", "complaints", "data_usage_gb", "gender", "contract", "internet_service", "tech_support", "payment_method" ], "cv_roc_auc": "0.828 ± 0.015", "locked_test_roc_auc_day59": 0.832, "intended_use": "rank customers for retention calls; not for pricing or credit decisions", "monitoring": "monthly PSI on inputs, quarterly AUC on new outcomes, retrain if AUC < 0.78", "sklearn_version": "1.9.1" }
🧠 सारे data पर फिर train क्यों?

बंद test set ने कल अपना काम कर दिया: उसने बताया कि method कितना अच्छा है। Production के लिए हम चाहते हैं कि model हर customer से सीखे, इसलिए वही pipeline और settings सभी 3,000 rows पर फिर fit करते हैं – कोई नई tuning नहीं।

Step 2: monthly risk list

Python – score_customers.py
import joblib
import numpy as np
import pandas as pd

def load_churn(path="telecom_churn.csv"):
    df = pd.read_csv(path, keep_default_na=False, na_values=[""])
    df["total_charges"] = df["total_charges"].fillna(df["monthly_charges"] * df["tenure_months"])
    return df

model = joblib.load("churn_model_v1.joblib")
pre, clf = model[0], model[-1]
names = pre.get_feature_names_out()

ACTIONS = {"contract_Monthly": "Offer yearly plan at 15% off", "tech_support_No": "Add 3 months free tech support",
           "complaints": "Senior agent callback on open complaints", "tenure_months": "Welcome-back / onboarding help",
           "monthly_charges": "Review plan – suggest a better-value pack", "internet_service_Fiber": "Fiber quality check visit"}

def label(j, Z, mean):
    key = names[j].split("__", 1)[1]
    if names[j].startswith("num__"):
        if key == "senior_citizen":
            return key, "senior citizen"
        return key, ("high " if Z[j] > mean[j] else "short " if key == "tenure_months" else "low ") + key.replace("_", " ")
    return key, key.replace("_", " ", 1).replace("_", " ")

def explain(Z, mean):
    contrib = (Z - mean) * clf.coef_[0]
    top = [label(j, Z, mean) for j in np.argsort(contrib)[::-1][:3] if contrib[j] > 0]
    action = next((ACTIONS[k] for k, _ in top if k in ACTIONS), "Standard loyalty offer")
    return ", ".join(t for _, t in top), action

def monthly_risk_list(customers, capacity=600):
    X = customers[model.feature_names_in_]
    p = model.predict_proba(X)[:, 1]
    Z = pre.transform(X); Z = Z.toarray() if hasattr(Z, "toarray") else Z
    mean = np.asarray(Z.mean(axis=0)).ravel()
    out = customers[["customer_id", "contract", "tenure_months", "monthly_charges"]].copy()
    out["churn_risk"] = p.round(3)
    out["risk_band"] = pd.cut(p, [0, 0.3, 0.6, 1], labels=["Low", "Medium", "High"])
    expl = [explain(Z[i], mean) for i in range(len(out))]
    out["top_reasons"] = [e[0] for e in expl]; out["suggested_action"] = [e[1] for e in expl]
    out["value_at_risk_₹"] = (out["churn_risk"] * out["monthly_charges"] * 12).round(0)
    return out.sort_values("value_at_risk_₹", ascending=False).head(capacity)

active = load_churn().query("churn == 'No'")          # this month: score customers who are still with us
risk = monthly_risk_list(active, capacity=600)
risk.to_csv("risk_list_this_month.csv", index=False)
print(f"Scored {len(active):,} active customers → call list of {len(risk)} saved to risk_list_this_month.csv")
print(risk.head(6).to_string(index=False))
print("\nRisk bands in the call list:", risk["risk_band"].value_counts().to_dict())
hm = risk[risk["risk_band"].isin(["High", "Medium"])]
print(f"High + Medium: {len(hm)} customers | avg risk {hm['churn_risk'].mean():.0%} | value at risk ₹{hm['value_at_risk_₹'].sum() / 1e5:.1f} lakh/yr")
Scored 2,126 active customers → call list of 600 saved to risk_list_this_month.csv customer_id contract tenure_months monthly_charges churn_risk risk_band top_reasons suggested_action value_at_risk_₹ CUST12993 Monthly 23 1336.0 0.851 High high monthly charges, contract Monthly, short tenure months Review plan – suggest a better-value pack 13643.0 CUST10745 Monthly 46 1362.0 0.814 High high complaints, high monthly charges, contract Monthly Senior agent callback on open complaints 13304.0 CUST11822 Monthly 1 1139.0 0.848 High short tenure months, contract Monthly, high monthly charges Welcome-back / onboarding help 11590.0 CUST10268 Monthly 29 1200.0 0.795 High contract Monthly, high monthly charges, high complaints Offer yearly plan at 15% off 11448.0 CUST10672 Monthly 13 1158.0 0.804 High short tenure months, contract Monthly, high monthly charges Welcome-back / onboarding help 11172.0 CUST11505 Monthly 10 1096.0 0.834 High short tenure months, contract Monthly, high monthly charges Welcome-back / onboarding help 10969.0 Risk bands in the call list: {'Medium': 354, 'Low': 137, 'High': 109} High + Medium: 463 customers | avg risk 49% | value at risk ₹22.5 lakh/yr
💼 Value at risk से rank करें

हम सिर्फ़ risk से नहीं, churn risk × सालाना bill से sort करते हैं। 60% risk वाला ₹1,200/महीना customer 70% वाले ₹199 customer से ज़्यादा मायने रखता है। यह एक line model को revenue बचाने के business लक्ष्य से जोड़ती है।

Schedule – run on the 1st of every month (Linux cron)
# crontab -e
0 6 1 * *  cd /opt/teleone-churn && /usr/bin/python3 score_customers.py >> logs/score.log 2>&1

Step 3: retention app

Python – app_retention.py
# app_retention.py – run: streamlit run app_retention.py
import joblib
import pandas as pd
import streamlit as st

st.set_page_config(page_title="TeleOne Retention", page_icon="📞", layout="wide")
model = joblib.load("churn_model_v1.joblib")
st.title("📞 TeleOne – Retention Assistant")
tab1, tab2 = st.tabs(["This month’s call list", "Check one customer"])

with tab1:
    risk = pd.read_csv("risk_list_this_month.csv")
    band = st.multiselect("Risk band", ["High", "Medium", "Low"], default=["High", "Medium"])
    view = risk[risk["risk_band"].isin(band)]
    c1, c2, c3 = st.columns(3)
    c1.metric("Customers to call", len(view))
    c2.metric("Avg risk", f"{view['churn_risk'].mean():.0%}")
    c3.metric("Value at risk", f"₹{view['value_at_risk_₹'].sum() / 1e5:.1f} lakh / yr")
    st.dataframe(view, use_container_width=True, hide_index=True)
    st.download_button("Download CSV for the dialler", view.to_csv(index=False), "call_list.csv")

with tab2:
    a, b = st.columns(2)
    row = {"senior_citizen": int(a.checkbox("Senior citizen")),
           "tenure_months": a.slider("Tenure (months)", 1, 72, 6),
           "monthly_charges": a.number_input("Monthly bill (₹)", 149, 1500, 850),
           "complaints": a.slider("Complaints (last 6 months)", 0, 8, 2),
           "data_usage_gb": a.number_input("Data usage (GB/month)", 0.0, 300.0, 40.0),
           "gender": b.selectbox("Gender", ["Female", "Male"]),
           "contract": b.selectbox("Contract", ["Monthly", "One year", "Two year"]),
           "internet_service": b.selectbox("Internet", ["Fiber", "DSL", "None"]),
           "tech_support": b.selectbox("Tech support", ["No", "Yes", "No internet"]),
           "payment_method": b.selectbox("Payment", ["UPI AutoPay", "Credit Card", "Bank Transfer", "Cash"])}
    row["total_charges"] = row["monthly_charges"] * row["tenure_months"]
    p = model.predict_proba(pd.DataFrame([row]))[0, 1]
    st.metric("Churn risk", f"{p:.0%}")
    st.progress(float(p))
    if p >= 0.6:
        st.error("High risk – call today with a retention offer")
    elif p >= 0.3:
        st.warning("Medium risk – include in this month’s campaign")
    else:
        st.success("Low risk – no action needed")
HTML
<div style="font-family:system-ui,sans-serif;padding:12px;background:#fff">
<h3 style="margin:0 0 8px">📞 TeleOne – Retention Assistant</h3>
<div style="display:flex;gap:6px;margin-bottom:10px"><span style="padding:5px 10px;border-bottom:2px solid #ff4b4b;font-weight:600">This month’s call list</span><span style="padding:5px 10px;color:#6b7280">Check one customer</span></div>
<div style="display:grid;grid-template-columns:repeat(3,1fr);gap:8px;margin-bottom:10px">
<div style="background:#f8fafc;border-radius:8px;padding:8px"><small>Customers to call</small><div style="font-size:22px;font-weight:700">463</div></div>
<div style="background:#f8fafc;border-radius:8px;padding:8px"><small>Avg risk</small><div style="font-size:22px;font-weight:700">49%</div></div>
<div style="background:#f8fafc;border-radius:8px;padding:8px"><small>Value at risk</small><div style="font-size:22px;font-weight:700">₹22.5 lakh / yr</div></div></div>
<table style="width:100%;border-collapse:collapse;font-size:12px"><tr style="background:#f1f5f9"><th align="left">customer</th><th>risk</th><th align="left">top reasons</th><th align="left">suggested action</th></tr>
<tr><td>CUST12993</td><td align="center"><b style="color:#dc2626">85%</b></td><td>high monthly charges, contract Monthly, short tenure</td><td>Review plan – better-value pack</td></tr>
<tr><td>CUST10745</td><td align="center"><b style="color:#dc2626">81%</b></td><td>high complaints, high monthly charges, contract Monthly</td><td>Senior agent callback on complaints</td></tr>
<tr><td>CUST10268</td><td align="center"><b style="color:#dc2626">80%</b></td><td>contract Monthly, high monthly charges, high complaints</td><td>Offer yearly plan at 15% off</td></tr></table>
<button style="margin-top:10px;background:#ff4b4b;color:#fff;border:0;padding:7px 12px;border-radius:8px">Download CSV for the dialler</button></div>
▶  How the Streamlit app looks with this month’s list (High + Medium filter)

Step 4: CRM API

Python – api.py (tested with Flask’s test client)
import joblib, pandas as pd
from flask import Flask, request, jsonify
app = Flask(__name__)
model = joblib.load("churn_model_v1.joblib")
FIELDS = list(model.feature_names_in_)

@app.post("/score")
def score():
    rows = request.get_json(silent=True)
    rows = rows if isinstance(rows, list) else [rows]
    bad = [i for i, r in enumerate(rows) if not isinstance(r, dict) or set(FIELDS) - set(r)]
    if bad:
        return jsonify(error=f"rows {bad} are missing fields", required=FIELDS), 400
    p = model.predict_proba(pd.DataFrame(rows)[FIELDS])[:, 1]
    return jsonify([{"churn_risk": round(float(x), 3), "call": bool(x >= 0.3)} for x in p])

client = app.test_client()
cust = {"senior_citizen": 0, "tenure_months": 3, "monthly_charges": 950, "total_charges": 2850, "complaints": 2,
        "data_usage_gb": 35.0, "gender": "Female", "contract": "Monthly", "internet_service": "Fiber",
        "tech_support": "No", "payment_method": "Cash"}
loyal = dict(cust, tenure_months=60, contract="Two year", tech_support="Yes", complaints=0, total_charges=57000)
r = client.post("/score", json=[cust, loyal]); print(r.status_code, r.get_json())
r = client.post("/score", json={"tenure_months": 5}); print(r.status_code, r.get_json()["error"])
200 [{'call': True, 'churn_risk': 0.904}, {'call': False, 'churn_risk': 0.033}] 400 rows [0] are missing fields

Step 5: GitHub repository

Project structure
teleone-churn/
├── README.md                ← business summary first (template below)
├── PROJECT_CHARTER.md       ← Day 56
├── requirements.txt
├── data/sample_customers.csv
├── notebooks/
│   ├── 01_problem_and_audit.ipynb      (Day 56)
│   ├── 02_eda_insights.ipynb           (Day 57)
│   ├── 03_features_models.ipynb        (Day 58)
│   └── 04_evaluation_impact.ipynb      (Day 59)
├── src/  churn.py  (load_churn, add_features, make_model)
├── train_final.py   score_customers.py   api.py   app_retention.py
├── models/  churn_model_v1.joblib   model_card.json
└── reports/ figures/   final_report.md   slides.pdf

Step 6: final report

Markdown – reports/final_report.md
# TeleOne Churn Prediction – Final Report

## 1. Problem
29% of customers churned, taking ≈ ₹6.6 lakh of monthly revenue (≈ ₹80 lakh a year).
The retention team can call ~600 customers a month and needs to know whom to call and why.

## 2. What drives churn (EDA, Day 57)
- Monthly contracts churn ~44% vs ~9% for two-year contracts (largest effect).
- First 6 months, multiple complaints, no tech support and Fiber plans raise risk.
- Gender has no effect; payment method differences were not significant.

## 3. Model (Days 58–59)
- Logistic regression on the 11 original columns (engineered features added nothing).
- 5-fold CV ROC-AUC ≈ 0.82; locked test ROC-AUC 0.83 – no sign of leakage or overfitting.
- Well calibrated; similar performance for women and men.

## 4. Business impact (agreed assumptions)
- Calling the top 20% reaches 2.3× more churners than random calling.
- Expected net ≈ ₹12 lakh per monthly campaign vs ≈ ₹3 lakh for random calls.

## 5. Recommendations
1. Use the monthly risk list (sorted by value at risk) for retention calls.
2. Bundle free tech support for monthly Fiber customers; push yearly-plan upgrades.
3. Run a 2-month A/B pilot (call vs hold-out) to measure the real save-rate.
4. Monitor input drift monthly; retrain when AUC on new outcomes < 0.78.

## 6. Limitations
Simulated data, single snapshot, save-rate and offer acceptance are assumptions.

Step 7: present करें

Slideसामग्री
1Title + एक line नतीजा: “उन्हीं calls से 2.3× ज़्यादा churners तक पहुँचें”
2₹ में समस्या: 29% churn, साल में ₹80 lakh
3कौन churn करता है: contract × tenure heatmap
4Top 5 drivers (lift chart)
5तरीका: data → model → risk list (एक diagram)
6Model quality: test AUC, gains chart
7Business impact: model vs random calling
8Demo: retention app
9सुझाव + A/B pilot plan
10सीमाएँ, monitoring, अगले कदम
Your 2-minute interview pitch
“TeleOne was losing 29% of its customers – about ₹80 lakh a year – and the retention
team could only call 600 people a month. I framed it as a classification problem, audited
the data (and caught a silent NaN bug), and found in EDA that monthly contracts, the first
six months, complaints and missing tech support drive churn.
I compared five models with cross-validation; plain logistic regression won with AUC 0.83
on a locked test set, and my engineered features did not help, so I kept it simple.
Using agreed costs, calling the top 20% reaches 2.3× more churners than random calls –
about ₹12 lakh net per campaign. I shipped a monthly risk list with reasons and suggested
offers, a Streamlit app for agents and a Flask API, and proposed an A/B pilot to measure
the real save-rate.”

आपने कर दिखाया 🎓

🐍
Python और pandasDays 1–20: variables से पूरे EDA project तक।
📊
Visual storytellingDays 21–25: Matplotlib, Seaborn, Plotly, dashboards।
📐
Statistics और SQLDays 26–35: tests, A/B experiments, joins, windows।
🤖
Machine learningDays 36–51: regression से neural networks तक, deploy किए।
💼
Job-readyDays 52–60: Excel, Power BI, Git, resume, interviews और major project।
60 दिन, एक पूरा data-science toolkit
🚀 आगे क्या?

इस project को public dataset (Kaggle पर IBM Telco churn) या अपने domain पर दोहराएँ, README और app के साथ GitHub पर publish करें, हर हफ़्ते LinkedIn पर एक insight post करें, और Day 54 की योजना से apply करना शुरू करें। बनाते रहें – हर महीने एक छोटा project आपकी skills तेज़ रखता है।

🏅 आज के Job Skills

✔ Production model फिर train करके version करना✔ Actionable, value-ranked risk list बनाना✔ Streamlit app और JSON API देना✔ Final report लिखकर data project present करना

Practice tasks

🏋️ Practice – ख़ुद करें

Task 1: Risk list में हर customer के लिए “क्यों” वाक्य जोड़ें, जैसे “Monthly plan, सिर्फ़ 3 महीने, 2 complaints”।
Task 2: अगला महीना simulate करें: हर active customer का tenure 1 बढ़ाकर फिर score करें। कितने customers का risk band बदलता है?
Solution देखें
Python
import joblib, pandas as pd
m = joblib.load("churn_model_v1.joblib")
df = pd.read_csv("telecom_churn.csv", keep_default_na=False, na_values=[""]).query("churn == 'No'").copy()
df["total_charges"] = df["total_charges"].fillna(df["monthly_charges"] * df["tenure_months"])
band = lambda p: pd.cut(p, [0, 0.3, 0.6, 1], labels=["Low", "Medium", "High"])
now = band(m.predict_proba(df[m.feature_names_in_])[:, 1])
df["tenure_months"] = (df["tenure_months"] + 1).clip(upper=72); df["total_charges"] += df["monthly_charges"]
later = band(m.predict_proba(df[m.feature_names_in_])[:, 1])
print((now != later).sum(), "customers change band;", pd.crosstab(now, later))
19 customers change band; col_0 Low Medium High row_0 Low 1589 0 0 Medium 14 414 0 High 0 5 104
Task 3: अपना 2-मिनट pitch record करें, repository publish करें और link LinkedIn पर share करें।

Quick quiz

🧠 Quick Quiz – ख़ुद को जाँचें

1. Call list को risk की जगह value at risk से sort क्यों करें?
Risk × सालाना bill।
2. Final production model किस पर train होता है?
कोई नई tuning नहीं।
3. Model card में क्या होना चाहिए?
Users और auditors के लिए documentation।
4. Project presentation की सबसे अच्छी पहली slide?
जवाब से शुरू करें।
5. असली save-rate कैसे पता चलेगा?
मापें, मानें नहीं।

Interview corner

💼 Interview Corner

अपना end-to-end project बताइए।

ऊपर वाला 2-मिनट pitch: rupees में समस्या, data audit, मुख्य EDA drivers, ईमानदार model तुलना (सरल model जीता), test AUC 0.83, business impact 2.3× ज़्यादा churners, risk list + app + API दिए, और अगला कदम A/B pilot।

ज़्यादा समय या data होता तो क्या अलग करते?

Time-to-churn model करने के लिए कई monthly snapshots लेते, experiments से offer uplift मापते (uplift modelling), usage और support-ticket text features जोड़ते, ज़्यादा data पर boosting से फिर तुलना करते, और monitoring alerts के साथ retraining automate करते।

सारांश

  • Final model सारे data पर फिर train, model card के साथ version किया।
  • Value at risk से ranked monthly risk list, कारणों और actions के साथ।
  • Agents के लिए Streamlit app, CRM के लिए Flask API।
  • Report + 10-slide deck + 2-मिनट pitch = job-ready portfolio project।
  • 60-दिन का Data Science course पूरा करने पर बधाई! 🎉
➡️ आगे

Course पूरा! आगे: हमारे HTML, CSS और JavaScript day-wise courses से websites बनाएँ।

अक्सर पूछे जाने वाले प्रश्न (FAQ)

क्या यह project resume पर डाल सकता हूँ?
हाँ – इसे portfolio का मुख्य project बनने के लिए ही design किया गया है। नाम बदलें, अपने extensions जोड़ें (A/B pilot design, नया dataset) और live app का link दें।
सारा code और datasets कहाँ से download करूँ?
Login करके इस course page पर “Datasets + पूरा Code Download” button लें – इसमें हर dataset और हर दिन का code चलाने लायक files में है।
← Data Science (60 Days)
🔗

Share this topic with a friend

यह topic किसी दोस्त को भेजें

Found it useful? Send it to a classmate learning the same thing.

अच्छा लगा? जो दोस्त यही सीख रहा है, उसे भेज दीजिए।

Course पूरा! आगे सीखेंMySQL + DBMS + RDBMS आपकी प्रगति: 60 / 60 (100%) · अगला course आगे बढ़ें →

यह lesson कैसा लगा?

आपकी राय से हम content और बेहतर बनाते हैं।

अपना review और सुझाव लिखें (वैकल्पिक)

Review approve होने के बाद आपका नाम और शहर इसके साथ public दिख सकते हैं। Email या phone न लिखें।

▶ CodingEasily on YouTube

Video से सीखें – आसान Hindi में

चुनी हुई video: RDBMS भाग 3 – Class XI Commerce IT

▶ Channel subscribe करें