Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

【绘制入学至今的条形图及环形图版本】windows下绘制更美观的条形和环形图(低于1%占比的消费去除文字标注) #21

Open
Photen opened this issue Dec 21, 2024 · 2 comments

Comments

@Photen
Copy link

Photen commented Dec 21, 2024

from Crypto.Cipher import AES
from Crypto.Util.Padding import unpad
import base64
import json
import matplotlib.pyplot as plt
import requests
import platform
import datetime

def decrypt_aes_ecb(encrypted_data: str) -> str:
    
    key = encrypted_data[:16].encode('utf-8')
    encrypted_data = encrypted_data[16:]
    encrypted_data_bytes = base64.b64decode(encrypted_data)
    
    cipher = AES.new(key, AES.MODE_ECB)
    
    decrypted_data = unpad(cipher.decrypt(encrypted_data_bytes), AES.block_size)

    return decrypted_data.decode('utf-8')

idserial = ""
servicehall = ""
all_data = dict()

if __name__ == "__main__":
    # 读入账户信息
    try:
        with open("config.json", "r", encoding='utf-8') as f:
            account = json.load(f)
            idserial = account["idserial"]
            servicehall = account["servicehall"]
    except Exception as e:
        print("账户信息读取失败,请重新输入")
        idserial = input("请输入学号: ")
        servicehall = input("请输入服务代码: ")
        with open("config.json", "w", encoding='utf-8') as f:
            json.dump({"idserial": idserial, "servicehall": servicehall}, f, indent=4)
    
    endtime = datetime.datetime.now().strftime("%Y-%m-%d")
    print(f"开始获取数据,开始日期为2000-01-01,截止日期为{endtime}")
    # 发送请求,得到加密后的字符串
    url = f"https://card.tsinghua.edu.cn/business/querySelfTradeList?pageNumber=0&pageSize=5000&starttime=2000-01-01&endtime={endtime}&idserial={idserial}&tradetype=-1"
    cookie = {
        "servicehall": servicehall,
    }
    response = requests.post(url, cookies=cookie)

    # 解密字符串
    encrypted_string = json.loads(response.text)["data"]
    decrypted_string = decrypt_aes_ecb(encrypted_string)

    # 整理数据
    data = json.loads(decrypted_string)
    for item in data["resultData"]["rows"]:
        try:
            if item["mername"] in all_data:
                all_data[item["mername"]] += item["txamt"]
            else:
                all_data[item["mername"]] = item["txamt"]
        except Exception as e:
            pass
    all_data = {k: round(v / 100, 2) for k, v in all_data.items()} # 将分转换为元,并保留两位小数
    print(len(all_data))
    # 输出结果
    all_data = dict(sorted(all_data.items(), key=lambda x: x[1], reverse=False))

    # 存储结果
    with open("result.txt", "w", encoding='utf-8') as f:
        for k, v in all_data.items():
            f.write(f"{k}: {v}\n")
    if platform.system() == "Darwin":
        plt.rcParams['font.sans-serif'] = ['Arial Unicode MS']
    elif platform.system() == "Linux":
        plt.rcParams['font.family'] = ['Droid Sans Fallback', 'DejaVu Sans']
    else:
        plt.rcParams['font.sans-serif'] = ['SimHei']
        
    plt.figure(figsize=(14,12))
    plt.style.use('seaborn')

    # 设置seaborn使用中文字体
    plt.rcParams['font.sans-serif'] = ['SimHei']
    plt.rcParams['axes.unicode_minus'] = False


    plt.barh(list(all_data.keys()), list(all_data.values()))
    for index, value in enumerate(list(all_data.values())):
        plt.text(value + 0.01 * max(all_data.values()),
                index,
                str(value),
                va='center')
        
    # plt.tight_layout()
    plt.xlim(0, 1.2 * max(all_data.values()))
    plt.title("华清大学食堂消费情况")
    plt.xlabel("消费金额(元)")
    plt.savefig("result.png", dpi = 400)
    plt.show()

    plt.figure(figsize=(10,10))
    lables_pie = list(all_data.keys())
    sizes_pie = list(all_data.values())
    lables_pie = [lables_pie[i]  if sizes_pie[i]/sum(sizes_pie) >=0.01  else '' for i in range(len(lables_pie))]
    plt.pie(list(all_data.values()), labels=lables_pie, autopct='%1.1f%%',pctdistance=0.9, labeldistance=1.1, startangle=90, counterclock=False, wedgeprops=dict(width=0.3, edgecolor='w'))

    plt.title("华清大学食堂消费情况")
    plt.savefig("result_pie.png", dpi = 400)
    plt.show()

时间范围取从2000年1月1日到程序运行的日期,经验证为入学年份起(无法查询本科的就餐记录),并新增了绘制环形图的功能。

注意此处仅做了windows适配。

@Photen
Copy link
Author

Photen commented Dec 21, 2024

补充:上文指研究生无法查询本科时的就餐记录,不是本科生无法查询本科生就餐记录

@JoannaWHN
Copy link

学校服务器端也只保存到2023年7月底的消费记录,之前的查不到

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants