Spaces:
Sleeping
Sleeping
Download mcp_tools.py from CognitiveScience/psyc3000: direct link, hf CLI and curl.
- Browser
- Download file 4.7 kB
-
https://huggingface.co/spaces/CognitiveScience/psyc3000/resolve/main/mcp_tools.py
- Command line
-
hf download hf://spaces/CognitiveScience/psyc3000/mcp_tools.py
-
curl -L -o mcp_tools.py https://huggingface.co/spaces/CognitiveScience/psyc3000/resolve/main/mcp_tools.py
4.7 kB
| # mcp_tools.py | |
| import numpy as np | |
| import pingouin as pg | |
| import matplotlib.pyplot as plt | |
| import io | |
| import base64 | |
| import json | |
| def plot_group_distribution(groups_str): | |
| groups = [np.array([float(x) for x in g.split(",")]) for g in groups_str.split(";")] | |
| fig, axes = plt.subplots(1, 3, figsize=(12, 4)) | |
| # Histogram | |
| for g in groups: | |
| axes[0].hist(g, alpha=0.5) | |
| axes[0].set_title("Histogram") | |
| # Boxplot | |
| axes[1].boxplot(groups) | |
| axes[1].set_title("Boxplot") | |
| # QQ plot (first group) | |
| pg.qqplot(groups[0], ax=axes[2]) | |
| axes[2].set_title("QQ Plot (Group 1)") | |
| buf = io.BytesIO() | |
| fig.savefig(buf, format="png") | |
| buf.seek(0) | |
| return base64.b64encode(buf.read()).decode() | |
| def assumption_checks(groups_str): | |
| import pandas as pd | |
| groups = [np.array([float(x) for x in g.split(",")]) for g in groups_str.split(";")] | |
| # Normality (Shapiro) with safety guard | |
| normality = [] | |
| for i, g in enumerate(groups): | |
| if len(g) < 4: | |
| normality.append({ | |
| "group": f"G{i+1}", | |
| "error": "Normality test requires at least 4 samples." | |
| }) | |
| else: | |
| result = pg.normality(g).to_dict(orient="records")[0] | |
| normality.append({ | |
| "group": f"G{i+1}", | |
| **result | |
| }) | |
| # Homogeneity (Levene) | |
| levene = pg.homoscedasticity(groups, method="levene").to_dict(orient="records")[0] | |
| return { | |
| "normality": normality, | |
| "homogeneity": levene | |
| } | |
| def posthoc_tests(groups_str, method="games-howell"): | |
| import pandas as pd | |
| groups = [np.array([float(x) for x in g.split(",")]) for g in groups_str.split(";")] | |
| data = [] | |
| for i, g in enumerate(groups): | |
| for val in g: | |
| data.append({"value": val, "group": f"G{i+1}"}) | |
| df = pd.DataFrame(data) | |
| result = pg.pairwise_ttests( | |
| dv="value", | |
| between="group", | |
| data=df, | |
| padjust="bonf", | |
| parametric=(method == "tukey"), | |
| effsize="hedges" | |
| ) | |
| return result.to_dict(orient="records") | |
| # ----------------------------- | |
| # Helper: convert Pingouin DF → JSON | |
| # ----------------------------- | |
| def pg_to_json(df): | |
| """Convert Pingouin single-row DataFrame to JSON dict.""" | |
| return df.to_dict(orient="records")[0] | |
| # ----------------------------- | |
| # Welch t-test (independent, unequal variances) | |
| # ----------------------------- | |
| def welch_t_test(group1_str, group2_str, alternative="two-sided"): | |
| g1 = np.array([float(x) for x in group1_str.split(",")]) | |
| g2 = np.array([float(x) for x in group2_str.split(",")]) | |
| result = pg.ttest(g1, g2, paired=False, correction=True, alternative=alternative) | |
| return pg_to_json(result) | |
| # ----------------------------- | |
| # Student t-test (independent, equal variances) | |
| # ----------------------------- | |
| def student_t_test(group1_str, group2_str, alternative="two-sided"): | |
| g1 = np.array([float(x) for x in group1_str.split(",")]) | |
| g2 = np.array([float(x) for x in group2_str.split(",")]) | |
| result = pg.ttest(g1, g2, paired=False, correction=False, alternative=alternative) | |
| return pg_to_json(result) | |
| # ----------------------------- | |
| # Paired t-test (same subjects measured twice) | |
| # ----------------------------- | |
| def paired_t_test(group1_str, group2_str, alternative="two-sided"): | |
| g1 = np.array([float(x) for x in group1_str.split(",")]) | |
| g2 = np.array([float(x) for x in group2_str.split(",")]) | |
| result = pg.ttest(g1, g2, paired=True, alternative=alternative) | |
| return pg_to_json(result) | |
| # ----------------------------- | |
| # One-sample t-test (sample vs population mean) | |
| # ----------------------------- | |
| def one_sample_t_test(group_str, population_mean, alternative="two-sided"): | |
| g = np.array([float(x) for x in group_str.split(",")]) | |
| # Adjust sample for one-sample t-test | |
| adjusted = g - float(population_mean) | |
| # Pingouin one-sample t-test: y=None, popmean implicitly = 0 | |
| result = pg.ttest(adjusted, y=None, paired=False, alternative=alternative) | |
| return pg_to_json(result) | |
| # ----------------------------- | |
| # One-way ANOVA (multiple independent groups) | |
| # ----------------------------- | |
| def one_way_anova(groups_str): | |
| """ | |
| groups_str format: | |
| "1,2,3; 4,5,6; 7,8,9" | |
| """ | |
| groups = [np.array([float(x) for x in g.split(",")]) for g in groups_str.split(";")] | |
| # Build DataFrame for Pingouin | |
| import pandas as pd | |
| data = [] | |
| for i, g in enumerate(groups): | |
| for val in g: | |
| data.append({"value": val, "group": f"G{i+1}"}) | |
| df = pd.DataFrame(data) | |
| result = pg.anova(dv="value", between="group", data=df) | |
| return pg_to_json(result) | |