OO_hw5_test

OO_hw5_test

Charles Lv7

简易hw5程序对拍器分享

到了第二单元电梯周,我深刻感觉到了写对拍器的重要性,那个几百行的输出如果要肉眼判断正确性真是个痛苦的事,所以在此简单分享一下我的对拍程序。(由于时间戳不太好验证,所以我的对拍程序只验证结果的正确性)

数据生成器:

generate.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
import random

MAX_INT=1<<31-1
MAX_FLOOR = 11
TIME_LIMIT=40
id_dict = {}

def get_id() :
id = random.randint(1, MAX_INT)
while (id_dict.get(id) == False) :
id = random.randint(1, MAX_INT)
id_dict[id] = True
return id

def get_time_gap() :
chance = random.randint(0, MAX_INT) % 100
if (chance < 5) :
return 10
elif (chance >= 95) :
return 5
elif (chance >= 5 and chance < 15 or chance >= 85 and chance < 95) :
return random.uniform(1.0, 5.0)
else :
return random.uniform(0, 1.0)

def get_floor() :
floor = random.randint(0, MAX_INT) % MAX_FLOOR + 1
return floor

def generate(num) :
time = 0.0
for _ in range(num) :
if (time > TIME_LIMIT) :
break
time += get_time_gap()
id = str(get_id())
from_floor = str(get_floor())
to_floor = str(get_floor())
while (to_floor == from_floor) :
to_floor = str(get_floor())
print('[' + str(format(time, '.1f')) + ']' + id + '-FROM-' + from_floor + '-TO-' + to_floor)

#main()
num = random.randint(0, MAX_INT) % 100 + 1
generate(num)

结果对拍程序:

outputChecker.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
from colorfulPrint import ColorfulPrint

class Req:
def __init__(self, req):
eles = self.parseReq(req)
self.id = int(eles[0])
self.ff = int(eles[2])
self.tf = int(eles[4])
def parseReq(self, req):
req = req.replace('\n', '')
index = req.index(']')
req = req[index + 1:]
return req.split('-')
def getId(self):
return self.id
def getFromFloor(self):
return self.ff
def getToFloor(self):
return self.tf

STATE_OPEN = 0
STATE_CLOSE = 1
MAX_FLOOR = 11
MIN_FLOOR = 1
MAX_NUM = 6
MIN_NUM = 0

reqDic = {}
floors = []
states = []
passengers = []
lastMoveTime = []
lastOpenTime = []
lastOpTime = []
flag = [0]

def printError(msg, l = 0):
if l == 0:
msg = ' ***** ' + msg + ' ***** '
else:
msg = ' ***** ' + msg + ' IN LINE: ' + str(l) + ' ***** '
ColorfulPrint.colorfulPrint(msg, ColorfulPrint.MODE_BOLD, ColorfulPrint.COLOR_RED)
flag[0] = 0

def initElevator():
reqDic.clear()
floors.clear()
states.clear()
passengers.clear()
lastMoveTime.clear()
lastOpenTime.clear()
lastOpTime.clear()
flag[0] = 0
for i in range(6):
floors.append(1)
states.append(STATE_CLOSE)
passengers.append([])
lastMoveTime.append(-10.0)
lastOpenTime.append(-10.0)
lastOpTime.append(-1.0)

def processInput():
with open('stdin.txt', 'r') as f:
tot = f.readlines()
for ele in tot:
req = Req(ele)
reqDic[req.getId()] = req

def checkOutput():
initElevator()
processInput()
flag[0] = 1
with open('stdout.txt', 'r') as f:
tot = f.readlines()
count = 1
for line in tot:
process(line, count)
count += 1
if len(reqDic) != 0:
printError('SOME REQUESTS ARE NOT SATIFIED!')
for i in range(4):
if len(passengers[i]) != 0:
printError('SOMEONE IS TRAPPED IN ELEVATOR! ELEVATOR ID: ' + str(i + 1))
if states[i] != STATE_CLOSE:
printError('ELEVATOR IS NOT CLOSE! ELEVATOR ID: ' + str(i + 1))
if flag[0] == 1:
ColorfulPrint.colorfulPrint(' ===== OUTPUT ACCEPTED ===== ', ColorfulPrint.MODE_BOLD, ColorfulPrint.COLOR_GREEN)
return True
else:
printError('WRONG ANSWER!')
return False

def process(read, lineNum):
read = read.replace('\n', '')
index = read.index(']')
opTime = float(read[1:index - 1])
read = read[index + 1:]
eles = read.split('-')

if opTime < lastOpTime[0]:
printError('INCORRECT OUTPUT ORDER!', lineNum)
lastOpTime[0] = opTime

if eles[0] == 'ARRIVE':
index = int(eles[2]) - 1
if not 0 <= index <= 5:
printError('UNKNOW ELEVATOR ID!', lineNum)
return
if states[index] != STATE_CLOSE:
printError('MOVE WHEN DORR IS OPEN!', lineNum)
if opTime - lastMoveTime[index] < 0.4 - 0.00001:
printError('MOVE TOO FAST!', lineNum)
lastMoveTime[index] = opTime
if int(eles[1]) > MAX_FLOOR or int(eles[1]) < MIN_FLOOR:
printError('ELEVATOR ON A NON-EXISTENT FLOOR!', lineNum)
if floors[index] - int(eles[1]) != 1 and floors[index] - int(eles[1]) != -1:
printError('ILLEGAL ELEVATOR MOVEMENT!', lineNum)
floors[index] = int(eles[1])

elif eles[0] == 'OPEN':
index = int(eles[2]) - 1
if not 0 <= index <= 5:
printError('UNKNOW ELEVATOR ID!', lineNum)
return
if states[index] != STATE_CLOSE:
printError('ELEVATOR ALREADY OPEN!', lineNum)
states[index] = STATE_OPEN
lastOpenTime[index] = opTime
if floors[index] != int(eles[1]):
printError('ELEVATOR UNMATCHED FLOOR!', lineNum)

elif eles[0] == 'CLOSE':
index = int(eles[2]) - 1
lastMoveTime[index] = opTime
if not 0 <= index <= 5:
printError('UNKNOW ELEVATOR ID!', lineNum)
return
if states[index] != STATE_OPEN:
printError('ELEVATOR ALREADY CLOSE!', lineNum)
states[index] = STATE_CLOSE
if floors[index] != int(eles[1]):
printError('ELEVATOR UNMATCH FLOOR!', lineNum)
if opTime - lastOpenTime[index] < 0.4 - 0.00001:
printError('CLOSE TOO FAST!', lineNum)

elif eles[0] == 'IN':
index = int(eles[3]) - 1
passengerIndex = int(eles[1])
if not 0 <= index <= 5:
printError('UNKNOW ELEVATOR ID!', lineNum)
return
if states[index] != STATE_OPEN:
printError('PASSENGER CAN\'T IN!', lineNum)
passengers[index].append(passengerIndex)
req = reqDic.get(passengerIndex)
if req == None:
printError('PASSENGER NOT EXIST!', lineNum)
else:
if req.getFromFloor() != int(eles[2]) :
printError('IN MESSAGE NUMATCH REQUEST!', lineNum)
if len(passengers[index]) > MAX_NUM:
printError('ELEVATOR OVERLOAD!', lineNum)
if floors[index] != int(eles[2]):
printError('ELEVATOR UNMATCHED FLOOR!', lineNum)

elif eles[0] == 'OUT':
index = int(eles[3]) - 1
passengerIndex = int(eles[1])
if states[index] != STATE_OPEN:
printError('PASSENGER CAN\'T OUT!', lineNum)
if passengerIndex not in passengers[index]:
printError('PASSENGER NOT IN ELEVATOR!', lineNum)
else:
passengers[index].remove(passengerIndex)
req = reqDic.get(passengerIndex)
if req == None:
printError('PASSENGER NOT EXIST!', lineNum)
else:
if req.getToFloor() != int(eles[2]) :
printError('OUT MESSAGE NUMATCH REQUEST!', lineNum)
reqDic.pop(passengerIndex)

else:
printError('UNKNOW OPTION!', lineNum)

if __name__ == "__main__":
checkOutput()

终端渲染包:

colorfulPrint.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
# 支持两种模式:正常(NORMAL)和加粗(BOLD)
# 支持8种颜色:灰色、红色、绿色、黄色、蓝色、粉色、青色、白色
class ColorfulPrint():
MODE_NORMAL = 1
MODE_BOLD = 2
COLOR_GRAY = 0
COLOR_RED = 1
COLOR_GREEN = 2
COLOR_YELLOW = 3
COLOR_BLUE = 4
COLOR_PINK = 5
COLOR_CYAN = 6
COLOR_WHITE = 7
@staticmethod
def colorfulPrint(msg, mode, color):
head = '\033['
if mode == ColorfulPrint.MODE_NORMAL:
head = head + '0;'
elif mode == ColorfulPrint.MODE_BOLD:
head = head + '1;'
else:
print('\033[1;31;40m' + ' ***** MODE ERROR ***** ' + '\033[0m')
return
if 0 <= color <= 7:
head = head + str(30 + color) + ';40m'
else:
print('\033[1;31;40m' + ' ***** COLOR ERROR ***** ' + '\033[0m')
tail = '\033[0m'
print(head + msg + tail)


if __name__ == "__main__":
# 彩色打印示例
ColorfulPrint.colorfulPrint('This is a test', ColorfulPrint.MODE_BOLD, ColorfulPrint.COLOR_BLUE)

自动化测试程序:

judger.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
import os
from outputChecker import checkOutput
from colorfulPrint import ColorfulPrint
times = []

if __name__ == "__main__":
waCount = 0
accCount = 0
badCount = 0
tleCount = 0
passCount = 0
failCount = 0
x = 50
for i in range(x) :
ColorfulPrint.colorfulPrint(' >>>>>>>>>>>>>>>>>>>>>>> TEST {} <<<<<<<<<<<<<<<<<<<<<<<< '.format(i + 1), ColorfulPrint.MODE_BOLD, ColorfulPrint.COLOR_BLUE)
cmd = 'python3 generate.py > stdin.txt'
os.system(cmd)
cmd = '.\datainput_student_win64.exe | java -jar code.jar > stdout.txt'
os.system(cmd)
temp = checkOutput()
if temp:
passCount += 1
else:
failCount += 1
waCount += 1
with open('stdin.txt', 'r') as f:
con = f.read()
with open('./logWA/stdin' + str(i + 1) + '.txt', 'w') as f:
f.write(con)
with open('stdout.txt', 'r') as f:
con = f.read()
with open('./logWA/stdout' + str(i + 1) + '.txt', 'w') as f:
f.write(con)
if waCount == 0:
ColorfulPrint.colorfulPrint(' ===== YOU HAVE PASSED ALL TESTPOINT ===== ', ColorfulPrint.MODE_BOLD, ColorfulPrint.COLOR_GREEN)
ColorfulPrint.colorfulPrint(' ===== TESTPOINT PASSED: ' + str(x) + '/' + str(x) + ' ===== ', ColorfulPrint.MODE_BOLD, ColorfulPrint.COLOR_GREEN)
else:
ColorfulPrint.colorfulPrint(' ***** YOU HAVE NOT PASSED ALL TESTPOINT ***** ', ColorfulPrint.MODE_BOLD, ColorfulPrint.COLOR_RED)
ColorfulPrint.colorfulPrint(' ***** TESTPOINT PASSED: ' + str(x - waCount) + '/' + str(x) + ' ***** ', ColorfulPrint.MODE_BOLD, ColorfulPrint.COLOR_RED)
ColorfulPrint.colorfulPrint(' ===== Time accept: ' + str(accCount) + '/' + str(x) + ' rate: ' + str(accCount * 100 / x) + '% =====', ColorfulPrint.MODE_BOLD, ColorfulPrint.COLOR_GREEN)
ColorfulPrint.colorfulPrint(' ##### Bad performance: ' + str(badCount) + '/' + str(x) + ' rate: ' + str(badCount * 100 / x) + '% #####', ColorfulPrint.MODE_BOLD, ColorfulPrint.COLOR_YELLOW)
ColorfulPrint.colorfulPrint(' ***** Tle: ' + str(tleCount) + '/' + str(x) + ' rate: ' + str(tleCount * 100 / x) + '% *****', ColorfulPrint.MODE_BOLD, ColorfulPrint.COLOR_RED)
ColorfulPrint.colorfulPrint(' ===== Output correct: ' + str(passCount) + '/' + str(x) + ' rate: ' + str(passCount * 100 / x) + '% =====', ColorfulPrint.MODE_BOLD, ColorfulPrint.COLOR_GREEN)
ColorfulPrint.colorfulPrint(' ***** Output incorrect: ' + str(failCount) + '/' + str(x) + ' rate: ' + str(failCount * 100 / x) + '% *****', ColorfulPrint.MODE_BOLD, ColorfulPrint.COLOR_RED)

使用方法:

将上面四个文件及datainput_student_win64.exe放于同一目录下,并将自己程序的code.jar导出放于该路径,运行Python judger.py即可自动化测试50次,在测试结束后会生成测试报告。

Hacker机

hacker.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
import os

My_path = 'D:/coding_file/study/Lesson/oo_lesson/OO/test/hw5'
names = ['Caster', 'Saber', 'Rider', 'Lancer',
'Archer', 'Assign'] # other person jar name

os.chdir(My_path)
i = 0
# os.system('python production.py')
while i <= len(names)-1:
print(">>>>>The comparison result with "+str(names[i]) + " is:")
os.system('.\datainput_student_win64.exe | java -jar '+str(names[i])+'.jar > stdout.txt')
os.system('python outputChecker.py')
i = i+1
  • Title: OO_hw5_test
  • Author: Charles
  • Created at : 2023-03-26 07:51:05
  • Updated at : 2023-03-26 14:33:58
  • Link: https://charles2530.github.io/2023/03/26/oo-hw5-test/
  • License: This work is licensed under CC BY-NC-SA 4.0.
Comments