徐欢的第二次作业
这个作业属于哪个课程 | https://edu.cnblogs.com/campus/zjlg/rjjc |
---|---|
这个作业的目标 | 实现一个命令行文本计数统计程序。能正确统计导入的纯英文txt文本中的字符数,单词数,句子数。 |
姓名-学号 | 徐欢-2022329301135 |
作业码云地址:https://gitee.com/xuhuanspace/second-assignment
一、作业描述
(1)基础功能实现
实现一个命令行文本计数统计程序。能正确统计导入的纯英文txt文本中的字符数,单词数,句子数。
具体命令行界面要求举例:
命令模式: wc.exe [-参数] [文件名]
wc.exe -c file.txt 统计字符数
wc.exe -w file.txt 统计单词数
- 项目文档应包含项目说明,写入 README.MD
- 码云上传的项目要求必须通过多次提交体现各个版本更迭和运行结果截图
(2)拓展功能实现
①统计代码行、空行、注释行等,并提供相应命令接口
②编写对应的单元测试
a. 实现基本功能的测试;
b. 单元测试包含更多的测试用例;
③使用选用的IDE附带的工具进行performance test
二、项目目录
三、功能实现及功能测试
(1)V2.0基础功能实现
功能说明:该程序可以实现的功能是对输入的纯英文.txt
文本中的字符数、单词数和句子数进行正确统计
- 指令参数:
-c
输出字符数
-w
输出单词数
-s
输出句子数 - 指令格式:
wc.exe [-参数] [文件地址]
- 功能实现代码展示
% 统计字符数(包括字母、数字)
if isstrprop(char, 'digit') ||isstrprop(char, 'alpha')
numChars = numChars + 1;
end
% 统计单词数
if isspace(char) || char == ',' || char == '.' || char == '?' || char == '!' || char == ':' || char == ';' || char == '-'
if wordInProgress
numWords = numWords + 1;
wordInProgress = false;
end
elseif ~isspace(char) && ~ismember(char, {',', '.', '?', '!', ':', ';', '-'})
wordInProgress = true;
end
% 统计句子数
if char == '.' || char == '?' || char == '!'
% 检查句子结束符前面是否有字母或数字(避免缩写或数字后的点被误认为是句子结束)
if i > 1 && (isstrprop(fileContents(i-1), 'alpha')|| isstrprop(fileContents(i-1), 'digit'))
numSentences = numSentences + 1;
end
end
程序保护:该程序可以判断用户输入参数、文件名是否正确,并在输入不正确时进行及时的提醒
% 检查参数数量
if numel(args) < 2
disp('参数不足,请重新输入。');
continue;
end
% 检查参数是否有效
param = args{1};
if ~ismember(param, validParams)
disp(['无效参数:', param, '。请输入 -c, -w, 或 -s。']);
continue;
end
% 检查文件名是否存在
filename = args{2};
if ~exist(filename, 'file')
disp(['文件不存在:', filename, '。请检查文件名并重试。']);
continue;
end
进行测试:
测试集测试结果
对test中的三个文件分别进行测试,如下展示其中一个测试集的测试结果:
(2)V3.0拓展功能实现
功能说明:该程序可以在上述的基础上,可以实现对输入的纯英文.txt
文本中的句子数进行细分,实现对陈述句、问句和感叹句的统计,同时可以实现对内容的代码行数、空行数和注释行数的统计
- 新增指令参数:
-l
输出代码行数
-e
输出空行数
-r
输出注释行数 - 指令格式:
wc.exe [-参数] [文件地址]
- 新增部分的功能实现代码展示
% 判断空行
if isempty(line)
numEmptyLines = numEmptyLines + 1; % 计为空行
else
% 判断注释行
if startsWith(line, '%')
numCommentLines = numCommentLines + 1; % 计为注释行
else
% 非空且非注释行,计为代码行
numCodeLines = numCodeLines + 1;
end
% 遍历行中的每个字符
for j = 1:length(line)
A = line(j);
% 对非空行统计字符数(包括字母、数字)
%内容同上,不赘述
% 统计单词数
%内容同上,不赘述
% 统计句子数
if ismember(A, {'.', '?', '!'})
if j > 1 && (isletter(line(j-1)) || isdigit(line(j-1)))
numSentences = numSentences + 1;
% 分类句子类型
if A == '.'
sumstr(1) = sumstr(1) + 1; % 陈述句
elseif A == '!'
sumstr(2) = sumstr(2) + 1; % 感叹句
elseif A == '?'
sumstr(3) = sumstr(3) + 1; % 问句
end
end
end
end
end
end
% 检查文件末尾是否有一个未完成的单词
if wordInProgress
numWords = numWords + 1;
end
对功能进行测试:
对test中的四个文件分别进行测试,可以实现拓展功能,如下展示其中一个测试集的测试结果:
单元测试:
classdef test_wc_main < matlab.unittest.TestCase
properties
testFile % 存储测试文件的绝对路径
end
methods (TestMethodSetup)
function setTestFilePath(testCase)
% 指定您创建的文件的绝对路径
testCase.testFile = fullfile('E:', 'Todesk\大三上课程\软件技术基础\matlab代码\V3.0', 'myTestFile.txt');
end
end
methods (Test)
function testCharacterCount(testCase)
% 测试字符数统计
param = '-c';
expectedChars = 115; % 根据文件内容计算
result = testCase.runWC(param);
testCase.verifyEqual(result.numChars, expectedChars, 'Character count test failed.');
end
function testWordCount(testCase)
% 测试单词数统计
param = '-w';
expectedWords = 31; % 根据文件内容计算
result = testCase.runWC(param);
testCase.verifyEqual(result.numWords, expectedWords, 'Word count test failed.');
end
function testSentenceCount(testCase)
% 测试句子数统计
param = '-s';
expectedSentences = [3, 1, 1]; % 2陈述句, 1感叹句, 1问句
result = testCase.runWC(param);
testCase.verifyEqual(result.numSentences, sum(expectedSentences), 'Total sentence count test failed.');
testCase.verifyEqual(result.numStatement, expectedSentences(1), 'Statement count test failed.');
testCase.verifyEqual(result.numExclamatory, expectedSentences(2), 'Exclamatory count test failed.');
testCase.verifyEqual(result.numInterrogative, expectedSentences(3), 'Interrogative count test failed.');
end
function testCodeLineCount(testCase)
% 测试代码行数统计
param = '-l';
expectedCodeLines = 5; % 2行代码
result = testCase.runWC(param);
testCase.verifyEqual(result.numCodeLines, expectedCodeLines, 'Code line count test failed.');
end
function testEmptyLineCount(testCase)
% 测试空行统计
param = '-e';
expectedEmptyLines = 1; % 1行空行
result = testCase.runWC(param);
testCase.verifyEqual(result.numEmptyLines, expectedEmptyLines, 'Empty line count test failed.');
end
function testCommentLineCount(testCase)
% 测试注释行统计
param = '-r';
expectedCommentLines = 1; % 1行注释
result = testCase.runWC(param);
testCase.verifyEqual(result.numCommentLines, expectedCommentLines, 'Comment line count test failed.');
end
end
methods
function result = runWC(testCase, param, filename)
% 模拟用户输入并执行 wc_main_v0_3 函数
if nargin < 3
filename = testCase.testFile; % 默认使用手动创建的测试文件
end
% 调用 wc_main_v0_3 函数并获取结果
result = wc_main_v0_3(param, filename);
end
end
end
该段代码是一个 MATLAB 类定义(classdef
),名为 test_wc_main
,它继承自 matlab.unittest.TestCase
。这个类是为了测试 wc_main_v0_3
的函数而设计的。
testCharacterCount
:测试字符数统计功能。它期望wc_main_v0_3
函数返回的结果中的字符数与预期的 115 个字符相匹配。testWordCount
:测试单词数统计功能。它期望单词数与预期的 31 个单词相匹配。testSentenceCount
:测试句子数统计功能。这里稍微复杂一些,因为它不仅测试总句子数(期望为 3+1+1=5 句),还分别测试了陈述句、感叹句和问句的数量。这意味着 * * *wc_main_v0_3
函数需要能够区分不同类型的句子,并分别计数。testCodeLineCount
:测试代码行数统计功能。这里有一个问题,注释中提到“2行代码”,但期望的代码行数被设置为 5。这可能是一个错误或者是对测试目标的误解。testEmptyLineCount
:测试空行统计功能。期望有 1 行空行。testCommentLineCount
:测试注释行统计功能。期望有 1 行注释。
测试结果:
(3)V4.0性能测试
- 使用
tic
和toc
测量执行时间
tic; % 开始计时
% 代码块
toc; % 结束计时并显示时间
- 使用
MATLAB Profiler
Profiler会显示每个函数的调用次数、总时间和自时间(不包括子函数调用)。
profile on;
% 代码块
profile viewer;
profile off;
- 使用
memory
函数
用来查看MATLAB工作区使用的内存情况。
memory; % 显示当前内存使用情况
whos; % 显示工作区中所有变量的详细信息,包括大小
四、新的感悟
我对MATLAB的单元测试框架有了更深刻的理解。从属性的定义到方法的分类(包括设置方法、测试方法和辅助方法),在分析过程中,我遇到了路径处理、函数依赖、测试准确性等多个技术挑战。通过查阅文档、尝试不同的解决方案,并最终找到问题的答案,我感受到了克服技术难题的成就感。
由于前期主要是仅多次在matlab中进行多次检验和修正,并没有及时上传到gitee中,导致版本次数较少。后来在探索过程中意识到可以通过git log
查看每一次历史记录,意识到了及时上传每次版本进行记录备份的有效性。