作业统计系统

liudagou's home / 2023-09-03 / 原文

蒟蒻自己开发的作业统计系统,虽然很简单但是可以满足老师较大部分的需求,代码如下
编译器:DEV C++
可执行文件


#include <iostream>
#include <windows.h>
#include <time.h>
#include <conio.h>
#include <vector>
#include <algorithm>
#define int long long
using namespace std;
int all, snum, sum_pts, sum, pts, mmin = 0x3f3f3f3f3f, mmax, max_name, q[5000], qnum;
short wait_time = 20;
double av_pts;
pair<int, string> rrnk[5000];
char _;

int find_size(int x)
{
    int cnt = 0;
    while (x != 0)
    {
        cnt++;
        x /= 10;
    }
    return cnt;
}
int read()
{
    int x = 0, f = 1;
    char ch = getchar();
    while (ch == ' ')
        ch = getchar();
    if (ch == '-')
    {
        f = -1;
        ch = '0';
    }
    while (ch <= '9' && ch >= '0')
    {
        x = x * 10 + ch - 48;
        ch = getchar();
    }
    return x * f;
}
void show(bool f)
{
    CONSOLE_CURSOR_INFO cursor_info = {20, f};
    SetConsoleCursorInfo(GetStdHandle(STD_OUTPUT_HANDLE), &cursor_info);
}
void c(string a)
{
    int l = a.size();
    for (int i = 0; i < l; i++) 
    {
        cout << a[i];
        Sleep(wait_time);
    }
    printf("\n");
}
void cc(string a)
{
    int l = a.size();
    for (int i = 0; i < l; i++)
    {
        cout << a[i];
        Sleep(wait_time);
    }
}
struct node
{
    string name;
    int p[5000], pts;
} a[5000];
void gotoxy(int x = 0, int y = 0)
{
    COORD c;
    c.X = x, c.Y = y;
    SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), c);
}
void cls(int p)
{
    printf("\b");
    for (int i = 1; i <= p; i++)
        cout << ' ';
}
void color(int n)
{
    SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), n);
}

void js()
{
    show(0);
    c("欢迎使用智能作业统计系统\n");
    c("此程序可以帮助老师对每次考试的成绩进行分析与总结\n");
    c("1.开始使用");
    c("2.关于程序");
    c("3.急速模式");
    _ = _getch();
    while (_ != '1' && _ != '2' && _ != '3')
    {
        _ = _getch();
    }
    system("CLS");
    if (_ == '3')
    {
        if (wait_time == 20)
        {
            wait_time = 2;
            c("开启急速模式");
            Sleep(200);
        }
        else
        {
            wait_time = 20;
            c("关闭急速模式");
            Sleep(200);
        }
        system("CLS");
        js();
    }
    return;
}
void warning()
{
    cc("此程序的作者:"), color(175), cc("未抑郁的刘大狗"), color(7), puts("\n");
    c("注意:在程序运行中请不要随意输入字符,否则字符全部会停留在缓冲区中");
    c("      这将导致在运行中用错误的输入,影响程序的正常运行");
    _getch();
    system("CLS");
}
void pre_us()
{
    c("请一次输入每个题目的分数");
    cc("结束请输入"), color(79), cout << 123456, color(7), puts("\n");
    show(1);
    for (int i = 1, s;; i++)
    {
        cout << i << ".";
        color(23), s = read(), color(7);
        if (s == 123456)
            break;
        while (s < 1 && s != 123456)
        {
            show(0);
            cc("您输入的分数有误,请重新输入");
            Sleep(300);
            gotoxy(1, i + 3);
            cls(30);
            gotoxy(find_size(i) + 2, i + 2);
            cls(100);
            gotoxy(find_size(i) + 1, i + 2);
            show(1);
            color(23);
            s = read();
            color(7);
        }
        if (s == 123456)
            break;
        q[++qnum] = s;
        all += s;
    }
    show(0);
    system("CLS");
    if (qnum == 0)
    {
        c("老师,看来您的工作真轻松连一道题目都没有");
        c("bye bye!");
        _getch();
        exit(0);
    }
    cc("总分为:");
    color(165);
    cout << all;
    color(7);
    puts("\n");
    cc("请输入每位同学的姓名(字节数大于1),结束请输入");
    color(79);
    cout << "end";
    color(7);
    puts("\n");
    show(1);
    color(1);
    while (cin >> a[++snum].name && a[snum].name != "end")
    {
        max_name = max(max_name, (long long)a[snum].name.size());
        color(snum % 15 + 1);
    }
    color(7);
    show(0);
    snum--;
    if (snum == 0)
    {
        system("CLS");
        c("老师,看来您的工作真轻松连一个同学都没有");
        c("bye bye!");
        _getch();
        exit(0);
    }
    c("\n准备工作结束啦!"), getch();
    system("CLS");
    for (int i = 1; i <= snum; i++)
    {
        for (int j = 1; j <= qnum; j++)
            a[i].p[j] = q[j];
    }
}
void us(int k)
{
    while (1)
    {
        cc("请输入第");
        cout << k;
        cc("个同学 ");
        color(176);
        cout << a[k].name;
        color(7);
        c(" 的得分情况\n");
        cc("请输入有错误的题号,结束请输入 ");
        color(71);
        cout << 123456;
        color(7);
        puts("\n");
        color(23);
        show(1);
        sum = read();
        show(0);
        color(7);
        if (sum == 123456)
            break;
        while ((sum < 1 || sum > qnum) && sum != 123456)
        {
            c("您输入的题号有误,请重新输入");
            Sleep(300);
            gotoxy(1, 5);
            cls(50);
            gotoxy(1, 4);
            cls(50);
            gotoxy(0, 4);
            color(23);
            show(1);
            sum = read();
            show(0);
            color(7);
        }
        if (sum == 123456)
            break;
        c("请输入该同学获得的分数");
        color(23);
        show(1);
        pts = read();
        show(0);
        color(7);
        while (pts > q[sum] || pts < 0)
        {
            c("您输入的分数有误,请重新输入");
            Sleep(300);
            gotoxy(1, 6);
            cls(50);
            gotoxy(1, 7);
            cls(50);
            gotoxy(0, 6);
            color(23);
            show(1);
            pts = read();
            show(0);
            color(7);
        }
        a[k].p[sum] = pts;
        system("CLS");
    }
    system("CLS");
    return;
}
void pre_basic()
{
    show(0);
    for (int i = 1; i <= snum; i++)
    {
        for (int j = 1; j <= qnum; j++)
            a[i].pts += a[i].p[j];
        sum_pts += a[i].pts;
        mmin = min(mmin, a[i].pts);
        mmax = max(mmax, a[i].pts);
    }
    av_pts = sum_pts * 1.0 / snum;
    for (int i = 1; i <= snum; i++)
    {
        rrnk[i].first = a[i].pts;
        rrnk[i].second = a[i].name;
    }
    std::sort(rrnk + 1, rrnk + 1 + snum);
}
void basic()
{
    cc("此次测试共有");
    color(143);
    cout << snum;
    color(7);
    c("人参加\n");
    cc("此次考试一共有");
    color(159);
    cout << qnum;
    color(7);
    cc("道题目,总分为");
    color(95);
    cout << all;
    color(7);
    puts("\n");
    cc("这次考试的平均分为");
    color(23);
    cout << av_pts;
    color(7);
    puts("\n");
    cc("最高分为");
    color(79);
    cout << mmax;
    color(7);
    cc(",最低分为");
    color(79);
    cout << mmin;
    color(7);
    puts("\n");
}
void rnk()
{
    c("排序规则:分数高的在上,分数低的在下,分数一样的按名字的字典序排列\n");
    int len_snum = find_size(snum), len_all = find_size(all);
    cc("排名");
    for (int i = 1; i <= len_snum; i++)
        cout << " ";
    cc("| 姓名");
    for (int i = 1; i < max_name; i++)
        cout << " ";
    c("| 分数");
    for (int i = snum; i >= 1; i--)
    {
        cout << snum - i + 1;
        int len = find_size(snum - i + 1);
        for (int j = 1; j + len - 4 <= len_snum; j++)
            cout << " ";
        cout << "| " << rrnk[i].second;
        for (int j = 1; j + rrnk[i].second.size() - 3 <= max_name; j++)
            cout << " ";
        cout << "| " << rrnk[i].first << endl;
    }
}
void ques()
{
    c("请输入题号");
    color(23);
    show(1);
    sum = read();
    show(0);
    color(7);
    while (sum < 1 || sum > qnum)
    {
        c("您输入的题号有误,请重新输入");
        Sleep(300);
        gotoxy(1, 1);
        cls(50);
        gotoxy(1, 2);
        cls(50);
        gotoxy(0, 1);
        color(23);
        show(1);
        sum = read();
        show(0);
        color(7);
    }
    system("CLS");
    int q_pts = 0, right_q = 0, q_stu[5020], q_max, q_min = 0x3f3f3f3f3f;
    for (int i = 1; i <= snum; i++)
    {
        q_pts += a[i].p[sum];
        if (a[i].p[sum] == q[sum])
            q_stu[++right_q] = i;
        q_max = max(q_max, a[i].p[sum]);
        q_min = min(q_min, a[i].p[sum]);
    }
    double av_q_pts = q_pts * 1.0 / snum, good = 100.0 * right_q / snum;
    cc("这道题目的满分为:");
    color(63);
    cout << q[sum];
    color(7);
    puts("\n");
    cc("这道题目的平均分为:");
    color(95);
    cout << av_q_pts;
    color(7);
    puts("\n");
    cc("最高分为");
    color(71);
    cout << q_max;
    color(7);
    cc(",最低分为");
    color(71);
    cout << q_min;
    color(7);
    puts("\n");
    cc("一共有");
    color(31);
    cout << right_q;
    color(7);
    cc("人做对这道题目,正确率为");
    color(31);
    cout << good << "%";
    color(7);
    cout << "\n";
    c("以下是做对的同学:");
    for (int i = 1; i <= right_q; i++)
    {
        color(i % 5);
        cout << a[q_stu[i]].name;
        for (int j = 1; j <= max_name - (long long)a[q_stu[i]].name.size() + 1; j++)
            cout << " ";
        if (i % 5 == 0)
            cout << endl;
    }
}
void stud()
{
    int id = -1, x, s_right = 0;
    string s_name;
    c("请输入同学姓名(请勿随意输入换行)");
    while (1)
    {
        color(23);
        show(1);
        cin >> s_name;
        show(0);
        color(7);
        for (int i = 1; i <= snum; i++)
            if (a[i].name == s_name)
            {
                id = i;
                break;
            }
        if (id != -1)
            break;
        c("您输入的姓名,请重新输入");
        Sleep(300);
        gotoxy(1, 1), cls(100);
        gotoxy(1, 2), cls(100);
        gotoxy(0, 1);
    }
    system("CLS");
    for (int i = 1; i <= snum; i++)
        if (s_name == rrnk[i].second)
        {
            x = i;
            break;
        }
    for (int i = 1; i <= qnum; i++)
        if (a[id].p[i] == q[i])
            s_right++;
    color(23);
    cout << s_name;
    color(7);
    cc("的得分为");
    color(47);
    cout << a[id].pts;
    color(7);
    cc("是全班的第");
    color(63);
    cout << x;
    color(7);
    cc("名\n");
    cc("在这场考试中");
    color(23);
    cout << s_name;
    color(7);
    cc("做对了");
    color(95);
    cout << s_right;
    color(7);
    c("道题目\n");
    cout << s_name;
    cc("在这场考试中的正确率为");
    color(111);
    cout << (double)s_right * 100.0 / qnum << "%";
    color(7);
}
void choes()
{
    color(7);
    c("1.输出此次考试的基本信息\n");
    c("2.输出成绩排行榜\n");
    c("3.查看具体一道题的情况\n");
    c("4.查看具体一位同学的答题情况\n");
    c("5.结束");
    _ = getch();
    system("CLS");
    if (_ == '1')
    {
        basic();
        _getch();
    }
    if (_ == '2')
    {
        rnk();
        _getch();
    }
    if (_ == '3')
    {
        ques();
        _getch();
    }
    if (_ == '4')
    {
        stud();
        _getch();
    }
    system("CLS");
}
signed main()
{
    js();
    if (_ == '2')
        warning();
    pre_us();
    for (int i = 1; i <= snum; i++)
        us(i);
    pre_basic();
    while (_ != '5')
        choes();
    return 0;
}