「BUAA OO Unit 1 HW1」面向测试小白的简易评测机
「BUAA OO Unit 1 HW1」面向测试小白的简易评测机
声明:本评测机所使用数据生成来自郭鸿宇同学,这对本评测机非常重要
Part 0 前言
笔者的配置与环境
- Windows10家庭版
- Pycharm 2021.3.2
- Anaconda1.9.7,其中用于python项目的python版本为3.6,但是应该是python3就可以
- IDEA 2021.3.2
面向人群
所有人,无论是否有python基础或者评测机搭建经验。
定位
基于本篇博客,您可以从零迅速搭建一个适合您的评测机,并且对您的项目路径没有要求。得益于数据输入输出和数据生成模块的解耦合,您可以快速迁移本评测机的输入输出,并更换您需要的数据生成模块,提高了泛用性。
Part 1 准备工作
- 若没有,则安装Anaconda,并安装一个python3的环境,这将在Part5附录部分介绍
- 若没有,则安装IDEA和Pycharm
Part 2 获取java jar包
目的
为了避免不同同学的Java项目结构目录、依赖包等的不同导致的无谓的麻烦,将Java项目打包为jar包,方法可移植性强。
过程
在IDEA中创建项目,并将代码置于其中,测试可以运行即可。如果有依赖包,则需要导入依赖包。
File->Project Structure->Artifacts->+->JAR->From modules with dependencies...


Main Class中选中程序入口类->OK->Cancel
修改
Name(也可以不改)->Apply->OK
Build->Build Artifacts,然后在其中选择刚才Name的项,然后Build


- 在项目目录/out/artifacts/
Name下可以找到生成的jar包
须知
对于本次作业,课程组提供的官方输入输出包需要被注释掉,同时需要自行将原MainClass中的Scanner切换回标准的Scanner SCANNER = new Scanner(System.in)。同时,本评测机暂不支持预解析模式输入。
Part 2 修改评测机参数
pipline.py
import sympy # 如果报错显示没有这个包,就需要导入
from xeger import Xeger
import random
import subprocess
from subprocess import STDOUT, PIPE
from gendata import genData
def execute_java(stdin):
cmd = ['java', '-jar', 'archer.jar']# 更改为自己的.jar包名
proc = subprocess.Popen(cmd, stdin=PIPE, stdout=PIPE, stderr=STDOUT)
stdout, stderr = proc.communicate(stdin.encode())
return stdout.decode().strip()
x = sympy.Symbol('x')
X = Xeger(limit=10)
cnt = 1
while True:
cnt = cnt + 1
if cnt % 1000 == 0:
print(cnt)
poly, ans = genData()
#print(poly)
f = sympy.parse_expr(poly)
strr = execute_java(poly)
#print(strr)
g = sympy.parse_expr(strr)
if sympy.simplify(f).equals(g) :
print("AC : " + str(cnt))
else:
print("!!WA!! with " + "poly : " + poly + " YOURS: " + strr)
上述代码中需要改jar包为自己的包名。
其他不修改即可正常使用,也可根据需求自行修改。
gendata.py
"""
Auther: GHY
Date: 20222022/3/5
"""
import random
import sympy
intPool = [0,1,2,3,4] # 常量池
hasWhiteSpace = False # 是否加入空白字符
hasLeadZeros = False # 数字是否有前导零,如果传入sympy的表达式中数字有前导零,sympy将无法识别
maxTerm = 10 # 表达式中的最大项数
maxFactor = 3 # 项中最大因子个数
specialData = ["1","x-x","-1"] # 可以放一些特殊数据
globalPointer = 0
def rd(a,b) :
return random.randint(a,b)
def getWhiteSpace():
if hasWhiteSpace==False:
return ""
str = ""
cnt = rd(0,2)
for i in range(cnt):
type = rd(0,1)
if type==0:
str = str + " "
else:
str = str + "\t"
return str
def getSymbol():
if rd(0,1)==1:
return "+"
else:
return "-"
def getNum(positive):
result = ""
integer = intPool[rd(0,len(intPool)-1)]
iszero = rd(0,2)
for i in range(iszero):
result = result + "0"
if hasLeadZeros==False:
result = ""
result = result + str(integer)
if rd(0,1)==1:
if positive==True:
result = "+" + result
else:
result = getSymbol() + result
# print("num:"+result)
return result
def getExponent():
result = "**"
result = result + getWhiteSpace()
case = rd(0,2)
if rd(0,1)==1:
result = result + "+"
if case==0:
result = result + "0"
elif case==1:
result = result + "1"
else:
result = result + "2"
# result = result + getNum(True)
# print("exponent:"+result)
return result
def getPower():
result = "x"
if rd(0,1)==1:
result = result + getWhiteSpace() + getExponent()
# print("Power:"+result)
return result
def getTerm(genExpr):
factorNum = rd(1,maxFactor)
result = ""
if rd(0,1)==1:
result = getSymbol()+getWhiteSpace()
for i in range(factorNum):
factor = rd(0,2)
if factor==0:
result = result + getNum(False)
elif factor==1:
result = result + getPower()
elif factor==2 and genExpr==True:
result = result + getExpr(True)
else:
result = result + "0"
if i < factorNum-1:
result = result + getWhiteSpace() + "*" + getWhiteSpace()
# print("term:"+result)
return result
def getExpr(isFactor):
termNum = rd(1,maxTerm)
result = getWhiteSpace()
genExpr = True
if isFactor==True:
genExpr = False
for i in range(termNum):
result = result + getSymbol() + getWhiteSpace() + getTerm(genExpr) + getWhiteSpace()
if isFactor==True:
result = "(" + result + ")"
if rd(0,1)==1:
result = result + getWhiteSpace() + getExponent()
# print("Expr:"+result)
return result
def genData():
global globalPointer
if globalPointer<len(specialData):
expr = specialData[globalPointer]
globalPointer = globalPointer + 1
else:
expr = getExpr(False)
x = sympy.Symbol('x')
simplifed = sympy.expand(eval(expr))
return str(expr),str(simplifed)
x = sympy.Symbol('x')
fx = "+x**+0*x**0++3++x**+1*+1"
y = sympy.expand(eval(fx))
print(y)
上述代码不修改即可正常使用,也可根据需求修改数据生成方式。
Part 3 评测机架构
本评测机仅需要将jar包、pipline.py和gendata.py放在同一目录下即可,无其他要求。
对于多个jar包,允许在多个文件夹中分别存放评测机,同时测试运行。
Part 4 有待改进的地方
- Part2中要求注释掉官方包及切换回Scanner的原因是,目前笔者没有办法在获取输出时跳过第一行,但这应该可以做到。
Part 5 附录:如何从0配置本评测机可运行的 python+Anaconda 环境
一、下载pycharm:
此步仅执行连接中步骤1.2.3,即不进行后续python安装即环境变量的配置。仅安装pycharm。
https://www.runoob.com/w3cnote/pycharm-windows-install.html
二、Anaconda安装教程
如果没有特定版本需求,可选择文中版本安装,此版本默认安装python3.7
https://zhuanlan.zhihu.com/p/75717350
三、创建python项目时关联Anaconda的python.exe
仅参考步骤五即可
https://www.cnblogs.com/yuxuefeng/articles/9235431.html
四、安装 xeger库:见链接方法一
https://www.cnblogs.com/ShineLeBlog/p/10893419.html
五、更新sympy库
同上,在此界面取消Anaconda模式后,找到sympy库双击。

勾选 Spectify version ,选择1.9版本,点击 Install Package。
「BUAA OO Unit 1 HW1」面向测试小白的简易评测机的更多相关文章
- 「BUAA OO Unit 4 HW16」第四单元总结与课程回顾
「BUAA OO Unit 4 HW16」第四单元总结与课程回顾 目录 「BUAA OO Unit 4 HW16」第四单元总结与课程回顾 Part 0 第四单元作业架构设计 架构设计概要 AppRun ...
- 「BUAA OO Unit 2 HW8」第二单元总结
「BUAA OO Unit 2 HW8」第二单元总结 目录 「BUAA OO Unit 2 HW8」第二单元总结 Part 0 前言 Part 1 第五次作业 1.1 作业要求 1.2 架构设计 1. ...
- 「BUAA OO Pre」 Pre 2总结回顾概览
「BUAA OO Pre」 Pre 2总结回顾概览 目录 「BUAA OO Pre」 Pre 2总结回顾概览 Part 0 前言 写作背景 定位 您可以在这里期望获得 您在这里无法期望获得 对读者前置 ...
- 「BUAA OO Pre」Git生成多个ssh key并连接GitLab仓库
「BUAA OO Pre」Git生成多个ssh key并连接GitLab仓库 Part 0 前言 写作背景 笔者在配置学校GitLab的ssh key时遇到一些问题,原因应为曾经配置过GitHub的s ...
- 【翻译】西川善司「实验做出的游戏图形」「GUILTY GEAR Xrd -SIGN-」中实现的「纯卡通动画的实时3D图形」的秘密,前篇(2)
Lighting和Shading(2)镜面反射的控制和模拟次级表面散射技术 http://www.4gamer.net/games/216/G021678/20140703095/index_2.ht ...
- OO Unit 1 表达式求导
OO Unit 1 表达式求导 面向对象学习小结 前言 本博主要内容目录: 基于度量来分析⾃己的程序结构 缺点反思 重构想法 关于BUG 自己程序出现过的BUG 分析⾃己发现别人程序bug所采⽤的策略 ...
- 「雅礼集训 2018 Day2」农民
传送门 Description 「搞 OI 不如种田.」 小 D 在家种了一棵二叉树,第 ii 个结点的权值为 \(a_i\). 小 D 为自己种的树买了肥料,每天给树施肥. 可是几天后,小 D 却 ...
- 「Mobile Testing Summit China 2016」 中国移动互联网测试大会-议题征集
时至北京盛夏,一场由 TesterHome 主办的关于移动互联网测试技术的盛会正在紧锣密鼓的筹备中.只要你关注软件质量,热爱测试,期待学习,都欢迎你加入这次移动测试技术大会中和我们一起分享经验.探讨话 ...
- 「七天自制PHP框架」第二天:模型与数据库
往期回顾:「七天自制PHP框架」第一天:路由与控制器,点击此处 什么是模型? 我们的WEB系统一定会和各种数据打交道,实际开发过程中,往往一个类对应了关系数据库的一张或多张数据表,这里就会出现两个问题 ...
随机推荐
- ubuntu输入正确密码重新跳到登录界面
原因一:/etc/profile或者/etc/enviroment 配置错误 (很多开发人员在配置完java环境之后容易出现这种情况) 解决办法(已验证): 1,开机后在登录界面按下shift+c ...
- 3D建模服务提供更高效、专业的能力,“筑”力开发者
3D建模服务(3D Modeling Kit)是HMS Core在图形图像领域又一技术开放.3D建模产品的定位就是要做快速.简洁.低成本的3D制作能力,并陆续开放给有3D模型.动画游戏制作等能力诉求的 ...
- 【Azure Developer】Azure Logic App 示例: 解析 Request Body 的 JSON 的表达式? triggerBody()?
问题描述 通过Azure Logic App(逻辑应用)实现无代码的处理JSON数据.但是如何获取Request Body中的一个属性值呢? 例如:如何来获取以下JSON结构中的 ObjectName ...
- 优化.NET 应用程序 CPU 和内存的11 个实践
https://michaelscodingspot.com/cpu-bound-memory-bound/ 优化.NET 应用程序 CPU 和内存的11 个实践 凡事都有其限度,对吧?汽车只能开这么 ...
- 带你十天轻松搞定 Go 微服务系列(五)
序言 我们通过一个系列文章跟大家详细展示一个 go-zero 微服务示例,整个系列分十篇文章,目录结构如下: 环境搭建 服务拆分 用户服务 产品服务 订单服务(本文) 支付服务 RPC 服务 Auth ...
- 带你十天轻松搞定 Go 微服务系列(七)
序言 我们通过一个系列文章跟大家详细展示一个 go-zero 微服务示例,整个系列分十篇文章,目录结构如下: 环境搭建 服务拆分 用户服务 产品服务 订单服务 支付服务 RPC 服务 Auth 验证( ...
- python关于一些地址存储问题的知识
在一个类型进行转换后不能马上进行操作.要先进行存储否则操作无效 原理一个类型转换后成为一个新的类型但是没有人接受它属于空值所以做任何操作都无效 li=[] print(li.append) 也是报错的 ...
- python 小兵(3)字典
字典 # 存储数据 字典的查找快一些# 不可哈希的,就是可变的数据 可变的数据不能哈希 不可变的数据能哈希# python3.6 版本以上 字典默认是有序的, 咱们怎么写的就怎么打印出来# 但是 出去 ...
- plsql 函数的定义 包规范和包主体。
/* 一.函数? 1.函数定义 函数的内容 根据实际需要来定义 2.使用的方式 */ -- 定义函数 根据部门编号查询出部门的总人数 create or replace function fn( de ...
- servlet单例模式以及servlet的请求流程
目录 一.servlet 单例模式: 二.servlet的请求流程: ★ 流程: ★ 详细过程如下: 一.servlet 单例模式: tomcat服务器,通过Java的反射机制来自动调用servl ...