lab2回顾——P1(Poetic Walks)

2024-01-02 07:50
文章标签 回顾 p1 lab2 walks poetic

本文主要是介绍lab2回顾——P1(Poetic Walks),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

lab2的主题是Abstract Data Type (ADT) and Object-Oriented Programming (OOP)

写在开头

抽象数据类型(ADT)和面向对象编程(OOP)是软件构造中最为重要的概念之一。在实践中,它们被广泛应用于各种程序设计任务,以期提高代码的可重用性、可维护性和可扩展性。

ADT 是一种“自我包容”的数据类型,它通过对数据和操作的抽象来实现对程序的组织和管理。与具体的实现方式无关,ADT的定义只关注它所扮演的角色以及其所需提供的接口,从而使程序的不同部分能够协同工作,并达到预期的目的。ADT 的优点在于,它可以使程序逻辑更加清晰、简洁、易于理解和修改,同时也增强了代码的可重用性。

然而,ADT 仍然缺乏一些关键的特性和功能,例如封装、多态和继承等,这些特性可以通过面向对象编程的方式来实现。面向对象编程是一种基于类和对象思想的编程范式,它使我们可以将 ADT 的思想进一步扩展到程序中,同时还提供了更为灵活、复杂的代码组织方式,以增强程序的可扩展性和可维护性。

在 OOP 中,ADT 被视为一个类,它包含了属性和方法来描述其数据和操作。类是一个模板,它定义了对象所具有的共同特征和行为,而对象则是类的一个实例化。针对同一个类,可以创建许多个不同的对象,它们之间可以相互交互、调用方法,并共享类所定义的属性和方法。

OOP 的好处在于,它提供了更加灵活和可扩展的代码组织方式,将程序设计中的复杂度分解到了更小的单元中,从而使得程序实现过程更为直观和自然,同时也增强了代码的可重用性和可维护性。除此之外,OOP 还支持多态和继承等特性,这些特性可以充分发挥 ADT 的优点,同时还有助于进一步减少代码的冗余,增强代码的可读性和可维护性。

总之,ADT 和 OOP 都是软件构造中非常重要的概念,两者可以相辅相成,在程序设计中起到至关重要的作用。通过对 ADT 和 OOP 的深入理解和实践,我们可以更好地理解程序的运作原理,并在编写代码时更为高效、安全和易于维护。

实验要求理解

Poetic Walks 是 MIT 6.031 课程中的一道实验,它是一个基于图数据结构和文学创作的小项目。该实验旨在让我们通过编写代码,将现有的诗歌作为输入数据,然后生成新的诗歌。生成过程采用了古典诗歌的格式和风格,同时也涉及到了图论算法的应用。

在实验中,首先需要根据诗歌中的韵律、节奏等特征,将每个单词转化成图中的节点,并建立相邻节点之间的边,形成一个语言模型。

最后,利用图论算法(例如深度优先搜索、广度优先搜索等),在建立好的语言模型上进行“漫步”,不断地生成新的句子和诗行,直至达到指定数量或达到预设的目标。通过生成的新诗,可以发现与原有诗歌的共性和差异,从而反映出代码实现的原理和功能。

总的来说,Poetic Walks 实验结合了文学和计算机科学的两个领域,利用数据结构和算法技术进行文学创作,既有趣味性又具备实用性。通过完成这个实验,我们可以深入了解图论算法和语言建模等方面的知识,同时也增强了对代码组织和规范化的理解。

实验环境

本次实验延续上一次的配置,未发现任何配置上的问题
环境:IntelliJ IDEA Community Edition 2021.1 x64、JDK8。
Libs(用到的第三方库):junit-4.12.jar、hamcrest-core-1.3.jar。
使用Git新建和导入仓库的操作与lab1的类似,即clone所需文件,建立Git仓库。
本次实验需要统计JUnit测试用例的代码覆盖度,在IntelliJ IDEA中已内置此工具。
在这里插入图片描述

任务要求

P1大致可以分为5个小任务:
①为Graph编写测试用例,需要划分等价类,实现良好的测试覆盖率。
②构造 Graph 接口来实现 spec 中的功能,并以 ConcreteEdgesGraph 和 ConcreteVerticesGraph 两种方式实现接口。
③将 ADT 泛型化。
④根据文件中的输入,使用③中的ADT构造 poet(有向图),最后实现生成 poem。
⑤对代码进行覆盖率测试。

具体实现

编写测试用例Test

Graph接口的静态构造方法:

/*** Create an empty graph.** @param <L> type of vertex labels in the graph, must be immutable* @return a new empty weighted directed graph*/public static <L> Graph<L> empty() {return new ConcreteEdgesGraph<L>();}

GraphStaticTest.java的运行结果:
在这里插入图片描述
GraphInstanceTest.java:
对add()、set()、remove()、vertices()、sources()、targets()等方法写测试策略

实现ConcreteEdgesGraph

ConcreteEdgesGraph 类

分别写出Abstraction function、AF(vertices, edges)、Representation invariant和Safety from rep exposure。
例如Abstraction function需要指明私有变量vertices、edges的含义——
vertices:点的集合
edges:边的列表
它们实现了点与有向边组成有向图的抽象接口。

Edge类

同理如上。
其中AF(source, target, weight) = From the source to the target’s edge, whose value is the weight。

测试策略

测试方法分别有
testConcreteEdgesGraphToString(),testEdge(),testGetSource(),testGetTarget(),testGetWeight(),testToString(),testEquals(),testHashCode()

实现ConcreteVerticesGraph

同理如上。
其中ConcreteVerticesGraph 类涉及到的方法有:

public Vertex(String name);
private void checkRep();
public String getName();
public Map<String, Integer> getSources();
public Map<String, Integer> getTargets();
public int setSource(String vertex, int weight);
public int setTarget(String vertex, int weight);
public int setWeight(String vertex, int weight, Map<String, Integer> temp);
public String toString();
public boolean equals(Object other);
public int hashCode();

测试类中涉及的方法有:

testGraghToString();
testVertex();
testGetSource();
testGetTarget();
testSetSource();
testSetTarget();
testToString();
testEquals();
testHashCode();

测试结果如图:
在这里插入图片描述

设计诗歌 Poetic walks

Poetic walks 是一个 MIT 实验室的项目,旨在将人类诗歌与计算机科学相结合,从而生成新的、具有艺术性的文本。
首先需要处理诗歌的数据,包括从现有的文本中提取单词、句子以及诗歌的格式等信息。
对于每个单词,需要将其转换为带权有向图中的一个点,以便在计算机上进行操作和比较。
最终目标是将人类诗歌和计算机科学相结合,从而创造出新的具有艺术性的文本。
思路如下:

public class GraphPoet {private final Graph<String> graph = Graph.empty();/*** Create a new poet with the graph from corpus (as described above).** @param corpus text file from which to derive the poet's affinity graph* @throws IOException if the corpus file cannot be found or read*/public GraphPoet(File corpus) throws IOException {BufferedReader br = new BufferedReader(new FileReader(corpus));//打开输入流,缓存读入数据String read;while ((read = br.readLine()) != null) {//将read保存至集合String[] word = read.split("\\s");for (int i = 0; i < word.length - 1; i++) {int weight = graph.set(word[i].toLowerCase(), word[i + 1].toLowerCase(), 1);if (weight >= 1) {graph.set(word[i].toLowerCase(), word[i + 1].toLowerCase(), weight + 1);}}}br.close();checkRep();}/*checkRep检查不变性:1.graph内所有点非空2.graph内所有边的weight不为0(遍历检查vertex的sources边)*/private void checkRep() {for (String vertex : graph.vertices()) {if (vertex == null) {throw new IllegalArgumentException("Vertex cannot be null");}if (vertex.isEmpty()) {throw new IllegalArgumentException("Vertex cannot be empty");}Map<String, Integer> sources = graph.sources(vertex);for (Map.Entry<String, Integer> entry : sources.entrySet()) {if (entry.getValue() < 0) {throw new IllegalArgumentException("Source weight cannot be negative");}}}}/*** Generate a poem.** @param input string from which to create the poem* @return poem (as described above)*/public String poem(String input) {if (input == null) {throw new IllegalArgumentException("The input is empty!");}if (input.equals("")) return "";String[] word = input.split("\\s");String poem = word[0] + " ";for (int i = 0; i < word.length - 1; i++) {if (graph.vertices().contains(word[i + 1].toLowerCase())) {Map<String, Integer> sources = graph.sources(word[i + 1].toLowerCase());Map<String, Integer> targets = graph.targets(word[i].toLowerCase());String max = null;int maxValue = 0;for (String source : sources.keySet()) {if (targets.containsKey(source)) {if (sources.get(source) + targets.get(source) > maxValue) {max = source;maxValue = sources.get(source) + targets.get(source);}}}if (max != null)poem = poem.concat(max + " ");}poem = poem.concat(word[i + 1] + " ");}checkRep();return poem;}/***  toString()*  @return 以字符串形式返回poet的结构*/@Overridepublic String toString() {checkRep();return graph.toString();}
}

总结

好不容易终于做完了。

首先在看MIT网站上的实验要求描述就受到了很大震撼——英文原文看不懂,翻译过来又因为文化差异的缘故,根本看不懂是什么意思!!!╥﹏╥导致我理解上花了大量时间。后来几次软构课经过王老师将课上知识与实验二要求结合起来讲,我才渐渐理解了任务一的要求——利用泛型化实现对vertex、edge等各个类的ADT。慢慢的,我也理解到泛型化的巨大力量和作用——它不但简化了工作量和代码量,也使得程序的主次层次更为分明。

总结起来,在总时间的占用中,主要的部分并不是代码的编写和实现,而是ADT的设计和测试用例的编写。这也使我更能专注于从实现功能的角度去完成整个项目。Spec的编写和测试用例的编写是最让我感到头痛的,因为这不同于写代码,要设计一个合格的ADT需要考虑许多内容。

在实验的完成中我也收获了许多教训和经验。首先,我得时刻提醒自己不能总是在先完成主程序的编写后再完成测试用例,否则这样会花费更多的时间,要时刻遵循“测试优先”的原则。我还是比较满意于自己对ADT的设计的。但这也只是开始,希望接下来能在lab3中有更好的表现。给自己加油!

这篇关于lab2回顾——P1(Poetic Walks)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/561791

相关文章

Java基础回顾系列-第七天-高级编程之IO

Java基础回顾系列-第七天-高级编程之IO 文件操作字节流与字符流OutputStream字节输出流FileOutputStream InputStream字节输入流FileInputStream Writer字符输出流FileWriter Reader字符输入流字节流与字符流的区别转换流InputStreamReaderOutputStreamWriter 文件复制 字符编码内存操作流(

Java基础回顾系列-第五天-高级编程之API类库

Java基础回顾系列-第五天-高级编程之API类库 Java基础类库StringBufferStringBuilderStringCharSequence接口AutoCloseable接口RuntimeSystemCleaner对象克隆 数字操作类Math数学计算类Random随机数生成类BigInteger/BigDecimal大数字操作类 日期操作类DateSimpleDateForma

Java基础回顾系列-第三天-Lambda表达式

Java基础回顾系列-第三天-Lambda表达式 Lambda表达式方法引用引用静态方法引用实例化对象的方法引用特定类型的方法引用构造方法 内建函数式接口Function基础接口DoubleToIntFunction 类型转换接口Consumer消费型函数式接口Supplier供给型函数式接口Predicate断言型函数式接口 Stream API 该篇博文需重点了解:内建函数式

Java基础回顾系列-第二天-面向对象编程

面向对象编程 Java类核心开发结构面向对象封装继承多态 抽象类abstract接口interface抽象类与接口的区别深入分析类与对象内存分析 继承extends重写(Override)与重载(Overload)重写(Override)重载(Overload)重写与重载之间的区别总结 this关键字static关键字static变量static方法static代码块 代码块String类特

Java基础回顾系列-第六天-Java集合

Java基础回顾系列-第六天-Java集合 集合概述数组的弊端集合框架的优点Java集合关系图集合框架体系图java.util.Collection接口 List集合java.util.List接口java.util.ArrayListjava.util.LinkedListjava.util.Vector Set集合java.util.Set接口java.util.HashSetjava

Java基础回顾系列-第九天-数据库编程

Java基础回顾系列-第九天-数据库编程 数据库简介工具包java.sql API 内容与数据库建立连接执行SQL语句数据库检索和更新查询结果SQL类型对应Java类型映射元数据异常 API方法DriverManagerConnectionStatementPreparedStatementCallableStatementResultSetjava.sql.Date批处理、存储过程、事务

Java基础回顾系列-第一天-基本语法

基本语法 Java基础回顾系列-第一天-基本语法基础常识人机交互方式常用的DOS命令什么是计算机语言(编程语言) Java语言简介Java程序运行机制Java虚拟机(Java Virtual Machine)垃圾收集机制(Garbage Collection) Java语言的特点面向对象健壮性跨平台性 编写第一个Java程序什么是JDK, JRE下载及安装 JDK配置环境变量 pathHe

Vue2电商项目(二) Home模块的开发;(还需要补充js节流和防抖的回顾链接)

文章目录 一、Home模块拆分1. 三级联动组件TypeNav2. 其余组件 二、发送请求的准备工作1. axios的二次封装2. 统一管理接口API----跨域3. nprogress进度条 三、 vuex模块开发四、TypeNav三级联动组件开发1. 动态展示三级联动数据2. 三级联动 动态背景(1)、方式一:CSS样式(2)、方式二:JS 3. 控制二三级数据隐藏与显示--绑定styl

【大模型基础】P1 N-Gram 模型

目录 N-Gram 概述N-Gram 构建过程TokenN-Gram 实例第1步 构建实验语料库第2步 把句子分成 N 个 “Gram”第3步 计算每个 Bigram 在语料库中的词频第4步 计算出现的概率第5步 生成下一个词第6步:输入前缀,生成连续文本 上述实例完整代码N-Gram 的局限性 N-Gram 概述 N-Gram 诞生于统计学 NLP 初期,为解决词序列冗长导致的

一个vue重新回顾,好多年前写的

在校期间简单跟着视频学习的代码,后面上传到github仓库就一直没有使用了,今天重新加载,重新启动。下面是启动时候遇到的问题,主要原因是我这部电脑是新电脑,很多环境还没有搭建。 成功启动后的页面效果 这里采用的思维是双向数据绑定,MVVM.附上一段目录结构。 APP.vue 下面展示一些 内联代码片。 <template><div id="app"><keep-alive exclude