崔麗紅
摘要:基于光標(biāo)閱讀機(jī)評卷系統(tǒng),定制實現(xiàn)了一種課程教學(xué)滿意度測評系統(tǒng)。介紹了測評系統(tǒng)組成,給出了信息卡打印、數(shù)據(jù)匯總分析處理兩個功能模塊的實現(xiàn)方法和源代碼,為快速準(zhǔn)確采集處理來源分散、數(shù)量巨大的測評信息提供了一種簡單易用的輔助工具。
關(guān)鍵詞:測評卡設(shè)計;課程編碼;匯總統(tǒng)計;數(shù)據(jù)分析
中圖分類號:G424 文獻(xiàn)標(biāo)識碼:A 文章編號:1009-3044(2016)36-0121-03
光學(xué)標(biāo)記閱讀機(jī)(Optical Mark Reader),簡稱OMR,是一種高速的信息錄入設(shè)備,它集光、機(jī)、電于一體,運(yùn)用光電轉(zhuǎn)換原理以極快的速度識別填涂點(diǎn),從載有信息的信息卡上讀取數(shù)據(jù),并通過數(shù)據(jù)電纜送入計算機(jī)。由于OMR每秒鐘錄入數(shù)千個信息,且誤碼率極低。因此,OMR在標(biāo)準(zhǔn)化考試、報名管理、稅務(wù)申報、戶籍管理、人口普查、投票選舉、民意測驗、干部測評、彩票發(fā)行等眾多領(lǐng)域被應(yīng)用。
為實現(xiàn)課程教學(xué)質(zhì)量考核評價信息處理達(dá)到智能化、考評方法的規(guī)范化和輔助決策科學(xué)化,提高考評數(shù)據(jù)分析處理能力和工作效率,增強(qiáng)考評結(jié)果的信度和效度,我們研發(fā)了“基于OMR的課程教學(xué)質(zhì)量滿意度測評系統(tǒng)”(簡稱系統(tǒng)),系統(tǒng)供教務(wù)部門測評課程教學(xué)質(zhì)量時對各種數(shù)據(jù)信息進(jìn)行統(tǒng)計匯總和分析處理,生成各種考評資料,管理各種考評信息,為準(zhǔn)確評價課程提供依據(jù)。系統(tǒng)與人工制作發(fā)放紙質(zhì)測評表、人工統(tǒng)計相比,它解決了人工易出錯、效率低下,以及測評結(jié)果計算機(jī)數(shù)據(jù)錄入中的瓶頸問題,把人們從繁重的機(jī)械勞動中解脫出來。系統(tǒng)與直接用網(wǎng)絡(luò)測評系統(tǒng)相比,解決了需要將學(xué)生集中到計算機(jī)房以及匿名評價人數(shù)不易控制問題,可以集中學(xué)生在短暫時間內(nèi)實施完成,使采集處理那些來源分散而數(shù)量巨大的信息變得輕而易舉,快速而準(zhǔn)確。
1 測評系統(tǒng)組成與使用流程
系統(tǒng)由光標(biāo)閱讀機(jī)、打印機(jī)、機(jī)讀信息卡和配套軟件、數(shù)據(jù)處理分析應(yīng)用軟件組成。系統(tǒng)應(yīng)用特點(diǎn)是統(tǒng)一制卡、分散填涂、集中錄入、快速處理。根據(jù)要采集的信息設(shè)計印制信息卡,并編制相應(yīng)的應(yīng)用軟件,然后把信息卡分發(fā)下去分散填涂,再把填涂好的卡收集起來用OMR閱讀,最后由計算機(jī)進(jìn)行分析處理和管理。因此,按照考評的工作流程,完成一次考評活動可分為“考評準(zhǔn)備”〉“滿意度測評”〉“測評結(jié)果輸出”〉“測評結(jié)果分析”四個部分。
2 測評系統(tǒng)編程中具體代碼實現(xiàn)
2.1 測評機(jī)讀信息卡設(shè)計
根據(jù)測評課程的特點(diǎn)、要求和測評過程,合理設(shè)計機(jī)讀信息卡。匿名情況下,學(xué)號不涂寫。學(xué)生班次可以制卡時直接打印。編號的含義可以為在有多頁情況下的頁碼,也可以為學(xué)生班次,可以制卡時直接打印。通常情況下,測評信息卡片制作時,課程名稱可在Microsoft Word中輸入套打。本文為了便于后續(xù)匯總統(tǒng)計,將所有課程統(tǒng)一編碼放在數(shù)據(jù)庫中,在自主研發(fā)的軟件中讀取數(shù)據(jù)庫輸入課程名稱套打,優(yōu)點(diǎn)有二:一是可以分門別類選擇課程進(jìn)行選擇輸入打印,減少輸入錯誤;二是編碼時只要將同一門課程的編碼設(shè)置相同,之后不管這門課程出現(xiàn)在哪一張卡片中,以及在卡片中的名稱如何,都可以正確匯總出這門課程測評票數(shù)。三是自由操作卡片中的所有信息。
2.1.1 讀取課程代碼
void CTXPropertyPage1::GetCodeMain()
{//讀取學(xué)生班次的代碼,以便在信息卡中按學(xué)生班次輸入課程
CComboBox* pBox1 = (CComboBox*)GetDlgItem(IDC_COMBO_CODEMAIN);
CString str;
int index=pBox1->GetCurSel();
pBox1->GetLBText(index,str);
ASSERT(m_pDB);
ASSERT(m_pDB->IsOpen());
CString strRecordIdQuery = _T( "name ='") + str + _T("'") ;
int nCodeMain;
CDaoRecordset rs(m_pDB);
try { CString strSelect(_T("Select * From ["));
strSelect += "codemain";//表名稱
strSelect += _T("]");
rs.Open(dbOpenDynaset,strSelect);
if ( rs . FindFirst ( strRecordIdQuery ) )
{ COleVariant var;
var = rs.GetFieldValue(2);
nCodeMain=V_I2(&var);}}
catch (CDaoException* e)
{ DisplayDaoException(e);
e->Delete();
return; }
rs.Close();
m_GeoAtt.m_nCodeMain=nCodeMain;
SetDlgItemInt(IDC_E_CODE_MAIN,nCodeMain);}
void CTXPropertyPage1::SetCodeSbCurSel_init()
{//設(shè)置當(dāng)前課程編碼和名稱
CComboBox* pBox2 = (CComboBox*)GetDlgItem(IDC_COMBO_CODESB);
ASSERT(m_pDB);
ASSERT(m_pDB->IsOpen());
int nCodeSb;
CDaoRecordset rs(m_pDB);
CString strCodeMain;
strCodeMain.Format("%d",m_GeoAtt.m_nCodeMain);
CString strSQL(_T("Select * From ["));
strSQL += "codesb";//表名稱
strSQL += _T("] ");
strSQL += "WHERE ([codemain] = " + strCodeMain +_T(" ) or ( [codemain] =0 ) ");
try {// Open the recordset using the filtered SQL string
rs.Open( dbOpenDynaset, strSQL );
pBox2->ResetContent();
COleVariant var;
rs.MoveFirst();
var = rs.GetFieldValue(1);
pBox2->AddString(CCrack::strVARIANT(var));
var=rs.GetFieldValue(2);
nCodeSb=V_I2(&var);
pBox2->SetCurSel(0);
rs.MoveNext();
while (!rs.IsEOF())
{ var = rs.GetFieldValue(1);
pBox2->AddString(CCrack::strVARIANT(var));
rs.MoveNext(); }}
catch (CDaoException* e)
{ DisplayDaoException(e);
e->Delete();
return; }
rs.Close();
if(!m_bFirst)
{ m_GeoAtt.m_nCodeSb=nCodeSb;
SetDlgItemInt(IDC_E_CODESB,nCodeSb);
CString str;
pBox2->GetLBText(pBox2->GetCurSel(),str);
SetDlgItemText(IDC_E_TEXT,str);}}
2.1.2 輸出課程信息及代碼
void CDrawView::SaveFilesAs()
{//在保存時輸出設(shè)計的信息卡的課程代碼和名稱
CFileDialog filedlg(FALSE,"*.drw","測評卡.drw",OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT,
"系統(tǒng)內(nèi)部文件 (*.drw) |*.drw|| ",NULL);
CMainFrame *pMainFrm = ((CMainFrame *)AfxGetMainWnd());
filedlg.m_ofn.lpstrInitialDir=pMainFrm->m_sMainDirectory;
if(filedlg.DoModal() == IDOK)
{ CString filename = filedlg.GetPathName();
CDrawDoc* pDoc = GetDocument();
pDoc->DoSave(filename);
//將套打結(jié)果存為與原始文件同名的txt格式文件
POSITION pos = pDoc->m_objects.GetHeadPosition();
int id = filename.ReverseFind('.');
filename=filename.Left(id)+".txt";
ofstream outfile(filename);
int iKechengshu=0;
int iXuhao=0; //套打數(shù)據(jù)記錄,輸出制卡時所填涂的隊號或頁碼
while (pos != NULL)
{ CDrawObj* pObj = pDoc->m_objects.GetNext(pos);
if(pObj->IsKindOf( RUNTIME_CLASS( CDrawRect)) &&!pObj->IsKindOf( RUNTIME_CLASS( CDrawText)))
{ iXuhao++;
if(pObj->m_GraphicAtt.m_nIndexfillmode)
{outfile< outfile< pos = pDoc->m_objects.GetHeadPosition(); //套打數(shù)據(jù)記錄,輸出序號、班級號、課程編碼和課程名稱 while (pos != NULL) { CDrawObj* pObj = pDoc->m_objects.GetNext(pos); if(pObj->IsKindOf( RUNTIME_CLASS( CDrawText)))
{ iKechengshu++;
outfile<
outfile< outfile.close(); }} 輸出文件的文本文件內(nèi)容,第一行為填涂的頁碼(編碼),其余各行為:序號、班號、課程編碼和課程名稱。實際上,在設(shè)計卡片時可將編號和20門課程的位置處分別留有矩形空白和文字空白,只需在輸入時將多余位置設(shè)為白色,即可不打印輸出課程名為空白的行。 2.2 測評信息處理 圖1 測評信息卡保存文件數(shù)據(jù)內(nèi)容 評估結(jié)果處理代碼如下: // InstrXlsFilePath為上面的測評結(jié)果統(tǒng)計表;InstrXlsFilePath為制卡時輸出的卡片信息文本文件 // OutstrXlsFilePath為輸出的結(jié)果文件 void CMainFrame::ProcessSourceData(CString InstrXlsFilePath,CString InstrTxtFilePath,CString OutstrXlsFilePath) { //寫表頭開始 CStringArray sampleArray; sampleArray.RemoveAll(); sampleArray.Add("序號"); sampleArray.Add("課程編碼"); sampleArray.Add("課程名稱"); sampleArray.Add("優(yōu)秀"); sampleArray.Add("良好"); sampleArray.Add("合格"); sampleArray.Add("不合格"); ((CMainFrame*)AfxGetMainWnd())->ExportData(OutstrXlsFilePath,sampleArray); //寫表頭結(jié)束 CString stringBianhao="",stringXuhao="",stringZhuanyeBianma="",stringBianma="",stringKechengming="",stringAll=""; CString stringYouxiu="",stringLianghao="",stringHege="",stringBuhege=""; CStdioFile infile1; if(!infile1.Open(InstrTxtFilePath,CFile::modeRead)) { MessageBox("file error"); return; } infile1.ReadString(stringBianhao); int iYouxiu, iLianghao,iHege,iBuhege; int iTotalRows; iTotalRows = 0; for(int iItem = 0; iItem < 20; iItem ++) { sampleArray.RemoveAll(); CString strXuhao; strXuhao.Format("%d",iItem+1); sampleArray.Add(strXuhao); infile1.ReadString(stringAll); int nPositon; //空格位置 nPositon = 0; //第一個空格位置 for(int i=0;i stringKechengming = stringAll.Right(stringAll.GetLength()-nPositon);//最后一個 stringAll=stringAll.Left(nPositon); for(int j=0;j { if(stringAll.GetAt(j)==(' ')) nPositon=j; } stringKechengming = stringAll.Right(stringAll.GetLength()-nPositon);//倒數(shù)第二個 //處理空白情況 if(stringKechengming.Find("空白")==-1 ) { stringAll=stringAll.Left(nPositon); for(int k=0;k {if(stringAll.GetAt(k)==(' ')) nPositon=k;} stringBianma = stringAll.Right(stringAll.GetLength()-nPositon);//倒數(shù)第二個 sampleArray.Add(stringBianma);
sampleArray.Add(stringKechengming);
{ //excel 文件讀取優(yōu)秀、良好、合格和不合格結(jié)果
CStringArray sampleArray2;
CSpreadSheet ssResult(InstrXlsFilePath,"測評原始數(shù)據(jù)"); ssResult.BeginTransaction();
iTotalRows=ssResult.GetTotalRows();
iYouxiu=0; iLianghao=0; iHege=0; iBuhege=0;
for(int M=3;M { ssResult.ReadRow(sampleArray2,M); //MessageBox(sampleArray2[2]); if(sampleArray2[2].GetAt(iItem)=='A') iYouxiu++; if(sampleArray2[2].GetAt(iItem)=='B') iLianghao++; if(sampleArray2[2].GetAt(iItem)=='C') iHege++; if(sampleArray2[2].GetAt(iItem)=='D') iBuhege++; }} stringYouxiu.Format("%d",iYouxiu); stringLianghao.Format("%d",iLianghao); stringHege.Format("%d",iHege); stringBuhege.Format("%d",iBuhege); sampleArray.Add(stringYouxiu); sampleArray.Add(stringLianghao); sampleArray.Add(stringHege); sampleArray.Add(stringBuhege); ((CMainFrame*)AfxGetMainWnd())->ExportData(OutstrXlsFilePath,sampleArray); }} stringAll=""; iTotalRows = iTotalRows-2;//從第三行開始 stringAll.Format("成功匯總了%d條數(shù)據(jù)",iTotalRows); AfxMessageBox(stringAll);} void CMainFrame::ExportData(CString strXlsFlile, CStringArray &m_strarray) {//導(dǎo)出為Microsoft excel格式文件 CSpreadSheet ssSave(strXlsFlile,"DATA"); ssSave.BeginTransaction(); ssSave.AddRow(m_strarray); ssSave.Commit();} 3 結(jié)束語 通過以上思路實現(xiàn)了一個基于光標(biāo)閱讀機(jī)讀入數(shù)據(jù),然后利用程序進(jìn)行統(tǒng)計分析,可以實現(xiàn)學(xué)校課程教學(xué)質(zhì)量滿意度的測評,實踐表明,只要在涂卡過程中完成按照要求進(jìn)行,系統(tǒng)就能夠滿足快速準(zhǔn)確測評的需要。使用過程中也發(fā)現(xiàn)一些問題,比如使用激光打印機(jī)打印卡片可使卡片受熱發(fā)生彎曲,讀卡時易出現(xiàn)卡紙現(xiàn)象,應(yīng)保持信息卡的平整、干燥、潔凈,不折疊,可以使光標(biāo)閱讀機(jī)卡紙率大大下降;使用簽字筆或熒光筆涂卡會出現(xiàn)不能識別的情況;讀卡程序輸出的excel文件版本過老,使作者編寫的處理程序無法讀取數(shù)據(jù)等,在系統(tǒng)開發(fā)過程中要注意解決這些問題,可進(jìn)一步提高系統(tǒng)使用效率。