# ---------------------------------------------------------------------------
# survey_analysis.py
#
# Three hundred students in one school answered six questions about their
# phones, their sleep and their marks. This program reads the answers and
# looks for what is actually in them:
#
#   1. How much screen time does a student really have?
#   2. Does it go up with age?
#   3. Do students who are on a screen longer sleep less?
#   4. Is there anything in the file connecting screen time to marks?
#   5. Who has their own phone, and does that change anything?
#
# The survey carries NO names — only a response number. That was decided
# before a single form was handed out, and it is the reason the results can
# be put on a notice board at all.
# ---------------------------------------------------------------------------

import pandas as pd
import matplotlib.pyplot as plt

pd.set_option("display.width", 110)
pd.set_option("display.max_columns", 12)

# --- 1. Read -------------------------------------------------------------
df = pd.read_csv("survey.csv")
print("Forms collected :", len(df))
print("Questions       :", list(df.columns))
print()

# --- 2. Clean ------------------------------------------------------------
# A survey always comes back with questions left blank. Which ones, and how
# many, has to be reported: a result worked out from 294 forms should not be
# presented as though 302 people said it.
print("--- Answers left blank ---")
print(df.isnull().sum())
print()

# "yes" and "Yes" are the same answer typed differently.
df["uses_social_media"] = df["uses_social_media"].str.strip().str.title()

# Screen hours is the question this whole survey is about, so a form without
# it is no use. Sleep and marks are dropped only where each is needed, so one
# blank answer does not throw the rest of that form away.
df = df.dropna(subset=["screen_hours"])
print("Forms used for the main figures:", len(df))
print()

# --- 3. Question 1: how much screen time? --------------------------------
print("--- Screen hours on a school day ---")
print(df["screen_hours"].describe().round(2))
print()
print("Median               :", df["screen_hours"].median(), "hours")
print("More than 6 hours    :", (df["screen_hours"] > 6).sum(), "students",
      "(", round((df["screen_hours"] > 6).mean() * 100, 1), "% )")
print("Less than 2 hours    :", (df["screen_hours"] < 2).sum(), "students")
print()

plt.figure(figsize=(8.5, 4.5))
plt.hist(df["screen_hours"].values, bins=14, color="#3b7dd8", edgecolor="white")
plt.axvline(df["screen_hours"].median(), color="#c0392b", linestyle="--",
            label="Median")
plt.title("Screen time on a school day")
plt.xlabel("Hours")
plt.ylabel("Number of students")
plt.legend()
plt.tight_layout()
plt.savefig("chart1_screen_hours.png")
plt.close()

# --- 4. Question 2: does it grow with age? -------------------------------
order = ["VIII", "IX", "X", "XI", "XII"]
by_class = df.groupby("class")["screen_hours"].agg(["count", "mean", "median"]).round(2)
by_class = by_class.reindex(order)

print("--- Screen time by class ---")
print(by_class)
print()
print("Class VIII to Class XII:", by_class.loc["VIII", "mean"], "->",
      by_class.loc["XII", "mean"], "hours")
print()

plt.figure(figsize=(8, 4.5))
plt.bar(by_class.index, by_class["mean"], color="#4c9f70")
plt.title("Average screen time, class by class")
plt.xlabel("Class")
plt.ylabel("Average hours on a school day")
plt.tight_layout()
plt.savefig("chart2_by_class.png")
plt.close()

# --- 5. Question 3: screen time against sleep ----------------------------
sleep = df.dropna(subset=["sleep_hours"])
print("--- Sleep ---")
print("Forms with the sleep question answered:", len(sleep))
print(sleep["sleep_hours"].describe().round(2))
print()
print("Correlation between screen hours and sleep hours:",
      round(sleep["screen_hours"].corr(sleep["sleep_hours"]), 3))
print()

# cut() sorts a number into named bands, which turns a scatter of readings
# into a table anybody can read.
bands = pd.cut(sleep["screen_hours"],
               bins=[0, 2, 4, 6, 24],
               labels=["Under 2 h", "2 to 4 h", "4 to 6 h", "Over 6 h"])
by_band = sleep.groupby(bands, observed=True)["sleep_hours"].agg(["count", "mean"]).round(2)
print("--- Average sleep, by how long the screen is on ---")
print(by_band)
print()

plt.figure(figsize=(8, 4.5))
plt.bar(by_band.index.astype(str), by_band["mean"], color="#a05fc0")
plt.axhline(8, color="#c0392b", linestyle="--", label="8 hours")
plt.title("Average sleep against screen time")
plt.xlabel("Screen time on a school day")
plt.ylabel("Average sleep (hours)")
plt.legend()
plt.tight_layout()
plt.savefig("chart3_sleep.png")
plt.close()

# --- 6. Question 4: screen time against marks ----------------------------
marks = df.dropna(subset=["last_exam_percent"])
print("--- Marks ---")
print("Forms with the marks question answered:", len(marks))
print("Correlation between screen hours and last exam percentage:",
      round(marks["screen_hours"].corr(marks["last_exam_percent"]), 3))
print()

mband = pd.cut(marks["screen_hours"], bins=[0, 2, 4, 6, 24],
               labels=["Under 2 h", "2 to 4 h", "4 to 6 h", "Over 6 h"])
marks_by_band = marks.groupby(mband, observed=True)["last_exam_percent"].agg(
    ["count", "mean", "min", "max"]).round(1)
print("--- Last exam percentage, by screen time ---")
print(marks_by_band)
print()
print("Note the min and max columns. Every band has students at both ends, so")
print("this is a pattern across the school, not a rule about any one student.")
print()

plt.figure(figsize=(8, 4.5))
plt.bar(marks_by_band.index.astype(str), marks_by_band["mean"], color="#c9772f")
plt.title("Average last-exam percentage, by screen time")
plt.xlabel("Screen time on a school day")
plt.ylabel("Average percentage")
plt.tight_layout()
plt.savefig("chart4_marks.png")
plt.close()

# --- 7. Question 5: whose phone is it? -----------------------------------
device = df.groupby("main_device")["screen_hours"].agg(["count", "mean"]).round(2)
device = device.sort_values("count", ascending=False)
print("--- Main device used ---")
print(device)
print()
social = df["uses_social_media"].value_counts()
print("--- Uses social media ---")
print(social)
print("Share saying yes:", round(social.get("Yes", 0) / social.sum() * 100, 1), "%")
print()

plt.figure(figsize=(8.5, 4.5))
plt.barh(device.index[::-1], device["count"][::-1], color="#2f8fa8")
plt.title("Which device students mainly use")
plt.xlabel("Number of students")
plt.tight_layout()
plt.savefig("chart5_devices.png")
plt.close()

# --- 8. The sheet that goes back to the school ---------------------------
summary = pd.DataFrame({
    "students": by_class["count"],
    "avg_screen_hours": by_class["mean"],
})
summary.to_csv("class_summary.csv")

print("Charts saved : chart1_screen_hours.png .. chart5_devices.png")
print("Summary saved: class_summary.csv")
