-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
7 changed files
with
251 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,169 @@ | ||
import os | ||
import sys | ||
import time | ||
|
||
from PyQt5.QtGui import QColor, QFont, QPalette | ||
from PyQt5.QtWidgets import (QApplication, QCheckBox, QComboBox, QFileDialog, QHBoxLayout, QLabel, QLineEdit, QMainWindow, | ||
QPushButton, QTextEdit, QVBoxLayout, QWidget) | ||
|
||
from ProgramCompareUI import ProgramCompare | ||
|
||
|
||
class MainWindow(QMainWindow): | ||
|
||
def __init__(self): | ||
super().__init__() | ||
self.initUI() | ||
self.std = None | ||
self.cmp = None | ||
self.setData = None | ||
self.programCompare = None | ||
|
||
def initUI(self): | ||
self.setWindowTitle("ProgramCompare") | ||
|
||
# 创建主窗口的中心部件 | ||
central_widget = QWidget(self) | ||
self.setCentralWidget(central_widget) | ||
|
||
# 创建主布局 | ||
main_layout = QVBoxLayout() | ||
central_widget.setLayout(main_layout) | ||
|
||
########## 创建文件选择部件 | ||
file_layout = QHBoxLayout() | ||
main_layout.addLayout(file_layout) | ||
|
||
# 创建按钮上传std.cpp | ||
self.std_button = QPushButton("std.cpp") | ||
self.std_button.clicked.connect(self.upload_std) | ||
file_layout.addWidget(self.std_button) | ||
|
||
# 创建按钮上传cmp.cpp | ||
self.cmp_button = QPushButton("cmp.cpp") | ||
self.cmp_button.clicked.connect(self.upload_cmp) | ||
file_layout.addWidget(self.cmp_button) | ||
|
||
# 创建按钮上传setData.py | ||
self.setData_button = QPushButton("setData.py") | ||
self.setData_button.clicked.connect(self.upload_setData) | ||
file_layout.addWidget(self.setData_button) | ||
|
||
# 创建选择菜单设置cppstd | ||
self.cppstd_comboBox = QComboBox() | ||
self.cppstd_comboBox.addItem("c++17") | ||
self.cppstd_comboBox.addItem("c++14") | ||
self.cppstd_comboBox.addItem("c++11") | ||
file_layout.addWidget(self.cppstd_comboBox) | ||
|
||
self.compile_button = QPushButton("compile") | ||
self.compile_button.clicked.connect(self.compile) | ||
file_layout.addWidget(self.compile_button) | ||
|
||
########## 创建中心文本框 | ||
self.textbox = QTextEdit() | ||
self.textbox.setReadOnly(True) # 设置为只读 | ||
main_layout.addWidget(self.textbox) | ||
|
||
########## 创建执行部件 | ||
run_layout = QHBoxLayout() | ||
main_layout.addLayout(run_layout) | ||
|
||
# 创建输入框输入样例数 | ||
self.test_label = QLabel("test number") | ||
self.testNum_LineEdit = QLineEdit() | ||
self.testNum_LineEdit.setText("10") | ||
run_layout.addWidget(self.test_label) | ||
run_layout.addWidget(self.testNum_LineEdit) | ||
|
||
# 创建选择框选择是否显示输入内容和输出内容 | ||
self.show_input_checkBox = QCheckBox("show_input") | ||
run_layout.addWidget(self.show_input_checkBox) | ||
self.show_output_checkBox = QCheckBox("show_output") | ||
run_layout.addWidget(self.show_output_checkBox) | ||
|
||
# 创建按钮执行makeData | ||
self.makeData_button = QPushButton("makeData") | ||
self.makeData_button.clicked.connect(self.makeData) | ||
run_layout.addWidget(self.makeData_button) | ||
|
||
# 创建按钮执行bruteJudge | ||
self.bruteJudge_button = QPushButton("bruteJudge") | ||
self.bruteJudge_button.clicked.connect(self.bruteJudge) | ||
run_layout.addWidget(self.bruteJudge_button) | ||
|
||
def log(self, message: str): | ||
self.textbox.append(f"[{time.strftime('%Y-%m-%d %H:%M:%S', time.localtime())}] " + message) | ||
|
||
def upload_std(self): | ||
file_path, _ = QFileDialog.getOpenFileName(self, "std.cpp", "", "CPP Files (*.cpp)") | ||
if file_path: | ||
self.std = file_path | ||
self.log(f"Upload std.cpp: {file_path}") | ||
|
||
def upload_cmp(self): | ||
file_path, _ = QFileDialog.getOpenFileName(self, "cmp.cpp", "", "CPP Files (*.cpp)") | ||
if file_path: | ||
self.cmp = file_path | ||
self.log(f"Upload cmp.cpp: {file_path}") | ||
|
||
def upload_setData(self): | ||
file_path, _ = QFileDialog.getOpenFileName(self, "setData.py", "", "Python Files (*.py)") | ||
if file_path: | ||
# 加载生成器 | ||
with open(file_path, "r") as file: | ||
setData_code = file.read() | ||
namespace = {} | ||
exec(setData_code, namespace) | ||
self.setData = namespace.get("setData") | ||
self.log(f"Upload setData.py: {file_path}") | ||
|
||
def compile(self): | ||
if self.std == None or self.cmp == None or self.setData == None: | ||
self.log("Please upload file first.") | ||
return | ||
cppstd = self.cppstd_comboBox.currentText() | ||
self.log("Compiling...") | ||
self.programCompare = ProgramCompare(self.setData, self.std, self.cmp, self.textbox.append, cppstd) | ||
|
||
def makeData(self): | ||
if self.programCompare == None: | ||
self.log("Please complie first.") | ||
return | ||
testNum = int(self.testNum_LineEdit.text()) | ||
for id in range(1, testNum + 1): | ||
self.programCompare.makeData(id) | ||
self.log(f"Make {testNum} test data finish.") | ||
|
||
def bruteJudge(self): | ||
if self.programCompare == None: | ||
self.log("Please complie first.") | ||
return | ||
testNum = int(self.testNum_LineEdit.text()) | ||
show_input = self.show_input_checkBox.isChecked() | ||
show_output = self.show_output_checkBox.isChecked() | ||
correct, wrong = 0, 0 | ||
for id in range(1, testNum + 1): | ||
if self.programCompare.compare(id, show_input, show_output): | ||
correct += 1 | ||
else: | ||
wrong += 1 | ||
self.log(f"Brute judge {testNum} test data finish. {correct} correct, {wrong} wrong.") | ||
|
||
|
||
if __name__ == "__main__": | ||
# 设置./temp为workspace | ||
workspace = os.path.join(os.getcwd(), 'temp') | ||
if not os.path.exists(workspace): | ||
os.mkdir(workspace) | ||
os.chdir(workspace) | ||
|
||
font = QFont() | ||
font.setFamily("Consolas") | ||
font.setPointSize(14) | ||
app = QApplication(sys.argv) | ||
window = MainWindow() | ||
window.setFont(font) | ||
window.show() | ||
window.resize(1024, 640) | ||
sys.exit(app.exec_()) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,54 @@ | ||
# https://github.com/luogu-dev/cyaron/wiki | ||
import os | ||
|
||
|
||
def setColor(s, color): | ||
return f"<span style='color: {color};font-weight: bold;'>{s}</span>" | ||
|
||
|
||
class ProgramCompare: | ||
|
||
def __init__(self, setData, std: str, cmp: str, writeln, cppstd='c++17', optimize='O2'): | ||
# 编译源代码 | ||
self.setData = setData | ||
self.writeln = writeln | ||
self.std_exe = os.path.splitext(std)[0] + '.exe' | ||
self.cmp_exe = os.path.splitext(cmp)[0] + '.exe' | ||
if os.system(f'g++ "{std}" -o "{self.std_exe}" -std={cppstd} -{optimize} -fexec-charset=GBK -w') != 0: | ||
writeln(setColor("std.cpp compile failed.", "red")) | ||
elif os.system(f'g++ "{cmp}" -o "{self.cmp_exe}" -std={cppstd} -{optimize} -fexec-charset=GBK -w') != 0: | ||
writeln(setColor("cmp.cpp compile failed.", "red")) | ||
else: | ||
writeln(setColor("Compile successful.", "green")) | ||
|
||
def __del__(self): | ||
os.system('del *.exe') | ||
|
||
def compare(self, id: int = 1, show_input=True, show_output=True): | ||
# 产生样例输入 | ||
with open(f'test{id}.in', 'w') as file: | ||
self.setData(file, id) | ||
# 获取样例答案和样例输出 | ||
std_out = os.popen(self.std_exe + ' < ' + f'test{id}.in').read() | ||
cmp_out = os.popen(self.cmp_exe + ' < ' + f'test{id}.in').read() | ||
if std_out == cmp_out: | ||
self.writeln(setColor('AC:', 'green') + f'test{id}.in') | ||
return True | ||
else: | ||
self.writeln(setColor('WA:', 'red') + f'test{id}.in') | ||
if show_input: | ||
with open(f'test{id}.in', 'r', encoding='utf-8') as file: | ||
self.writeln(setColor('input:', 'Chocolate')) | ||
self.writeln(file.read()) | ||
if show_output: | ||
self.writeln(setColor('std_out:', 'blue')) | ||
self.writeln(std_out) | ||
self.writeln(setColor('cmp_out:', 'purple')) | ||
self.writeln(cmp_out) | ||
return False | ||
|
||
def makeData(self, id: int = 1): | ||
# 使用setData产生样例输入并用std_exe产生样例答案 | ||
with open(f'test{id}.in', 'w') as file: | ||
self.setData(file, id) | ||
os.system(f'{self.std_exe} < test{id}.in > test{id}.out') |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
#include <iostream> | ||
int main() { | ||
int a, b; | ||
std::cin >> a >> b; | ||
std::cout << a + b << '\n'; | ||
} |
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
from io import TextIOWrapper | ||
from random import randint | ||
|
||
|
||
def setData(file: TextIOWrapper, id=1): | ||
write = lambda *x: file.write(' '.join([str(i) for i in x]) + ' ') | ||
writeln = lambda *x: file.write(' '.join([str(i) for i in x]) + '\n') | ||
################### | ||
a = randint(1, 2e9) | ||
b = randint(1, 2e9) | ||
writeln(a, b) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
#include <iostream> | ||
int main() { | ||
long long a, b; | ||
std::cin >> a >> b; | ||
std::cout << a + b << '\n'; | ||
} |