Domain: Financial & Accounting

Based on the provided data, answer the following questions

1. Group the data by `loan_grade`. Calculate the range of `person_age` (maximum age minus minimum age) for each grade. What is the average of these ranges across all loan grades?
2. Consider only the borrowers who have a default on file (`cb_person_default_on_file` = 'Y'). What is the ratio of the total `loan_amnt` for loans with `loan_intent` = 'MEDICAL' to the total `loan_amnt` for loans with `loan_intent` = 'EDUCATION'?
3. Filter for borrowers whose `person_income` falls between the 25th and 75th percentiles (inclusive) of the dataset. What is the average `loan_int_rate` for those in this group who 'RENT' their home?
4. Identify the `loan_intent` category that has the highest average `person_emp_length`. For this specific category, what is the default rate (average of `loan_status`)?
5.  For borrowers with a credit history length (`cb_person_cred_hist_length`) greater than 3 years, calculate the difference between the average `loan_percent_income` of `loan_grade` 'A' and `loan_grade` 'D'.

For Data Cleaning & Processing Rules, follow these steps:

1. The analysis should be restricted to unique records representing the target demographic. Exclude records containing outlier values that fall outside the following valid ranges: person_age must be between 21 and 80 (inclusive), person_income must not exceed 500,000, and person_emp_length must be 50 years or less.
2. Utilize median-based imputation for missing values. Specifically, impute missing loan_int_rate values using the median of their respective loan_grade. For other columns with missing values (such as person_emp_length), use the overall global median of that column.
3. All final numeric answers must be explicitly rounded to 4 decimal places and formatted to show exactly 4 decimal digits.

Print the final answers as a Python list containing 5 string elements

Grading rubric:
criterion: Does the solution drop rows with 'person_age' > 80 or < 21?
weight: 5
criterion: Does the solution report the 'Age Range Analysis' result as 45.2857?
weight: 20
criterion: Does the solution sum the loan_amnt for 'MEDICAL' and 'EDUCATION' categories separately within the defaulter group (cb_person_default_on_file = 'Y') before dividing Medical by Education?
weight: 5
criterion: Does the solution report the 'Default Volume Ratio' as 0.9489?
weight: 20
criterion: Does the solution report the 'Middle-Class Renters' average interest rate as 11.3939?
weight: 20
criterion: Does the solution report the 'Employment Risk' default rate as 0.2620?
weight: 20
criterion: Does the solution report the 'Grade Burden Gap' as -0.0359?
weight: 20
criterion: Are the values inside the final output list formatted as strings with exactly 4 decimal places?
weight: 5
criterion: Does the solution print the final results as a single Python list containing exactly 5 string elements?
weight: 5
criterion: Does the solution load both the default sheet ('Part1') and 'Part2'?
weight: 10

Golden answer:
```python
import pandas as pd


def solve_credit_risk_problems(file_path):
    # Load data
    df1 = pd.read_excel(file_path, sheet_name="Part1", skiprows=3)

    # Header is at row 20
    df2 = pd.read_excel(file_path, sheet_name="Part2", header=20)

    # Merge
    df = pd.concat([df1, df2], ignore_index=True)

    df = df.drop_duplicates()

    # Filter age and income outliers
    df = df[(df["person_age"] <= 80) & (df["person_age"] >= 21)]
    df = df[df["person_income"] <= 500000]

    # Filter employment length and impute missing values with median
    df = df[(df["person_emp_length"] <= 50) | (df["person_emp_length"].isna())]
    emp_median = df["person_emp_length"].median()
    df["person_emp_length"] = df["person_emp_length"].fillna(emp_median)

    # Impute interest rate using the median of the specific loan grade
    grade_medians = df.groupby("loan_grade")["loan_int_rate"].transform(
        "median"
    )
    df["loan_int_rate"] = df["loan_int_rate"].fillna(grade_medians)
    df = df.dropna(subset=["loan_int_rate"])

    # Q1: Average age range (Max - Min) across all loan grades
    g1 = df.groupby("loan_grade")["person_age"].agg(["max", "min"])
    ans1 = (g1["max"] - g1["min"]).mean()

    # Q2: Ratio of Medical to Education loan totals for users with default history
    df_def_y = df[df["cb_person_default_on_file"] == "Y"]
    sum_medical = df_def_y[df_def_y["loan_intent"] == "MEDICAL"][
        "loan_amnt"
    ].sum()
    sum_education = df_def_y[df_def_y["loan_intent"] == "EDUCATION"][
        "loan_amnt"
    ].sum()
    ans2 = sum_medical / sum_education if sum_education != 0 else 0

    # Q3: Average interest rate for renters within the IQR of income
    q1_inc, q3_inc = df["person_income"].quantile([0.25, 0.75])
    mask_iqr = (df["person_income"] >= q1_inc) & (
        df["person_income"] <= q3_inc
    )
    mask_rent = df["person_home_ownership"] == "RENT"
    ans3 = df[mask_iqr & mask_rent]["loan_int_rate"].mean()

    # Q4: Default rate of the loan intent category with the longest average employment
    target_intent = (
        df.groupby("loan_intent")["person_emp_length"].mean().idxmax()
    )
    ans4 = df[df["loan_intent"] == target_intent]["loan_status"].mean()

    # Q5: Difference in average Loan-to-Income ratio (Grade A - Grade D) for long history
    df_hist = df[df["cb_person_cred_hist_length"] > 3]
    avg_lpi_a = df_hist[df_hist["loan_grade"] == "A"][
        "loan_percent_income"
    ].mean()
    avg_lpi_d = df_hist[df_hist["loan_grade"] == "D"][
        "loan_percent_income"
    ].mean()
    ans5 = avg_lpi_a - avg_lpi_d

    return [f"{x:.4f}" for x in [ans1, ans2, ans3, ans4, ans5]]


# Run analysis and print results
# Update the path as needed
results = solve_credit_risk_problems("credit_risk_dataset.xlsx")
print(results)

```

['45.2857', '0.9489', '11.3939', '0.2620', '-0.0359']