看數(shù)學(xué)老師是如何一鍵搞定報(bào)告和試卷的

本文將介紹Matlab的兩個(gè)實(shí)用技巧。一鍵生成Word版本的報(bào)告和PDF版本的數(shù)學(xué)試卷。其中第一個(gè)技巧Matlab之前都是通過(guò)調(diào)用COM接口來(lái)實(shí)現(xiàn)的,類似于VBA,雖然可做的事情很多,但并不適合一般的童鞋。第二個(gè)技巧,靈感來(lái)源于一位研究僧同學(xué)。大致意思是根據(jù)現(xiàn)有的數(shù)學(xué)題庫(kù)來(lái)科學(xué)快捷的生成一份試卷。本文提供的只是初稿,如果需求大的話,作者會(huì)在Github上保持更新。

1. 自動(dòng)化報(bào)告

測(cè)試平臺(tái): MATLAB 2015b

先來(lái)看一個(gè)最簡(jiǎn)單的例子(demo1.m)

% demo1.m
import mlreportgen.dom.*;
d = Document('demo1','docx');
open(d);
append(d,'hello world!');
close(d);
rptview(d.OutputPath);
import mlreportgen.dom.*;

第一行是將所需要的類和函數(shù)導(dǎo)入工作空間。這里我們最常用的類就是Document.

d = Document('test','docx');
open(d);

在第二、三行中我們新建一個(gè)文檔,其中文件類型docx可以替換成html或者pdf. Document類的相關(guān)屬性可以通過(guò)命令查看 (doc mlreportgen.dom.Document)

append(d,'hello world!');

在第四行我們給文檔添加了一句經(jīng)典的話,我們還可以自定義它們的樣式。比如加粗、斜體、改成藍(lán)色、字體大小等等。

% 替換上面的一行代碼
p=Text('hello world');
p.Style={Bold(true),FontSize('16pt'),Color('blue')};
p.Strike='double';
append(d,p)

這里出現(xiàn)了第一個(gè)文檔類:Text,即文本。Matlab提供了很多可調(diào)節(jié)的屬性,如下表。修改起來(lái)也很方便,如要把文本改為斜體,則添加:p.Italic=1;即可。

Text的屬性 取值 備注
Bold true/false 加粗
Color str('red'、'blue'等) 顏色
Italic true/false 斜體
BackgroundColor str 背景色
Underline str('single'、'dotdash'等) 下劃線
FontFamilyName str 字體
FontSize str('12pt') 字體大小
Strike str 刪除線
StyleName str 模板中的樣式名

接下來(lái)我們將生成一個(gè)更復(fù)雜的文檔。首先想想一個(gè)word文檔一班都有哪些元素。MATLAB提供了很多(下面的表格僅列出了部分)。本文主要介紹其中的五個(gè):頁(yè)面設(shè)置、標(biāo)題、段落、表格、圖片。

屬性 含義
CustomAttribute Custom element attribute
CustomElement Custom element of a document
CustomText Plain text to be appended to a custom element
DOCXPageFooter Page footer for a Word document.
DOCXPageHdrFtr Page Base class for page header and footer
DOCXPageHeader Page header for a Word document.
DOCXPageMargins Margins of pages in a Word page layout
DOCXPageSize Size, orientation of pages in a Word layout
DOCXSection Page layout section of a Word document
Document Create a dom document
ExternalLink Create a hyperlink to an external target
Form Defines a form
FormalTable Create a formal table
Group Group of document objects
Heading Create a heading paragraph.
HorizontalRule Create a horizontal rule.
Image Create an image to be included in a report.
ImageArea Defines an image area as a hyperlink
InternalLink Create a hyperlink to a target in this
LinkTarget Create a target for a hyperlink.
ListItem Item in a list
Node Defines a document node
Object Defines a document object
OrderedList Ordered (numbered) list
Paragraph Create a formatted block of text, i.e., a paragraph.
Table Create a table.
TableColSpecGroup Defines style of a group of table columns
TableEntry Create a table Entry
TableRow Creates a table row
Template Create a template for a document
Text Create a text object

接下來(lái)我們做一個(gè)完整的模板。首先新建空白文檔。

% demo2.m
import mlreportgen.dom.*;
d=Document('demo2','docx');
open(d);

1.1 頁(yè)面

頁(yè)面設(shè)置包括頁(yè)面大小('A4'等)、頁(yè)面方向、頁(yè)邊距.

% 頁(yè)面設(shè)置
s = d.CurrentDOCXSection;
s.PageSize.Orientation  ='landscape'; % portrait(default)
s.PageSize.Height = '8.5in';
s.PageSize.Width = '11in';
s.PageMargins.Left = '3.0cm';
s.PageMargins.Right = '3.0cm';
s.PageMargins.Top = '2.5cm';
s.PageMargins.Bottom = '2.5cm';
% 中文字體樣式設(shè)置
heiti=FontFamily;
heiti.FamilyName='Arial';
heiti.EastAsiaFamilyName='黑體';
songti=FontFamily;
songti.FamilyName='Arial';
songti.EastAsiaFamilyName='宋體';

1.2 標(biāo)題

標(biāo)題的初始格式由模板中自帶的標(biāo)題樣式?jīng)Q定,當(dāng)然也可以自己修改。

%% 標(biāo)題
p=Heading(1,'Matlab 自動(dòng)化報(bào)告模板');% 一級(jí)標(biāo)題
%p.Color='red';
%p.HAlign='center';
p.Style={heiti,Color('red'),HAlign('center')};
append(d,p);

1.3 段落

與文本不同,段落除下文本的屬性外,還有邊距、對(duì)齊、首行縮進(jìn)、行間距、段前、段后等屬性需要調(diào)節(jié)。在下面的代碼框中,F(xiàn)irstLineIndent代表首行縮進(jìn)的寬度,LineSpacing代表行間距,OuterMargin代表邊距。在這里我們還引入了一個(gè)新的類:ExternalLink(外部鏈接),當(dāng)然Matlab也提供文檔內(nèi)部鏈接:InternalLink.

%% 段落
append(d,Heading(2,'一、段落模板'));
s='這里是段落。';
s=repmat(s,[1,12]);
p = Paragraph(s);
% 中文字體樣式自定義
p.Style={songti,Color('blue'),...
    LineSpacing(1.5),...
    OuterMargin('10pt','0pt','0pt','10pt')};
p1=Text('下劃線。');%同段落差不多.
p1.Underline='single';
p1.Color='red';
append(p,p1);
append(p,s);
p2=ExternalLink('http://github.com/gasongjian/', '超鏈接');
append(p,p2);
p.FontSize='14pt';
p.FirstLineIndent='28pt';%這里差不多就是2個(gè)字符大小
append(d,p);

效果預(yù)覽:

1.4 簡(jiǎn)易表格

Matlab 支持直接從數(shù)組矩陣和元胞矩陣建立表格。如t=Table(magic(5))或者
t=Table(cell(5)). 也可以利用TableRow一行一行添加。一個(gè)單元格可以填充的元素很多(文本、圖像等),所以可調(diào)節(jié)的就是表格的邊框、單元格的大小、對(duì)齊等。本文給出一個(gè)簡(jiǎn)易的例子和一個(gè)復(fù)雜的例子。一件很遺憾的事就是不能合并單元格。當(dāng)寫(xiě)完demo2后,本文還將提供一種更為簡(jiǎn)便的方式。

%% 簡(jiǎn)易表格
append(d,Heading(2,'二、簡(jiǎn)單表格'));
t={'志明','語(yǔ)文','數(shù)學(xué)','英語(yǔ)'; ...
    '成績(jī)','70','98','89'; ...
    '等級(jí)','B','A','A'};
p=Table(t);

% 格式化單元格中的段落
for ii=1:p.NRows
    for jj=1:p.NCols
        t=entry(p,ii,jj);
         t.Children(1).Style={songti,...
            Color('green'),...
            FontSize('12pt'),...
            LineSpacing(1.0),...
            OuterMargin('0pt','0pt','0pt','0pt')};
    end
end

p.Style = {Border('single','blue','3px'), ...
               ColSep('single','blue','1px'), ...
               RowSep('single','blue','1px')};

p.Width = '50%';
p.HAlign='center';% 居中對(duì)齊
p.TableEntriesHAlign='center';
p.TableEntriesVAlign='middle';
append(d,p);

效果預(yù)覽:

1.5 復(fù)雜表格

%% 復(fù)雜表格
append(d,Heading(2,'三、復(fù)雜表格'));
q = Table(5);
q.Border = 'single';
q.ColSep = 'single';
q.RowSep = 'single';

row = TableRow;
te = TableEntry('算法名稱');
te.RowSpan = 2;
append(row, te);

te = TableEntry('第一類');
te.ColSpan = 2;
%te.Border = 'single';
append(row, te);
te = TableEntry('第二類');
te.ColSpan = 2;
%te.Border = 'single';
append(row, te);
append(q,row);

% 第二行
row=TableRow;
append(row,TableEntry('T1'));
append(row,TableEntry('T2'));
append(row,TableEntry('T3'));
append(row,TableEntry('T4'));
append(q,row);

% 其他行
t=TableRow;
append(t,TableEntry('條目'));
for i=1:4
    append(t,TableEntry(' '));
end
append(q,t);
append(q,clone(t));
append(q,clone(t));
append(q,clone(t));
q.TableEntriesStyle={Width('80'),Height('40')};
q.Style = {Border('single','green','3px'), ...
               ColSep('single','green','1px'), ...
               RowSep('single','green','1px')};

q.HAlign='center';% 居中對(duì)齊 
q.TableEntriesHAlign='center';
q.TableEntriesVAlign='middle';
append(d,q);

效果預(yù)覽:

1.6 圖片

%% 插入圖片
append(d,Heading(2,'四、圖片模板'));
p1 = Image('myPlot_img.png');
% ScaleToFit是為了使圖片大小適應(yīng)頁(yè)面,也可以換成下方的自定義大小設(shè)置
%p1.Style={HAlign('center'),ScaleToFit(1)};
p1.Style={HAlign('center'),Width('600px'),Height('400px')};
append(d,p1);

close(d);
rptview(d.OutputPath);

作為一個(gè)懶人,我希望寫(xiě)得更極致一點(diǎn), 即我只想關(guān)注內(nèi)容而忽略這些格式。這時(shí)候我們可以利用模板來(lái)實(shí)現(xiàn)這一切,把所需要的樣式都存在模板里。事實(shí)上新建Word文檔都是基于模板建立的,Matlab也是。通過(guò)在模板里修改默認(rèn)樣式或者新建樣式,我們可以極大簡(jiǎn)化上述代碼,從而使得上述工作不那么像編程。

1.7 巧用模板來(lái)簡(jiǎn)化代碼

% demo3.m
% 利用模板中的樣式來(lái)生成報(bào)告
% 如果是中文版Word,自帶樣式名稱請(qǐng)參見(jiàn)目錄下的pdf文檔

import mlreportgen.dom.*
% 模板文件 mytemplate.dotx 在文末會(huì)附下載鏈接
d=Document('demo3','docx',fullfile(pwd,'mytemplate'));
open(d);
%% 標(biāo)題
p=Paragraph('成績(jī)報(bào)告單','Heading 1');
append(d,p);
%% 文字段落(doc mlreportgen.dom.Paragraph)
append(d,Heading(2,'一、段落模板'));
s='這里是段落';
s=repmat(s,[1,30]);
p = Paragraph(s,'mypara1');%自定義段落樣式
append(d,p);
%% 添加空的段落行
for i=1:8
    append(d,' ');
end
%% 插入表格
append(d,Heading(2,'二、表格模板'));
t={'姓名','語(yǔ)文','數(shù)學(xué)','英語(yǔ)'; ...
    '成績(jī)','70','94','82'; ...
    '等級(jí)','C','A','B'}; 
p=Table(t,'mytable1');% 自定義表格樣式
append(d,p);
close(d);
rptview(d.OutputPath);

效果預(yù)覽:

到這一個(gè)完整的模板就差不多了,還有一些新的類需要讀者自己去探索。 接下來(lái)才是本文的正題,我們來(lái)玩一點(diǎn)好玩的事情。

2. 批量生成成績(jī)單

數(shù)據(jù)集和目標(biāo):

  1. 班級(jí)所有人的成績(jī)表(成績(jī).xlsx):姓名、語(yǔ)文、數(shù)學(xué)、總分;
  2. 給每個(gè)同學(xué)生一張成績(jī)單,其中只有自己一個(gè)人的分?jǐn)?shù)和相對(duì)應(yīng)的等級(jí)。
% SchoolReport.m
% n=學(xué)生人數(shù)
% 為使得程序可讀性加強(qiáng),我們需要格式化成績(jī)單
% 1. 第一行格式:姓名,各個(gè)學(xué)科,總分
% 2. 只有學(xué)生成績(jī),沒(méi)有其他很雜的信息。
% 3. 部分成績(jī)?nèi)艨杖?,?qǐng)不要用數(shù)字填充,可以空著或者文字(缺考)填充。

%% 數(shù)據(jù)導(dǎo)入
filename='成績(jī).xlsx';
savename='成績(jī)單';
[score,textdata]=xlsread(filename);
m=3; %學(xué)科數(shù)
n=size(score,1);% 學(xué)生人數(shù)
name=textdata(2:n+1,1);
mean_score=mean(score,'omitnan');
max_score=max(score,[],'omitnan');
grade=Gradegen(score); %Gradegen是自定義函數(shù),生成各個(gè)同學(xué)的等級(jí)

%模板,實(shí)考對(duì)應(yīng)變量score,等級(jí)對(duì)應(yīng)變量grade
template=cell(5,m+1);
template(1,1:m+1)={'姓名','語(yǔ)文','數(shù)學(xué)','總分'};
template(2:5,1)={'實(shí)考成績(jī)';'平均成績(jī)';'最高成績(jī)';'等級(jí)'};

%% 相關(guān)接口
import mlreportgen.dom.*;
d = Document(savename,'docx',fullfile(pwd,'mytemplate'));
open(d);

%% 開(kāi)始生成word成績(jī)單列表

% 添加分割線
hr = HorizontalRule();
hr.Style={Border('dotdash','blue','2px')};
append(d,hr);
% n是學(xué)生人數(shù),m是學(xué)科數(shù)
for i=1:n
    % 填充表格
    template{1,1}=name{i};
    for jj=2:m+1
        s=score(i,jj-1);
        if isnan(s)
            s='缺考';
        else
            s=num2str(s);
        end
        template{2,jj}=s;% 具體分?jǐn)?shù)
        template{3,jj}=sprintf('%4.2f',mean_score(jj-1));%學(xué)科平均分?jǐn)?shù)
        template{4,jj}=num2str(max_score(jj-1));%學(xué)科最高分?jǐn)?shù)
        template{5,jj}=grade{i,jj-1};% 等級(jí)
    end

    q=Table(template,'mytable2'); 
    q.TableEntriesStyle={Width('100'),Height('50')};
    append(d,q);
    append(d,clone(hr));
end
close(d);
rptview(d.OutputPath);

成果預(yù)覽:

schoolreport.png

除此之外,本文還提供了一個(gè)批量生成獎(jiǎng)狀的模板(在Word里也可以通過(guò)郵件合并功能實(shí)現(xiàn))供參考。

獎(jiǎng)狀.png

相關(guān)文件下載鏈接: 自動(dòng)化報(bào)告 github 項(xiàng)目地址

3. 中學(xué)數(shù)學(xué)試卷生成

在寫(xiě)這個(gè)之前,首先要感謝一位數(shù)學(xué)系學(xué)長(zhǎng)鮑宏昌。接下來(lái)要介紹的項(xiàng)目就是基于學(xué)長(zhǎng)開(kāi)發(fā)的中學(xué)試卷包:bhcexam

項(xiàng)目名稱: MathExamGen
項(xiàng)目平臺(tái): Windows+Matlab+Texlive(含bhcexam包)
項(xiàng)目地址: http://github.com/gasongjian/mathexamgen/
項(xiàng)目介紹:大體思路就是利用Matlab科學(xué)的整合數(shù)學(xué)題庫(kù)中的題目,然后生成相應(yīng)的tex文件,最后借助自帶的xelatex編譯器編譯成pdf文件。

3.1 數(shù)學(xué)題庫(kù)

存儲(chǔ)類型:csv或者數(shù)據(jù)庫(kù)
變量列表:

變量 變量名 描述 取值
1 ID 題目編號(hào) 6位數(shù)字
2 qtype 題目類型 1代表填空題,2代表選擇題等
3 question 題目?jī)?nèi)容 題目的latex代碼
4 options 題目相關(guān)信息 選擇題的四個(gè)選項(xiàng)等信息
5 answer 題目答案
6 topic 題目的考點(diǎn) 分級(jí)考點(diǎn),如:高二-數(shù)列-遞推

3.2 主要思路

結(jié)合Matlab的數(shù)據(jù)處理與分析功能,我們可以做很多事,例如

  1. 根據(jù)給定的類型要求和考點(diǎn)要求,隨機(jī)生成一張?jiān)嚲恚?/li>
  2. 結(jié)合單個(gè)同學(xué)的歷史數(shù)據(jù),生成適合他/她的試卷,在這份試卷中易錯(cuò)點(diǎn)出現(xiàn)的頻次更高一些;
  3. 由于所有試卷都是生成的,我們可以更科學(xué)快捷的評(píng)估單次考試。
exam.png

再次附上項(xiàng)目鏈接: 自動(dòng)化報(bào)告 github 項(xiàng)目地址數(shù)學(xué)試卷生成 github 項(xiàng)目地址

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容