Issue 2 – Loan Terms & Cashflow EDA with OOP + Per-Column Functional Summary
Goal
Analyze how loan terms and cashflows behave and how they relate to loan_status.
You must use:
- OOP: create a class that encapsulates loan-terms EDA.
- Functional programming: build a per-column numeric summary using a dict comprehension or
map.
Columns in scope
You are responsible for the following columns:
Loan structure & pricing
loan_amnt
funded_amnt
funded_amnt_inv
term
int_rate
installment
grade
sub_grade
initial_list_status
Cashflow / lifecycle
out_prncp
out_prncp_inv
total_pymnt
total_pymnt_inv
total_rec_prncp
total_rec_int
total_rec_late_fee
recoveries
collection_recovery_fee
last_pymnt_d
last_pymnt_amnt
next_pymnt_d
Shared target
loan_status (used for default-rate calculations)
Files to edit
src/eda_loan_terms.py
notebooks/eda_loan_terms_demo.ipynb
1. Implement the LoanTermsEDA class
In src/eda_loan_terms.py, create and implement:
"""
import pandas as pd
from typing import Dict, Any, List
NUMERIC_TERM_COLS = [
"loan_amnt", "funded_amnt", "funded_amnt_inv",
"int_rate", "installment",
"out_prncp", "out_prncp_inv",
"total_pymnt", "total_pymnt_inv",
"total_rec_prncp", "total_rec_int",
"total_rec_late_fee", "recoveries", "collection_recovery_fee",
"last_pymnt_amnt",
]
CATEGORICAL_TERM_COLS = [
"term", "grade", "sub_grade", "initial_list_status",
]
class LoanTermsEDA:
def init(self, df: pd.DataFrame, target_col: str = "loan_status"):
"""
Store the full DataFrame and the name of the target column.
"""
self.df = df
self.target_col = target_col
def numeric_terms_summary(self) -> pd.DataFrame:
"""
Return df[NUMERIC_TERM_COLS].describe().T
(one row per numeric term/cashflow column).
"""
...
def distribution_stats_for_column(self, col: str) -> Dict[str, float]:
"""
For a given numeric column, return stats in a dict:
- mean
- std
- min
- max
- q25 (25% quantile)
- q50 (median)
- q75 (75% quantile)
"""
...
def default_rate_by_term(self) -> pd.Series:
"""
Default rate (mean of target) per 'term' category.
"""
...
def default_rate_by_grade(self) -> pd.Series:
"""
Default rate per 'grade' (or per 'sub_grade', if you prefer).
"""
...
"""
2. Functional per-column numeric summary
Add a function that uses functional programming over numeric columns:
"""
def summarize_numeric_terms(eda: LoanTermsEDA) -> Dict[str, Dict[str, float]]:
"""
For each column in NUMERIC_TERM_COLS, call
eda.distribution_stats_for_column(col) and return a dict:
col_name -> stats_dict.
Implement this using a dict comprehension or map
to clearly show functional style.
"""
...
"""
Example idea:
"""
def summarize_numeric_terms(eda: LoanTermsEDA) -> Dict[str, Dict[str, float]]:
return {col: eda.distribution_stats_for_column(col) for col in NUMERIC_TERM_COLS}
"""
3. Create the demo notebook
In notebooks/eda_loan_terms_demo.ipynb:
- Load the dataset:
"""
import pandas as pd
from src.eda_loan_terms import LoanTermsEDA, summarize_numeric_terms
df = pd.read_csv("data/loan_sample.csv") # or the correct path
"""
- Instantiate the EDA class:
"""
eda = LoanTermsEDA(df, target_col="loan_status")
"""
- Run EDA:
"""
numeric_summary = eda.numeric_terms_summary()
per_column_stats = summarize_numeric_terms(eda)
default_by_term = eda.default_rate_by_term()
default_by_grade = eda.default_rate_by_grade()
"""
- Display at least:
"""
numeric_summary # describe() table of numeric loan terms
per_column_stats # dict of stats per numeric column
default_by_term # default rate by term (e.g., 36 vs 60 months)
default_by_grade # default rate by grade/sub_grade
"""
Optionally add a histogram of int_rate or loan_amnt and a short markdown comment.
(But no modeling, only EDA.)
Acceptance Criteria ✅
-
LoanTermsEDA:
- Initializes correctly with a DataFrame.
numeric_terms_summary() returns a DataFrame with one row per numeric term column.
distribution_stats_for_column(col) returns a stats dict for that column.
default_rate_by_term() and default_rate_by_grade() return Series with default rates.
-
Functional part:
summarize_numeric_terms(eda) uses a functional style (e.g. dict comprehension or map) to iterate over NUMERIC_TERM_COLS and call a method for each.
-
Notebook:
- Runs top-to-bottom with no errors.
- Shows numeric summaries, per-column stats, and default-rate-by-category analyses.
- Contains only EDA (no model training).
Issue 2 – Loan Terms & Cashflow EDA with OOP + Per-Column Functional Summary
Goal
Analyze how loan terms and cashflows behave and how they relate to
loan_status.You must use:
map.Columns in scope
You are responsible for the following columns:
Loan structure & pricing
loan_amntfunded_amntfunded_amnt_invtermint_rateinstallmentgradesub_gradeinitial_list_statusCashflow / lifecycle
out_prncpout_prncp_invtotal_pymnttotal_pymnt_invtotal_rec_prncptotal_rec_inttotal_rec_late_feerecoveriescollection_recovery_feelast_pymnt_dlast_pymnt_amntnext_pymnt_dShared target
loan_status(used for default-rate calculations)Files to edit
src/eda_loan_terms.pynotebooks/eda_loan_terms_demo.ipynb1. Implement the
LoanTermsEDAclassIn
src/eda_loan_terms.py, create and implement:"""
import pandas as pd
from typing import Dict, Any, List
NUMERIC_TERM_COLS = [
"loan_amnt", "funded_amnt", "funded_amnt_inv",
"int_rate", "installment",
"out_prncp", "out_prncp_inv",
"total_pymnt", "total_pymnt_inv",
"total_rec_prncp", "total_rec_int",
"total_rec_late_fee", "recoveries", "collection_recovery_fee",
"last_pymnt_amnt",
]
CATEGORICAL_TERM_COLS = [
"term", "grade", "sub_grade", "initial_list_status",
]
class LoanTermsEDA:
def init(self, df: pd.DataFrame, target_col: str = "loan_status"):
"""
Store the full DataFrame and the name of the target column.
"""
self.df = df
self.target_col = target_col
"""
2. Functional per-column numeric summary
Add a function that uses functional programming over numeric columns:
"""
def summarize_numeric_terms(eda: LoanTermsEDA) -> Dict[str, Dict[str, float]]:
"""
For each column in NUMERIC_TERM_COLS, call
eda.distribution_stats_for_column(col) and return a dict:
col_name -> stats_dict.
"""
Example idea:
"""
def summarize_numeric_terms(eda: LoanTermsEDA) -> Dict[str, Dict[str, float]]:
return {col: eda.distribution_stats_for_column(col) for col in NUMERIC_TERM_COLS}
"""
3. Create the demo notebook
In
notebooks/eda_loan_terms_demo.ipynb:"""
import pandas as pd
from src.eda_loan_terms import LoanTermsEDA, summarize_numeric_terms
df = pd.read_csv("data/loan_sample.csv") # or the correct path
"""
"""
eda = LoanTermsEDA(df, target_col="loan_status")
"""
"""
numeric_summary = eda.numeric_terms_summary()
per_column_stats = summarize_numeric_terms(eda)
default_by_term = eda.default_rate_by_term()
default_by_grade = eda.default_rate_by_grade()
"""
"""
numeric_summary # describe() table of numeric loan terms
per_column_stats # dict of stats per numeric column
default_by_term # default rate by term (e.g., 36 vs 60 months)
default_by_grade # default rate by grade/sub_grade
"""
Optionally add a histogram of
int_rateorloan_amntand a short markdown comment.(But no modeling, only EDA.)
Acceptance Criteria ✅
LoanTermsEDA:numeric_terms_summary()returns a DataFrame with one row per numeric term column.distribution_stats_for_column(col)returns a stats dict for that column.default_rate_by_term()anddefault_rate_by_grade()return Series with default rates.Functional part:
summarize_numeric_terms(eda)uses a functional style (e.g. dict comprehension ormap) to iterate overNUMERIC_TERM_COLSand call a method for each.Notebook: