提交最新文件:包含dist可执行文件、build编译目录及配置文件 #7

Merged
hnu202326010131 merged 2 commits from xingyuanxin_branch into main 3 months ago

@ -0,0 +1,62 @@
# -*- mode: python ; coding: utf-8 -*-
block_cipher = None
a = Analysis(
['src/app.py'],
pathex=[],
binaries=[],
datas=[
('src/storage/users.json', 'storage'),
('src/storage/config.json', 'storage'),
],
hiddenimports=[
'PyQt6.QtCore',
'PyQt6.QtWidgets',
'PyQt6.QtGui',
'smtplib',
'ssl',
'json',
'hashlib',
'secrets',
'datetime',
'random',
'math',
're',
'os',
'sys'
],
hookspath=[],
hooksconfig={},
runtime_hooks=[],
excludes=[],
win_no_prefer_redirects=False,
win_private_assemblies=False,
cipher=block_cipher,
noarchive=False,
)
pyz = PYZ(a.pure, a.zipped_data, cipher=block_cipher)
exe = EXE(
pyz,
a.scripts,
a.binaries,
a.zipfiles,
a.datas,
[],
name='MathStudySystem',
debug=False,
bootloader_ignore_signals=False,
strip=False,
upx=True,
upx_exclude=[],
runtime_tmpdir=None,
console=False,
disable_windowed_traceback=False,
argv_emulation=False,
target_arch=None,
codesign_identity=None,
entitlements_file=None,
icon=None,
)

@ -0,0 +1,33 @@
@echo off
echo 开始打包数学学习系统...
echo.
REM 检查是否安装了PyInstaller
python -c "import PyInstaller" 2>nul
if errorlevel 1 (
echo 错误未找到PyInstaller请先安装pip install pyinstaller
pause
exit /b 1
)
REM 清理之前的构建文件
if exist "build" rmdir /s /q "build"
if exist "dist" rmdir /s /q "dist"
if exist "__pycache__" rmdir /s /q "__pycache__"
echo 清理完成,开始打包...
echo.
REM 执行打包命令
pyinstaller --clean MathStudySystem.spec
if errorlevel 1 (
echo 打包失败!请检查错误信息。
pause
exit /b 1
)
echo.
echo 打包完成!可执行文件位于 dist 目录中。
echo.
pause

@ -0,0 +1,28 @@
#!/bin/bash
echo "开始打包数学学习系统..."
echo
# 检查是否安装了PyInstaller
if ! python -c "import PyInstaller" 2>/dev/null; then
echo "错误未找到PyInstaller请先安装pip install pyinstaller"
exit 1
fi
# 清理之前的构建文件
rm -rf build dist __pycache__
echo "清理完成,开始打包..."
echo
# 执行打包命令
pyinstaller --clean MathStudySystem.spec
if [ $? -ne 0 ]; then
echo "打包失败!请检查错误信息。"
exit 1
fi
echo
echo "打包完成!可执行文件位于 dist 目录中。"
echo

File diff suppressed because it is too large Load Diff

@ -0,0 +1,597 @@
('C:\\Users\\xyx29\\source\\软件工程导论\\MathStudySystem-develop\\mathstudysystem\\MathStudySystem-develop\\mathstudysystem\\dist\\MathStudySystem.exe',
False,
False,
False,
'E:\\Anaconda\\anaconda3\\Lib\\site-packages\\PyInstaller\\bootloader\\images\\icon-windowed.ico',
None,
False,
False,
b'<?xml version="1.0" encoding="UTF-8" standalone="yes"?>\n<assembly xmlns='
b'"urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">\n <trustInfo x'
b'mlns="urn:schemas-microsoft-com:asm.v3">\n <security>\n <requested'
b'Privileges>\n <requestedExecutionLevel level="asInvoker" uiAccess='
b'"false"/>\n </requestedPrivileges>\n </security>\n </trustInfo>\n '
b'<compatibility xmlns="urn:schemas-microsoft-com:compatibility.v1">\n <'
b'application>\n <supportedOS Id="{e2011457-1546-43c5-a5fe-008deee3d3f'
b'0}"/>\n <supportedOS Id="{35138b9a-5d96-4fbd-8e2d-a2440225f93a}"/>\n '
b' <supportedOS Id="{4a2f28e3-53b9-4441-ba9c-d69d4a4a6e38}"/>\n <s'
b'upportedOS Id="{1f676c76-80e1-4239-95bb-83d0f6d0da78}"/>\n <supporte'
b'dOS Id="{8e0f7a12-bfb3-4fe8-b9a5-48fd50a15a9a}"/>\n </application>\n <'
b'/compatibility>\n <application xmlns="urn:schemas-microsoft-com:asm.v3">'
b'\n <windowsSettings>\n <longPathAware xmlns="http://schemas.micros'
b'oft.com/SMI/2016/WindowsSettings">true</longPathAware>\n </windowsSett'
b'ings>\n </application>\n <dependency>\n <dependentAssembly>\n <ass'
b'emblyIdentity type="win32" name="Microsoft.Windows.Common-Controls" version='
b'"6.0.0.0" processorArchitecture="*" publicKeyToken="6595b64144ccf1df" langua'
b'ge="*"/>\n </dependentAssembly>\n </dependency>\n</assembly>',
True,
False,
None,
None,
None,
'C:\\Users\\xyx29\\source\\软件工程导论\\MathStudySystem-develop\\mathstudysystem\\MathStudySystem-develop\\mathstudysystem\\build\\MathStudySystem\\MathStudySystem.pkg',
[('pyi-contents-directory _internal', '', 'OPTION'),
('PYZ-00.pyz',
'C:\\Users\\xyx29\\source\\软件工程导论\\MathStudySystem-develop\\mathstudysystem\\MathStudySystem-develop\\mathstudysystem\\build\\MathStudySystem\\PYZ-00.pyz',
'PYZ'),
('struct',
'C:\\Users\\xyx29\\source\\软件工程导论\\MathStudySystem-develop\\mathstudysystem\\MathStudySystem-develop\\mathstudysystem\\build\\MathStudySystem\\localpycs\\struct.pyc',
'PYMODULE'),
('pyimod01_archive',
'C:\\Users\\xyx29\\source\\软件工程导论\\MathStudySystem-develop\\mathstudysystem\\MathStudySystem-develop\\mathstudysystem\\build\\MathStudySystem\\localpycs\\pyimod01_archive.pyc',
'PYMODULE'),
('pyimod02_importers',
'C:\\Users\\xyx29\\source\\软件工程导论\\MathStudySystem-develop\\mathstudysystem\\MathStudySystem-develop\\mathstudysystem\\build\\MathStudySystem\\localpycs\\pyimod02_importers.pyc',
'PYMODULE'),
('pyimod03_ctypes',
'C:\\Users\\xyx29\\source\\软件工程导论\\MathStudySystem-develop\\mathstudysystem\\MathStudySystem-develop\\mathstudysystem\\build\\MathStudySystem\\localpycs\\pyimod03_ctypes.pyc',
'PYMODULE'),
('pyimod04_pywin32',
'C:\\Users\\xyx29\\source\\软件工程导论\\MathStudySystem-develop\\mathstudysystem\\MathStudySystem-develop\\mathstudysystem\\build\\MathStudySystem\\localpycs\\pyimod04_pywin32.pyc',
'PYMODULE'),
('pyiboot01_bootstrap',
'E:\\Anaconda\\anaconda3\\Lib\\site-packages\\PyInstaller\\loader\\pyiboot01_bootstrap.py',
'PYSOURCE'),
('pyi_rth_inspect',
'E:\\Anaconda\\anaconda3\\Lib\\site-packages\\PyInstaller\\hooks\\rthooks\\pyi_rth_inspect.py',
'PYSOURCE'),
('pyi_rth_pyqt6',
'E:\\Anaconda\\anaconda3\\Lib\\site-packages\\PyInstaller\\hooks\\rthooks\\pyi_rth_pyqt6.py',
'PYSOURCE'),
('pyi_rth_pkgutil',
'E:\\Anaconda\\anaconda3\\Lib\\site-packages\\PyInstaller\\hooks\\rthooks\\pyi_rth_pkgutil.py',
'PYSOURCE'),
('app',
'C:\\Users\\xyx29\\source\\软件工程导论\\MathStudySystem-develop\\mathstudysystem\\MathStudySystem-develop\\mathstudysystem\\src\\app.py',
'PYSOURCE'),
('python311.dll', 'E:\\Anaconda\\anaconda3\\python311.dll', 'BINARY'),
('PyQt6\\Qt6\\plugins\\generic\\qtuiotouchplugin.dll',
'E:\\Anaconda\\anaconda3\\Lib\\site-packages\\PyQt6\\Qt6\\plugins\\generic\\qtuiotouchplugin.dll',
'BINARY'),
('PyQt6\\Qt6\\plugins\\iconengines\\qsvgicon.dll',
'E:\\Anaconda\\anaconda3\\Lib\\site-packages\\PyQt6\\Qt6\\plugins\\iconengines\\qsvgicon.dll',
'BINARY'),
('PyQt6\\Qt6\\plugins\\imageformats\\qico.dll',
'E:\\Anaconda\\anaconda3\\Lib\\site-packages\\PyQt6\\Qt6\\plugins\\imageformats\\qico.dll',
'BINARY'),
('PyQt6\\Qt6\\plugins\\imageformats\\qsvg.dll',
'E:\\Anaconda\\anaconda3\\Lib\\site-packages\\PyQt6\\Qt6\\plugins\\imageformats\\qsvg.dll',
'BINARY'),
('PyQt6\\Qt6\\plugins\\imageformats\\qtga.dll',
'E:\\Anaconda\\anaconda3\\Lib\\site-packages\\PyQt6\\Qt6\\plugins\\imageformats\\qtga.dll',
'BINARY'),
('PyQt6\\Qt6\\plugins\\imageformats\\qgif.dll',
'E:\\Anaconda\\anaconda3\\Lib\\site-packages\\PyQt6\\Qt6\\plugins\\imageformats\\qgif.dll',
'BINARY'),
('PyQt6\\Qt6\\plugins\\imageformats\\qwbmp.dll',
'E:\\Anaconda\\anaconda3\\Lib\\site-packages\\PyQt6\\Qt6\\plugins\\imageformats\\qwbmp.dll',
'BINARY'),
('PyQt6\\Qt6\\plugins\\platforms\\qwindows.dll',
'E:\\Anaconda\\anaconda3\\Lib\\site-packages\\PyQt6\\Qt6\\plugins\\platforms\\qwindows.dll',
'BINARY'),
('PyQt6\\Qt6\\plugins\\imageformats\\qicns.dll',
'E:\\Anaconda\\anaconda3\\Lib\\site-packages\\PyQt6\\Qt6\\plugins\\imageformats\\qicns.dll',
'BINARY'),
('PyQt6\\Qt6\\plugins\\imageformats\\qwebp.dll',
'E:\\Anaconda\\anaconda3\\Lib\\site-packages\\PyQt6\\Qt6\\plugins\\imageformats\\qwebp.dll',
'BINARY'),
('PyQt6\\Qt6\\plugins\\platforms\\qminimal.dll',
'E:\\Anaconda\\anaconda3\\Lib\\site-packages\\PyQt6\\Qt6\\plugins\\platforms\\qminimal.dll',
'BINARY'),
('PyQt6\\Qt6\\plugins\\platforms\\qoffscreen.dll',
'E:\\Anaconda\\anaconda3\\Lib\\site-packages\\PyQt6\\Qt6\\plugins\\platforms\\qoffscreen.dll',
'BINARY'),
('PyQt6\\Qt6\\plugins\\imageformats\\qjpeg.dll',
'E:\\Anaconda\\anaconda3\\Lib\\site-packages\\PyQt6\\Qt6\\plugins\\imageformats\\qjpeg.dll',
'BINARY'),
('PyQt6\\Qt6\\plugins\\imageformats\\qtiff.dll',
'E:\\Anaconda\\anaconda3\\Lib\\site-packages\\PyQt6\\Qt6\\plugins\\imageformats\\qtiff.dll',
'BINARY'),
('PyQt6\\Qt6\\plugins\\imageformats\\qpdf.dll',
'E:\\Anaconda\\anaconda3\\Lib\\site-packages\\PyQt6\\Qt6\\plugins\\imageformats\\qpdf.dll',
'BINARY'),
('PyQt6\\Qt6\\bin\\opengl32sw.dll',
'E:\\Anaconda\\anaconda3\\Lib\\site-packages\\PyQt6\\Qt6\\bin\\opengl32sw.dll',
'BINARY'),
('PyQt6\\Qt6\\plugins\\styles\\qmodernwindowsstyle.dll',
'E:\\Anaconda\\anaconda3\\Lib\\site-packages\\PyQt6\\Qt6\\plugins\\styles\\qmodernwindowsstyle.dll',
'BINARY'),
('_lzma.pyd', 'E:\\Anaconda\\anaconda3\\DLLs\\_lzma.pyd', 'EXTENSION'),
('_bz2.pyd', 'E:\\Anaconda\\anaconda3\\DLLs\\_bz2.pyd', 'EXTENSION'),
('unicodedata.pyd',
'E:\\Anaconda\\anaconda3\\DLLs\\unicodedata.pyd',
'EXTENSION'),
('select.pyd', 'E:\\Anaconda\\anaconda3\\DLLs\\select.pyd', 'EXTENSION'),
('_socket.pyd', 'E:\\Anaconda\\anaconda3\\DLLs\\_socket.pyd', 'EXTENSION'),
('_decimal.pyd', 'E:\\Anaconda\\anaconda3\\DLLs\\_decimal.pyd', 'EXTENSION'),
('_hashlib.pyd', 'E:\\Anaconda\\anaconda3\\DLLs\\_hashlib.pyd', 'EXTENSION'),
('_ssl.pyd', 'E:\\Anaconda\\anaconda3\\DLLs\\_ssl.pyd', 'EXTENSION'),
('PyQt6\\QtGui.pyd',
'E:\\Anaconda\\anaconda3\\Lib\\site-packages\\PyQt6\\QtGui.pyd',
'EXTENSION'),
('PyQt6\\sip.cp311-win_amd64.pyd',
'E:\\Anaconda\\anaconda3\\Lib\\site-packages\\PyQt6\\sip.cp311-win_amd64.pyd',
'EXTENSION'),
('PyQt6\\QtCore.pyd',
'E:\\Anaconda\\anaconda3\\Lib\\site-packages\\PyQt6\\QtCore.pyd',
'EXTENSION'),
('PyQt6\\QtWidgets.pyd',
'E:\\Anaconda\\anaconda3\\Lib\\site-packages\\PyQt6\\QtWidgets.pyd',
'EXTENSION'),
('api-ms-win-crt-stdio-l1-1-0.dll',
'E:\\Anaconda\\anaconda3\\api-ms-win-crt-stdio-l1-1-0.dll',
'BINARY'),
('api-ms-win-crt-environment-l1-1-0.dll',
'E:\\Anaconda\\anaconda3\\api-ms-win-crt-environment-l1-1-0.dll',
'BINARY'),
('api-ms-win-crt-process-l1-1-0.dll',
'E:\\Anaconda\\anaconda3\\api-ms-win-crt-process-l1-1-0.dll',
'BINARY'),
('VCRUNTIME140.dll', 'E:\\Anaconda\\anaconda3\\VCRUNTIME140.dll', 'BINARY'),
('zlib.dll', 'E:\\Anaconda\\anaconda3\\zlib.dll', 'BINARY'),
('api-ms-win-crt-math-l1-1-0.dll',
'E:\\Anaconda\\anaconda3\\api-ms-win-crt-math-l1-1-0.dll',
'BINARY'),
('api-ms-win-crt-time-l1-1-0.dll',
'E:\\Anaconda\\anaconda3\\api-ms-win-crt-time-l1-1-0.dll',
'BINARY'),
('api-ms-win-crt-conio-l1-1-0.dll',
'E:\\Anaconda\\anaconda3\\api-ms-win-crt-conio-l1-1-0.dll',
'BINARY'),
('api-ms-win-crt-string-l1-1-0.dll',
'E:\\Anaconda\\anaconda3\\api-ms-win-crt-string-l1-1-0.dll',
'BINARY'),
('api-ms-win-crt-heap-l1-1-0.dll',
'E:\\Anaconda\\anaconda3\\api-ms-win-crt-heap-l1-1-0.dll',
'BINARY'),
('api-ms-win-crt-locale-l1-1-0.dll',
'E:\\Anaconda\\anaconda3\\api-ms-win-crt-locale-l1-1-0.dll',
'BINARY'),
('api-ms-win-crt-convert-l1-1-0.dll',
'E:\\Anaconda\\anaconda3\\api-ms-win-crt-convert-l1-1-0.dll',
'BINARY'),
('api-ms-win-crt-runtime-l1-1-0.dll',
'E:\\Anaconda\\anaconda3\\api-ms-win-crt-runtime-l1-1-0.dll',
'BINARY'),
('api-ms-win-crt-filesystem-l1-1-0.dll',
'E:\\Anaconda\\anaconda3\\api-ms-win-crt-filesystem-l1-1-0.dll',
'BINARY'),
('PyQt6\\Qt6\\bin\\Qt6Network.dll',
'E:\\Anaconda\\anaconda3\\Lib\\site-packages\\PyQt6\\Qt6\\bin\\Qt6Network.dll',
'BINARY'),
('PyQt6\\Qt6\\bin\\Qt6Core.dll',
'E:\\Anaconda\\anaconda3\\Lib\\site-packages\\PyQt6\\Qt6\\bin\\Qt6Core.dll',
'BINARY'),
('MSVCP140.dll', 'E:\\Anaconda\\anaconda3\\MSVCP140.dll', 'BINARY'),
('VCRUNTIME140_1.dll',
'E:\\Anaconda\\anaconda3\\VCRUNTIME140_1.dll',
'BINARY'),
('PyQt6\\Qt6\\bin\\Qt6Gui.dll',
'E:\\Anaconda\\anaconda3\\Lib\\site-packages\\PyQt6\\Qt6\\bin\\Qt6Gui.dll',
'BINARY'),
('PyQt6\\Qt6\\bin\\Qt6Svg.dll',
'E:\\Anaconda\\anaconda3\\Lib\\site-packages\\PyQt6\\Qt6\\bin\\Qt6Svg.dll',
'BINARY'),
('api-ms-win-crt-utility-l1-1-0.dll',
'E:\\Anaconda\\anaconda3\\api-ms-win-crt-utility-l1-1-0.dll',
'BINARY'),
('PyQt6\\Qt6\\bin\\Qt6Pdf.dll',
'E:\\Anaconda\\anaconda3\\Lib\\site-packages\\PyQt6\\Qt6\\bin\\Qt6Pdf.dll',
'BINARY'),
('PyQt6\\Qt6\\bin\\Qt6Widgets.dll',
'E:\\Anaconda\\anaconda3\\Lib\\site-packages\\PyQt6\\Qt6\\bin\\Qt6Widgets.dll',
'BINARY'),
('liblzma.dll', 'D:\\Graphviz\\bin\\liblzma.dll', 'BINARY'),
('LIBBZ2.dll', 'E:\\Anaconda\\anaconda3\\Library\\bin\\LIBBZ2.dll', 'BINARY'),
('libcrypto-3-x64.dll',
'D:\\php\\php-8.4.7-Win32-vs17-x64\\libcrypto-3-x64.dll',
'BINARY'),
('libssl-3-x64.dll',
'D:\\php\\php-8.4.7-Win32-vs17-x64\\libssl-3-x64.dll',
'BINARY'),
('MSVCP140_2.dll', 'E:\\Anaconda\\anaconda3\\MSVCP140_2.dll', 'BINARY'),
('python3.dll', 'E:\\Anaconda\\anaconda3\\python3.dll', 'BINARY'),
('ucrtbase.dll', 'E:\\Anaconda\\anaconda3\\ucrtbase.dll', 'BINARY'),
('PyQt6\\Qt6\\bin\\MSVCP140.dll',
'E:\\Anaconda\\anaconda3\\Lib\\site-packages\\PyQt6\\Qt6\\bin\\MSVCP140.dll',
'BINARY'),
('PyQt6\\Qt6\\bin\\VCRUNTIME140_1.dll',
'E:\\Anaconda\\anaconda3\\Lib\\site-packages\\PyQt6\\Qt6\\bin\\VCRUNTIME140_1.dll',
'BINARY'),
('PyQt6\\Qt6\\bin\\VCRUNTIME140.dll',
'E:\\Anaconda\\anaconda3\\Lib\\site-packages\\PyQt6\\Qt6\\bin\\VCRUNTIME140.dll',
'BINARY'),
('PyQt6\\Qt6\\bin\\MSVCP140_1.dll',
'E:\\Anaconda\\anaconda3\\Lib\\site-packages\\PyQt6\\Qt6\\bin\\MSVCP140_1.dll',
'BINARY'),
('api-ms-win-core-synch-l1-2-0.dll',
'E:\\Anaconda\\anaconda3\\api-ms-win-core-synch-l1-2-0.dll',
'BINARY'),
('PyQt6\\Qt6\\bin\\MSVCP140_2.dll',
'E:\\Anaconda\\anaconda3\\Lib\\site-packages\\PyQt6\\Qt6\\bin\\MSVCP140_2.dll',
'BINARY'),
('api-ms-win-core-processthreads-l1-1-0.dll',
'E:\\Anaconda\\anaconda3\\api-ms-win-core-processthreads-l1-1-0.dll',
'BINARY'),
('api-ms-win-core-heap-l1-1-0.dll',
'E:\\Anaconda\\anaconda3\\api-ms-win-core-heap-l1-1-0.dll',
'BINARY'),
('api-ms-win-core-processthreads-l1-1-1.dll',
'E:\\Anaconda\\anaconda3\\api-ms-win-core-processthreads-l1-1-1.dll',
'BINARY'),
('api-ms-win-core-processenvironment-l1-1-0.dll',
'E:\\Anaconda\\anaconda3\\api-ms-win-core-processenvironment-l1-1-0.dll',
'BINARY'),
('api-ms-win-core-rtlsupport-l1-1-0.dll',
'E:\\Anaconda\\anaconda3\\api-ms-win-core-rtlsupport-l1-1-0.dll',
'BINARY'),
('api-ms-win-core-file-l1-2-0.dll',
'E:\\Anaconda\\anaconda3\\api-ms-win-core-file-l1-2-0.dll',
'BINARY'),
('api-ms-win-core-sysinfo-l1-1-0.dll',
'E:\\Anaconda\\anaconda3\\api-ms-win-core-sysinfo-l1-1-0.dll',
'BINARY'),
('api-ms-win-core-handle-l1-1-0.dll',
'E:\\Anaconda\\anaconda3\\api-ms-win-core-handle-l1-1-0.dll',
'BINARY'),
('api-ms-win-core-console-l1-1-0.dll',
'E:\\Anaconda\\anaconda3\\api-ms-win-core-console-l1-1-0.dll',
'BINARY'),
('api-ms-win-core-util-l1-1-0.dll',
'E:\\Anaconda\\anaconda3\\api-ms-win-core-util-l1-1-0.dll',
'BINARY'),
('api-ms-win-core-memory-l1-1-0.dll',
'E:\\Anaconda\\anaconda3\\api-ms-win-core-memory-l1-1-0.dll',
'BINARY'),
('api-ms-win-core-synch-l1-1-0.dll',
'E:\\Anaconda\\anaconda3\\api-ms-win-core-synch-l1-1-0.dll',
'BINARY'),
('api-ms-win-core-interlocked-l1-1-0.dll',
'E:\\Anaconda\\anaconda3\\api-ms-win-core-interlocked-l1-1-0.dll',
'BINARY'),
('api-ms-win-core-timezone-l1-1-0.dll',
'E:\\Anaconda\\anaconda3\\api-ms-win-core-timezone-l1-1-0.dll',
'BINARY'),
('api-ms-win-core-localization-l1-2-0.dll',
'E:\\Anaconda\\anaconda3\\api-ms-win-core-localization-l1-2-0.dll',
'BINARY'),
('api-ms-win-core-profile-l1-1-0.dll',
'E:\\Anaconda\\anaconda3\\api-ms-win-core-profile-l1-1-0.dll',
'BINARY'),
('api-ms-win-core-string-l1-1-0.dll',
'E:\\Anaconda\\anaconda3\\api-ms-win-core-string-l1-1-0.dll',
'BINARY'),
('api-ms-win-core-datetime-l1-1-0.dll',
'E:\\Anaconda\\anaconda3\\api-ms-win-core-datetime-l1-1-0.dll',
'BINARY'),
('api-ms-win-core-debug-l1-1-0.dll',
'E:\\Anaconda\\anaconda3\\api-ms-win-core-debug-l1-1-0.dll',
'BINARY'),
('api-ms-win-core-libraryloader-l1-1-0.dll',
'E:\\Anaconda\\anaconda3\\api-ms-win-core-libraryloader-l1-1-0.dll',
'BINARY'),
('api-ms-win-core-namedpipe-l1-1-0.dll',
'E:\\Anaconda\\anaconda3\\api-ms-win-core-namedpipe-l1-1-0.dll',
'BINARY'),
('api-ms-win-core-errorhandling-l1-1-0.dll',
'E:\\Anaconda\\anaconda3\\api-ms-win-core-errorhandling-l1-1-0.dll',
'BINARY'),
('api-ms-win-core-file-l1-1-0.dll',
'E:\\Anaconda\\anaconda3\\api-ms-win-core-file-l1-1-0.dll',
'BINARY'),
('api-ms-win-core-file-l2-1-0.dll',
'E:\\Anaconda\\anaconda3\\api-ms-win-core-file-l2-1-0.dll',
'BINARY'),
('storage\\config.json',
'C:\\Users\\xyx29\\source\\软件工程导论\\MathStudySystem-develop\\mathstudysystem\\MathStudySystem-develop\\mathstudysystem\\src\\storage\\config.json',
'DATA'),
('storage\\users.json',
'C:\\Users\\xyx29\\source\\软件工程导论\\MathStudySystem-develop\\mathstudysystem\\MathStudySystem-develop\\mathstudysystem\\src\\storage\\users.json',
'DATA'),
('PyQt6\\Qt6\\translations\\qt_fa.qm',
'E:\\Anaconda\\anaconda3\\Lib\\site-packages\\PyQt6\\Qt6\\translations\\qt_fa.qm',
'DATA'),
('PyQt6\\Qt6\\translations\\qt_help_tr.qm',
'E:\\Anaconda\\anaconda3\\Lib\\site-packages\\PyQt6\\Qt6\\translations\\qt_help_tr.qm',
'DATA'),
('PyQt6\\Qt6\\translations\\qtbase_pl.qm',
'E:\\Anaconda\\anaconda3\\Lib\\site-packages\\PyQt6\\Qt6\\translations\\qtbase_pl.qm',
'DATA'),
('PyQt6\\Qt6\\translations\\qt_help_gl.qm',
'E:\\Anaconda\\anaconda3\\Lib\\site-packages\\PyQt6\\Qt6\\translations\\qt_help_gl.qm',
'DATA'),
('PyQt6\\Qt6\\translations\\qt_uk.qm',
'E:\\Anaconda\\anaconda3\\Lib\\site-packages\\PyQt6\\Qt6\\translations\\qt_uk.qm',
'DATA'),
('PyQt6\\Qt6\\translations\\qt_hr.qm',
'E:\\Anaconda\\anaconda3\\Lib\\site-packages\\PyQt6\\Qt6\\translations\\qt_hr.qm',
'DATA'),
('PyQt6\\Qt6\\translations\\qt_help_nn.qm',
'E:\\Anaconda\\anaconda3\\Lib\\site-packages\\PyQt6\\Qt6\\translations\\qt_help_nn.qm',
'DATA'),
('PyQt6\\Qt6\\translations\\qtbase_ca.qm',
'E:\\Anaconda\\anaconda3\\Lib\\site-packages\\PyQt6\\Qt6\\translations\\qtbase_ca.qm',
'DATA'),
('PyQt6\\Qt6\\translations\\qt_zh_TW.qm',
'E:\\Anaconda\\anaconda3\\Lib\\site-packages\\PyQt6\\Qt6\\translations\\qt_zh_TW.qm',
'DATA'),
('PyQt6\\Qt6\\translations\\qt_tr.qm',
'E:\\Anaconda\\anaconda3\\Lib\\site-packages\\PyQt6\\Qt6\\translations\\qt_tr.qm',
'DATA'),
('PyQt6\\Qt6\\translations\\qtbase_bg.qm',
'E:\\Anaconda\\anaconda3\\Lib\\site-packages\\PyQt6\\Qt6\\translations\\qtbase_bg.qm',
'DATA'),
('PyQt6\\Qt6\\translations\\qtbase_en.qm',
'E:\\Anaconda\\anaconda3\\Lib\\site-packages\\PyQt6\\Qt6\\translations\\qtbase_en.qm',
'DATA'),
('PyQt6\\Qt6\\translations\\qt_help_ru.qm',
'E:\\Anaconda\\anaconda3\\Lib\\site-packages\\PyQt6\\Qt6\\translations\\qt_help_ru.qm',
'DATA'),
('PyQt6\\Qt6\\translations\\qt_help_zh_TW.qm',
'E:\\Anaconda\\anaconda3\\Lib\\site-packages\\PyQt6\\Qt6\\translations\\qt_help_zh_TW.qm',
'DATA'),
('PyQt6\\Qt6\\translations\\qt_lt.qm',
'E:\\Anaconda\\anaconda3\\Lib\\site-packages\\PyQt6\\Qt6\\translations\\qt_lt.qm',
'DATA'),
('PyQt6\\Qt6\\translations\\qt_ka.qm',
'E:\\Anaconda\\anaconda3\\Lib\\site-packages\\PyQt6\\Qt6\\translations\\qt_ka.qm',
'DATA'),
('PyQt6\\Qt6\\translations\\qtbase_sk.qm',
'E:\\Anaconda\\anaconda3\\Lib\\site-packages\\PyQt6\\Qt6\\translations\\qtbase_sk.qm',
'DATA'),
('PyQt6\\Qt6\\translations\\qtbase_fi.qm',
'E:\\Anaconda\\anaconda3\\Lib\\site-packages\\PyQt6\\Qt6\\translations\\qtbase_fi.qm',
'DATA'),
('PyQt6\\Qt6\\translations\\qtbase_zh_CN.qm',
'E:\\Anaconda\\anaconda3\\Lib\\site-packages\\PyQt6\\Qt6\\translations\\qtbase_zh_CN.qm',
'DATA'),
('PyQt6\\Qt6\\translations\\qt_nl.qm',
'E:\\Anaconda\\anaconda3\\Lib\\site-packages\\PyQt6\\Qt6\\translations\\qt_nl.qm',
'DATA'),
('PyQt6\\Qt6\\translations\\qt_ar.qm',
'E:\\Anaconda\\anaconda3\\Lib\\site-packages\\PyQt6\\Qt6\\translations\\qt_ar.qm',
'DATA'),
('PyQt6\\Qt6\\translations\\qtbase_da.qm',
'E:\\Anaconda\\anaconda3\\Lib\\site-packages\\PyQt6\\Qt6\\translations\\qtbase_da.qm',
'DATA'),
('PyQt6\\Qt6\\translations\\qt_help_bg.qm',
'E:\\Anaconda\\anaconda3\\Lib\\site-packages\\PyQt6\\Qt6\\translations\\qt_help_bg.qm',
'DATA'),
('PyQt6\\Qt6\\translations\\qt_de.qm',
'E:\\Anaconda\\anaconda3\\Lib\\site-packages\\PyQt6\\Qt6\\translations\\qt_de.qm',
'DATA'),
('PyQt6\\Qt6\\translations\\qt_pl.qm',
'E:\\Anaconda\\anaconda3\\Lib\\site-packages\\PyQt6\\Qt6\\translations\\qt_pl.qm',
'DATA'),
('PyQt6\\Qt6\\translations\\qtbase_nn.qm',
'E:\\Anaconda\\anaconda3\\Lib\\site-packages\\PyQt6\\Qt6\\translations\\qtbase_nn.qm',
'DATA'),
('PyQt6\\Qt6\\translations\\qtbase_hr.qm',
'E:\\Anaconda\\anaconda3\\Lib\\site-packages\\PyQt6\\Qt6\\translations\\qtbase_hr.qm',
'DATA'),
('PyQt6\\Qt6\\translations\\qtbase_ar.qm',
'E:\\Anaconda\\anaconda3\\Lib\\site-packages\\PyQt6\\Qt6\\translations\\qtbase_ar.qm',
'DATA'),
('PyQt6\\Qt6\\translations\\qtbase_hu.qm',
'E:\\Anaconda\\anaconda3\\Lib\\site-packages\\PyQt6\\Qt6\\translations\\qtbase_hu.qm',
'DATA'),
('PyQt6\\Qt6\\translations\\qt_help_ka.qm',
'E:\\Anaconda\\anaconda3\\Lib\\site-packages\\PyQt6\\Qt6\\translations\\qt_help_ka.qm',
'DATA'),
('PyQt6\\Qt6\\translations\\qt_cs.qm',
'E:\\Anaconda\\anaconda3\\Lib\\site-packages\\PyQt6\\Qt6\\translations\\qt_cs.qm',
'DATA'),
('PyQt6\\Qt6\\translations\\qt_gl.qm',
'E:\\Anaconda\\anaconda3\\Lib\\site-packages\\PyQt6\\Qt6\\translations\\qt_gl.qm',
'DATA'),
('PyQt6\\Qt6\\translations\\qt_help_hu.qm',
'E:\\Anaconda\\anaconda3\\Lib\\site-packages\\PyQt6\\Qt6\\translations\\qt_help_hu.qm',
'DATA'),
('PyQt6\\Qt6\\translations\\qtbase_nl.qm',
'E:\\Anaconda\\anaconda3\\Lib\\site-packages\\PyQt6\\Qt6\\translations\\qtbase_nl.qm',
'DATA'),
('PyQt6\\Qt6\\translations\\qt_help_fr.qm',
'E:\\Anaconda\\anaconda3\\Lib\\site-packages\\PyQt6\\Qt6\\translations\\qt_help_fr.qm',
'DATA'),
('PyQt6\\Qt6\\translations\\qt_help_ar.qm',
'E:\\Anaconda\\anaconda3\\Lib\\site-packages\\PyQt6\\Qt6\\translations\\qt_help_ar.qm',
'DATA'),
('PyQt6\\Qt6\\translations\\qt_ko.qm',
'E:\\Anaconda\\anaconda3\\Lib\\site-packages\\PyQt6\\Qt6\\translations\\qt_ko.qm',
'DATA'),
('PyQt6\\Qt6\\translations\\qtbase_it.qm',
'E:\\Anaconda\\anaconda3\\Lib\\site-packages\\PyQt6\\Qt6\\translations\\qtbase_it.qm',
'DATA'),
('PyQt6\\Qt6\\translations\\qtbase_lv.qm',
'E:\\Anaconda\\anaconda3\\Lib\\site-packages\\PyQt6\\Qt6\\translations\\qtbase_lv.qm',
'DATA'),
('PyQt6\\Qt6\\translations\\qt_help_en.qm',
'E:\\Anaconda\\anaconda3\\Lib\\site-packages\\PyQt6\\Qt6\\translations\\qt_help_en.qm',
'DATA'),
('PyQt6\\Qt6\\translations\\qt_help_pt_BR.qm',
'E:\\Anaconda\\anaconda3\\Lib\\site-packages\\PyQt6\\Qt6\\translations\\qt_help_pt_BR.qm',
'DATA'),
('PyQt6\\Qt6\\translations\\qtbase_ru.qm',
'E:\\Anaconda\\anaconda3\\Lib\\site-packages\\PyQt6\\Qt6\\translations\\qtbase_ru.qm',
'DATA'),
('PyQt6\\Qt6\\translations\\qt_nn.qm',
'E:\\Anaconda\\anaconda3\\Lib\\site-packages\\PyQt6\\Qt6\\translations\\qt_nn.qm',
'DATA'),
('PyQt6\\Qt6\\translations\\qt_ja.qm',
'E:\\Anaconda\\anaconda3\\Lib\\site-packages\\PyQt6\\Qt6\\translations\\qt_ja.qm',
'DATA'),
('PyQt6\\Qt6\\translations\\qt_help_zh_CN.qm',
'E:\\Anaconda\\anaconda3\\Lib\\site-packages\\PyQt6\\Qt6\\translations\\qt_help_zh_CN.qm',
'DATA'),
('PyQt6\\Qt6\\translations\\qtbase_fa.qm',
'E:\\Anaconda\\anaconda3\\Lib\\site-packages\\PyQt6\\Qt6\\translations\\qtbase_fa.qm',
'DATA'),
('PyQt6\\Qt6\\translations\\qt_help_es.qm',
'E:\\Anaconda\\anaconda3\\Lib\\site-packages\\PyQt6\\Qt6\\translations\\qt_help_es.qm',
'DATA'),
('PyQt6\\Qt6\\translations\\qt_ca.qm',
'E:\\Anaconda\\anaconda3\\Lib\\site-packages\\PyQt6\\Qt6\\translations\\qt_ca.qm',
'DATA'),
('PyQt6\\Qt6\\translations\\qt_pt_PT.qm',
'E:\\Anaconda\\anaconda3\\Lib\\site-packages\\PyQt6\\Qt6\\translations\\qt_pt_PT.qm',
'DATA'),
('PyQt6\\Qt6\\translations\\qt_pt_BR.qm',
'E:\\Anaconda\\anaconda3\\Lib\\site-packages\\PyQt6\\Qt6\\translations\\qt_pt_BR.qm',
'DATA'),
('PyQt6\\Qt6\\translations\\qt_en.qm',
'E:\\Anaconda\\anaconda3\\Lib\\site-packages\\PyQt6\\Qt6\\translations\\qt_en.qm',
'DATA'),
('PyQt6\\Qt6\\translations\\qt_help_hr.qm',
'E:\\Anaconda\\anaconda3\\Lib\\site-packages\\PyQt6\\Qt6\\translations\\qt_help_hr.qm',
'DATA'),
('PyQt6\\Qt6\\translations\\qt_bg.qm',
'E:\\Anaconda\\anaconda3\\Lib\\site-packages\\PyQt6\\Qt6\\translations\\qt_bg.qm',
'DATA'),
('PyQt6\\Qt6\\translations\\qt_fi.qm',
'E:\\Anaconda\\anaconda3\\Lib\\site-packages\\PyQt6\\Qt6\\translations\\qt_fi.qm',
'DATA'),
('PyQt6\\Qt6\\translations\\qtbase_ja.qm',
'E:\\Anaconda\\anaconda3\\Lib\\site-packages\\PyQt6\\Qt6\\translations\\qtbase_ja.qm',
'DATA'),
('PyQt6\\Qt6\\translations\\qtbase_tr.qm',
'E:\\Anaconda\\anaconda3\\Lib\\site-packages\\PyQt6\\Qt6\\translations\\qtbase_tr.qm',
'DATA'),
('PyQt6\\Qt6\\translations\\qt_hu.qm',
'E:\\Anaconda\\anaconda3\\Lib\\site-packages\\PyQt6\\Qt6\\translations\\qt_hu.qm',
'DATA'),
('PyQt6\\Qt6\\translations\\qt_sk.qm',
'E:\\Anaconda\\anaconda3\\Lib\\site-packages\\PyQt6\\Qt6\\translations\\qt_sk.qm',
'DATA'),
('PyQt6\\Qt6\\translations\\qt_help_cs.qm',
'E:\\Anaconda\\anaconda3\\Lib\\site-packages\\PyQt6\\Qt6\\translations\\qt_help_cs.qm',
'DATA'),
('PyQt6\\Qt6\\translations\\qt_help_da.qm',
'E:\\Anaconda\\anaconda3\\Lib\\site-packages\\PyQt6\\Qt6\\translations\\qt_help_da.qm',
'DATA'),
('PyQt6\\Qt6\\translations\\qtbase_gd.qm',
'E:\\Anaconda\\anaconda3\\Lib\\site-packages\\PyQt6\\Qt6\\translations\\qtbase_gd.qm',
'DATA'),
('PyQt6\\Qt6\\translations\\qtbase_he.qm',
'E:\\Anaconda\\anaconda3\\Lib\\site-packages\\PyQt6\\Qt6\\translations\\qtbase_he.qm',
'DATA'),
('PyQt6\\Qt6\\translations\\qt_help_sl.qm',
'E:\\Anaconda\\anaconda3\\Lib\\site-packages\\PyQt6\\Qt6\\translations\\qt_help_sl.qm',
'DATA'),
('PyQt6\\Qt6\\translations\\qt_help_ja.qm',
'E:\\Anaconda\\anaconda3\\Lib\\site-packages\\PyQt6\\Qt6\\translations\\qt_help_ja.qm',
'DATA'),
('PyQt6\\Qt6\\translations\\qtbase_es.qm',
'E:\\Anaconda\\anaconda3\\Lib\\site-packages\\PyQt6\\Qt6\\translations\\qtbase_es.qm',
'DATA'),
('PyQt6\\Qt6\\translations\\qtbase_uk.qm',
'E:\\Anaconda\\anaconda3\\Lib\\site-packages\\PyQt6\\Qt6\\translations\\qtbase_uk.qm',
'DATA'),
('PyQt6\\Qt6\\translations\\qt_help_nl.qm',
'E:\\Anaconda\\anaconda3\\Lib\\site-packages\\PyQt6\\Qt6\\translations\\qt_help_nl.qm',
'DATA'),
('PyQt6\\Qt6\\translations\\qtbase_zh_TW.qm',
'E:\\Anaconda\\anaconda3\\Lib\\site-packages\\PyQt6\\Qt6\\translations\\qtbase_zh_TW.qm',
'DATA'),
('PyQt6\\Qt6\\translations\\qt_zh_CN.qm',
'E:\\Anaconda\\anaconda3\\Lib\\site-packages\\PyQt6\\Qt6\\translations\\qt_zh_CN.qm',
'DATA'),
('PyQt6\\Qt6\\translations\\qtbase_ka.qm',
'E:\\Anaconda\\anaconda3\\Lib\\site-packages\\PyQt6\\Qt6\\translations\\qtbase_ka.qm',
'DATA'),
('PyQt6\\Qt6\\translations\\qt_help_it.qm',
'E:\\Anaconda\\anaconda3\\Lib\\site-packages\\PyQt6\\Qt6\\translations\\qt_help_it.qm',
'DATA'),
('PyQt6\\Qt6\\translations\\qtbase_ko.qm',
'E:\\Anaconda\\anaconda3\\Lib\\site-packages\\PyQt6\\Qt6\\translations\\qtbase_ko.qm',
'DATA'),
('PyQt6\\Qt6\\translations\\qt_help_pl.qm',
'E:\\Anaconda\\anaconda3\\Lib\\site-packages\\PyQt6\\Qt6\\translations\\qt_help_pl.qm',
'DATA'),
('PyQt6\\Qt6\\translations\\qt_da.qm',
'E:\\Anaconda\\anaconda3\\Lib\\site-packages\\PyQt6\\Qt6\\translations\\qt_da.qm',
'DATA'),
('PyQt6\\Qt6\\translations\\qt_he.qm',
'E:\\Anaconda\\anaconda3\\Lib\\site-packages\\PyQt6\\Qt6\\translations\\qt_he.qm',
'DATA'),
('PyQt6\\Qt6\\translations\\qt_fr.qm',
'E:\\Anaconda\\anaconda3\\Lib\\site-packages\\PyQt6\\Qt6\\translations\\qt_fr.qm',
'DATA'),
('PyQt6\\Qt6\\translations\\qtbase_de.qm',
'E:\\Anaconda\\anaconda3\\Lib\\site-packages\\PyQt6\\Qt6\\translations\\qtbase_de.qm',
'DATA'),
('PyQt6\\Qt6\\translations\\qtbase_cs.qm',
'E:\\Anaconda\\anaconda3\\Lib\\site-packages\\PyQt6\\Qt6\\translations\\qtbase_cs.qm',
'DATA'),
('PyQt6\\Qt6\\translations\\qt_sl.qm',
'E:\\Anaconda\\anaconda3\\Lib\\site-packages\\PyQt6\\Qt6\\translations\\qt_sl.qm',
'DATA'),
('PyQt6\\Qt6\\translations\\qt_it.qm',
'E:\\Anaconda\\anaconda3\\Lib\\site-packages\\PyQt6\\Qt6\\translations\\qt_it.qm',
'DATA'),
('PyQt6\\Qt6\\translations\\qtbase_pt_BR.qm',
'E:\\Anaconda\\anaconda3\\Lib\\site-packages\\PyQt6\\Qt6\\translations\\qtbase_pt_BR.qm',
'DATA'),
('PyQt6\\Qt6\\translations\\qt_ru.qm',
'E:\\Anaconda\\anaconda3\\Lib\\site-packages\\PyQt6\\Qt6\\translations\\qt_ru.qm',
'DATA'),
('PyQt6\\Qt6\\translations\\qt_help_de.qm',
'E:\\Anaconda\\anaconda3\\Lib\\site-packages\\PyQt6\\Qt6\\translations\\qt_help_de.qm',
'DATA'),
('PyQt6\\Qt6\\translations\\qt_help_ko.qm',
'E:\\Anaconda\\anaconda3\\Lib\\site-packages\\PyQt6\\Qt6\\translations\\qt_help_ko.qm',
'DATA'),
('PyQt6\\Qt6\\translations\\qtbase_fr.qm',
'E:\\Anaconda\\anaconda3\\Lib\\site-packages\\PyQt6\\Qt6\\translations\\qtbase_fr.qm',
'DATA'),
('PyQt6\\Qt6\\translations\\qt_help_uk.qm',
'E:\\Anaconda\\anaconda3\\Lib\\site-packages\\PyQt6\\Qt6\\translations\\qt_help_uk.qm',
'DATA'),
('PyQt6\\Qt6\\translations\\qt_gd.qm',
'E:\\Anaconda\\anaconda3\\Lib\\site-packages\\PyQt6\\Qt6\\translations\\qt_gd.qm',
'DATA'),
('PyQt6\\Qt6\\translations\\qt_sv.qm',
'E:\\Anaconda\\anaconda3\\Lib\\site-packages\\PyQt6\\Qt6\\translations\\qt_sv.qm',
'DATA'),
('PyQt6\\Qt6\\translations\\qt_help_sk.qm',
'E:\\Anaconda\\anaconda3\\Lib\\site-packages\\PyQt6\\Qt6\\translations\\qt_help_sk.qm',
'DATA'),
('PyQt6\\Qt6\\translations\\qt_es.qm',
'E:\\Anaconda\\anaconda3\\Lib\\site-packages\\PyQt6\\Qt6\\translations\\qt_es.qm',
'DATA'),
('PyQt6\\Qt6\\translations\\qt_lv.qm',
'E:\\Anaconda\\anaconda3\\Lib\\site-packages\\PyQt6\\Qt6\\translations\\qt_lv.qm',
'DATA'),
('PyQt6\\Qt6\\translations\\qt_help_ca.qm',
'E:\\Anaconda\\anaconda3\\Lib\\site-packages\\PyQt6\\Qt6\\translations\\qt_help_ca.qm',
'DATA'),
('base_library.zip',
'C:\\Users\\xyx29\\source\\软件工程导论\\MathStudySystem-develop\\mathstudysystem\\MathStudySystem-develop\\mathstudysystem\\build\\MathStudySystem\\base_library.zip',
'DATA')],
[],
False,
False,
1760262686,
[('runw.exe',
'E:\\Anaconda\\anaconda3\\Lib\\site-packages\\PyInstaller\\bootloader\\Windows-64bit-intel\\runw.exe',
'EXECUTABLE')],
'E:\\Anaconda\\anaconda3\\python311.dll')

@ -0,0 +1,575 @@
('C:\\Users\\xyx29\\source\\软件工程导论\\MathStudySystem-develop\\mathstudysystem\\MathStudySystem-develop\\mathstudysystem\\build\\MathStudySystem\\MathStudySystem.pkg',
{'BINARY': True,
'DATA': True,
'EXECUTABLE': True,
'EXTENSION': True,
'PYMODULE': True,
'PYSOURCE': True,
'PYZ': False,
'SPLASH': True,
'SYMLINK': False},
[('pyi-contents-directory _internal', '', 'OPTION'),
('PYZ-00.pyz',
'C:\\Users\\xyx29\\source\\软件工程导论\\MathStudySystem-develop\\mathstudysystem\\MathStudySystem-develop\\mathstudysystem\\build\\MathStudySystem\\PYZ-00.pyz',
'PYZ'),
('struct',
'C:\\Users\\xyx29\\source\\软件工程导论\\MathStudySystem-develop\\mathstudysystem\\MathStudySystem-develop\\mathstudysystem\\build\\MathStudySystem\\localpycs\\struct.pyc',
'PYMODULE'),
('pyimod01_archive',
'C:\\Users\\xyx29\\source\\软件工程导论\\MathStudySystem-develop\\mathstudysystem\\MathStudySystem-develop\\mathstudysystem\\build\\MathStudySystem\\localpycs\\pyimod01_archive.pyc',
'PYMODULE'),
('pyimod02_importers',
'C:\\Users\\xyx29\\source\\软件工程导论\\MathStudySystem-develop\\mathstudysystem\\MathStudySystem-develop\\mathstudysystem\\build\\MathStudySystem\\localpycs\\pyimod02_importers.pyc',
'PYMODULE'),
('pyimod03_ctypes',
'C:\\Users\\xyx29\\source\\软件工程导论\\MathStudySystem-develop\\mathstudysystem\\MathStudySystem-develop\\mathstudysystem\\build\\MathStudySystem\\localpycs\\pyimod03_ctypes.pyc',
'PYMODULE'),
('pyimod04_pywin32',
'C:\\Users\\xyx29\\source\\软件工程导论\\MathStudySystem-develop\\mathstudysystem\\MathStudySystem-develop\\mathstudysystem\\build\\MathStudySystem\\localpycs\\pyimod04_pywin32.pyc',
'PYMODULE'),
('pyiboot01_bootstrap',
'E:\\Anaconda\\anaconda3\\Lib\\site-packages\\PyInstaller\\loader\\pyiboot01_bootstrap.py',
'PYSOURCE'),
('pyi_rth_inspect',
'E:\\Anaconda\\anaconda3\\Lib\\site-packages\\PyInstaller\\hooks\\rthooks\\pyi_rth_inspect.py',
'PYSOURCE'),
('pyi_rth_pyqt6',
'E:\\Anaconda\\anaconda3\\Lib\\site-packages\\PyInstaller\\hooks\\rthooks\\pyi_rth_pyqt6.py',
'PYSOURCE'),
('pyi_rth_pkgutil',
'E:\\Anaconda\\anaconda3\\Lib\\site-packages\\PyInstaller\\hooks\\rthooks\\pyi_rth_pkgutil.py',
'PYSOURCE'),
('app',
'C:\\Users\\xyx29\\source\\软件工程导论\\MathStudySystem-develop\\mathstudysystem\\MathStudySystem-develop\\mathstudysystem\\src\\app.py',
'PYSOURCE'),
('python311.dll', 'E:\\Anaconda\\anaconda3\\python311.dll', 'BINARY'),
('PyQt6\\Qt6\\plugins\\generic\\qtuiotouchplugin.dll',
'E:\\Anaconda\\anaconda3\\Lib\\site-packages\\PyQt6\\Qt6\\plugins\\generic\\qtuiotouchplugin.dll',
'BINARY'),
('PyQt6\\Qt6\\plugins\\iconengines\\qsvgicon.dll',
'E:\\Anaconda\\anaconda3\\Lib\\site-packages\\PyQt6\\Qt6\\plugins\\iconengines\\qsvgicon.dll',
'BINARY'),
('PyQt6\\Qt6\\plugins\\imageformats\\qico.dll',
'E:\\Anaconda\\anaconda3\\Lib\\site-packages\\PyQt6\\Qt6\\plugins\\imageformats\\qico.dll',
'BINARY'),
('PyQt6\\Qt6\\plugins\\imageformats\\qsvg.dll',
'E:\\Anaconda\\anaconda3\\Lib\\site-packages\\PyQt6\\Qt6\\plugins\\imageformats\\qsvg.dll',
'BINARY'),
('PyQt6\\Qt6\\plugins\\imageformats\\qtga.dll',
'E:\\Anaconda\\anaconda3\\Lib\\site-packages\\PyQt6\\Qt6\\plugins\\imageformats\\qtga.dll',
'BINARY'),
('PyQt6\\Qt6\\plugins\\imageformats\\qgif.dll',
'E:\\Anaconda\\anaconda3\\Lib\\site-packages\\PyQt6\\Qt6\\plugins\\imageformats\\qgif.dll',
'BINARY'),
('PyQt6\\Qt6\\plugins\\imageformats\\qwbmp.dll',
'E:\\Anaconda\\anaconda3\\Lib\\site-packages\\PyQt6\\Qt6\\plugins\\imageformats\\qwbmp.dll',
'BINARY'),
('PyQt6\\Qt6\\plugins\\platforms\\qwindows.dll',
'E:\\Anaconda\\anaconda3\\Lib\\site-packages\\PyQt6\\Qt6\\plugins\\platforms\\qwindows.dll',
'BINARY'),
('PyQt6\\Qt6\\plugins\\imageformats\\qicns.dll',
'E:\\Anaconda\\anaconda3\\Lib\\site-packages\\PyQt6\\Qt6\\plugins\\imageformats\\qicns.dll',
'BINARY'),
('PyQt6\\Qt6\\plugins\\imageformats\\qwebp.dll',
'E:\\Anaconda\\anaconda3\\Lib\\site-packages\\PyQt6\\Qt6\\plugins\\imageformats\\qwebp.dll',
'BINARY'),
('PyQt6\\Qt6\\plugins\\platforms\\qminimal.dll',
'E:\\Anaconda\\anaconda3\\Lib\\site-packages\\PyQt6\\Qt6\\plugins\\platforms\\qminimal.dll',
'BINARY'),
('PyQt6\\Qt6\\plugins\\platforms\\qoffscreen.dll',
'E:\\Anaconda\\anaconda3\\Lib\\site-packages\\PyQt6\\Qt6\\plugins\\platforms\\qoffscreen.dll',
'BINARY'),
('PyQt6\\Qt6\\plugins\\imageformats\\qjpeg.dll',
'E:\\Anaconda\\anaconda3\\Lib\\site-packages\\PyQt6\\Qt6\\plugins\\imageformats\\qjpeg.dll',
'BINARY'),
('PyQt6\\Qt6\\plugins\\imageformats\\qtiff.dll',
'E:\\Anaconda\\anaconda3\\Lib\\site-packages\\PyQt6\\Qt6\\plugins\\imageformats\\qtiff.dll',
'BINARY'),
('PyQt6\\Qt6\\plugins\\imageformats\\qpdf.dll',
'E:\\Anaconda\\anaconda3\\Lib\\site-packages\\PyQt6\\Qt6\\plugins\\imageformats\\qpdf.dll',
'BINARY'),
('PyQt6\\Qt6\\bin\\opengl32sw.dll',
'E:\\Anaconda\\anaconda3\\Lib\\site-packages\\PyQt6\\Qt6\\bin\\opengl32sw.dll',
'BINARY'),
('PyQt6\\Qt6\\plugins\\styles\\qmodernwindowsstyle.dll',
'E:\\Anaconda\\anaconda3\\Lib\\site-packages\\PyQt6\\Qt6\\plugins\\styles\\qmodernwindowsstyle.dll',
'BINARY'),
('_lzma.pyd', 'E:\\Anaconda\\anaconda3\\DLLs\\_lzma.pyd', 'EXTENSION'),
('_bz2.pyd', 'E:\\Anaconda\\anaconda3\\DLLs\\_bz2.pyd', 'EXTENSION'),
('unicodedata.pyd',
'E:\\Anaconda\\anaconda3\\DLLs\\unicodedata.pyd',
'EXTENSION'),
('select.pyd', 'E:\\Anaconda\\anaconda3\\DLLs\\select.pyd', 'EXTENSION'),
('_socket.pyd', 'E:\\Anaconda\\anaconda3\\DLLs\\_socket.pyd', 'EXTENSION'),
('_decimal.pyd', 'E:\\Anaconda\\anaconda3\\DLLs\\_decimal.pyd', 'EXTENSION'),
('_hashlib.pyd', 'E:\\Anaconda\\anaconda3\\DLLs\\_hashlib.pyd', 'EXTENSION'),
('_ssl.pyd', 'E:\\Anaconda\\anaconda3\\DLLs\\_ssl.pyd', 'EXTENSION'),
('PyQt6\\QtGui.pyd',
'E:\\Anaconda\\anaconda3\\Lib\\site-packages\\PyQt6\\QtGui.pyd',
'EXTENSION'),
('PyQt6\\sip.cp311-win_amd64.pyd',
'E:\\Anaconda\\anaconda3\\Lib\\site-packages\\PyQt6\\sip.cp311-win_amd64.pyd',
'EXTENSION'),
('PyQt6\\QtCore.pyd',
'E:\\Anaconda\\anaconda3\\Lib\\site-packages\\PyQt6\\QtCore.pyd',
'EXTENSION'),
('PyQt6\\QtWidgets.pyd',
'E:\\Anaconda\\anaconda3\\Lib\\site-packages\\PyQt6\\QtWidgets.pyd',
'EXTENSION'),
('api-ms-win-crt-stdio-l1-1-0.dll',
'E:\\Anaconda\\anaconda3\\api-ms-win-crt-stdio-l1-1-0.dll',
'BINARY'),
('api-ms-win-crt-environment-l1-1-0.dll',
'E:\\Anaconda\\anaconda3\\api-ms-win-crt-environment-l1-1-0.dll',
'BINARY'),
('api-ms-win-crt-process-l1-1-0.dll',
'E:\\Anaconda\\anaconda3\\api-ms-win-crt-process-l1-1-0.dll',
'BINARY'),
('VCRUNTIME140.dll', 'E:\\Anaconda\\anaconda3\\VCRUNTIME140.dll', 'BINARY'),
('zlib.dll', 'E:\\Anaconda\\anaconda3\\zlib.dll', 'BINARY'),
('api-ms-win-crt-math-l1-1-0.dll',
'E:\\Anaconda\\anaconda3\\api-ms-win-crt-math-l1-1-0.dll',
'BINARY'),
('api-ms-win-crt-time-l1-1-0.dll',
'E:\\Anaconda\\anaconda3\\api-ms-win-crt-time-l1-1-0.dll',
'BINARY'),
('api-ms-win-crt-conio-l1-1-0.dll',
'E:\\Anaconda\\anaconda3\\api-ms-win-crt-conio-l1-1-0.dll',
'BINARY'),
('api-ms-win-crt-string-l1-1-0.dll',
'E:\\Anaconda\\anaconda3\\api-ms-win-crt-string-l1-1-0.dll',
'BINARY'),
('api-ms-win-crt-heap-l1-1-0.dll',
'E:\\Anaconda\\anaconda3\\api-ms-win-crt-heap-l1-1-0.dll',
'BINARY'),
('api-ms-win-crt-locale-l1-1-0.dll',
'E:\\Anaconda\\anaconda3\\api-ms-win-crt-locale-l1-1-0.dll',
'BINARY'),
('api-ms-win-crt-convert-l1-1-0.dll',
'E:\\Anaconda\\anaconda3\\api-ms-win-crt-convert-l1-1-0.dll',
'BINARY'),
('api-ms-win-crt-runtime-l1-1-0.dll',
'E:\\Anaconda\\anaconda3\\api-ms-win-crt-runtime-l1-1-0.dll',
'BINARY'),
('api-ms-win-crt-filesystem-l1-1-0.dll',
'E:\\Anaconda\\anaconda3\\api-ms-win-crt-filesystem-l1-1-0.dll',
'BINARY'),
('PyQt6\\Qt6\\bin\\Qt6Network.dll',
'E:\\Anaconda\\anaconda3\\Lib\\site-packages\\PyQt6\\Qt6\\bin\\Qt6Network.dll',
'BINARY'),
('PyQt6\\Qt6\\bin\\Qt6Core.dll',
'E:\\Anaconda\\anaconda3\\Lib\\site-packages\\PyQt6\\Qt6\\bin\\Qt6Core.dll',
'BINARY'),
('MSVCP140.dll', 'E:\\Anaconda\\anaconda3\\MSVCP140.dll', 'BINARY'),
('VCRUNTIME140_1.dll',
'E:\\Anaconda\\anaconda3\\VCRUNTIME140_1.dll',
'BINARY'),
('PyQt6\\Qt6\\bin\\Qt6Gui.dll',
'E:\\Anaconda\\anaconda3\\Lib\\site-packages\\PyQt6\\Qt6\\bin\\Qt6Gui.dll',
'BINARY'),
('PyQt6\\Qt6\\bin\\Qt6Svg.dll',
'E:\\Anaconda\\anaconda3\\Lib\\site-packages\\PyQt6\\Qt6\\bin\\Qt6Svg.dll',
'BINARY'),
('api-ms-win-crt-utility-l1-1-0.dll',
'E:\\Anaconda\\anaconda3\\api-ms-win-crt-utility-l1-1-0.dll',
'BINARY'),
('PyQt6\\Qt6\\bin\\Qt6Pdf.dll',
'E:\\Anaconda\\anaconda3\\Lib\\site-packages\\PyQt6\\Qt6\\bin\\Qt6Pdf.dll',
'BINARY'),
('PyQt6\\Qt6\\bin\\Qt6Widgets.dll',
'E:\\Anaconda\\anaconda3\\Lib\\site-packages\\PyQt6\\Qt6\\bin\\Qt6Widgets.dll',
'BINARY'),
('liblzma.dll', 'D:\\Graphviz\\bin\\liblzma.dll', 'BINARY'),
('LIBBZ2.dll', 'E:\\Anaconda\\anaconda3\\Library\\bin\\LIBBZ2.dll', 'BINARY'),
('libcrypto-3-x64.dll',
'D:\\php\\php-8.4.7-Win32-vs17-x64\\libcrypto-3-x64.dll',
'BINARY'),
('libssl-3-x64.dll',
'D:\\php\\php-8.4.7-Win32-vs17-x64\\libssl-3-x64.dll',
'BINARY'),
('MSVCP140_2.dll', 'E:\\Anaconda\\anaconda3\\MSVCP140_2.dll', 'BINARY'),
('python3.dll', 'E:\\Anaconda\\anaconda3\\python3.dll', 'BINARY'),
('ucrtbase.dll', 'E:\\Anaconda\\anaconda3\\ucrtbase.dll', 'BINARY'),
('PyQt6\\Qt6\\bin\\MSVCP140.dll',
'E:\\Anaconda\\anaconda3\\Lib\\site-packages\\PyQt6\\Qt6\\bin\\MSVCP140.dll',
'BINARY'),
('PyQt6\\Qt6\\bin\\VCRUNTIME140_1.dll',
'E:\\Anaconda\\anaconda3\\Lib\\site-packages\\PyQt6\\Qt6\\bin\\VCRUNTIME140_1.dll',
'BINARY'),
('PyQt6\\Qt6\\bin\\VCRUNTIME140.dll',
'E:\\Anaconda\\anaconda3\\Lib\\site-packages\\PyQt6\\Qt6\\bin\\VCRUNTIME140.dll',
'BINARY'),
('PyQt6\\Qt6\\bin\\MSVCP140_1.dll',
'E:\\Anaconda\\anaconda3\\Lib\\site-packages\\PyQt6\\Qt6\\bin\\MSVCP140_1.dll',
'BINARY'),
('api-ms-win-core-synch-l1-2-0.dll',
'E:\\Anaconda\\anaconda3\\api-ms-win-core-synch-l1-2-0.dll',
'BINARY'),
('PyQt6\\Qt6\\bin\\MSVCP140_2.dll',
'E:\\Anaconda\\anaconda3\\Lib\\site-packages\\PyQt6\\Qt6\\bin\\MSVCP140_2.dll',
'BINARY'),
('api-ms-win-core-processthreads-l1-1-0.dll',
'E:\\Anaconda\\anaconda3\\api-ms-win-core-processthreads-l1-1-0.dll',
'BINARY'),
('api-ms-win-core-heap-l1-1-0.dll',
'E:\\Anaconda\\anaconda3\\api-ms-win-core-heap-l1-1-0.dll',
'BINARY'),
('api-ms-win-core-processthreads-l1-1-1.dll',
'E:\\Anaconda\\anaconda3\\api-ms-win-core-processthreads-l1-1-1.dll',
'BINARY'),
('api-ms-win-core-processenvironment-l1-1-0.dll',
'E:\\Anaconda\\anaconda3\\api-ms-win-core-processenvironment-l1-1-0.dll',
'BINARY'),
('api-ms-win-core-rtlsupport-l1-1-0.dll',
'E:\\Anaconda\\anaconda3\\api-ms-win-core-rtlsupport-l1-1-0.dll',
'BINARY'),
('api-ms-win-core-file-l1-2-0.dll',
'E:\\Anaconda\\anaconda3\\api-ms-win-core-file-l1-2-0.dll',
'BINARY'),
('api-ms-win-core-sysinfo-l1-1-0.dll',
'E:\\Anaconda\\anaconda3\\api-ms-win-core-sysinfo-l1-1-0.dll',
'BINARY'),
('api-ms-win-core-handle-l1-1-0.dll',
'E:\\Anaconda\\anaconda3\\api-ms-win-core-handle-l1-1-0.dll',
'BINARY'),
('api-ms-win-core-console-l1-1-0.dll',
'E:\\Anaconda\\anaconda3\\api-ms-win-core-console-l1-1-0.dll',
'BINARY'),
('api-ms-win-core-util-l1-1-0.dll',
'E:\\Anaconda\\anaconda3\\api-ms-win-core-util-l1-1-0.dll',
'BINARY'),
('api-ms-win-core-memory-l1-1-0.dll',
'E:\\Anaconda\\anaconda3\\api-ms-win-core-memory-l1-1-0.dll',
'BINARY'),
('api-ms-win-core-synch-l1-1-0.dll',
'E:\\Anaconda\\anaconda3\\api-ms-win-core-synch-l1-1-0.dll',
'BINARY'),
('api-ms-win-core-interlocked-l1-1-0.dll',
'E:\\Anaconda\\anaconda3\\api-ms-win-core-interlocked-l1-1-0.dll',
'BINARY'),
('api-ms-win-core-timezone-l1-1-0.dll',
'E:\\Anaconda\\anaconda3\\api-ms-win-core-timezone-l1-1-0.dll',
'BINARY'),
('api-ms-win-core-localization-l1-2-0.dll',
'E:\\Anaconda\\anaconda3\\api-ms-win-core-localization-l1-2-0.dll',
'BINARY'),
('api-ms-win-core-profile-l1-1-0.dll',
'E:\\Anaconda\\anaconda3\\api-ms-win-core-profile-l1-1-0.dll',
'BINARY'),
('api-ms-win-core-string-l1-1-0.dll',
'E:\\Anaconda\\anaconda3\\api-ms-win-core-string-l1-1-0.dll',
'BINARY'),
('api-ms-win-core-datetime-l1-1-0.dll',
'E:\\Anaconda\\anaconda3\\api-ms-win-core-datetime-l1-1-0.dll',
'BINARY'),
('api-ms-win-core-debug-l1-1-0.dll',
'E:\\Anaconda\\anaconda3\\api-ms-win-core-debug-l1-1-0.dll',
'BINARY'),
('api-ms-win-core-libraryloader-l1-1-0.dll',
'E:\\Anaconda\\anaconda3\\api-ms-win-core-libraryloader-l1-1-0.dll',
'BINARY'),
('api-ms-win-core-namedpipe-l1-1-0.dll',
'E:\\Anaconda\\anaconda3\\api-ms-win-core-namedpipe-l1-1-0.dll',
'BINARY'),
('api-ms-win-core-errorhandling-l1-1-0.dll',
'E:\\Anaconda\\anaconda3\\api-ms-win-core-errorhandling-l1-1-0.dll',
'BINARY'),
('api-ms-win-core-file-l1-1-0.dll',
'E:\\Anaconda\\anaconda3\\api-ms-win-core-file-l1-1-0.dll',
'BINARY'),
('api-ms-win-core-file-l2-1-0.dll',
'E:\\Anaconda\\anaconda3\\api-ms-win-core-file-l2-1-0.dll',
'BINARY'),
('storage\\config.json',
'C:\\Users\\xyx29\\source\\软件工程导论\\MathStudySystem-develop\\mathstudysystem\\MathStudySystem-develop\\mathstudysystem\\src\\storage\\config.json',
'DATA'),
('storage\\users.json',
'C:\\Users\\xyx29\\source\\软件工程导论\\MathStudySystem-develop\\mathstudysystem\\MathStudySystem-develop\\mathstudysystem\\src\\storage\\users.json',
'DATA'),
('PyQt6\\Qt6\\translations\\qt_fa.qm',
'E:\\Anaconda\\anaconda3\\Lib\\site-packages\\PyQt6\\Qt6\\translations\\qt_fa.qm',
'DATA'),
('PyQt6\\Qt6\\translations\\qt_help_tr.qm',
'E:\\Anaconda\\anaconda3\\Lib\\site-packages\\PyQt6\\Qt6\\translations\\qt_help_tr.qm',
'DATA'),
('PyQt6\\Qt6\\translations\\qtbase_pl.qm',
'E:\\Anaconda\\anaconda3\\Lib\\site-packages\\PyQt6\\Qt6\\translations\\qtbase_pl.qm',
'DATA'),
('PyQt6\\Qt6\\translations\\qt_help_gl.qm',
'E:\\Anaconda\\anaconda3\\Lib\\site-packages\\PyQt6\\Qt6\\translations\\qt_help_gl.qm',
'DATA'),
('PyQt6\\Qt6\\translations\\qt_uk.qm',
'E:\\Anaconda\\anaconda3\\Lib\\site-packages\\PyQt6\\Qt6\\translations\\qt_uk.qm',
'DATA'),
('PyQt6\\Qt6\\translations\\qt_hr.qm',
'E:\\Anaconda\\anaconda3\\Lib\\site-packages\\PyQt6\\Qt6\\translations\\qt_hr.qm',
'DATA'),
('PyQt6\\Qt6\\translations\\qt_help_nn.qm',
'E:\\Anaconda\\anaconda3\\Lib\\site-packages\\PyQt6\\Qt6\\translations\\qt_help_nn.qm',
'DATA'),
('PyQt6\\Qt6\\translations\\qtbase_ca.qm',
'E:\\Anaconda\\anaconda3\\Lib\\site-packages\\PyQt6\\Qt6\\translations\\qtbase_ca.qm',
'DATA'),
('PyQt6\\Qt6\\translations\\qt_zh_TW.qm',
'E:\\Anaconda\\anaconda3\\Lib\\site-packages\\PyQt6\\Qt6\\translations\\qt_zh_TW.qm',
'DATA'),
('PyQt6\\Qt6\\translations\\qt_tr.qm',
'E:\\Anaconda\\anaconda3\\Lib\\site-packages\\PyQt6\\Qt6\\translations\\qt_tr.qm',
'DATA'),
('PyQt6\\Qt6\\translations\\qtbase_bg.qm',
'E:\\Anaconda\\anaconda3\\Lib\\site-packages\\PyQt6\\Qt6\\translations\\qtbase_bg.qm',
'DATA'),
('PyQt6\\Qt6\\translations\\qtbase_en.qm',
'E:\\Anaconda\\anaconda3\\Lib\\site-packages\\PyQt6\\Qt6\\translations\\qtbase_en.qm',
'DATA'),
('PyQt6\\Qt6\\translations\\qt_help_ru.qm',
'E:\\Anaconda\\anaconda3\\Lib\\site-packages\\PyQt6\\Qt6\\translations\\qt_help_ru.qm',
'DATA'),
('PyQt6\\Qt6\\translations\\qt_help_zh_TW.qm',
'E:\\Anaconda\\anaconda3\\Lib\\site-packages\\PyQt6\\Qt6\\translations\\qt_help_zh_TW.qm',
'DATA'),
('PyQt6\\Qt6\\translations\\qt_lt.qm',
'E:\\Anaconda\\anaconda3\\Lib\\site-packages\\PyQt6\\Qt6\\translations\\qt_lt.qm',
'DATA'),
('PyQt6\\Qt6\\translations\\qt_ka.qm',
'E:\\Anaconda\\anaconda3\\Lib\\site-packages\\PyQt6\\Qt6\\translations\\qt_ka.qm',
'DATA'),
('PyQt6\\Qt6\\translations\\qtbase_sk.qm',
'E:\\Anaconda\\anaconda3\\Lib\\site-packages\\PyQt6\\Qt6\\translations\\qtbase_sk.qm',
'DATA'),
('PyQt6\\Qt6\\translations\\qtbase_fi.qm',
'E:\\Anaconda\\anaconda3\\Lib\\site-packages\\PyQt6\\Qt6\\translations\\qtbase_fi.qm',
'DATA'),
('PyQt6\\Qt6\\translations\\qtbase_zh_CN.qm',
'E:\\Anaconda\\anaconda3\\Lib\\site-packages\\PyQt6\\Qt6\\translations\\qtbase_zh_CN.qm',
'DATA'),
('PyQt6\\Qt6\\translations\\qt_nl.qm',
'E:\\Anaconda\\anaconda3\\Lib\\site-packages\\PyQt6\\Qt6\\translations\\qt_nl.qm',
'DATA'),
('PyQt6\\Qt6\\translations\\qt_ar.qm',
'E:\\Anaconda\\anaconda3\\Lib\\site-packages\\PyQt6\\Qt6\\translations\\qt_ar.qm',
'DATA'),
('PyQt6\\Qt6\\translations\\qtbase_da.qm',
'E:\\Anaconda\\anaconda3\\Lib\\site-packages\\PyQt6\\Qt6\\translations\\qtbase_da.qm',
'DATA'),
('PyQt6\\Qt6\\translations\\qt_help_bg.qm',
'E:\\Anaconda\\anaconda3\\Lib\\site-packages\\PyQt6\\Qt6\\translations\\qt_help_bg.qm',
'DATA'),
('PyQt6\\Qt6\\translations\\qt_de.qm',
'E:\\Anaconda\\anaconda3\\Lib\\site-packages\\PyQt6\\Qt6\\translations\\qt_de.qm',
'DATA'),
('PyQt6\\Qt6\\translations\\qt_pl.qm',
'E:\\Anaconda\\anaconda3\\Lib\\site-packages\\PyQt6\\Qt6\\translations\\qt_pl.qm',
'DATA'),
('PyQt6\\Qt6\\translations\\qtbase_nn.qm',
'E:\\Anaconda\\anaconda3\\Lib\\site-packages\\PyQt6\\Qt6\\translations\\qtbase_nn.qm',
'DATA'),
('PyQt6\\Qt6\\translations\\qtbase_hr.qm',
'E:\\Anaconda\\anaconda3\\Lib\\site-packages\\PyQt6\\Qt6\\translations\\qtbase_hr.qm',
'DATA'),
('PyQt6\\Qt6\\translations\\qtbase_ar.qm',
'E:\\Anaconda\\anaconda3\\Lib\\site-packages\\PyQt6\\Qt6\\translations\\qtbase_ar.qm',
'DATA'),
('PyQt6\\Qt6\\translations\\qtbase_hu.qm',
'E:\\Anaconda\\anaconda3\\Lib\\site-packages\\PyQt6\\Qt6\\translations\\qtbase_hu.qm',
'DATA'),
('PyQt6\\Qt6\\translations\\qt_help_ka.qm',
'E:\\Anaconda\\anaconda3\\Lib\\site-packages\\PyQt6\\Qt6\\translations\\qt_help_ka.qm',
'DATA'),
('PyQt6\\Qt6\\translations\\qt_cs.qm',
'E:\\Anaconda\\anaconda3\\Lib\\site-packages\\PyQt6\\Qt6\\translations\\qt_cs.qm',
'DATA'),
('PyQt6\\Qt6\\translations\\qt_gl.qm',
'E:\\Anaconda\\anaconda3\\Lib\\site-packages\\PyQt6\\Qt6\\translations\\qt_gl.qm',
'DATA'),
('PyQt6\\Qt6\\translations\\qt_help_hu.qm',
'E:\\Anaconda\\anaconda3\\Lib\\site-packages\\PyQt6\\Qt6\\translations\\qt_help_hu.qm',
'DATA'),
('PyQt6\\Qt6\\translations\\qtbase_nl.qm',
'E:\\Anaconda\\anaconda3\\Lib\\site-packages\\PyQt6\\Qt6\\translations\\qtbase_nl.qm',
'DATA'),
('PyQt6\\Qt6\\translations\\qt_help_fr.qm',
'E:\\Anaconda\\anaconda3\\Lib\\site-packages\\PyQt6\\Qt6\\translations\\qt_help_fr.qm',
'DATA'),
('PyQt6\\Qt6\\translations\\qt_help_ar.qm',
'E:\\Anaconda\\anaconda3\\Lib\\site-packages\\PyQt6\\Qt6\\translations\\qt_help_ar.qm',
'DATA'),
('PyQt6\\Qt6\\translations\\qt_ko.qm',
'E:\\Anaconda\\anaconda3\\Lib\\site-packages\\PyQt6\\Qt6\\translations\\qt_ko.qm',
'DATA'),
('PyQt6\\Qt6\\translations\\qtbase_it.qm',
'E:\\Anaconda\\anaconda3\\Lib\\site-packages\\PyQt6\\Qt6\\translations\\qtbase_it.qm',
'DATA'),
('PyQt6\\Qt6\\translations\\qtbase_lv.qm',
'E:\\Anaconda\\anaconda3\\Lib\\site-packages\\PyQt6\\Qt6\\translations\\qtbase_lv.qm',
'DATA'),
('PyQt6\\Qt6\\translations\\qt_help_en.qm',
'E:\\Anaconda\\anaconda3\\Lib\\site-packages\\PyQt6\\Qt6\\translations\\qt_help_en.qm',
'DATA'),
('PyQt6\\Qt6\\translations\\qt_help_pt_BR.qm',
'E:\\Anaconda\\anaconda3\\Lib\\site-packages\\PyQt6\\Qt6\\translations\\qt_help_pt_BR.qm',
'DATA'),
('PyQt6\\Qt6\\translations\\qtbase_ru.qm',
'E:\\Anaconda\\anaconda3\\Lib\\site-packages\\PyQt6\\Qt6\\translations\\qtbase_ru.qm',
'DATA'),
('PyQt6\\Qt6\\translations\\qt_nn.qm',
'E:\\Anaconda\\anaconda3\\Lib\\site-packages\\PyQt6\\Qt6\\translations\\qt_nn.qm',
'DATA'),
('PyQt6\\Qt6\\translations\\qt_ja.qm',
'E:\\Anaconda\\anaconda3\\Lib\\site-packages\\PyQt6\\Qt6\\translations\\qt_ja.qm',
'DATA'),
('PyQt6\\Qt6\\translations\\qt_help_zh_CN.qm',
'E:\\Anaconda\\anaconda3\\Lib\\site-packages\\PyQt6\\Qt6\\translations\\qt_help_zh_CN.qm',
'DATA'),
('PyQt6\\Qt6\\translations\\qtbase_fa.qm',
'E:\\Anaconda\\anaconda3\\Lib\\site-packages\\PyQt6\\Qt6\\translations\\qtbase_fa.qm',
'DATA'),
('PyQt6\\Qt6\\translations\\qt_help_es.qm',
'E:\\Anaconda\\anaconda3\\Lib\\site-packages\\PyQt6\\Qt6\\translations\\qt_help_es.qm',
'DATA'),
('PyQt6\\Qt6\\translations\\qt_ca.qm',
'E:\\Anaconda\\anaconda3\\Lib\\site-packages\\PyQt6\\Qt6\\translations\\qt_ca.qm',
'DATA'),
('PyQt6\\Qt6\\translations\\qt_pt_PT.qm',
'E:\\Anaconda\\anaconda3\\Lib\\site-packages\\PyQt6\\Qt6\\translations\\qt_pt_PT.qm',
'DATA'),
('PyQt6\\Qt6\\translations\\qt_pt_BR.qm',
'E:\\Anaconda\\anaconda3\\Lib\\site-packages\\PyQt6\\Qt6\\translations\\qt_pt_BR.qm',
'DATA'),
('PyQt6\\Qt6\\translations\\qt_en.qm',
'E:\\Anaconda\\anaconda3\\Lib\\site-packages\\PyQt6\\Qt6\\translations\\qt_en.qm',
'DATA'),
('PyQt6\\Qt6\\translations\\qt_help_hr.qm',
'E:\\Anaconda\\anaconda3\\Lib\\site-packages\\PyQt6\\Qt6\\translations\\qt_help_hr.qm',
'DATA'),
('PyQt6\\Qt6\\translations\\qt_bg.qm',
'E:\\Anaconda\\anaconda3\\Lib\\site-packages\\PyQt6\\Qt6\\translations\\qt_bg.qm',
'DATA'),
('PyQt6\\Qt6\\translations\\qt_fi.qm',
'E:\\Anaconda\\anaconda3\\Lib\\site-packages\\PyQt6\\Qt6\\translations\\qt_fi.qm',
'DATA'),
('PyQt6\\Qt6\\translations\\qtbase_ja.qm',
'E:\\Anaconda\\anaconda3\\Lib\\site-packages\\PyQt6\\Qt6\\translations\\qtbase_ja.qm',
'DATA'),
('PyQt6\\Qt6\\translations\\qtbase_tr.qm',
'E:\\Anaconda\\anaconda3\\Lib\\site-packages\\PyQt6\\Qt6\\translations\\qtbase_tr.qm',
'DATA'),
('PyQt6\\Qt6\\translations\\qt_hu.qm',
'E:\\Anaconda\\anaconda3\\Lib\\site-packages\\PyQt6\\Qt6\\translations\\qt_hu.qm',
'DATA'),
('PyQt6\\Qt6\\translations\\qt_sk.qm',
'E:\\Anaconda\\anaconda3\\Lib\\site-packages\\PyQt6\\Qt6\\translations\\qt_sk.qm',
'DATA'),
('PyQt6\\Qt6\\translations\\qt_help_cs.qm',
'E:\\Anaconda\\anaconda3\\Lib\\site-packages\\PyQt6\\Qt6\\translations\\qt_help_cs.qm',
'DATA'),
('PyQt6\\Qt6\\translations\\qt_help_da.qm',
'E:\\Anaconda\\anaconda3\\Lib\\site-packages\\PyQt6\\Qt6\\translations\\qt_help_da.qm',
'DATA'),
('PyQt6\\Qt6\\translations\\qtbase_gd.qm',
'E:\\Anaconda\\anaconda3\\Lib\\site-packages\\PyQt6\\Qt6\\translations\\qtbase_gd.qm',
'DATA'),
('PyQt6\\Qt6\\translations\\qtbase_he.qm',
'E:\\Anaconda\\anaconda3\\Lib\\site-packages\\PyQt6\\Qt6\\translations\\qtbase_he.qm',
'DATA'),
('PyQt6\\Qt6\\translations\\qt_help_sl.qm',
'E:\\Anaconda\\anaconda3\\Lib\\site-packages\\PyQt6\\Qt6\\translations\\qt_help_sl.qm',
'DATA'),
('PyQt6\\Qt6\\translations\\qt_help_ja.qm',
'E:\\Anaconda\\anaconda3\\Lib\\site-packages\\PyQt6\\Qt6\\translations\\qt_help_ja.qm',
'DATA'),
('PyQt6\\Qt6\\translations\\qtbase_es.qm',
'E:\\Anaconda\\anaconda3\\Lib\\site-packages\\PyQt6\\Qt6\\translations\\qtbase_es.qm',
'DATA'),
('PyQt6\\Qt6\\translations\\qtbase_uk.qm',
'E:\\Anaconda\\anaconda3\\Lib\\site-packages\\PyQt6\\Qt6\\translations\\qtbase_uk.qm',
'DATA'),
('PyQt6\\Qt6\\translations\\qt_help_nl.qm',
'E:\\Anaconda\\anaconda3\\Lib\\site-packages\\PyQt6\\Qt6\\translations\\qt_help_nl.qm',
'DATA'),
('PyQt6\\Qt6\\translations\\qtbase_zh_TW.qm',
'E:\\Anaconda\\anaconda3\\Lib\\site-packages\\PyQt6\\Qt6\\translations\\qtbase_zh_TW.qm',
'DATA'),
('PyQt6\\Qt6\\translations\\qt_zh_CN.qm',
'E:\\Anaconda\\anaconda3\\Lib\\site-packages\\PyQt6\\Qt6\\translations\\qt_zh_CN.qm',
'DATA'),
('PyQt6\\Qt6\\translations\\qtbase_ka.qm',
'E:\\Anaconda\\anaconda3\\Lib\\site-packages\\PyQt6\\Qt6\\translations\\qtbase_ka.qm',
'DATA'),
('PyQt6\\Qt6\\translations\\qt_help_it.qm',
'E:\\Anaconda\\anaconda3\\Lib\\site-packages\\PyQt6\\Qt6\\translations\\qt_help_it.qm',
'DATA'),
('PyQt6\\Qt6\\translations\\qtbase_ko.qm',
'E:\\Anaconda\\anaconda3\\Lib\\site-packages\\PyQt6\\Qt6\\translations\\qtbase_ko.qm',
'DATA'),
('PyQt6\\Qt6\\translations\\qt_help_pl.qm',
'E:\\Anaconda\\anaconda3\\Lib\\site-packages\\PyQt6\\Qt6\\translations\\qt_help_pl.qm',
'DATA'),
('PyQt6\\Qt6\\translations\\qt_da.qm',
'E:\\Anaconda\\anaconda3\\Lib\\site-packages\\PyQt6\\Qt6\\translations\\qt_da.qm',
'DATA'),
('PyQt6\\Qt6\\translations\\qt_he.qm',
'E:\\Anaconda\\anaconda3\\Lib\\site-packages\\PyQt6\\Qt6\\translations\\qt_he.qm',
'DATA'),
('PyQt6\\Qt6\\translations\\qt_fr.qm',
'E:\\Anaconda\\anaconda3\\Lib\\site-packages\\PyQt6\\Qt6\\translations\\qt_fr.qm',
'DATA'),
('PyQt6\\Qt6\\translations\\qtbase_de.qm',
'E:\\Anaconda\\anaconda3\\Lib\\site-packages\\PyQt6\\Qt6\\translations\\qtbase_de.qm',
'DATA'),
('PyQt6\\Qt6\\translations\\qtbase_cs.qm',
'E:\\Anaconda\\anaconda3\\Lib\\site-packages\\PyQt6\\Qt6\\translations\\qtbase_cs.qm',
'DATA'),
('PyQt6\\Qt6\\translations\\qt_sl.qm',
'E:\\Anaconda\\anaconda3\\Lib\\site-packages\\PyQt6\\Qt6\\translations\\qt_sl.qm',
'DATA'),
('PyQt6\\Qt6\\translations\\qt_it.qm',
'E:\\Anaconda\\anaconda3\\Lib\\site-packages\\PyQt6\\Qt6\\translations\\qt_it.qm',
'DATA'),
('PyQt6\\Qt6\\translations\\qtbase_pt_BR.qm',
'E:\\Anaconda\\anaconda3\\Lib\\site-packages\\PyQt6\\Qt6\\translations\\qtbase_pt_BR.qm',
'DATA'),
('PyQt6\\Qt6\\translations\\qt_ru.qm',
'E:\\Anaconda\\anaconda3\\Lib\\site-packages\\PyQt6\\Qt6\\translations\\qt_ru.qm',
'DATA'),
('PyQt6\\Qt6\\translations\\qt_help_de.qm',
'E:\\Anaconda\\anaconda3\\Lib\\site-packages\\PyQt6\\Qt6\\translations\\qt_help_de.qm',
'DATA'),
('PyQt6\\Qt6\\translations\\qt_help_ko.qm',
'E:\\Anaconda\\anaconda3\\Lib\\site-packages\\PyQt6\\Qt6\\translations\\qt_help_ko.qm',
'DATA'),
('PyQt6\\Qt6\\translations\\qtbase_fr.qm',
'E:\\Anaconda\\anaconda3\\Lib\\site-packages\\PyQt6\\Qt6\\translations\\qtbase_fr.qm',
'DATA'),
('PyQt6\\Qt6\\translations\\qt_help_uk.qm',
'E:\\Anaconda\\anaconda3\\Lib\\site-packages\\PyQt6\\Qt6\\translations\\qt_help_uk.qm',
'DATA'),
('PyQt6\\Qt6\\translations\\qt_gd.qm',
'E:\\Anaconda\\anaconda3\\Lib\\site-packages\\PyQt6\\Qt6\\translations\\qt_gd.qm',
'DATA'),
('PyQt6\\Qt6\\translations\\qt_sv.qm',
'E:\\Anaconda\\anaconda3\\Lib\\site-packages\\PyQt6\\Qt6\\translations\\qt_sv.qm',
'DATA'),
('PyQt6\\Qt6\\translations\\qt_help_sk.qm',
'E:\\Anaconda\\anaconda3\\Lib\\site-packages\\PyQt6\\Qt6\\translations\\qt_help_sk.qm',
'DATA'),
('PyQt6\\Qt6\\translations\\qt_es.qm',
'E:\\Anaconda\\anaconda3\\Lib\\site-packages\\PyQt6\\Qt6\\translations\\qt_es.qm',
'DATA'),
('PyQt6\\Qt6\\translations\\qt_lv.qm',
'E:\\Anaconda\\anaconda3\\Lib\\site-packages\\PyQt6\\Qt6\\translations\\qt_lv.qm',
'DATA'),
('PyQt6\\Qt6\\translations\\qt_help_ca.qm',
'E:\\Anaconda\\anaconda3\\Lib\\site-packages\\PyQt6\\Qt6\\translations\\qt_help_ca.qm',
'DATA'),
('base_library.zip',
'C:\\Users\\xyx29\\source\\软件工程导论\\MathStudySystem-develop\\mathstudysystem\\MathStudySystem-develop\\mathstudysystem\\build\\MathStudySystem\\base_library.zip',
'DATA')],
'python311.dll',
False,
False,
False,
[],
None,
None,
None)

Binary file not shown.

@ -0,0 +1,235 @@
('C:\\Users\\xyx29\\source\\软件工程导论\\MathStudySystem-develop\\mathstudysystem\\MathStudySystem-develop\\mathstudysystem\\build\\MathStudySystem\\PYZ-00.pyz',
[('PyQt6',
'E:\\Anaconda\\anaconda3\\Lib\\site-packages\\PyQt6\\__init__.py',
'PYMODULE'),
('_compat_pickle',
'E:\\Anaconda\\anaconda3\\Lib\\_compat_pickle.py',
'PYMODULE'),
('_compression', 'E:\\Anaconda\\anaconda3\\Lib\\_compression.py', 'PYMODULE'),
('_py_abc', 'E:\\Anaconda\\anaconda3\\Lib\\_py_abc.py', 'PYMODULE'),
('_pydecimal', 'E:\\Anaconda\\anaconda3\\Lib\\_pydecimal.py', 'PYMODULE'),
('_pyi_rth_utils',
'E:\\Anaconda\\anaconda3\\Lib\\site-packages\\PyInstaller\\fake-modules\\_pyi_rth_utils\\__init__.py',
'PYMODULE'),
('_pyi_rth_utils.qt',
'E:\\Anaconda\\anaconda3\\Lib\\site-packages\\PyInstaller\\fake-modules\\_pyi_rth_utils\\qt.py',
'PYMODULE'),
('_strptime', 'E:\\Anaconda\\anaconda3\\Lib\\_strptime.py', 'PYMODULE'),
('_threading_local',
'E:\\Anaconda\\anaconda3\\Lib\\_threading_local.py',
'PYMODULE'),
('argparse', 'E:\\Anaconda\\anaconda3\\Lib\\argparse.py', 'PYMODULE'),
('ast', 'E:\\Anaconda\\anaconda3\\Lib\\ast.py', 'PYMODULE'),
('base64', 'E:\\Anaconda\\anaconda3\\Lib\\base64.py', 'PYMODULE'),
('bisect', 'E:\\Anaconda\\anaconda3\\Lib\\bisect.py', 'PYMODULE'),
('bz2', 'E:\\Anaconda\\anaconda3\\Lib\\bz2.py', 'PYMODULE'),
('calendar', 'E:\\Anaconda\\anaconda3\\Lib\\calendar.py', 'PYMODULE'),
('contextlib', 'E:\\Anaconda\\anaconda3\\Lib\\contextlib.py', 'PYMODULE'),
('contextvars', 'E:\\Anaconda\\anaconda3\\Lib\\contextvars.py', 'PYMODULE'),
('copy', 'E:\\Anaconda\\anaconda3\\Lib\\copy.py', 'PYMODULE'),
('csv', 'E:\\Anaconda\\anaconda3\\Lib\\csv.py', 'PYMODULE'),
('dataclasses', 'E:\\Anaconda\\anaconda3\\Lib\\dataclasses.py', 'PYMODULE'),
('datetime', 'E:\\Anaconda\\anaconda3\\Lib\\datetime.py', 'PYMODULE'),
('decimal', 'E:\\Anaconda\\anaconda3\\Lib\\decimal.py', 'PYMODULE'),
('dis', 'E:\\Anaconda\\anaconda3\\Lib\\dis.py', 'PYMODULE'),
('email', 'E:\\Anaconda\\anaconda3\\Lib\\email\\__init__.py', 'PYMODULE'),
('email._encoded_words',
'E:\\Anaconda\\anaconda3\\Lib\\email\\_encoded_words.py',
'PYMODULE'),
('email._header_value_parser',
'E:\\Anaconda\\anaconda3\\Lib\\email\\_header_value_parser.py',
'PYMODULE'),
('email._parseaddr',
'E:\\Anaconda\\anaconda3\\Lib\\email\\_parseaddr.py',
'PYMODULE'),
('email._policybase',
'E:\\Anaconda\\anaconda3\\Lib\\email\\_policybase.py',
'PYMODULE'),
('email.base64mime',
'E:\\Anaconda\\anaconda3\\Lib\\email\\base64mime.py',
'PYMODULE'),
('email.charset',
'E:\\Anaconda\\anaconda3\\Lib\\email\\charset.py',
'PYMODULE'),
('email.contentmanager',
'E:\\Anaconda\\anaconda3\\Lib\\email\\contentmanager.py',
'PYMODULE'),
('email.encoders',
'E:\\Anaconda\\anaconda3\\Lib\\email\\encoders.py',
'PYMODULE'),
('email.errors',
'E:\\Anaconda\\anaconda3\\Lib\\email\\errors.py',
'PYMODULE'),
('email.feedparser',
'E:\\Anaconda\\anaconda3\\Lib\\email\\feedparser.py',
'PYMODULE'),
('email.generator',
'E:\\Anaconda\\anaconda3\\Lib\\email\\generator.py',
'PYMODULE'),
('email.header',
'E:\\Anaconda\\anaconda3\\Lib\\email\\header.py',
'PYMODULE'),
('email.headerregistry',
'E:\\Anaconda\\anaconda3\\Lib\\email\\headerregistry.py',
'PYMODULE'),
('email.iterators',
'E:\\Anaconda\\anaconda3\\Lib\\email\\iterators.py',
'PYMODULE'),
('email.message',
'E:\\Anaconda\\anaconda3\\Lib\\email\\message.py',
'PYMODULE'),
('email.parser',
'E:\\Anaconda\\anaconda3\\Lib\\email\\parser.py',
'PYMODULE'),
('email.policy',
'E:\\Anaconda\\anaconda3\\Lib\\email\\policy.py',
'PYMODULE'),
('email.quoprimime',
'E:\\Anaconda\\anaconda3\\Lib\\email\\quoprimime.py',
'PYMODULE'),
('email.utils', 'E:\\Anaconda\\anaconda3\\Lib\\email\\utils.py', 'PYMODULE'),
('fnmatch', 'E:\\Anaconda\\anaconda3\\Lib\\fnmatch.py', 'PYMODULE'),
('fractions', 'E:\\Anaconda\\anaconda3\\Lib\\fractions.py', 'PYMODULE'),
('getopt', 'E:\\Anaconda\\anaconda3\\Lib\\getopt.py', 'PYMODULE'),
('gettext', 'E:\\Anaconda\\anaconda3\\Lib\\gettext.py', 'PYMODULE'),
('gzip', 'E:\\Anaconda\\anaconda3\\Lib\\gzip.py', 'PYMODULE'),
('hashlib', 'E:\\Anaconda\\anaconda3\\Lib\\hashlib.py', 'PYMODULE'),
('hmac', 'E:\\Anaconda\\anaconda3\\Lib\\hmac.py', 'PYMODULE'),
('importlib',
'E:\\Anaconda\\anaconda3\\Lib\\importlib\\__init__.py',
'PYMODULE'),
('importlib._abc',
'E:\\Anaconda\\anaconda3\\Lib\\importlib\\_abc.py',
'PYMODULE'),
('importlib._bootstrap',
'E:\\Anaconda\\anaconda3\\Lib\\importlib\\_bootstrap.py',
'PYMODULE'),
('importlib._bootstrap_external',
'E:\\Anaconda\\anaconda3\\Lib\\importlib\\_bootstrap_external.py',
'PYMODULE'),
('importlib.abc',
'E:\\Anaconda\\anaconda3\\Lib\\importlib\\abc.py',
'PYMODULE'),
('importlib.machinery',
'E:\\Anaconda\\anaconda3\\Lib\\importlib\\machinery.py',
'PYMODULE'),
('importlib.metadata',
'E:\\Anaconda\\anaconda3\\Lib\\importlib\\metadata\\__init__.py',
'PYMODULE'),
('importlib.metadata._adapters',
'E:\\Anaconda\\anaconda3\\Lib\\importlib\\metadata\\_adapters.py',
'PYMODULE'),
('importlib.metadata._collections',
'E:\\Anaconda\\anaconda3\\Lib\\importlib\\metadata\\_collections.py',
'PYMODULE'),
('importlib.metadata._functools',
'E:\\Anaconda\\anaconda3\\Lib\\importlib\\metadata\\_functools.py',
'PYMODULE'),
('importlib.metadata._itertools',
'E:\\Anaconda\\anaconda3\\Lib\\importlib\\metadata\\_itertools.py',
'PYMODULE'),
('importlib.metadata._meta',
'E:\\Anaconda\\anaconda3\\Lib\\importlib\\metadata\\_meta.py',
'PYMODULE'),
('importlib.metadata._text',
'E:\\Anaconda\\anaconda3\\Lib\\importlib\\metadata\\_text.py',
'PYMODULE'),
('importlib.readers',
'E:\\Anaconda\\anaconda3\\Lib\\importlib\\readers.py',
'PYMODULE'),
('importlib.resources',
'E:\\Anaconda\\anaconda3\\Lib\\importlib\\resources\\__init__.py',
'PYMODULE'),
('importlib.resources._adapters',
'E:\\Anaconda\\anaconda3\\Lib\\importlib\\resources\\_adapters.py',
'PYMODULE'),
('importlib.resources._common',
'E:\\Anaconda\\anaconda3\\Lib\\importlib\\resources\\_common.py',
'PYMODULE'),
('importlib.resources._itertools',
'E:\\Anaconda\\anaconda3\\Lib\\importlib\\resources\\_itertools.py',
'PYMODULE'),
('importlib.resources._legacy',
'E:\\Anaconda\\anaconda3\\Lib\\importlib\\resources\\_legacy.py',
'PYMODULE'),
('importlib.resources.abc',
'E:\\Anaconda\\anaconda3\\Lib\\importlib\\resources\\abc.py',
'PYMODULE'),
('importlib.resources.readers',
'E:\\Anaconda\\anaconda3\\Lib\\importlib\\resources\\readers.py',
'PYMODULE'),
('importlib.util',
'E:\\Anaconda\\anaconda3\\Lib\\importlib\\util.py',
'PYMODULE'),
('inspect', 'E:\\Anaconda\\anaconda3\\Lib\\inspect.py', 'PYMODULE'),
('ipaddress', 'E:\\Anaconda\\anaconda3\\Lib\\ipaddress.py', 'PYMODULE'),
('json', 'E:\\Anaconda\\anaconda3\\Lib\\json\\__init__.py', 'PYMODULE'),
('json.decoder',
'E:\\Anaconda\\anaconda3\\Lib\\json\\decoder.py',
'PYMODULE'),
('json.encoder',
'E:\\Anaconda\\anaconda3\\Lib\\json\\encoder.py',
'PYMODULE'),
('json.scanner',
'E:\\Anaconda\\anaconda3\\Lib\\json\\scanner.py',
'PYMODULE'),
('logging', 'E:\\Anaconda\\anaconda3\\Lib\\logging\\__init__.py', 'PYMODULE'),
('lzma', 'E:\\Anaconda\\anaconda3\\Lib\\lzma.py', 'PYMODULE'),
('numbers', 'E:\\Anaconda\\anaconda3\\Lib\\numbers.py', 'PYMODULE'),
('opcode', 'E:\\Anaconda\\anaconda3\\Lib\\opcode.py', 'PYMODULE'),
('pathlib', 'E:\\Anaconda\\anaconda3\\Lib\\pathlib.py', 'PYMODULE'),
('pickle', 'E:\\Anaconda\\anaconda3\\Lib\\pickle.py', 'PYMODULE'),
('pkgutil', 'E:\\Anaconda\\anaconda3\\Lib\\pkgutil.py', 'PYMODULE'),
('pprint', 'E:\\Anaconda\\anaconda3\\Lib\\pprint.py', 'PYMODULE'),
('py_compile', 'E:\\Anaconda\\anaconda3\\Lib\\py_compile.py', 'PYMODULE'),
('quopri', 'E:\\Anaconda\\anaconda3\\Lib\\quopri.py', 'PYMODULE'),
('random', 'E:\\Anaconda\\anaconda3\\Lib\\random.py', 'PYMODULE'),
('secrets', 'E:\\Anaconda\\anaconda3\\Lib\\secrets.py', 'PYMODULE'),
('selectors', 'E:\\Anaconda\\anaconda3\\Lib\\selectors.py', 'PYMODULE'),
('services',
'C:\\Users\\xyx29\\source\\软件工程导论\\MathStudySystem-develop\\mathstudysystem\\MathStudySystem-develop\\mathstudysystem\\src\\services\\__init__.py',
'PYMODULE'),
('services.question_service',
'C:\\Users\\xyx29\\source\\软件工程导论\\MathStudySystem-develop\\mathstudysystem\\MathStudySystem-develop\\mathstudysystem\\src\\services\\question_service.py',
'PYMODULE'),
('services.storage_service',
'C:\\Users\\xyx29\\source\\软件工程导论\\MathStudySystem-develop\\mathstudysystem\\MathStudySystem-develop\\mathstudysystem\\src\\services\\storage_service.py',
'PYMODULE'),
('services.user_service',
'C:\\Users\\xyx29\\source\\软件工程导论\\MathStudySystem-develop\\mathstudysystem\\MathStudySystem-develop\\mathstudysystem\\src\\services\\user_service.py',
'PYMODULE'),
('shutil', 'E:\\Anaconda\\anaconda3\\Lib\\shutil.py', 'PYMODULE'),
('signal', 'E:\\Anaconda\\anaconda3\\Lib\\signal.py', 'PYMODULE'),
('smtplib', 'E:\\Anaconda\\anaconda3\\Lib\\smtplib.py', 'PYMODULE'),
('socket', 'E:\\Anaconda\\anaconda3\\Lib\\socket.py', 'PYMODULE'),
('ssl', 'E:\\Anaconda\\anaconda3\\Lib\\ssl.py', 'PYMODULE'),
('statistics', 'E:\\Anaconda\\anaconda3\\Lib\\statistics.py', 'PYMODULE'),
('string', 'E:\\Anaconda\\anaconda3\\Lib\\string.py', 'PYMODULE'),
('stringprep', 'E:\\Anaconda\\anaconda3\\Lib\\stringprep.py', 'PYMODULE'),
('subprocess', 'E:\\Anaconda\\anaconda3\\Lib\\subprocess.py', 'PYMODULE'),
('tarfile', 'E:\\Anaconda\\anaconda3\\Lib\\tarfile.py', 'PYMODULE'),
('tempfile', 'E:\\Anaconda\\anaconda3\\Lib\\tempfile.py', 'PYMODULE'),
('textwrap', 'E:\\Anaconda\\anaconda3\\Lib\\textwrap.py', 'PYMODULE'),
('threading', 'E:\\Anaconda\\anaconda3\\Lib\\threading.py', 'PYMODULE'),
('token', 'E:\\Anaconda\\anaconda3\\Lib\\token.py', 'PYMODULE'),
('tokenize', 'E:\\Anaconda\\anaconda3\\Lib\\tokenize.py', 'PYMODULE'),
('tracemalloc', 'E:\\Anaconda\\anaconda3\\Lib\\tracemalloc.py', 'PYMODULE'),
('typing', 'E:\\Anaconda\\anaconda3\\Lib\\typing.py', 'PYMODULE'),
('ui',
'C:\\Users\\xyx29\\source\\软件工程导论\\MathStudySystem-develop\\mathstudysystem\\MathStudySystem-develop\\mathstudysystem\\src\\ui\\__init__.py',
'PYMODULE'),
('ui.main_window',
'C:\\Users\\xyx29\\source\\软件工程导论\\MathStudySystem-develop\\mathstudysystem\\MathStudySystem-develop\\mathstudysystem\\src\\ui\\main_window.py',
'PYMODULE'),
('urllib', 'E:\\Anaconda\\anaconda3\\Lib\\urllib\\__init__.py', 'PYMODULE'),
('urllib.parse',
'E:\\Anaconda\\anaconda3\\Lib\\urllib\\parse.py',
'PYMODULE'),
('utils',
'C:\\Users\\xyx29\\source\\软件工程导论\\MathStudySystem-develop\\mathstudysystem\\MathStudySystem-develop\\mathstudysystem\\src\\utils\\__init__.py',
'PYMODULE'),
('utils.security_utils',
'C:\\Users\\xyx29\\source\\软件工程导论\\MathStudySystem-develop\\mathstudysystem\\MathStudySystem-develop\\mathstudysystem\\src\\utils\\security_utils.py',
'PYMODULE'),
('zipfile', 'E:\\Anaconda\\anaconda3\\Lib\\zipfile.py', 'PYMODULE'),
('zipimport', 'E:\\Anaconda\\anaconda3\\Lib\\zipimport.py', 'PYMODULE')])

@ -0,0 +1,27 @@
This file lists modules PyInstaller was not able to find. This does not
necessarily mean this module is required for running your program. Python and
Python 3rd-party packages include a lot of conditional or optional modules. For
example the module 'ntpath' only exists on Windows, whereas the module
'posixpath' only exists on Posix systems.
Types if import:
* top-level: imported at the top-level - look at these first
* conditional: imported within an if-statement
* delayed: imported within a function
* optional: imported within a try-except-statement
IMPORTANT: Do NOT post this list to the issue-tracker. Use it as a basis for
tracking down the missing module yourself. Thanks!
missing module named pyimod02_importers - imported by E:\Anaconda\anaconda3\Lib\site-packages\PyInstaller\hooks\rthooks\pyi_rth_pkgutil.py (delayed)
missing module named 'org.python' - imported by copy (optional)
missing module named pwd - imported by posixpath (delayed, conditional, optional), shutil (delayed, optional), tarfile (optional), pathlib (delayed, optional), subprocess (delayed, conditional, optional)
missing module named grp - imported by shutil (delayed, optional), tarfile (optional), pathlib (delayed, optional), subprocess (delayed, conditional, optional)
missing module named posix - imported by os (conditional, optional), posixpath (optional), shutil (conditional), importlib._bootstrap_external (conditional)
missing module named resource - imported by posix (top-level)
excluded module named _frozen_importlib - imported by importlib (optional), importlib.abc (optional), zipimport (top-level)
missing module named _frozen_importlib_external - imported by importlib._bootstrap (delayed), importlib (optional), importlib.abc (optional), zipimport (top-level)
missing module named org - imported by pickle (optional)
missing module named _posixsubprocess - imported by subprocess (conditional)
missing module named fcntl - imported by subprocess (optional)

File diff suppressed because it is too large Load Diff

Binary file not shown.

@ -0,0 +1 @@
PyQt6==6.7.0

@ -0,0 +1,14 @@
from PyQt6.QtWidgets import QApplication
from ui.main_window import MainWindow
def main() -> None:
"""应用程序入口:创建 QApplication显示主窗口并进入事件循环。"""
app = QApplication([])
window = MainWindow()
window.show()
app.exec()
if __name__ == "__main__":
main()

@ -0,0 +1,66 @@
"""
邮件服务模块基于 SMTP 发送验证码邮件支持 TLS/SSL
"""
import smtplib
import ssl
from email.message import EmailMessage
from typing import Dict
from .storage_service import StorageService
class EmailService:
"""负责发送邮件验证码的服务类。"""
def __init__(self, storage: StorageService) -> None:
"""初始化邮件服务,依赖存储服务获取 SMTP 配置。"""
self.storage = storage
def send_verification_code(self, to_email: str, code: str) -> bool:
"""发送验证码到指定邮箱。
参数:
to_email: 收件人邮箱
code: 验证码字符串
返回:
True 表示发送成功False 表示失败
"""
config = self.storage.load_config().get('smtp', {})
server = config.get('server', '')
port = int(config.get('port', 587))
username = config.get('username', '')
password = config.get('password', '')
use_tls = bool(config.get('use_tls', True))
use_ssl = bool(config.get('use_ssl', False))
sender_name = config.get('sender_name', 'Math Study App')
if not server or not username or not password:
return False
msg = EmailMessage()
msg['Subject'] = '数学学习软件注册验证码'
msg['From'] = f"{sender_name} <{username}>"
msg['To'] = to_email
msg.set_content(f"您的注册验证码为:{code}\n该验证码10分钟内有效。")
try:
if use_ssl:
context = ssl.create_default_context()
with smtplib.SMTP_SSL(server, port, context=context) as smtp:
smtp.login(username, password)
smtp.send_message(msg)
else:
with smtplib.SMTP(server, port) as smtp:
if use_tls:
smtp.starttls(context=ssl.create_default_context())
smtp.login(username, password)
smtp.send_message(msg)
return True
except Exception:
return False
def update_smtp_config(self, config: Dict) -> None:
"""更新并保存 SMTP 配置。"""
data = self.storage.load_config()
data['smtp'] = config
self.storage.save_config(data)

@ -0,0 +1,231 @@
"""
试题服务模块按小学/初中/高中生成选择题试卷并保证同一试卷题目不重复
"""
import random
import math
from typing import List, Dict
class QuestionService:
"""负责生成不同年级难度的选择题。"""
def __init__(self) -> None:
"""初始化题目服务。"""
random.seed()
def generate_questions(self, level: str, count: int) -> List[Dict]:
"""生成指定年级与数量的题目列表。
参数:
level: 'primary'|'middle'|'high' 三选一
count: 题目数量
返回:
题目字典列表每个字典包含 stem, options, answer_index
"""
generators = {
'primary': self._gen_primary,
'middle': self._gen_middle,
'high': self._gen_high,
}
gen = generators.get(level)
if not gen:
raise ValueError('无效的年级选项')
seen = set()
questions: List[Dict] = []
while len(questions) < count:
q = gen()
if q['stem'] in seen:
continue
seen.add(q['stem'])
questions.append(q)
return questions
def _gen_primary(self) -> Dict:
"""生成一题小学难度的四则运算选择题(可带括号)。"""
# 随机选择运算类型:简单四则运算或带括号的复合运算
if random.choice([True, False]):
# 简单四则运算
a = random.randint(1, 50)
b = random.randint(1, 50)
op = random.choice(['+', '-', '*', '/'])
if op == '+':
ans = a + b
stem = f"计算:{a} + {b} = ?"
elif op == '-':
ans = a - b
stem = f"计算:{a} - {b} = ?"
elif op == '*':
ans = a * b
stem = f"计算:{a} × {b} = ?"
else: # 除法,确保整除
ans = a
b = random.randint(1, 10)
a = ans * b # 确保整除
stem = f"计算:{a} ÷ {b} = ?"
else:
# 带括号的复合运算
a = random.randint(1, 20)
b = random.randint(1, 20)
c = random.randint(1, 20)
# 随机选择括号运算类型
bracket_type = random.choice(['add_mul', 'sub_mul', 'mul_add', 'mul_sub'])
if bracket_type == 'add_mul':
ans = (a + b) * c
stem = f"计算:({a} + {b}) × {c} = ?"
elif bracket_type == 'sub_mul':
ans = (a - b) * c
stem = f"计算:({a} - {b}) × {c} = ?"
elif bracket_type == 'mul_add':
ans = a * (b + c)
stem = f"计算:{a} × ({b} + {c}) = ?"
else: # mul_sub
ans = a * (b - c)
stem = f"计算:{a} × ({b} - {c}) = ?"
options = self._make_options(ans)
return {'stem': stem, 'options': options, 'answer_index': options.index(str(ans))}
def _gen_middle(self) -> Dict:
"""生成一题初中难度的题目,至少包含一个平方或开根号运算。"""
# 随机选择题目类型:平方运算、开根号运算或混合运算
question_type = random.choice(['square', 'sqrt', 'mixed'])
if question_type == 'square':
# 平方运算题目
a = random.randint(2, 15)
b = random.randint(1, 10)
if random.choice([True, False]):
# (a + b)²
ans = (a + b) ** 2
stem = f"计算:({a} + {b})² = ?"
else:
# a² + b²
ans = a ** 2 + b ** 2
stem = f"计算:{a}² + {b}² = ?"
elif question_type == 'sqrt':
# 开根号运算题目
# 选择完全平方数确保结果为整数
perfect_squares = [4, 9, 16, 25, 36, 49, 64, 81, 100, 121, 144, 169, 196, 225]
a = random.choice(perfect_squares)
b = random.randint(1, 10)
if random.choice([True, False]):
# √a + b
ans = int(math.sqrt(a)) + b
stem = f"计算:√{a} + {b} = ?"
else:
# √a × b
ans = int(math.sqrt(a)) * b
stem = f"计算:√{a} × {b} = ?"
else: # mixed
# 混合运算:既有平方又有开根号
perfect_square = random.choice([4, 9, 16, 25, 36, 49, 64, 81, 100])
a = random.randint(2, 8)
# √perfect_square + a²
ans = int(math.sqrt(perfect_square)) + a ** 2
stem = f"计算:√{perfect_square} + {a}² = ?"
options = self._make_options(ans)
return {'stem': stem, 'options': options, 'answer_index': options.index(str(ans))}
def _gen_high(self) -> Dict:
"""生成一题高中难度的题目至少包含一个sin、cos或tan运算符。"""
# 随机选择题目类型:基础三角函数、三角函数运算或复合运算
question_type = random.choice(['basic_trig', 'trig_calc', 'mixed_trig'])
if question_type == 'basic_trig':
# 基础三角函数值计算
# 使用特殊角度确保结果为常见值
special_angles = [0, 30, 45, 60, 90, 120, 135, 150, 180]
angle = random.choice(special_angles)
func = random.choice(['sin', 'cos', 'tan'])
# 计算三角函数值(转换为弧度)
rad = math.radians(angle)
if func == 'sin':
ans = round(math.sin(rad), 2)
stem = f"计算sin({angle}°) = ?(保留两位小数)"
elif func == 'cos':
ans = round(math.cos(rad), 2)
stem = f"计算cos({angle}°) = ?(保留两位小数)"
else: # tan
if angle in [90, 270]: # tan在这些角度未定义
angle = 45
rad = math.radians(angle)
ans = round(math.tan(rad), 2)
stem = f"计算tan({angle}°) = ?(保留两位小数)"
elif question_type == 'trig_calc':
# 三角函数运算
angle1 = random.choice([30, 45, 60])
angle2 = random.choice([30, 45, 60])
func1 = random.choice(['sin', 'cos'])
func2 = random.choice(['sin', 'cos'])
rad1 = math.radians(angle1)
rad2 = math.radians(angle2)
if func1 == 'sin':
val1 = math.sin(rad1)
else:
val1 = math.cos(rad1)
if func2 == 'sin':
val2 = math.sin(rad2)
else:
val2 = math.cos(rad2)
# 随机选择运算符
if random.choice([True, False]):
ans = round(val1 + val2, 2)
stem = f"计算:{func1}({angle1}°) + {func2}({angle2}°) = ?(保留两位小数)"
else:
ans = round(val1 * val2, 2)
stem = f"计算:{func1}({angle1}°) × {func2}({angle2}°) = ?(保留两位小数)"
else: # mixed_trig
# 混合运算:三角函数与代数运算
angle = random.choice([30, 45, 60])
a = random.randint(2, 5)
func = random.choice(['sin', 'cos', 'tan'])
rad = math.radians(angle)
if func == 'sin':
trig_val = math.sin(rad)
elif func == 'cos':
trig_val = math.cos(rad)
else:
trig_val = math.tan(rad)
ans = round(a * trig_val + a, 2)
stem = f"计算:{a} × {func}({angle}°) + {a} = ?(保留两位小数)"
options = self._make_options(ans, float_mode=True)
correct = f"{ans:.2f}"
return {'stem': stem, 'options': options, 'answer_index': options.index(correct)}
def _make_options(self, answer, float_mode: bool = False) -> List[str]:
"""根据正确答案生成 4 个选项包含正确答案与3个干扰项"""
opts = set()
if float_mode:
correct = f"{answer:.2f}"
opts.add(correct)
while len(opts) < 4:
delta = random.uniform(-5, 5)
opts.add(f"{answer + delta:.2f}")
else:
correct = str(answer)
opts.add(correct)
while len(opts) < 4:
delta = random.randint(-10, 10)
opts.add(str(answer + delta))
options = list(opts)
random.shuffle(options)
return options

@ -0,0 +1,106 @@
"""
存储服务模块使用 JSON 文件持久化数据不使用数据库
提供用户数据与配置数据的读写接口
"""
import json
import os
import sys
from typing import Dict, Any, List
class StorageService:
"""使用 JSON 文件进行数据持久化的服务类。"""
def __init__(self) -> None:
"""初始化存储路径并确保必要文件存在。"""
# 获取应用程序的基础目录
if getattr(sys, 'frozen', False):
# 如果是打包后的可执行文件
base_dir = sys._MEIPASS
self.storage_dir = os.path.join(base_dir, 'storage')
else:
# 如果是开发环境
base_dir = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
self.storage_dir = os.path.join(base_dir, 'storage')
self.users_file = os.path.join(self.storage_dir, 'users.json')
self.config_file = os.path.join(self.storage_dir, 'config.json')
self._ensure_files()
def _ensure_files(self) -> None:
"""确保存储目录与文件存在,如不存在则创建。"""
os.makedirs(self.storage_dir, exist_ok=True)
if not os.path.exists(self.users_file):
with open(self.users_file, 'w', encoding='utf-8') as f:
json.dump({'users': []}, f, ensure_ascii=False, indent=2)
if not os.path.exists(self.config_file):
with open(self.config_file, 'w', encoding='utf-8') as f:
json.dump({
'smtp': {
'server': '',
'port': 587,
'username': '',
'password': '',
'use_tls': True,
'use_ssl': False,
'sender_name': 'Math Study App'
}
}, f, ensure_ascii=False, indent=2)
def load_users(self) -> Dict[str, List[Dict[str, Any]]]:
"""读取用户列表数据。返回字典 {'users': [...]}。"""
with open(self.users_file, 'r', encoding='utf-8') as f:
return json.load(f)
def save_users(self, data: Dict[str, List[Dict[str, Any]]]) -> None:
"""写入用户列表数据到文件。"""
with open(self.users_file, 'w', encoding='utf-8') as f:
json.dump(data, f, ensure_ascii=False, indent=2)
def load_config(self) -> Dict[str, Any]:
"""读取配置数据(包含 SMTP 配置)。"""
with open(self.config_file, 'r', encoding='utf-8') as f:
return json.load(f)
def save_config(self, data: Dict[str, Any]) -> None:
"""写入配置数据到文件。"""
with open(self.config_file, 'w', encoding='utf-8') as f:
json.dump(data, f, ensure_ascii=False, indent=2)
def get_user(self, email: str) -> Dict[str, Any] | None:
"""根据邮箱获取用户字典,不存在返回 None。"""
users = self.load_users().get('users', [])
for u in users:
if u.get('email') == email:
return u
return None
def get_user_by_username(self, username: str) -> Dict[str, Any] | None:
"""根据用户名获取用户字典,不存在返回 None。"""
users = self.load_users().get('users', [])
for u in users:
if u.get('username') == username:
return u
return None
def username_exists(self, username: str) -> bool:
"""判断指定用户名是否已被占用。"""
return self.get_user_by_username(username) is not None
def upsert_user(self, user: Dict[str, Any]) -> None:
"""插入或更新用户字典,并立即持久化。"""
data = self.load_users()
users = data.get('users', [])
found = False
for i, u in enumerate(users):
if u.get('email') == user.get('email'):
users[i] = user
found = True
break
if not found:
users.append(user)
self.save_users({'users': users})
def user_exists(self, email: str) -> bool:
"""判断指定邮箱的用户是否存在。"""
return self.get_user(email) is not None

@ -0,0 +1,174 @@
"""
用户服务模块处理注册验证码用户名设置登录与修改密码逻辑
不依赖真实邮件与SMTP仅进行邮箱格式校验与本地验证码生成/校验
"""
import time
from typing import Any, Dict
from utils.security_utils import (
validate_email,
validate_password_strength,
generate_verification_code,
hash_password,
verify_password,
)
from .storage_service import StorageService
# 删除 EmailService 依赖
class UserService:
"""封装用户相关业务逻辑的服务类。"""
def __init__(self, storage: StorageService) -> None:
"""初始化用户服务,仅注入存储服务。"""
self.storage = storage
def request_registration(self, email: str) -> tuple[bool, str]:
"""发起注册请求:校验邮箱,生成验证码并本地保存(不发送邮件)。
参数:
email: 用户邮箱
返回:
(success, message) 二元组message包含提示与模拟验证码信息
"""
if not validate_email(email):
return False, '邮箱格式不正确'
existing = self.storage.get_user(email)
if existing and existing.get('verified'):
return False, '该邮箱已注册'
code = generate_verification_code()
salt, code_hash = hash_password(code)
user = existing or {'email': email}
user.update({
'verified': False,
'code_salt': salt.hex(),
'code_hash': code_hash.hex(),
'code_time': int(time.time()),
'password_salt': '',
'password_hash': '',
'username': user.get('username', ''),
'created_at': user.get('created_at') or int(time.time()),
})
self.storage.upsert_user(user)
# 不发送邮件,直接提示验证码供用户在下一步手动输入
return True, f'验证码已生成(模拟):{code},请前往验证码页面手动输入'
def verify_code(self, email: str, code: str) -> tuple[bool, str]:
"""校验验证码并标记邮箱已验证。
参数:
email: 用户邮箱
code: 用户输入的验证码
返回:
(success, message)
"""
user = self.storage.get_user(email)
if not user:
return False, '用户不存在,请先注册'
if int(time.time()) - int(user.get('code_time', 0)) > 600:
return False, '验证码已过期,请重新获取'
salt_hex = user.get('code_salt', '')
hash_hex = user.get('code_hash', '')
if not salt_hex or not hash_hex:
return False, '未找到验证码信息'
salt = bytes.fromhex(salt_hex)
hash_bytes = bytes.fromhex(hash_hex)
if not verify_password(code, salt, hash_bytes):
return False, '验证码不正确'
user['verified'] = True
# 清除验证码信息
user['code_salt'] = ''
user['code_hash'] = ''
self.storage.upsert_user(user)
return True, '邮箱验证成功,请设置用户名与密码'
def set_username(self, email: str, username: str) -> tuple[bool, str]:
"""设置用户名:校验格式与唯一性,并写入用户信息。
参数:
email: 目标用户邮箱
username: 待设置的用户名3-16字母数字与下划线
返回:
(success, message)
"""
user = self.storage.get_user(email)
if not user or not user.get('verified'):
return False, '邮箱未验证或用户不存在'
uname = (username or '').strip()
if not (3 <= len(uname) <= 16) or not all(c.isalnum() or c == '_' for c in uname):
return False, '用户名需为3-16位且仅包含字母、数字或下划线'
if self.storage.username_exists(uname):
return False, '该用户名已被占用'
user['username'] = uname
self.storage.upsert_user(user)
return True, '用户名设置成功'
def set_password(self, email: str, password: str, confirm: str) -> tuple[bool, str]:
"""设置或重置密码:校验强度、确认一致并持久化哈希。"""
if password != confirm:
return False, '两次输入的密码不一致'
if not validate_password_strength(password):
return False, '密码需为6-10位且包含大小写字母与数字'
user = self.storage.get_user(email)
if not user or not user.get('verified'):
return False, '邮箱未验证或用户不存在'
salt, pwd_hash = hash_password(password)
user['password_salt'] = salt.hex()
user['password_hash'] = pwd_hash.hex()
self.storage.upsert_user(user)
return True, '密码设置成功'
def complete_registration(self, email: str) -> tuple[bool, str]:
"""完成注册:要求用户已设置用户名与密码,方视为完成。
参数:
email: 用户邮箱
返回:
(success, message)
"""
user = self.storage.get_user(email)
if not user:
return False, '用户不存在'
if not user.get('verified'):
return False, '邮箱未验证'
if not user.get('username'):
return False, '请先设置用户名'
if not user.get('password_hash'):
return False, '请先设置密码'
# 已经持久化,无需额外操作,这里仅作为流程校验提示
return True, '注册完成'
def login(self, email: str, password: str) -> tuple[bool, str]:
"""邮箱登录:校验邮箱存在与密码匹配。"""
user = self.storage.get_user(email)
if not user or not user.get('password_hash'):
return False, '用户不存在或未设置密码'
salt_hex = user.get('password_salt', '')
hash_hex = user.get('password_hash', '')
ok = verify_password(password, bytes.fromhex(salt_hex), bytes.fromhex(hash_hex))
if not ok:
return False, '密码不正确'
return True, '登录成功'
def login_by_username(self, username: str, password: str) -> tuple[bool, str]:
"""用户名登录:根据用户名查询并校验密码。"""
user = self.storage.get_user_by_username(username)
if not user or not user.get('password_hash'):
return False, '用户不存在或未设置密码'
salt_hex = user.get('password_salt', '')
hash_hex = user.get('password_hash', '')
ok = verify_password(password, bytes.fromhex(salt_hex), bytes.fromhex(hash_hex))
if not ok:
return False, '密码不正确'
return True, '登录成功'
def change_password(self, email: str, old_password: str, new_password: str, confirm: str) -> tuple[bool, str]:
"""修改密码:校验原密码正确并设置新密码。"""
user = self.storage.get_user(email)
if not user:
return False, '用户不存在'
salt_hex = user.get('password_salt', '')
hash_hex = user.get('password_hash', '')
if not verify_password(old_password, bytes.fromhex(salt_hex), bytes.fromhex(hash_hex)):
return False, '原密码不正确'
return self.set_password(email, new_password, confirm)

@ -0,0 +1,11 @@
{
"smtp": {
"server": "",
"port": 587,
"username": "",
"password": "",
"use_tls": true,
"use_ssl": false,
"sender_name": "Math Study App"
}
}

@ -0,0 +1,15 @@
{
"users": [
{
"email": "shenyongye@163.com",
"verified": true,
"code_salt": "",
"code_hash": "",
"code_time": 1760256425,
"password_salt": "e09f40c04b33d5f482ff682b3d43192b",
"password_hash": "dffeab45544b194e5f7efeb632cbe75eef3b46fbff23531692c7ef0e9a83f24b",
"username": "echo",
"created_at": 1760256425
}
]
}

@ -0,0 +1,585 @@
from PyQt6.QtWidgets import (
QMainWindow, QWidget, QStackedWidget, QVBoxLayout, QHBoxLayout,
QLabel, QLineEdit, QPushButton, QMessageBox, QRadioButton, QButtonGroup, QSpinBox
)
from PyQt6.QtCore import Qt
from services.storage_service import StorageService
from services.user_service import UserService
from services.question_service import QuestionService
class MainWindow(QMainWindow):
"""应用主窗口:组织各个页面并承载业务服务。"""
def __init__(self) -> None:
"""初始化主窗口并构建基础页面。"""
super().__init__()
self.setWindowTitle("数学学习软件")
self.setFixedSize(900, 600)
# 业务服务初始化
self.storage_service = StorageService()
self.session_email = None
self.user_service = UserService(self.storage_service)
self.question_service = QuestionService()
# 页面容器
self.stack = QStackedWidget()
self.setCentralWidget(self.stack)
# 构建页面:登录、注册(邮箱/验证码/用户名密码)、选择、答题、结果、修改密码
self._build_login_page() # index 0
self._build_register_email_page() # index 1
self._build_verify_page() # index 2
self._build_set_credentials_page() # index 3
self._build_choice_page() # index 4
self._build_quiz_page() # index 5
self._build_result_page() # index 6
self._build_change_password_page() # index 7
# 默认显示登录页
self.stack.setCurrentIndex(0)
def _build_login_page(self) -> None:
"""构建登录页面:支持用户名或邮箱登录。"""
page = QWidget()
layout = QVBoxLayout(page)
layout.setAlignment(Qt.AlignmentFlag.AlignTop)
title = QLabel("登录")
title.setAlignment(Qt.AlignmentFlag.AlignCenter)
title.setStyleSheet("font-size: 22px; font-weight: bold; margin: 16px 0;")
layout.addWidget(title)
self.login_identifier = QLineEdit()
self.login_identifier.setPlaceholderText("请输入邮箱或用户名")
layout.addWidget(self.login_identifier)
self.login_password = QLineEdit()
self.login_password.setPlaceholderText("请输入密码")
self.login_password.setEchoMode(QLineEdit.EchoMode.Password)
layout.addWidget(self.login_password)
btn_row = QHBoxLayout()
self.btn_login = QPushButton("登录")
self.btn_to_register = QPushButton("去注册")
btn_row.addWidget(self.btn_login)
btn_row.addWidget(self.btn_to_register)
layout.addLayout(btn_row)
self.btn_login.clicked.connect(self._on_login)
self.btn_to_register.clicked.connect(lambda: self.stack.setCurrentIndex(1))
self.stack.addWidget(page)
def _on_login(self) -> None:
"""处理登录逻辑:根据输入自动识别邮箱或用户名进行登录,并在成功后进入选择页。"""
identifier = (self.login_identifier.text() or "").strip()
password = self.login_password.text() or ""
if not identifier or not password:
QMessageBox.warning(self, "提示", "账号与密码均不能为空")
return
# 判断是否为邮箱
if "@" in identifier:
ok, msg = self.user_service.login(identifier, password)
if ok:
self.session_email = identifier
else:
QMessageBox.warning(self, "提示", msg or "登录失败")
return
else:
ok, msg = self.user_service.login_by_username(identifier, password)
if ok:
# 通过用户名获取邮箱,记录会话
user = self.storage_service.get_user_by_username(identifier)
self.session_email = user.get('email') if user else None
else:
QMessageBox.warning(self, "提示", msg or "登录失败")
return
QMessageBox.information(self, "提示", "登录成功")
# 跳转到选择页
self.stack.setCurrentIndex(4)
def _build_register_email_page(self) -> None:
"""构建注册第一步:邮箱输入页面。"""
page = QWidget()
layout = QVBoxLayout(page)
layout.setAlignment(Qt.AlignmentFlag.AlignTop)
title = QLabel("注册 - 邮箱验证")
title.setAlignment(Qt.AlignmentFlag.AlignCenter)
title.setStyleSheet("font-size: 22px; font-weight: bold; margin: 16px 0;")
layout.addWidget(title)
self.register_email = QLineEdit()
self.register_email.setPlaceholderText("请输入邮箱地址")
layout.addWidget(self.register_email)
btn_row = QHBoxLayout()
self.btn_send_code = QPushButton("获取验证码")
self.btn_back_to_login = QPushButton("返回登录")
btn_row.addWidget(self.btn_send_code)
btn_row.addWidget(self.btn_back_to_login)
layout.addLayout(btn_row)
self.btn_send_code.clicked.connect(self._on_send_code)
self.btn_back_to_login.clicked.connect(lambda: self.stack.setCurrentIndex(0))
self.stack.addWidget(page)
def _on_send_code(self) -> None:
"""处理发送验证码逻辑:验证邮箱格式并生成验证码。"""
email = (self.register_email.text() or "").strip()
if not email:
QMessageBox.warning(self, "提示", "请输入邮箱地址")
return
ok, msg = self.user_service.request_registration(email)
if ok:
self.session_email = email
QMessageBox.information(self, "提示", msg)
# 跳转到验证码页面
self.stack.setCurrentIndex(2)
else:
QMessageBox.warning(self, "提示", msg)
def _build_verify_page(self) -> None:
"""构建注册第二步:验证码验证页面。"""
page = QWidget()
layout = QVBoxLayout(page)
layout.setAlignment(Qt.AlignmentFlag.AlignTop)
title = QLabel("注册 - 验证码验证")
title.setAlignment(Qt.AlignmentFlag.AlignCenter)
title.setStyleSheet("font-size: 22px; font-weight: bold; margin: 16px 0;")
layout.addWidget(title)
self.verify_code = QLineEdit()
self.verify_code.setPlaceholderText("请输入6位验证码")
layout.addWidget(self.verify_code)
btn_row = QHBoxLayout()
self.btn_verify = QPushButton("验证")
self.btn_back_to_email = QPushButton("返回上一步")
btn_row.addWidget(self.btn_verify)
btn_row.addWidget(self.btn_back_to_email)
layout.addLayout(btn_row)
self.btn_verify.clicked.connect(self._on_verify_code)
self.btn_back_to_email.clicked.connect(lambda: self.stack.setCurrentIndex(1))
self.stack.addWidget(page)
def _on_verify_code(self) -> None:
"""处理验证码验证逻辑。"""
code = (self.verify_code.text() or "").strip()
if not code:
QMessageBox.warning(self, "提示", "请输入验证码")
return
if not self.session_email:
QMessageBox.warning(self, "提示", "会话已过期,请重新注册")
self.stack.setCurrentIndex(1)
return
ok, msg = self.user_service.verify_code(self.session_email, code)
if ok:
QMessageBox.information(self, "提示", msg)
# 跳转到设置用户名密码页面
self.stack.setCurrentIndex(3)
else:
QMessageBox.warning(self, "提示", msg)
def _build_set_credentials_page(self) -> None:
"""构建注册第三步:设置用户名和密码页面。"""
page = QWidget()
layout = QVBoxLayout(page)
layout.setAlignment(Qt.AlignmentFlag.AlignTop)
title = QLabel("注册 - 设置用户名和密码")
title.setAlignment(Qt.AlignmentFlag.AlignCenter)
title.setStyleSheet("font-size: 22px; font-weight: bold; margin: 16px 0;")
layout.addWidget(title)
self.register_username = QLineEdit()
self.register_username.setPlaceholderText("请输入用户名3-16位字母数字下划线")
layout.addWidget(self.register_username)
self.register_password = QLineEdit()
self.register_password.setPlaceholderText("请输入密码6-10位包含大小写字母和数字")
self.register_password.setEchoMode(QLineEdit.EchoMode.Password)
layout.addWidget(self.register_password)
self.register_confirm = QLineEdit()
self.register_confirm.setPlaceholderText("请确认密码")
self.register_confirm.setEchoMode(QLineEdit.EchoMode.Password)
layout.addWidget(self.register_confirm)
btn_row = QHBoxLayout()
self.btn_complete_register = QPushButton("完成注册")
self.btn_back_to_verify = QPushButton("返回上一步")
btn_row.addWidget(self.btn_complete_register)
btn_row.addWidget(self.btn_back_to_verify)
layout.addLayout(btn_row)
self.btn_complete_register.clicked.connect(self._on_complete_register)
self.btn_back_to_verify.clicked.connect(lambda: self.stack.setCurrentIndex(2))
self.stack.addWidget(page)
def _on_complete_register(self) -> None:
"""处理完成注册逻辑:设置用户名和密码。"""
username = (self.register_username.text() or "").strip()
password = self.register_password.text() or ""
confirm = self.register_confirm.text() or ""
if not username or not password or not confirm:
QMessageBox.warning(self, "提示", "请填写完整信息")
return
if not self.session_email:
QMessageBox.warning(self, "提示", "会话已过期,请重新注册")
self.stack.setCurrentIndex(1)
return
# 设置用户名
ok, msg = self.user_service.set_username(self.session_email, username)
if not ok:
QMessageBox.warning(self, "提示", msg)
return
# 设置密码
ok, msg = self.user_service.set_password(self.session_email, password, confirm)
if not ok:
QMessageBox.warning(self, "提示", msg)
return
# 完成注册
ok, msg = self.user_service.complete_registration(self.session_email)
if ok:
QMessageBox.information(self, "提示", "注册成功!请登录")
# 清空表单并跳转到登录页
self.register_email.clear()
self.verify_code.clear()
self.register_username.clear()
self.register_password.clear()
self.register_confirm.clear()
self.session_email = None
self.stack.setCurrentIndex(0)
else:
QMessageBox.warning(self, "提示", msg)
def _build_choice_page(self) -> None:
"""构建选择页面:选择年级和题目数量。"""
page = QWidget()
layout = QVBoxLayout(page)
layout.setAlignment(Qt.AlignmentFlag.AlignTop)
title = QLabel("选择题目难度和数量")
title.setAlignment(Qt.AlignmentFlag.AlignCenter)
title.setStyleSheet("font-size: 22px; font-weight: bold; margin: 16px 0;")
layout.addWidget(title)
# 年级选择
grade_label = QLabel("选择年级:")
layout.addWidget(grade_label)
self.grade_group = QButtonGroup()
grade_layout = QHBoxLayout()
self.primary_radio = QRadioButton("小学")
self.middle_radio = QRadioButton("初中")
self.high_radio = QRadioButton("高中")
self.grade_group.addButton(self.primary_radio, 0)
self.grade_group.addButton(self.middle_radio, 1)
self.grade_group.addButton(self.high_radio, 2)
grade_layout.addWidget(self.primary_radio)
grade_layout.addWidget(self.middle_radio)
grade_layout.addWidget(self.high_radio)
layout.addLayout(grade_layout)
# 默认选择小学
self.primary_radio.setChecked(True)
# 题目数量选择
count_label = QLabel("选择题目数量:")
layout.addWidget(count_label)
self.question_count = QSpinBox()
self.question_count.setMinimum(10)
self.question_count.setMaximum(30)
self.question_count.setValue(15)
layout.addWidget(self.question_count)
btn_row = QHBoxLayout()
self.btn_start_quiz = QPushButton("开始答题")
self.btn_change_password = QPushButton("修改密码")
self.btn_logout = QPushButton("退出登录")
btn_row.addWidget(self.btn_start_quiz)
btn_row.addWidget(self.btn_change_password)
btn_row.addWidget(self.btn_logout)
layout.addLayout(btn_row)
self.btn_start_quiz.clicked.connect(self._on_start_quiz)
self.btn_change_password.clicked.connect(lambda: self.stack.setCurrentIndex(7))
self.btn_logout.clicked.connect(self._on_logout)
self.stack.addWidget(page)
def _on_start_quiz(self) -> None:
"""开始答题:生成题目并跳转到答题页面。"""
# 获取选择的年级
grade_map = {0: 'primary', 1: 'middle', 2: 'high'}
grade = grade_map[self.grade_group.checkedId()]
count = self.question_count.value()
try:
self.questions = self.question_service.generate_questions(grade, count)
self.current_question = 0
self.user_answers = []
self._show_current_question()
self.stack.setCurrentIndex(5)
except Exception as e:
QMessageBox.warning(self, "提示", f"生成题目失败:{str(e)}")
def _on_logout(self) -> None:
"""退出登录:清空会话并返回登录页。"""
self.session_email = None
self.login_identifier.clear()
self.login_password.clear()
QMessageBox.information(self, "提示", "已退出登录")
self.stack.setCurrentIndex(0)
def _build_quiz_page(self) -> None:
"""构建答题页面:显示题目和选项。"""
page = QWidget()
layout = QVBoxLayout(page)
layout.setAlignment(Qt.AlignmentFlag.AlignTop)
# 进度显示
self.progress_label = QLabel()
self.progress_label.setAlignment(Qt.AlignmentFlag.AlignCenter)
self.progress_label.setStyleSheet("font-size: 16px; margin: 10px 0;")
layout.addWidget(self.progress_label)
# 题目显示
self.question_label = QLabel()
self.question_label.setAlignment(Qt.AlignmentFlag.AlignLeft)
self.question_label.setStyleSheet("font-size: 18px; margin: 20px 0; padding: 10px; border: 1px solid #ccc;")
self.question_label.setWordWrap(True)
layout.addWidget(self.question_label)
# 选项
self.option_group = QButtonGroup()
self.option_radios = []
for i in range(4):
radio = QRadioButton()
radio.setStyleSheet("font-size: 16px; margin: 5px 0;")
self.option_group.addButton(radio, i)
self.option_radios.append(radio)
layout.addWidget(radio)
# 按钮
btn_row = QHBoxLayout()
self.btn_prev = QPushButton("上一题")
self.btn_next = QPushButton("下一题")
self.btn_submit = QPushButton("提交答案")
btn_row.addWidget(self.btn_prev)
btn_row.addWidget(self.btn_next)
btn_row.addWidget(self.btn_submit)
layout.addLayout(btn_row)
self.btn_prev.clicked.connect(self._on_prev_question)
self.btn_next.clicked.connect(self._on_next_question)
self.btn_submit.clicked.connect(self._on_submit_quiz)
self.stack.addWidget(page)
def _show_current_question(self) -> None:
"""显示当前题目。"""
if not hasattr(self, 'questions') or not self.questions:
return
question = self.questions[self.current_question]
total = len(self.questions)
# 更新进度
self.progress_label.setText(f"{self.current_question + 1} 题 / 共 {total}")
# 更新题目
self.question_label.setText(question['stem'])
# 更新选项
for i, option in enumerate(question['options']):
self.option_radios[i].setText(f"{chr(65+i)}. {option}")
# 恢复之前的选择
if self.current_question < len(self.user_answers):
selected = self.user_answers[self.current_question]
if selected is not None:
self.option_radios[selected].setChecked(True)
else:
# 清空选择
for radio in self.option_radios:
radio.setChecked(False)
# 更新按钮状态
self.btn_prev.setEnabled(self.current_question > 0)
self.btn_next.setEnabled(self.current_question < total - 1)
def _on_prev_question(self) -> None:
"""上一题。"""
self._save_current_answer()
if self.current_question > 0:
self.current_question -= 1
self._show_current_question()
def _on_next_question(self) -> None:
"""下一题。"""
self._save_current_answer()
if self.current_question < len(self.questions) - 1:
self.current_question += 1
self._show_current_question()
def _save_current_answer(self) -> None:
"""保存当前题目的答案。"""
selected = self.option_group.checkedId()
# 确保user_answers列表足够长
while len(self.user_answers) <= self.current_question:
self.user_answers.append(None)
self.user_answers[self.current_question] = selected if selected >= 0 else None
def _on_submit_quiz(self) -> None:
"""提交答案并计算分数。"""
self._save_current_answer()
# 检查是否有未答题目
unanswered = []
for i, answer in enumerate(self.user_answers):
if answer is None:
unanswered.append(i + 1)
if unanswered:
reply = QMessageBox.question(
self, "提示",
f"还有第 {', '.join(map(str, unanswered))} 题未作答,确定要提交吗?",
QMessageBox.StandardButton.Yes | QMessageBox.StandardButton.No
)
if reply == QMessageBox.StandardButton.No:
return
# 计算分数
correct = 0
total = len(self.questions)
for i, question in enumerate(self.questions):
if i < len(self.user_answers) and self.user_answers[i] == question['answer_index']:
correct += 1
self.score = correct
self.total_questions = total
self._show_result()
self.stack.setCurrentIndex(6)
def _build_result_page(self) -> None:
"""构建结果页面:显示分数和操作选项。"""
page = QWidget()
layout = QVBoxLayout(page)
layout.setAlignment(Qt.AlignmentFlag.AlignCenter)
title = QLabel("答题结果")
title.setAlignment(Qt.AlignmentFlag.AlignCenter)
title.setStyleSheet("font-size: 22px; font-weight: bold; margin: 16px 0;")
layout.addWidget(title)
self.score_label = QLabel()
self.score_label.setAlignment(Qt.AlignmentFlag.AlignCenter)
self.score_label.setStyleSheet("font-size: 24px; margin: 20px 0; color: #2196F3;")
layout.addWidget(self.score_label)
btn_row = QHBoxLayout()
self.btn_continue = QPushButton("继续做题")
self.btn_exit = QPushButton("退出")
btn_row.addWidget(self.btn_continue)
btn_row.addWidget(self.btn_exit)
layout.addLayout(btn_row)
self.btn_continue.clicked.connect(lambda: self.stack.setCurrentIndex(4))
self.btn_exit.clicked.connect(self._on_logout)
self.stack.addWidget(page)
def _show_result(self) -> None:
"""显示答题结果。"""
if hasattr(self, 'score') and hasattr(self, 'total_questions'):
percentage = (self.score / self.total_questions) * 100
self.score_label.setText(
f"您答对了 {self.score} 题,共 {self.total_questions}\n"
f"正确率:{percentage:.1f}%"
)
def _build_change_password_page(self) -> None:
"""构建修改密码页面。"""
page = QWidget()
layout = QVBoxLayout(page)
layout.setAlignment(Qt.AlignmentFlag.AlignTop)
title = QLabel("修改密码")
title.setAlignment(Qt.AlignmentFlag.AlignCenter)
title.setStyleSheet("font-size: 22px; font-weight: bold; margin: 16px 0;")
layout.addWidget(title)
self.old_password = QLineEdit()
self.old_password.setPlaceholderText("请输入原密码")
self.old_password.setEchoMode(QLineEdit.EchoMode.Password)
layout.addWidget(self.old_password)
self.new_password = QLineEdit()
self.new_password.setPlaceholderText("请输入新密码6-10位包含大小写字母和数字")
self.new_password.setEchoMode(QLineEdit.EchoMode.Password)
layout.addWidget(self.new_password)
self.confirm_new_password = QLineEdit()
self.confirm_new_password.setPlaceholderText("请确认新密码")
self.confirm_new_password.setEchoMode(QLineEdit.EchoMode.Password)
layout.addWidget(self.confirm_new_password)
btn_row = QHBoxLayout()
self.btn_change_pwd = QPushButton("修改密码")
self.btn_back_to_choice = QPushButton("返回")
btn_row.addWidget(self.btn_change_pwd)
btn_row.addWidget(self.btn_back_to_choice)
layout.addLayout(btn_row)
self.btn_change_pwd.clicked.connect(self._on_change_password)
self.btn_back_to_choice.clicked.connect(lambda: self.stack.setCurrentIndex(4))
self.stack.addWidget(page)
def _on_change_password(self) -> None:
"""处理修改密码逻辑。"""
old_pwd = self.old_password.text() or ""
new_pwd = self.new_password.text() or ""
confirm_pwd = self.confirm_new_password.text() or ""
if not old_pwd or not new_pwd or not confirm_pwd:
QMessageBox.warning(self, "提示", "请填写完整信息")
return
if not self.session_email:
QMessageBox.warning(self, "提示", "会话已过期,请重新登录")
self.stack.setCurrentIndex(0)
return
ok, msg = self.user_service.change_password(self.session_email, old_pwd, new_pwd, confirm_pwd)
if ok:
QMessageBox.information(self, "提示", "密码修改成功")
# 清空表单并返回选择页
self.old_password.clear()
self.new_password.clear()
self.confirm_new_password.clear()
self.stack.setCurrentIndex(4)
else:
QMessageBox.warning(self, "提示", msg)

@ -0,0 +1,79 @@
"""
安全工具模块提供邮箱校验密码强度校验验证码生成密码哈希与校验
遵循 Google Python 风格指南所有函数均提供中文函数级注释
"""
import re
import secrets
import string
import hashlib
from typing import Tuple
def validate_email(email: str) -> bool:
"""验证邮箱格式是否正确。
参数:
email: 待验证的邮箱字符串
返回:
True 表示格式合法False 表示格式不合法
"""
pattern = r"^[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,}$"
return re.match(pattern, email) is not None
def validate_password_strength(password: str) -> bool:
"""验证密码是否满足强度要求6-10位必须包含大小写字母和数字。
参数:
password: 待验证的密码字符串
返回:
True 表示满足要求False 表示不满足
"""
if not (6 <= len(password) <= 10):
return False
has_upper = any(c.isupper() for c in password)
has_lower = any(c.islower() for c in password)
has_digit = any(c.isdigit() for c in password)
return has_upper and has_lower and has_digit
def generate_verification_code(length: int = 6) -> str:
"""生成数字验证码字符串。
参数:
length: 验证码长度默认为 6
返回:
由数字组成的验证码字符串
"""
return ''.join(secrets.choice(string.digits) for _ in range(length))
def hash_password(password: str, salt: bytes | None = None) -> Tuple[bytes, bytes]:
"""对密码进行 PBKDF2 哈希。
参数:
password: 原始密码
salt: 可选的盐值若未提供则自动生成
返回:
(salt, pwd_hash) 二元组其中 salt 为随机盐pwd_hash 为哈希值
"""
if salt is None:
salt = secrets.token_bytes(16)
pwd_hash = hashlib.pbkdf2_hmac(
'sha256', password.encode('utf-8'), salt, 100_000
)
return salt, pwd_hash
def verify_password(password: str, salt: bytes, pwd_hash: bytes) -> bool:
"""校验密码是否与存储的哈希匹配。
参数:
password: 用户输入的密码
salt: 存储的盐值
pwd_hash: 存储的密码哈希
返回:
True 表示匹配False 表示不匹配
"""
calc_hash = hashlib.pbkdf2_hmac('sha256', password.encode('utf-8'), salt, 100_000)
return secrets.compare_digest(calc_hash, pwd_hash)

@ -0,0 +1,189 @@
# 数学学习系统 - 打包说明
## 项目概述
数学学习系统是一个基于PyQt6的桌面应用程序提供用户注册、登录、数学题目练习等功能。本文档说明如何将项目打包成独立的可执行文件。
## 系统要求
- **操作系统**: Windows 10/11, macOS 10.14+, Linux (Ubuntu 18.04+)
- **Python版本**: 3.8+
- **内存**: 至少 4GB RAM
- **磁盘空间**: 至少 200MB 可用空间
## 打包环境准备
### 1. 安装依赖
```bash
# 安装项目依赖
pip install -r requirements.txt
# 安装打包工具
pip install pyinstaller
```
### 2. 解决环境冲突
如果遇到 pathlib 包冲突错误,执行:
```bash
conda remove pathlib -y
```
## 打包过程
### 方法一:使用配置文件打包
1. **使用 Windows 批处理脚本**
```cmd
build.bat
```
2. **使用 Linux/Mac Shell 脚本**
```bash
chmod +x build.sh
./build.sh
```
### 方法二:手动打包
```bash
# 清理之前的构建文件
pyinstaller --clean MathStudySystem.spec
```
## 打包配置说明
### MathStudySystem.spec 文件
- **入口文件**: `src/app.py`
- **数据文件**: 包含 `src/storage/` 目录下的配置文件
- **隐藏导入**: 包含所有必要的Python模块
- **输出模式**: 单文件可执行程序
- **窗口模式**: 无控制台窗口
### 关键配置项
```python
datas=[
('src/storage/users.json', 'storage'),
('src/storage/config.json', 'storage'),
],
hiddenimports=[
'PyQt6.QtCore',
'PyQt6.QtWidgets',
'PyQt6.QtGui',
# ... 其他必要模块
],
console=False, # 无控制台窗口
```
## 打包结果
### 输出文件
- **位置**: `dist/MathStudySystem.exe` (Windows)
- **大小**: 约 35MB
- **类型**: 独立可执行文件
### 文件结构
```
项目根目录/
├── dist/
│ └── MathStudySystem.exe # 可执行文件
├── build/ # 构建临时文件
├── MathStudySystem.spec # 打包配置
├── build.bat # Windows打包脚本
└── build.sh # Linux/Mac打包脚本
```
## 部署说明
### 1. 文件分发
- 将 `dist/MathStudySystem.exe` 复制到目标计算机
- 无需安装Python或其他依赖
- 可直接双击运行
### 2. 首次运行
程序首次运行时会自动创建必要的配置文件:
- 用户数据文件
- SMTP配置文件
### 3. 数据存储
- 用户数据存储在程序内部
- 配置文件随程序一起打包
- 运行时数据保存在临时目录
## 故障排除
### 常见问题
1. **pathlib 冲突**
```bash
conda remove pathlib -y
```
2. **缺少模块错误**
- 检查 `hiddenimports` 列表
- 添加缺失的模块到 spec 文件
3. **文件路径错误**
- 确认 `datas` 配置中的源路径正确
- 检查 `storage_service.py` 中的路径逻辑
4. **程序无法启动**
- 检查目标系统是否支持
- 确认没有缺少系统依赖
### 调试模式
如需调试,可临时修改 spec 文件:
```python
console=True, # 显示控制台
debug=True, # 启用调试模式
```
## 性能优化
### 减小文件大小
1. **排除不必要的模块**
```python
excludes=['tkinter', 'matplotlib', 'numpy'],
```
2. **启用UPX压缩**
```python
upx=True,
```
### 提升启动速度
- 使用 `--onedir` 模式(多文件)
- 预编译Python字节码
- 优化导入结构
## 版本信息
- **PyInstaller版本**: 6.16.0
- **Python版本**: 3.11.7
- **PyQt6版本**: 6.7.0
- **打包日期**: 2025年10月12日
## 技术支持
如遇到打包问题,请检查:
1. Python环境配置
2. 依赖包版本兼容性
3. 系统权限设置
4. 防病毒软件干扰
---
**注意**: 打包后的可执行文件仅适用于构建时的操作系统架构。如需跨平台部署,请在目标平台上重新打包。
Loading…
Cancel
Save