不会敲代码的医学博士用AI维护个人网站的V2.1
严格意义上来说从零搭建个人网站已经完成了,后续应该是不断添加功能和维护的过程。以后的标题就改成现在这样,有样学样记录一下版本号。
因为我租的服务器规模比较小(单核小内存),带博客系统和内置AI应该很有压力,所以只使用比较简单的结构:
后端: FastAPI + Gunicorn + PostgreSQL,前端: 静态HTML/JavaScript(由Nginx直接服务),反向代理: Nginx(HTTPS终止 + 静态文件服务)
当然,是某AI模型帮我设计的(狗头)。至于模型的名字大家看页面排版就知道。
这次想加入的是一个统计方法建议的新功能。一般在分析实验数据的时候,要先看分组数和样本量,然后看分布、方差齐性,再决定使用的统计方法。看来看去有点费时间,还不一定正确。有时候判断流程和标准记不清还要检查。如果有这样一个工具可以检查数据,输出推荐的或者符合统计学规则的检验方法,就非常实用和方便了。
一、告诉大模型我的要求:

思考片刻,大模型就告诉了我推荐的方案,甚至还有确认细节的步骤:

二、开工!
上传之前保存的md运维文档,上传文件路径和主页html文档,告诉大模型我是不会敲代码的非专业人员,让他带我在Powershell中操作。大模型很贴心地帮我检查Python包、目录结构等等,完善准备工作。
后端Python分析:
from fastapi import APIRouter, HTTPException
from pydantic import BaseModel
from typing import List, Optional
import scipy.stats as stats
router = APIRouter(prefix="/api/stats", tags=["stats"])
class StatsRequest(BaseModel):
groups: List[List[float]]
group_names: List[str]
paired: bool = False
class StepResult(BaseModel):
test_name: str
details: str
passed: bool
class StatsResponse(BaseModel):
recommendation: str
reason: str
post_hoc: Optional[str]
steps: List[StepResult]
@router.post("/analyze", response_model=StatsResponse)
def analyze(req: StatsRequest):
groups = req.groups
names = req.group_names
paired = req.paired
n_groups = len(groups)
steps = []
if n_groups < 2:
raise HTTPException(status_code=400, detail="At least 2 groups are required.")
ns = [len(g) for g in groups]
if paired:
if len(set(ns)) != 1:
raise HTTPException(
status_code=400,
detail=f"Paired analysis requires equal sample sizes across all groups. "
f"Current sizes: {', '.join(f'{names[i]}: n={ns[i]}' for i in range(n_groups))}"
)
normality_results = []
all_normal = True
for i, g in enumerate(groups):
if len(g) < 3:
normality_results.append((names[i], None, None, False))
all_normal = False
steps.append(StepResult(
test_name=f"Normality - {names[i]}",
details=f"n={len(g)}: too few observations to run Shapiro-Wilk (minimum n=3). Assumed non-normal.",
passed=False
))
else:
stat, p = stats.shapiro(g)
normal = p > 0.05
if not normal:
all_normal = False
normality_results.append((names[i], stat, p, normal))
steps.append(StepResult(
test_name=f"Normality - {names[i]}",
details=f"Shapiro-Wilk: W={stat:.4f}, p={p:.4f} -> {'normal distribution' if normal else 'non-normal distribution'}",
passed=normal
))
if not all_normal:
if n_groups == 2:
if paired:
return StatsResponse(
recommendation="Wilcoxon Signed-Rank Test",
reason=(
f"Decision path: 2 groups -> paired -> normality check failed "
f"({'; '.join(f'{r[0]}: p={r[2]:.4f}, non-normal' if r[2] is not None else f'{r[0]}: n too small' for r in normality_results)}). "
f"Non-parametric alternative to the paired t-test is recommended."
),
post_hoc=None,
steps=steps
)
else:
return StatsResponse(
recommendation="Mann-Whitney U Test",
reason=(
f"Decision path: 2 groups -> unpaired -> normality check failed "
f"({'; '.join(f'{r[0]}: p={r[2]:.4f}, non-normal' if r[2] is not None else f'{r[0]}: n too small' for r in normality_results)}). "
f"Non-parametric alternative to the independent t-test is recommended."
),
post_hoc=None,
steps=steps
)
else:
if paired:
return StatsResponse(
recommendation="Friedman Test",
reason=(
f"Decision path: {n_groups} groups -> paired -> normality check failed "
f"({'; '.join(f'{r[0]}: p={r[2]:.4f}, non-normal' if r[2] is not None else f'{r[0]}: n too small' for r in normality_results)}). "
f"Non-parametric alternative to repeated measures ANOVA is recommended."
),
post_hoc="Post-hoc: Wilcoxon Signed-Rank Test with Bonferroni correction for pairwise comparisons.",
steps=steps
)
else:
return StatsResponse(
recommendation="Kruskal-Wallis Test",
reason=(
f"Decision path: {n_groups} groups -> unpaired -> normality check failed "
f"({'; '.join(f'{r[0]}: p={r[2]:.4f}, non-normal' if r[2] is not None else f'{r[0]}: n too small' for r in normality_results)}). "
f"Non-parametric alternative to one-way ANOVA is recommended."
),
post_hoc="Post-hoc: Dunn's test with Bonferroni correction for pairwise comparisons.",
steps=steps
)
levene_stat, levene_p = stats.levene(*groups)
equal_var = levene_p > 0.05
steps.append(StepResult(
test_name="Variance Homogeneity (Levene's Test)",
details=f"Levene's test: W={levene_stat:.4f}, p={levene_p:.4f} -> {'equal variances' if equal_var else 'unequal variances'}",
passed=equal_var
))
normality_summary = "; ".join(
f"{r[0]}: p={r[2]:.4f}, normal" for r in normality_results
)
if n_groups == 2:
if paired:
return StatsResponse(
recommendation="Paired t-Test",
reason=(
f"Decision path: 2 groups -> paired -> all groups normally distributed ({normality_summary}). "
f"Paired t-test is the appropriate parametric test."
),
post_hoc=None,
steps=steps
)
else:
if equal_var:
return StatsResponse(
recommendation="Independent Samples t-Test",
reason=(
f"Decision path: 2 groups -> unpaired -> all groups normally distributed ({normality_summary}) "
f"-> equal variances (Levene's p={levene_p:.4f}). "
f"Standard independent samples t-test is appropriate."
),
post_hoc=None,
steps=steps
)
else:
return StatsResponse(
recommendation="Welch's t-Test",
reason=(
f"Decision path: 2 groups -> unpaired -> all groups normally distributed ({normality_summary}) "
f"-> unequal variances (Levene's p={levene_p:.4f}). "
f"Welch's t-test does not assume equal variances and is recommended."
),
post_hoc=None,
steps=steps
)
else:
if paired:
return StatsResponse(
recommendation="Repeated Measures ANOVA",
reason=(
f"Decision path: {n_groups} groups -> paired -> all groups normally distributed ({normality_summary}). "
f"Repeated measures ANOVA accounts for within-subject correlation."
),
post_hoc="Post-hoc: Bonferroni-corrected pairwise t-tests for within-subject comparisons.",
steps=steps
)
else:
if equal_var:
return StatsResponse(
recommendation="One-Way ANOVA",
reason=(
f"Decision path: {n_groups} groups -> unpaired -> all groups normally distributed ({normality_summary}) "
f"-> equal variances (Levene's p={levene_p:.4f}). "
f"One-way ANOVA is the standard parametric test for multiple independent groups."
),
post_hoc="Post-hoc: Tukey's HSD test for all pairwise comparisons.",
steps=steps
)
else:
return StatsResponse(
recommendation="Welch's One-Way ANOVA",
reason=(
f"Decision path: {n_groups} groups -> unpaired -> all groups normally distributed ({normality_summary}) "
f"-> unequal variances (Levene's p={levene_p:.4f}). "
f"Welch's ANOVA does not assume variance homogeneity."
),
post_hoc="Post-hoc: Games-Howell test for pairwise comparisons (does not assume equal variances).",
steps=steps
)
自学了一点点代码的我还是知道这一段是在干什么的,总结一下就是这样的一个决策流程:

(另一个很好用的大模型生成的流程图)
接下来更新main.py注册新功能,重启测试新路由,再设计一下前端页面html即可。html的代码就不贴上来了,比较长而且都是网页设计方面的东西。接着在主页放一个新功能的入口就完成啦!
别忘了让大模型帮我更新md运维文档,下次让他打工更方便。

网页观感不错,试了试功能基本可用,输出的结果应该比较靠谱。
感叹编程大模型的发展实在是迅速,没有代码功底的非专业人员,只要会复制粘贴也能做网站实现简单的功能了;而且还像模像样的。
三、换一种复制粘贴的方法
和大模型聊天的时候,他提到可以用VScode的ssh remote插件链接VPS服务器,鼠标点击操作文件和管理代码更加方便直观,还自带Terminal功能可以取代Powershell。
赶紧加入插件,按照步骤链接上了VPS。由于我有本地私钥,不用输密码打开VScode直连,体验相当棒!
我:你咋不早说?
大模型:你也没问啊,非要我带你用Powershell
AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。
更多推荐



所有评论(0)