「BUAA OO Unit 1 HW1」面向测试小白的简易评测机

声明:本评测机所使用数据生成来自郭鸿宇同学,这对本评测机非常重要

Part 0 前言

笔者的配置与环境

  1. Windows10家庭版
  2. Pycharm 2021.3.2
  3. Anaconda1.9.7,其中用于python项目的python版本为3.6,但是应该是python3就可以
  4. IDEA 2021.3.2

面向人群

所有人,无论是否有python基础或者评测机搭建经验。

定位

基于本篇博客,您可以从零迅速搭建一个适合您的评测机,并且对您的项目路径没有要求。得益于数据输入输出和数据生成模块的解耦合,您可以快速迁移本评测机的输入输出,并更换您需要的数据生成模块,提高了泛用性。

Part 1 准备工作

  1. 若没有,则安装Anaconda,并安装一个python3的环境,这将在Part5附录部分介绍
  2. 若没有,则安装IDEA和Pycharm

Part 2 获取java jar包

目的

为了避免不同同学的Java项目结构目录、依赖包等的不同导致的无谓的麻烦,将Java项目打包为jar包,方法可移植性强

过程

  1. 在IDEA中创建项目,并将代码置于其中,测试可以运行即可。如果有依赖包,则需要导入依赖包。

  2. File ->Project Structure->Artifacts->+->JAR->From modules with dependencies...

  1. Main Class中选中程序入口类->OK->Cancel

  2. 修改Name(也可以不改)->Apply->OK

  3. Build->Build Artifacts,然后在其中选择刚才Name的项,然后Build

  1. 在项目目录/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 有待改进的地方

  1. 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」面向测试小白的简易评测机的更多相关文章

  1. 「BUAA OO Unit 4 HW16」第四单元总结与课程回顾

    「BUAA OO Unit 4 HW16」第四单元总结与课程回顾 目录 「BUAA OO Unit 4 HW16」第四单元总结与课程回顾 Part 0 第四单元作业架构设计 架构设计概要 AppRun ...

  2. 「BUAA OO Unit 2 HW8」第二单元总结

    「BUAA OO Unit 2 HW8」第二单元总结 目录 「BUAA OO Unit 2 HW8」第二单元总结 Part 0 前言 Part 1 第五次作业 1.1 作业要求 1.2 架构设计 1. ...

  3. 「BUAA OO Pre」 Pre 2总结回顾概览

    「BUAA OO Pre」 Pre 2总结回顾概览 目录 「BUAA OO Pre」 Pre 2总结回顾概览 Part 0 前言 写作背景 定位 您可以在这里期望获得 您在这里无法期望获得 对读者前置 ...

  4. 「BUAA OO Pre」Git生成多个ssh key并连接GitLab仓库

    「BUAA OO Pre」Git生成多个ssh key并连接GitLab仓库 Part 0 前言 写作背景 笔者在配置学校GitLab的ssh key时遇到一些问题,原因应为曾经配置过GitHub的s ...

  5. 【翻译】西川善司「实验做出的游戏图形」「GUILTY GEAR Xrd -SIGN-」中实现的「纯卡通动画的实时3D图形」的秘密,前篇(2)

    Lighting和Shading(2)镜面反射的控制和模拟次级表面散射技术 http://www.4gamer.net/games/216/G021678/20140703095/index_2.ht ...

  6. OO Unit 1 表达式求导

    OO Unit 1 表达式求导 面向对象学习小结 前言 本博主要内容目录: 基于度量来分析⾃己的程序结构 缺点反思 重构想法 关于BUG 自己程序出现过的BUG 分析⾃己发现别人程序bug所采⽤的策略 ...

  7. 「雅礼集训 2018 Day2」农民

    传送门 Description  「搞 OI 不如种田.」 小 D 在家种了一棵二叉树,第 ii 个结点的权值为 \(a_i\). 小 D 为自己种的树买了肥料,每天给树施肥. 可是几天后,小 D 却 ...

  8. 「Mobile Testing Summit China 2016」 中国移动互联网测试大会-议题征集

    时至北京盛夏,一场由 TesterHome 主办的关于移动互联网测试技术的盛会正在紧锣密鼓的筹备中.只要你关注软件质量,热爱测试,期待学习,都欢迎你加入这次移动测试技术大会中和我们一起分享经验.探讨话 ...

  9. 「七天自制PHP框架」第二天:模型与数据库

    往期回顾:「七天自制PHP框架」第一天:路由与控制器,点击此处 什么是模型? 我们的WEB系统一定会和各种数据打交道,实际开发过程中,往往一个类对应了关系数据库的一张或多张数据表,这里就会出现两个问题 ...

随机推荐

  1. 洛谷P1002过河卒(60分)

    逻辑没问题,运行超时,得分60 写注释了,不多解释 import java.util.Scanner; public class D1 { static int a,b,c,d,con; //棋盘大小 ...

  2. glibc-2.18升级

    1.下载文件下载地址:https://mirrors.tuna.tsinghua.edu.cn/gnu/glibc/glibc-2.18.tar.gz 2.安装部署解压tar -zxvf glibc- ...

  3. 布客&#183;ApacheCN 编程/后端/大数据/人工智能学习资源 2020.9

    公告 ApacheCN 项目的最终目标:五年内备份并翻译 Github 上的所有教程(其实快被我们啃完了,剩下的不多了). 警告各位培训班:对 ApacheCN 宣传文章的举报,也将视为对 Apach ...

  4. keystore文件

    [-] keystore操作 运行时签名文件路径debug 生成签名文件打包时使用 获取MD5和SH1 修改keystore文件密码 修改keystore文件别名 修改keystore文件别名的密码 ...

  5. 一致性协议之ZAB

    前言 一致性协议 包括 Paxos,Raft,2PC,3PC等等,今天我们讲一种协议,ZAB 协议,该协议应该是所有一致性协议中生产环境中应用最多的了.为什么呢?因为他是为 Zookeeper 设计的 ...

  6. mysql入门基础增删查改

    数据查询语法(DQL) DQL就是数据查询语言,数据库执行DQL语句不会对数据进行改变,而是让数据库发送结果集给客户端. 语法: SELECT selection_list /*要查询的列名称*/ F ...

  7. Redis高可用(持久化、主从复制、哨兵、集群)

    Redis高可用(持久化.主从复制.哨兵.集群) 目录 Redis高可用(持久化.主从复制.哨兵.集群) 一.Redis高可用 1. Redis高可用概述 2. Redis高可用策略 二.Redis持 ...

  8. JAVA String介绍、常量池及String、StringBuilder和StringBuffer得区别. 以及8种基本类型的包装类和常量池得简单介绍

    一.概述 String是代表字符串的类,本身是一个最终类,使用final修饰,不能被继承. 二.定义方式   方式一:直接赋值法 String str1 = "hello"; 方式 ...

  9. logger模块和re模块总结

    很多程序都有记录日志的需求,并且日志中包含的信息即有正常的程序访问日志,还可能有错误.警告等信息输出,python的logging模块提供了标准的日志接口,你可以通过它存储各种格式的日志,loggin ...

  10. 扯 C++ 里的 Lambda

    之前写(抄) parsec 的时候, 在重载 operator>> 的时候, operator>> 需要接收一个 lambda, 之后返回一个 Component<R&g ...