软件构造lab2

2021年春季学期
计算学部《软件构造》课程

Lab 2实验报告
 

姓名

麦昌瀚

学号

190110920

班号

7

电子邮件

835889372@qq.com

手机号码

19997980598

 

目录

1 实验目标概述··· 1

2 实验环境配置··· 1

3 实验过程··· 1

3.1 Poetic Walks· 1

3.1.1 Get the code and prepare Git repository· 1

3.1.2 Problem 1: Test Graph <String>· 1

3.1.3 Problem 2: Implement Graph <String>· 1

3.1.3.1 Implement ConcreteEdgesGraph· 2

3.1.3.2 Implement ConcreteVerticesGraph· 2

3.1.4 Problem 3: Implement generic Graph<L>· 2

3.1.4.1 Make the implementations generic· 2

3.1.4.2 Implement Graph.empty()· 2

3.1.5 Problem 4: Poetic walks· 2

3.1.5.1 Test GraphPoet· 2

3.1.5.2 Implement GraphPoet· 2

3.1.5.3 Graph poetry slam·· 2

3.1.6 使用Eclemma检查测试的代码覆盖度··· 2

3.1.7 Before you’re done· 2

3.2 Re-implement the Social Network in Lab1· 2

3.2.1 FriendshipGraph类··· 2

3.2.2 Person类··· 3

3.2.3 客户端main()· 3

3.2.4 测试用例··· 3

3.2.5 提交至Git仓库··· 3

4 实验进度记录··· 3

5 实验过程中遇到的困难与解决途径··· 3

6 实验过程中收获的经验、教训、感想··· 4

6.1 实验过程中收获的经验和教训··· 4

6.2 针对以下方面的感受··· 4

  1. 实验目标概述

本次实验训练抽象数据类型(ADT)的设计、规约、测试,并使用面向对象编程(OOP)技术实现ADT。具体来说:

  1. 针对给定的应用问题,从问题描述中识别所需的ADT;
  2. 设计ADT规约(pre-condition、post-condition)并评估规约的质量;
  3. 根据ADT的规约设计测试用例;
  4. ADT的泛型化;
  5. 根据规约设计ADT的多种不同的实现;针对每种实现,设计其表示(representation)、表示不变性(rep invariant)、抽象过程(abstraction function)
  6. 使用OOP实现ADT,并判定表示不变性是否违反、各实现是否存在表示泄露(rep exposure);
  7. 测试ADT的实现并评估测试的覆盖度;
  8. 使用ADT及其实现,为应用问题开发程序;
  9. 在测试代码中,能够写出testing strategy并据此设计测试用例。
  1. 实验环境配置

简要陈述你配置本次实验所需环境的过程,必要时可以给出屏幕截图。

特别是要记录配置过程中遇到的问题和困难,以及如何解决的。

本次实验要在eclipse中配置EclEmma,可以直接在eclipse中的市场中安装

在这里给出你的GitHub Lab2仓库的URL地址(Lab2-学号)。

https://github.com/ComputerScienceHIT/HIT-Lab2-190110920

  1. 实验过程

请仔细对照实验手册,针对三个问题中的每一项任务,在下面各节中记录你的实验过程、阐述你的设计思路和问题求解思路,可辅之以示意图或关键源代码加以说明(但千万不要把你的源代码全部粘贴过来!)。

    1. Poetic Walks

实现具有标记顶点的Graph并测试。然后实现一个使用单词的图生成诗歌的类

      1. Get the code and prepare Git repository

网址https://github.com/rainywang/Spring2020_HITCS_SC_Lab2/tree/master/P1

然后在gitbash直接执行

git clone https://github.com/rainywang/Spring2020_HITCS_SC_Lab2.git下载工程文件

然后打开自己本次实验github库的网址,在F盘中执行:

git clone https://github.com/ComputerScienceHIT/Lab2-190110920.git

      1. Problem 1: Test Graph <String>

思路:这是针对Graph<String>设计相应的测试策略,主要针对里面的每个方法进行等价类划分的测试。

testadd():测试是否能加入一个新的顶点,如果返回true则成功,如果返回false则没能加入。

testSet():加入一条新的边,测试返回值是否是0,如果是0则成功,反之失败。再继续向图中以一定权重加刚才加入的边,测试返回值是否是刚才的权重。最后以0权重加入这条边,判断是否存在边

testRemove():向图中加入一定的边,删除某顶点,测试被删除顶点的边是否依然存在

testVertices():向图中加入顶点测试集合是否正确

testSources():向图中加入顶点和边测试是否返回源头点和权重

testTargets():向图中加入顶点和边测试某个顶点相连是否正确

      1. Problem 2: Implement Graph <String>

以下各部分,请按照MIT页面上相应部分的要求,逐项列出你的设计和实现思路/过程/结果。

        1. Implement ConcreteEdgesGraph

1. 实现EDGE类:

(1).EDGE中的字段应该包括边的长度,边的起点和终点,所以定义私有类型的这些变量:

(2).在EDGE中需要实现的方法如下图所示:

Edge

初始化构造方法,初始化新边的两个点和边的权值

checkRep

检查表示不变性,边不为空且权值大于等于0

getsource

返回边的一个点source

gettarget

返回边的另外点target

getweight

返回边的weight

toString

返回一条边的字符串,形式为“起点->终点权重为xx”

(3).测试策略:

     测试终点的返回值

    public void testGetsource()

    测试源点的返回值

    public void testGettarget()

  

测试权值的返回值

public void testGetweight() {

2 实现ConcreteEdgesGraph类:

(1).ConcreteEdgesGraph的字段中应该包括顶点set表和边list表,定义私有类型的表如下图所示:

    (2).在ConcreteEdgesGraph中需要实现的方法如下图所示:

ConcreteEdgesGraph

构造方法

checkRep

检查表示不变性,edges长度是大于0的实数,有起始的节点

add

顶点不为空时,添加一个顶点进入点表中

set

输入source,target,weight,分别为边的起点、终点和权值。若权值为负,返回-1。若权值为正且新边已经存在,则除去原边并添加新边。若权值为正且新边不存在,则直接添加新边。若权值为0且新边已经存在,则出去原边。只要改变了原边权值,都返回原边权值,没有权值则返回0

remove

除去某个点及与它相邻的所有边。只需要遍历edges,寻找是否有边的起点或者终点为该点,直接删去即可,使用迭代器实现。

vertices

返回所有的点集

sources

输入一个终点,返回与它相连的所有边和起点构成的Map

targets

输入一个起点,返回与它相连的所有边和终点构成为的Map

toString

将整个图中所有点的指向转化为一条字符串输出

(3).AF,RI和Safety from rep exposure如下:

// Abstraction function:

    // AF(vertices)=图中的点

    // AF(edges)=图中的边

    // Representation invariant:

    // edges长度是大于0的实数,有起始的节点

    // vertex点必须包含在vertices中

    // 两个点之间最多只有一条边

    // Safety from rep exposure:

    // 将vertices和edges设置为private

    // 由于vertices和edges是mutable,所以在返回他们时进行了defensive copies

     (4).测试策略:

继承Graph的测试策略,只需要增加toString的测试

测试结果:

        1. Implement ConcreteVerticesGraph

1. 实现Vertices类:

(1).Vertices的字段中应当包括点的名字,点的源点表Map,点的终点表Map,定义私有类型的表如下图所示:

(2).在Vertices需要实现的方法如下图所示:

Vertex

初始化构造方法,用点的名字创建

checkRep

检查表示不变性,每个边的权值应该大于0

getmark

返回点的名字mark

getsource

返回能到达该点的所有点和边构成的Map

gettarget

返回某个点能到达的所有点和边构成的Map

addsource

在源点Map中加入某源点,若weight不为0,则将其加入source中(若源点已存在,则更新其weight并返回原weight,不存在则直接构建新点并返回0)。若weight为0,则移除源点(不存在返回0,存在返回原weight)

addtarget

在终点Map中加入某终点,若weight不为0,则将其加入target中(若终点已存在,则更新其weight并返回原weight,不存在则直接构建新点并返回0)。若weight为0,则移除终点(不存在返回0,存在返回原weight)

removesource

在源点表中删除某起始点,并返回旧的边长

removetarget

在终点表中删除某终点,并返回旧的边长

toString

得到一个点的字符串表示

(3).AF,RI和Safety from rep exposure如下

// Abstraction function:

// AF(vertices)={图中所有的vertices[i]|0<=i<vertices.sizes()}

// Representation invariant:

// vertices中不能有重复点

// Safety from rep exposure:

// 设置vertices为private

// 由于vertices是mutable,所以在返回他们时进行了defensive copies

(4).测试策略:

/* Testing strategy

     * 测试点的返回值

public void testGetmark()

    /* Testing strategy

     * 测试点的所有源点和边返回值

    public void testGetsource()

   

    /* Testing strategy

     * 测试点的所有终点和边返回值

    public void testGettarget()

   

    /* Testing strategy

     * 按照加入的点划分:点已经存在,点不存在

     * 按照加入的权值划分:权值为0,权值大于0,权值小于0

    public void testAddsource()

   

    /* Testing strategy

     * 按照加入的点划分:点已经存在,点不存在

     * 按照加入的权值划分:权值为0,权值大于0,权值小于0

    public void testAddtarget()

   

    /* Testing strategy

     * 按照移除的点划分:点已经存在,点不存在

    public void testRemovesource()

   

    /* Testing strategy

     * 按照移除的点划分:点已经存在,点不存在

    public void testRemovetarget()

.2 实现ConcreteVerticesGraph类:

(1).ConcreteVerticesGraph的字段为Vertex构成的List,定义私有类型的表如下图所示:

(2).在ConcreteVerticesGraph需要实现的方法如下图所示:

ConcreteVerticesGraph

构造方法

checkRep

检查表示不变性,vertices中不能有重复点

add

顶点不为空时,添加一个顶点进入点表中

set

输入source,target,weight,分别为边的起点、终点和权值。若权值为负,返回-1。若权值为正且新边已经存在,则除去原边并添加新边。若权值为正且新边不存在,则直接添加新边。若权值为0且新边已经存在,则出去原边。只要改变了原边权值,都返回原边权值,没有权值则返回0

remove

除去某个点及与它相邻的所有边。只需要遍历vertices,寻找是否有与待删除点相同的名字的点直接删去即可,如果名字不相同,则在该点的源点表和终点表中寻找删去即可,使用迭代器实现。

vertices

返回所有的点集

sources

输入一个终点,返回与它相连的所有边和起点构成的Map

targets

输入一个起点,返回与它相连的所有边和终点构成为的Map

toString

将整个图中所有点的指向转化为一条字符串输出

(3).AF,RI和Safety from rep exposure如下

// Abstraction function:

    // AF(vertices)={图中所有的vertices[i]|0<=i<vertices.sizes()}

    // Representation invariant:

    // vertices中不能有重复点

    // Safety from rep exposure:

    // 设置vertices为private

    // 由于vertices是mutable,所以在返回他们时进行了defensive copies

(4).测试策略:

继承Graph的测试策略,只需要增加toString的测试即可

结果:

      1. Problem 3: Implement generic Graph<L>
        1. Make the implementations generic

使用泛型实现

        1. Implement Graph.empty()

只需调用一个具体的实现:

补充测试策略:

结果:

      1. Problem 4: Poetic walks

任务要求我们实现一个类,利用之前实现的图结构,能够将语料库转化为该种图结构,并且在图中搜索,完成对输入的诗句的句子进行扩充。

        1. Test GraphPoet

测试策略:具体实现读入一系列满足要求的文件

/* Testing strategy

     * 按需要读入的文件划分:空文件,一行输入,多行输入

    public void testGraphPoet() throws IOException{

     final GraphPoet nimoy = new GraphPoet(new File("test/P1/poet/empty.txt"));

         final String input = "Test the system.";

         assertEquals("Test the system.",nimoy.poem(input));

         final GraphPoet nimoy1 = new GraphPoet(new File("test/P1/poet/oneline.txt"));

         final String input1 = "Test the system.";

        。。。。。。

   

    /* Testing strategy

     * 按图中边权值划分:权值全为1,两点之间权值有不为1且有几条边

     * 覆盖每个取值如下:

    public void testPoem() throws IOException

     

    /* Testing strategy

     * 按需要读入的文件划分:空文件,不是空文件

     * 覆盖每个取值如下:

public void testtoString() throws IOException

结果:

Implement GraphPoet

        1. Graph poetry slam

(1). GraphPoet的字段为String构成的Graph,定义私有类型的表如下图所示:

(2). AF,RI和Safety from rep exposure如下图:

(3).在GraphPoet中需要实现的方法如下图所示:

GraphPoet

输入文件的路径,一行一行读入,储存在List中,然后每次取相邻的元素,在图中添加新的边

checkRep

检查不变性,必须保存从语料库文件生成的图

poem

输入需要进行扩充的字符串,声明声明一个StringBuilder保存,每次读取一个词,当前词作为source,下一个词作为target,然后在garph中寻找source的终点表中是否有与target的源点表中相同的元素,并且找到权值最大的和的点加入source和target之间

toString

调用ConcreteEdgesGraph中的toString方法,将整个图中所有点的指向转化为一条字符串输出

      1. 使用Eclemma检查测试的代码覆盖度

      1. Before you’re done

通过Git提交当前版本到GitHub上你的Lab2仓库:

Git add

Git commit -m “xxxx”

Git push origin master

项目的目录结构:

    1. Re-implement the Social Network in Lab1

这次实验要求我们基于Poetic Walks中定义的Graph<L>及其两种实现(本人使用的是ConcreteVerticesGraph<L>),实现Lab1中Social NetWorek中的各种功能,并且尽可能复用ConcreteVerticesGraph<L>中已经实现的方法,然后运行提供的main()和执行Lab1中的Junit测试用例,使之正常运行。

      1. FriendshipGraph

(1).FriendshipGraph的字段为Person构成的ConcreteEdgesGraph,定义私有类型的表如下图所示:

(2).在FriendshipGraph需要实现的方法如下图所示:

FriendshipGraph

构造方法

addVertex

在图中增加新Person,只需要调用ConcreteEdgesGraph中的add即可:

addEdge

为某个人增加朋友,a为这个人,b为增加的朋友,直接调用ConcreteEdgesGraph中的set即可:

getallprople

直接返回即可:

getDistance

得到两个人之间的最短距离。与Lab1类似,稍加修改即可:

实现此功能我们需要了解先广方式求最短路径的方法。首先我们需要知道若两个Person对象为同一个,则返回0。然后定义一个Map集合theway和一个Person队列myqueue,队列myqueue用来储存广搜的遍历结果,theway的Map集合用来储存广搜的所有元素及他们与第一个元素的距离。具体实现方法为首先将第一个元素c1入队,并且把第一个元素c1和下标0入集合,当队列非空时,弹出队首元素top,并且得到top在集合theway中的下标distance,然后定义一个Map为friend,执行personGraph.targets(top)得到队首元素的所有朋友的Map,然后定义Set为allfriend,对刚才的friend执行keySet()得到allfriend,只要allfriend中的元素与c2不同,就把这些元素全部入队,并且把这些元素及下标distance+1放入集合。只要队列非空,继续执行以上步骤,直到找到某个元素与c2相同并且返回这个元素在集合theway中的下标。如果直到队列为空还没找到c2,则返回-1

main

复制Lab1的即可

      1. Person类

(1).FriendshipGraph的字段为Person构成的ConcreteEdgesGraph,定义私有类型的表如下图所示:

(2).在FriendshipGraph需要实现的方法如下图所示:

Person

没有重复名字则加入,构造方法

getmyname

返回本人名字,直接返回即可

      1. 客户端main()

按照Lab1中的main复制过来即可

      1. 测试用例

     * Testing strategy

     * 创建对象:创建四个对象即可

    public void addVertextest() {

       

    /*

     * Testing strategy

     * 加入无向图朋友:只需要任取两组点都加入朋友即可

    public void addEdgetest() {

       

    /*

     * Testing strategy

     * 按照两个人之间的距离划分:距离为0,距离为-1,距离为大于1

     * 按照是否同一个人划分:同一个人之间距离,两个人之间距离

     * 覆盖每个取值如下:

    public void getDistancetest()

   

    /*

     * Testing strategy

     * 看返回的personGraph是否包含所有图中的元素即可

    public void getallpropletest()

   

      1. }提交至Git仓库

git add . lab2-190110920

git commit -m “P2”

git push origin master

目录结构:

  1. 实验进度记录

请使用表格方式记录你的进度情况,以超过半小时的连续编程时间为一行。

每次结束编程时,请向该表格中增加一行。不要事后胡乱填写。

不要嫌烦,该表格可帮助你汇总你在每个任务上付出的时间和精力,发现自己不擅长的任务,后续有意识的弥补。

日期

时间段

计划任务

实际完成情况

5.30

18:00-22:00

P1中边图类

完成

6.2

16:00-22:30

P1点图类

未完成

6.3

19:00-23:00

P1点图类

完成

6.9

18:00-22:30

P1中的诗集类

完成

6.10

19:00-22:30

P1中点图和边图的test

完成

6.11

17:50-19:20

写部分报告

完成

6.12

9:00-10:30

P1所有测试

完成

6.13

9:00-15:00

P2及测试

完成

6.13

19:00-24:00

写后续报告

完成

  1. 实验过程中遇到的困难与解决途径

遇到的难点

解决途径

不是非常理解泛型

查找资料

  1. 实验过程中收获的经验、教训、感想
    1. 实验过程中收获的经验和教训

在自行设计多种类来实现功能的情况下,自己设计的很多类之间有很多重复和矛盾的部分,很多关系弄不清楚,代码很冗杂,测试起来也较麻烦。对于java还是不够熟练,需要多加练习

    1. 针对以下方面的感受
  1. 面向ADT的编程和直接面向应用场景编程,你体会到二者有何差异?

答:面向对象与面向过程的编程的思路完全不同。

  1. 使用泛型和不使用泛型的编程,对你来说有何差异?

答:泛型更加灵活。

  1. 在给出ADT的规约后就开始编写测试用例,优势是什么?你是否能够适应这种测试方式?

答:能够及时修改。不适应。

  1. P1设计的ADT在多个应用场景下使用,这种复用带来什么好处?

答:可以提高代码的利用率,减少重复。

  1. P3要求你从0开始设计ADT并使用它们完成一个具体应用,你是否已适应从具体应用场景到ADT的“抽象映射”?相比起P1给出了ADT非常明确的rep和方法、ADT之间的逻辑关系,P3要求你自主设计这些内容,你的感受如何?

答:很多方法用的很繁琐,并且很多类很重复,一些功能没有用到。

  1. 为ADT撰写specification, invariants, RI, AF,时刻注意ADT是否有rep exposure,这些工作的意义是什么?你是否愿意在以后编程中坚持这么做?

答:防止内部变量被外部修改。很繁琐。

  1. 关于本实验的工作量、难度、deadline。

答:工作量很大,写测试也用很多时间,报告的内容太多,deadline不合适。

  1. 《软件构造》课程进展到目前,你对该课程有何体会和建议?

希望减少英文,增加中文指导的使用。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: RT-LAB软件是一个实时仿真平台,用于开发和测试各种电力系统和控制系统。RT-LAB软件培训旨在帮助个人和团队掌握使用该平台进行仿真和实时测试的技能。 RT-LAB软件培训涵盖了从基础知识到高级技术的全面内容。首先,培训将介绍RT-LAB软件的基本原理和功能,包括其架构、界面和主要工具。参与者将了解如何在软件中创建模型、配置仿真参数和观察仿真结果。 在培训的进一步阶段,参与者将深入学习RT-LAB软件的高级功能,如实时系统建模和控制算法设计。培训还将介绍如何使用RT-LAB软件进行硬件在环仿真,将虚拟模型与实际硬件进行连接和测试。 培训期间,参与者将有机会通过实际案例和实践项目来应用所学知识。他们将学习如何使用RT-LAB软件解决电力系统和控制系统的实际问题,并进一步优化系统性能。 RT-LAB软件培训还提供了与专业导师和其他参与者进行交流和讨论的机会。参与者可以分享经验、学习最佳实践,并获取来自行业专家的指导。 通过参加RT-LAB软件培训,个人和团队可以充分利用该软件平台的优势,提高仿真和测试的效率和准确性。这将有助于加快产品开发和测试周期,并为电力系统和控制系统的设计和优化提供更好的支持。 ### 回答2: RT-LAB 是一种实时仿真软件平台,广泛应用于电力系统、机械系统、汽车系统和航空航天等领域的研究和开发中。对于那些需要进行实时仿真和控制系统开发的工程师和科研人员来说,接受RT-LAB软件培训是非常有益和必要的。 RT-LAB软件培训可以帮助学员掌握RT-LAB软件的基本原理和使用方法。培训内容通常包括软件架构、建模和仿真技术、实时控制算法的设计和实现以及硬件接口和数据采集等方面的知识。学员将通过理论讲解和实际操作来学习和运用软件的各种功能和工具。 参加RT-LAB软件培训的好处有很多。首先,培训可以帮助学员快速上手并熟练使用RT-LAB软件,提升工作效率。其次,培训可以帮助学员深入了解软件的各项功能和应用场景,从而更好地应用于实际工程项目中。另外,培训还可以提供实时仿真和控制系统设计的相关知识和技巧,为学员在相关领域的研究和开发中提供支持和指导。此外,培训还可以帮助学员建立良好的团队合作和沟通能力,与其他专业人员进行有效的合作和交流。 总之,RT-LAB软件培训对于想要在实时仿真和控制系统开发领域有所建树的工程师和科研人员来说是非常重要的。通过培训,学员可以快速掌握软件的使用方法,提升工作效率并应用于实际工程项目中。同时,培训还可以提供相关知识和技巧,帮助学员在研究和开发中取得更好的成果。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值