psyc3000 / app02.py
CognitiveScience's picture
Rename app.py to app02.py
a0a8a05 verified
Raw History Blame Contribute Delete
11.9 kB
# app.py
import asyncio
asyncio.set_event_loop_policy(asyncio.DefaultEventLoopPolicy())
import gradio as gr
import mcp_tools
from mcp_tools import posthoc_tests, assumption_checks
import spaces
@spaces.GPU
def init_gpu():
return "GPU initialized"
import json, tempfile, os
def save_json_to_file(data, filename):
path = os.path.join(tempfile.gettempdir(), filename)
with open(path, "w") as f:
json.dump(data, f)
return path
import base64
def save_png_to_file(img, filename):
if img is None:
return None
img.save(filename, format="PNG")
return filename
from io import BytesIO
from PIL import Image
import matplotlib.pyplot as plt
def ui_plot(groups_str):
# Parse semicolon-separated groups
groups = []
for g in groups_str.split(";"):
nums = [float(x) for x in g.split(",")]
groups.append(nums)
# Example plot: boxplot of groups
fig, ax = plt.subplots()
ax.boxplot(groups)
ax.set_title("Group Plot")
ax.set_xlabel("Group")
ax.set_ylabel("Value")
buf = BytesIO()
fig.savefig(buf, format="png")
buf.seek(0)
return Image.open(buf)
# -----------------------------
# UI helper wrappers
# -----------------------------
def ui_welch(g1, g2, alt):
return mcp_tools.welch_t_test(g1, g2, alt)
def ui_student(g1, g2, alt):
return mcp_tools.student_t_test(g1, g2, alt)
def ui_paired(g1, g2, alt):
return mcp_tools.paired_t_test(g1, g2, alt)
#def ui_one_sample(g, mu, alt):
# return mcp_tools.one_sample_t_test(g, mu, alt)
def parse_group(text):
# Split on commas, strip whitespace, convert to float
return [float(x.strip()) for x in text.split(",") if x.strip()]
def ui_os(g, mu, alternative):
import numpy as np
import pingouin as pg
g = np.array(parse_group(g), dtype=float)
if mu is None:
mu = 0
mu = float(mu)
adjusted = g - mu
result = pg.ttest(adjusted, y=None, alternative=alternative)
print("DEBUG ui_os:", g, mu, alternative)
return {
"T": float(result["T"].iloc[0]),
"dof": int(result["dof"].iloc[0]),
"alternative": alternative,
"p_val": float(result["p-val"].iloc[0]),
"CI95": [float(result["CI95%"].iloc[0][0]), float(result["CI95%"].iloc[0][1])],
"cohen_d": float(result["cohen-d"].iloc[0]),
"power": float(result["power"].iloc[0]),
"BF10": str(result["BF10"].iloc[0])
}
def ui_anova(groups):
return mcp_tools.one_way_anova(groups)
# -----------------------------
# Modern Light Theme
# -----------------------------
theme = gr.themes.Soft(
primary_hue="blue",
secondary_hue="gray",
neutral_hue="gray",
)
# -----------------------------
# Main UI
# -----------------------------
with gr.Blocks(title="Stat3001 — Statistical Tests") as demo:
gr.Markdown(
"""
# 📊 Stat3001 — Statistical Analysis Toolkit
Clean, modern, and powered by **Pingouin** for robust statistical results.
"""
)
groups_input = gr.Textbox(
label="Groups (semicolon-separated)",
placeholder="Example: 1,2,3; 4,5,6; 7,8,9",
value="1,2,3; 4,5,6; 7,8,9"
)
load_example = gr.Button("Load example")
load_example.click(lambda: "1,2,3; 4,5,6; 7,8,9", None, groups_input)
# Shared input for both ANOVA and post-hoc
# -----------------------------------------
# SHARED COMPONENTS (define BEFORE tabs)
# -----------------------------------------
# Shared input area
# ---------------------------------------------------
# Welch t-test
# ---------------------------------------------------
with gr.Tab("Welch t-test"):
with gr.Column():
gr.Markdown("### Compare two independent groups (unequal variances).")
g1 = gr.Textbox(label="Group 1 (comma-separated numbers)")
g2 = gr.Textbox(label="Group 2 (comma-separated numbers)")
alt = gr.Radio(["two-sided", "less", "greater"], value="two-sided", label="Alternative hypothesis")
run = gr.Button("Run Welch t-test", variant="primary")
out = gr.JSON(label="Results")
download_welch = gr.DownloadButton("Download results")
#run.click(lambda *args: ui_welch(*args), inputs=[g1, g2, alt], outputs=[out])
run.click(ui_welch, inputs=[g1, g2, alt], outputs=out)
run.click(
lambda r: save_json_to_file(r, "welch_results.json"),
inputs=[out],
outputs=[download_welch]
)
example_welch = "23,25,28,30,32", "18,20,22,25,27"
example_anova = "1,2,3; 2,3,4; 3,4,5"
load_example = gr.Button("Load example")
load_example.click(
lambda: example_welch,
None,
[g1, g2]
)
# ---------------------------------------------------
# Student t-test
# ---------------------------------------------------
with gr.Tab("Student t-test"):
gr.Markdown("### Compare two independent groups (equal variances).")
with gr.Column():
g1_s = gr.Textbox(label="Group 1 (comma-separated numbers)")
g2_s = gr.Textbox(label="Group 2 (comma-separated numbers)")
alt_s = gr.Radio(["two-sided", "less", "greater"], value="two-sided", label="Alternative hypothesis")
example_student = ("10,12,14,15,16", "9,11,13,14,15")
load_example_student = gr.Button("Load example")
load_example_student.click(lambda: example_student, None, [g1_s, g1_s])
run_s = gr.Button("Run Student t-test", variant="primary")
out_s = gr.JSON(label="Results")
download_student = gr.DownloadButton("Download results")
run_s.click(ui_student, inputs=[g1_s, g1_s, alt_s], outputs=[out_s])
run_s.click(
lambda r: save_json_to_file(r, "student_results.json"),
inputs=[out_s],
outputs=[download_student]
)
#run.click(lambda *args: ui_welch(*args), inputs=[g1, g2, alt], outputs=[out])
#run.click(lambda r: ("results.json", json.dumps(r)), inputs=[out], outputs=[download])
# ---------------------------------------------------
# Paired t-test
# ---------------------------------------------------
with gr.Tab("Paired t-test"):
gr.Markdown("### Compare two related measurements (same subjects).")
with gr.Column():
g1_p = gr.Textbox(label="Group 1 (comma-separated numbers)")
g2_p = gr.Textbox(label="Group 2 (comma-separated numbers)")
alt_p = gr.Radio(["two-sided", "less", "greater"], value="two-sided", label="Alternative hypothesis")
example_paired = ("5,6,7,8,9", "6,7,8,9,10")
load_example_paired = gr.Button("Load example")
load_example_paired.click(lambda: example_paired, None, [g1_p, g2_p])
run_p = gr.Button("Run Paired t-test", variant="primary")
out_p = gr.JSON(label="Results")
download_paired = gr.DownloadButton("Download results")
run_p.click(ui_paired, inputs=[g1_p, g2_p, alt_p], outputs=[out_p])
run_p.click(
lambda r: save_json_to_file(r, "paired_results.json"),
inputs=[out_p],
outputs=[download_paired]
)
#run.click(lambda *args: ui_welch(*args), inputs=[g1, g2, alt], outputs=[out])
#run.click(lambda r: ("results.json", json.dumps(r)), inputs=[out], outputs=[download])
#run_p.click(ui_paired, inputs=[g1_p, g2_p, alt_p], outputs=out_p)
# ---------------------------------------------------
# One-sample t-test
# ---------------------------------------------------
with gr.Tab("One-sample t-test"):
with gr.Column():
g_os = gr.Textbox(label="Sample values (comma-separated)")
mu_os = gr.Number(label="Population mean", value=0)
alt_one = gr.Radio(["two-sided", "less", "greater"], value="two-sided")
out_os = gr.JSON(label="Results")
run_os = gr.Button("Run One-sample t-test", variant="primary")
download_os = gr.DownloadButton("Download results")
example_one_sample = "5,6,7,8,9"
load_example_one = gr.Button("Load example")
load_example_one.click(lambda: example_one_sample, None, [g_os])
run_os.click(ui_os, inputs=[g_os, mu_os, alt_one], outputs=[out_os])
run_os.click(
lambda r: save_json_to_file(r, "one_sample_results.json"),
inputs=[out_os],
outputs=[download_os]
)
# ---------------------------------------------------
# One-way ANOVA
# ---------------------------------------------------
# -----------------------------------------
# ANOVA TAB
# -----------------------------------------
with gr.Tab("ANOVA"):
with gr.Column():
run_anova = gr.Button("Run ANOVA")
out_anova = gr.JSON(label="Results")
run_anova.click(ui_anova, inputs=[groups_input], outputs=[out_anova])
# -----------------------------------------
# POST-HOC TAB
# -----------------------------------------
with gr.Tab("Post-hoc"):
with gr.Column():
method = gr.Radio(["games-howell", "tukey"], value="games-howell")
run_post = gr.Button("Run post-hoc tests")
out_post = gr.JSON(label="Results")
download_post = gr.DownloadButton("Download results")
run_post.click(lambda g, m: posthoc_tests(g, m),
inputs=[groups_input, method],
outputs=[out_post])
run_post.click(lambda r: save_json_to_file(r, "posthoc.json"),
inputs=[out_post],
outputs=[download_post])
# ---------------------------------------------------
# Assumption Checks
# ---------------------------------------------------
with gr.Tab("Assumption Checks"):
with gr.Column():
gr.Markdown("### Normality & Homogeneity")
run_assump = gr.Button("Run assumption checks", variant="primary")
out_assump = gr.JSON(label="Results")
download_assump = gr.DownloadButton("Download results")
# Use the shared groups_input
run_assump.click(
lambda g: assumption_checks(g),
inputs=[groups_input],
outputs=[out_assump]
)
run_assump.click(
lambda r: save_json_to_file(r, "assumption_checks.json"),
inputs=[out_assump],
outputs=[download_assump]
)
# ---------------------------------------------------
# Plots
# ---------------------------------------------------
with gr.Tab("Plot"):
with gr.Column():
run_plot = gr.Button("Generate Plot")
plot_output = gr.Image(type="pil", label="Plot")
download_plot = gr.DownloadButton("Download plot")
run_plot.click(ui_plot, inputs=[groups_input], outputs=[plot_output])
download_plot.click(
lambda img: save_png_to_file(img, "plot.png"),
inputs=[plot_output],
outputs=[download_plot]
)
# Main execution
if __name__ == "__main__":
demo.launch(
theme=theme,
server_name="0.0.0.0",
server_port=7860
)