用PB设计非标准化考试评分系统
王金辉 刘子英
随着非标准化考试在国内日益普及,非标准化考试评分系统的出现也势在必行。由于工作关系,笔者编写了一套计算机非标准化考试评分系统。以下是笔者开发中总结的经验和技巧,希望能与大家一起研究、探讨。
一、设计思路
为了简化编程,笔者将一些较为复杂、较困难的评分标准转化为较容易实现的评分细则,数据结构采用树的子树表示法,并主要以数据表Score_Tree实现,具体结构如图1。

图1
Score_Tree用于存放评分标准的所有条目内容及其关系,其中,Item_Code为评分标准条目代码、
Item_Parent_Code是上层条目代码、Score_flag用来区别该条目评分类型(直接比较给分、规则推理、函数计算)、max和min存储该条目的取值范围、string_value存储该条目的字符值、score是该条目的分值、cat_code为考题代码。
二、评分算法的实现
评分算法在Windows 95平台上,用PowerBuilder
开发工具实现。下面详细讲述评分算法的实现。
1.直接比较法
在评分系统中,有些考核点可通过属性值的直接比较实现。直接比较法的实现比较简单,在此不再详细说明。程序的实现主要是评价细则库和考卷库中条目数据的比较,算法重点考虑了如何提高数据库的查询效率和速度,如在查询字段上建立索引、按不同类别分段等。
2.函数计算法
有些考核点不能通过属性值的简单比较来评价,但经过公式或函数计算得出的结果可以通过直接比较法实现,如尺寸链中隐含尺寸的计算、两零部件之间的间隙、点到某一线段的距离等。函数计算法实现的难点在于,需要计算的情形多种多样,对于不同公式的函数其参数类型千差万别,数目多少不一,既不能用统一的模型来表达,也不可能在短时间内列举所有的计算公式。另一方面,考虑系统维护的方便,给用户留有充分的扩充余地,我们利用Watcom
C++ Class Builder将C语言编写的函数以动态链接库的形式用到PowerBuilder的应用当中,不但节省了宝贵的内存资源,而且,由于动态链接库中的函数代码不包含在应用程序中,从而大大节省了应用程序的代码量,同时也减少了因修改函数进而对整个应用程序进行修改的巨大工作量。函数计算法调用函数uf_getvalue_byfunction得到考生某考核点条目的值,然后通过直接比较法得出结论。其中全局函数f_value(FunctionName,
p)为Watcom C++
动态链接库中的函数,它用来计算考生某考核点条目的值。
函数计算法的核心函数uf_getvalue_byfunction代码如下:
public function decimal uf_getvalue_byfunction (string item_code, string
cat_code, string exam_id, string FunctionName);
dec p[]
integer i,li_un = 0
long ll_row
string s_code, s_value
ll_row=ds_rule.retrieve(item_code)
//检索parent_code = :item_code的考核点条目
for i=1 to ll_row
s_code=ds_rule.getitemstring(i,"item_code")
SELECT "paper_fact"."value" INTO :s_value
FROM "paper_fact"
WHERE("paper_fact"."item_code"=:s_code)AND("paper_fact"."exam_id"
= :exam_id)AND("paper_fact"."cat_code" = :cat_code);
if sqlca.sqlcode = 100 then //输出未作图信息
is_info = "未作图!"
elseif (sqlca.sqlcode = 0) and IsNumber(s_value) then
p[i] = dec(s_value)
else
//记录不确定点数并输出信息
is_info = "不确定!"
li_un += 1
end if
next
if li_un 〉 0 then return -9999
return f_value(FunctionName, p)
//通过全局函数计算返回考生该考核点条目的值
end function
3.推理法
推理法用于对条目值必须同时满足多个条件才能成立的考核点进行评分。在评分系统中,笔者以评分树的形式实现了规则的动态表示,即将各个前提转化为结论的子条目,若所有子条目值符合条件,则父条目成立,得出结论成立,而各子条目值的判断可以用直接比较法实现。具体程序如下:
integer i,premise_true,rule_true
long ll_row
string s_code,s_name
premise_true = 0
rule_true = 1
ll_row=ds_rule.retrieve(item_code)
for i=1 to ll_row
s_code=ds_rule.getitemstring(i,"item_code")
if ds_rule.retrieve(s_code) 〈〉 0 then
uf_score_byrule(s_code,exam_id,cat_code)
//递归调用实现多级规则推理
else
if uf_score_comp(s_code,cat_code,exam_id) = 1 then
premise_true = 1
is_info+="前提"+ s_code +"正确"
is_all_info += is_info
else
premise_true = 0
is_info = ""
is_info+="前提"+ s_code+"不正确"
is_all_info += is_info
end if
rule_true=rule_truepremise_true
if rule_true = 0 then return 0
end if
next
return rule_true
//0 表示不成立,1表示成立
本评分系统已在全国注册建筑师考试作图题评分系统中成功应用。