题目集4~6的总结^_^
一.前言
这三次大作业,有一个是答题判题程序的最后一个大题,还有两个分别是家居强电电路模拟程序第一次与第二次大题,也许是吸取了前三次大题的设计与测试的各种教训,虽然不能说这三次的设计与编程十分的轻松顺利,但是至少我已经有了足够的信心去面对我所遇到的困难,所以这三次的做题过程相对于前三次来说要更加的从容,更加得心应手。
首先对于答题判题程序-4,我认为主要考察的知识点还是是字符串匹配,需要用到正则表达式,除此外还涉及到继承的设计,因为此次新加的两个内容需要继承于题目类,所以此次题目的题量相对于答题判题程序-3来说又提升了一个层次,但是我认为在设计难度上并没有增加太大的难度。
其次对于家居强电电路模拟程序-1,这次题目作为一个题目集的开始,我认为主要考察的知识点是继承与多态,不同于之前的题目,此次题目对格式要求不多,所以不太需要使用到正则表达式,但是用正则表达式也有助于提取重要的信息,所以我在此次作业中也使用到了。作为题目1,其题目量不大,主要考察的是如何合理设计设备的父类与子类,需要考虑到有什么属性与方法,而且这次题目只考虑一条串联电路,同时还需要为下一次的题目设计做铺垫,因为有很多次迭代,所以并没有太大的难度。
对于家居强电电路模拟程序-2,我认为主要考察的知识点还是继承与多态,但不同于家居强电电路模拟程序-1,这一次的设计考虑到了电路设计,不但需要设计串联电路,还需要设计并联电路,并且需要考虑两者之间的几种搭配,所以这一次的题量相对于上一次来说提升了不少,所以我这次单设计就花了两天的时间,调试又花了一天,对于这次题目的设计我主要是通过在草稿纸上模拟所有存在的情况,并且考虑到各种设备与各种电路搭配的情况,所以此次题目难度相对于第一次来说提升了不少。
二.设计与分析、踩坑心得、改进建议
一:答题判题程序-4:
设计与分析:
  这道题的设计是建立在答题判题程序-3的基础上,有题目类、试卷类、答卷类、学生类、系统类,同时又新加了两个类,分别是选择题类和填空题类,都继承于题目类。
  由于这次的设计基于答题判题程序-3,所以这里只详细介绍新添加的选择题类与填空题类。
1.选择题类Choose_Question:
属性(由于其继承于题目类,所以题目类的所有属性与方法选择题类都具备,这里只介绍该类特有的属性与方法):
存储正确答案的集合correctAnswers(Set类型)
存储作答答案的集合userAnswers(Set类型)
方法:
方法一:对选择题进行批改()
(将集合correctAnswers与集合userAnswers中的内容进行比对。
答案包含所有正确答案且不含错误答案给满分;
包含一个错误答案或完全没有答案给0分;
包含部分正确答案且不含错误答案给一半分;)
这里展示详细代码:
点击查看代码
public int checkAnswer_Choose() {//对选择题进行批改
        if (this.userAnswers.equals(this.correctAnswers)) {
            return 1;  // 用户答案和正确答案完全一致
        } else if (this.correctAnswers.containsAll(this.userAnswers) && !this.userAnswers.isEmpty()) {
            return 2;  // 用户答案是正确答案的子集,且不为空
        } else {
            return 0;  // 含有错误答案或完全没有作答
        }
    }
方法二:输出题目得分情况()
(该方法就是根据每道选择题的得分情况进行相应的输出,该方法使用到了方法一。这段代码隐藏了一个非常难找的测试点,后续再详细解释)
这里展示详细代码:
点击查看代码
 public void output_score(String answer){
        switch (this.checkAnswer_Choose()) {
            case 0:
                System.out.println(this.getQuestionContent() + "~" + answer.trim() + "~false");//输出
                break;
            case 1:
                System.out.println(this.getQuestionContent() + "~" + answer.trim() + "~true");//输出
                break;
            case 2:
                System.out.println(this.getQuestionContent() + "~" + answer.trim() + "~partially correct");//输出
                break;
        }
    }
方法三:判断多选题得分情况(作答答案,该题分值)
(将写入的答案与标准答案对比,并返回该题得到的最终分值)
这里展示详细代码:
点击查看代码
//判断多选题得分情况
    public int get_Score_Question(String answer , int score){
        int end_score=-1 ;
        String[] parts1 = this.StandardAnswer.trim().split(" ");
        this.correctAnswers.addAll(Arrays.asList(parts1));
        String[] parts2 = answer.trim().split(" ");
        this.userAnswers.addAll(Arrays.asList(parts2));
        switch (this.checkAnswer_Choose()) {
            case 0:
                end_score=0;
                break;
            case 1:
                end_score=score;
                break;
            case 2:
                end_score=(int)(score/2);
                break;
        }
        return end_score;
    }
2.填空题类Gap_Question:
属性(由于其继承于题目类,所以题目类的所有属性与方法选择题类都具备,这里只介绍该类特有的属性与方法):
存储正确答案的集合correctAnswers(Set类型)
存储作答答案的集合userAnswers(Set类型)
方法:(这个类的所有方法与选择题类基本一致,这里只展示判断多选题得分情况方法。)
判断多选题得分情况(作答答案,该题分值)
(将写入的答案与标准答案对比,并返回该题得到的最终分值)
这里展示详细代码:
点击查看代码
public int get_Score_Question(String answer, int score){
        int end_score=-1 ;
        switch (this.checkAnswer_Gap(answer)) {
            case 0:
                end_score=0;
                break;
            case 1:
                end_score=score;
                break;
            case 2:
                end_score=(int)(score/2);
                break;
        }
        return end_score;
    }
}
类图的设计:
  此次类图的设计与上次几乎一致,多了两个类继承于题目类,这里只展示继承类的类图:
  填空题类与选择题类都继承于题目类,且两个类都对题目类的方法进行了重写,这使得当系统类在对题目集合中的题目进行判分和输出时,不需要考虑类的不同,直接调用类的对象的方法,这实现了面向对象语言的多态性。

  踩坑心得:
  其实这一次的作业我没有碰到过在答题判题程序-3碰到的那么多的问题,在程序-3中主要是有很多隐藏的输出格式上的测试点,所以去一个一个寻找的时候非常困难,所以在课后我也花了大量的时间去不断修改自己的代码,去寻找那些测试点,好在最后都通过了,而且这次的设计又是在上一次作业的基础上,所以没有踩到太多的坑,第一次提交就几乎得到了满分,唯一才到的坑就是最后一个测试点。
第一次提交:

  这个测试点卡了我很久很久,我改了很多很多代码都没有通过这个测试点,所以后面我就放弃了一段时间,在作业截至前的一天,我询问了碰到相同情况同学,询问他们是怎么通过的,我连着问了两个,但是他们给我的方法各不相同,而且我也按照他们的方法分别改代码,还是没有通过。
  第一个同学告诉我应该将填空题的答案按或字分割。
  第二个同学告诉我应该选在择题答案输出时保留最后一个空格前所有的空格。
  在按照第二个同学告诉我的方法改代码时,我在处理答卷信息的方法中,去除了处理作答答案字符串去除首尾空格的方法,结果惊奇的发现,我的最后一个测试点对了,但第一个测试点错了,也就是第一个测试样例不通过。
修改的地方:

修改之后的提交结果:

之后我就一直抱着试一试的心态,只专注于修改代码能够通过测试样例1。
修改前的测试样例与结果:

这里发现的问题是,我运行的结果中输出答案部分为A C ,没有把末尾的空格去除,而标准答案中去除了,所以我抱着试一试的心态,找到选择题输出题目得分情况的方法,去除输出答案的首尾空格。
修改的地方:

修改后的测试样例与结果:

之后再提交:

发现已经满分了,对于这一次的测试之旅,我表示非常的离谱,感觉像个无头苍蝇一样,撞着撞着就满分了。
  改进建议:
  我认为这一次需要改进的地方主要是在继承类的设计上,这一次作业中我分别设计了填空题类和选择题类继承于题目类,但是作为父类的题目类我没有抽象它,我认为我应该将提取三个类中相同的属性与方法,然后设计一个抽象类,之后再设计三个类继承与它,这样就更加符合面向对象设计中的各种设计原则。
二:家居强电电路模拟程序-1:
  设计与分析:
  这道题是一个新的题目类型的开始,在吸取了上一次题目类型的教训后,这次题目我花了更多的时间,并更加注重于设计方面,因为我认为只有在良好的设计基础上,才能够顺利的编程和调试。
  这一次我根据题目首先设计了两个基类,分别为设备类和电路类,再设计其他的子类。
  这里用一个简单的流程图来表示我的继承设计:

这里我并没有按老师的要求来设计,因为我觉得对于这一次作业来说,电路类可以不用看作一个设备,所以我就设计了两个基类。
1.设备类Device(抽象类):
属性:
设备编号id(String类型)
输入引脚(double类型)
输出引脚(double类型)
设备电压差(double类型)
方法:
除了一些基本的set、get方法外,有两个比较重要的抽象方法。
方法一(抽象方法,没有实体):
更新设备状态updateDevice(设备电压差)
(当设备得到分压后,根据自身的机制去调节设备状态)
方法二(抽象方法,没有实体):
获取设备状态getStatus()
(获取当前设备的状态,如开关状态、调速器挡位、灯光亮度等)
2.控制设备类Control_Device(抽象类):
属性:无特有属性,继承了设备类的所有属性。
方法:除了构造方法无特有方法,也是继承了设备类的所有方法。
3.受控设备类Controlled_Device(抽象类):
属性:无特有属性,继承了设备类的所有属性。
方法:除了构造方法无特有方法,也是继承了设备类的所有方法。
4.开关类Switch
属性:(这里只详细介绍该类特有的属性与方法,下面介绍其他类时相同)
开关状态state(boolean类型)
方法:
方法一:翻转开关状态toggle()
(开关为开时,翻转为关,为关时,翻转为开)
方法二(重写):更新设备状态updateDevice(分压值)
(开关状态为关则输出引脚电压为0,为开,则输出引脚电压为分压值)   
这里展示详细代码:
点击查看代码
 public void updateDevice(double inputVoltage) {//
        this.pin_Out = this.state ? (int) inputVoltage : 0;
    }
方法三(重写):获取设备状态getStatus()
(根据开关的状态输出相应的提示)
这里不展示详细代码。
5.调速器类Governor(抽象类):
属性:
挡位Level(double类型)
方法:除了构造方法无特有方法。
6.分档调速器类Grade_Governor:
属性:
设定挡位LEVELS(double[]类型,默认为四个挡位:0.0, 0.3, 0.6, 0.9)
方法:
方法一:加挡或减档increaseLevel()/decreaseLevel()
这里不展示详细代码。
方法二(重写):更新设备状态updateDevice(分压值)
(将输出引脚电压设为分压乘以挡位)
这里不展示详细代码。
方法三(重写):获取设备状态getStatus()
(获取分档调速器的挡位值)
这里不展示详细代码。
7.连续调速器类Continuous_Governor:
属性:无特有属性。
  
方法:
方法一:设置挡位(输入的挡位值,范围从0到1)
(将该调速器的挡位设为输入的挡位)
这里不展示详细代码。
  方法二(重写):更新设备状态updateDevice(分压值)
(将输出引脚电压设为分压乘以挡位)
这里不展示详细代码。
  方法三(重写):获取设备状态getStatus()
(获取分档调速器的挡位值)
这里不展示详细代码。
8.受控设备类Controlled_Device(抽象类):
属性:无特有属性,继承了设备类的所有属性。
方法:除了构造方法无特有方法,也是继承了设备类的所有方法。
9.灯类Lamp(抽象类)
属性:
灯的亮度brightness(double类型)
方法:除了构造方法无特有方法。
10.日光灯类DayLight_Lamp
属性:无特有属性。
方法:
方法一(重写):更新设备状态updateDevice(分压值)
(只要分压值大于0,则亮度为180,否则为0)
这里不展示详细代码。
方法二(重写):获取设备状态getStatus()
(获取日光灯的光照强度状态)
这里不展示详细代码。
11.白炽灯类Incandescent_Lamp
属性:无特有属性。
方法:
方法一(重写):更新设备状态updateDevice(分压值)
(按分压的比例来调节光强状态)
这里不展示详细代码。
方法二(重写):获取设备状态getStatus()
(获取白炽灯的光照强度状态)
这里不展示详细代码。
12.吊扇类Ceiling_Fan
属性:
风扇转速speed(double类型)
方法:
方法一(重写):更新设备状态updateDevice(分压值)
(按分压的比例来调节风扇转速状态)
这里不展示详细代码。
方法二(重写):获取设备状态getStatus()
(获取吊扇的风扇转速状态)
这里不展示详细代码。
13.电路类Circuit(抽象类)
(这一次作业设计该类是为了给下一次作业做铺垫,所以这次作业没有具体设计该类,留到下一次作业具体设计)
属性:无特有属性。
方法:无特有方法
14.串联电路类series_Circuit
属性:
存放设备列表devices(Map类型)
存放连接信息列表connections(List类型)
方法:
方法一:按设备的种类创建并存放设备addDevice(设备id)
这里展示详细代码:
点击查看代码
public void addDevice(String id) {
        switch (id.charAt(0)){
            case 'K':
                this.devices.put(id, new Switch(id));
                break;
            case 'F':
                this.devices.put(id, new Grade_Governor(id));
                break;
            case 'L':
                this.devices.put(id, new Continuous_Governor(id));
                break;
            case 'R':
                this.devices.put(id, new DayLight_Lamp(id));
                break;
            case 'B':
                this.devices.put(id, new Incandescent_Lamp(id));
                break;
            case 'D':
                this.devices.put(id, new Ceiling_Fan(id));
                break;
        }
    }
方法二:存放设备连接信息Connections(连接信息)
这里不展示详细代码。
方法三:传输分压trans_voltage()
(确保电路中所有开关闭合后,给电路中的设备分配电压)
这里展示详细代码:
点击查看代码
public void trans_voltage(){
        List<Switch> list = new ArrayList<>();
        boolean temp = true;
        for (Device device:this.devices.values()) {
            if(device.getId().startsWith("K")){
                list.add((Switch) device);
            }
        }
        for (Switch aswitch:list) {
            if(aswitch.getStatus().equals("turned on")){
                temp=false;
                break;
            }
        }
        if (temp) {
            for (String connect : this.connections) {
                String[] parts = connect.trim().split(" ");
                if (parts[0].equals("VCC")) {
                    if (devices.containsKey(parts[1].split("-")[0])) {
                        String id = parts[1].split("-")[0];
                        this.devices.get(id).setPin_In(220);
                        this.devices.get(id).updateDevice(this.devices.get(id).getPin_In());
                    }
                } else {
                    if (parts[1].equals("GND")) {
                        if (devices.containsKey(parts[0].split("-")[0])) {
                            devices.get(parts[0].split("-")[0]).setPin_Out(0);
                        }
                    } else {
                        if (devices.containsKey(parts[0].split("-")[0])) {
                            if (devices.containsKey(parts[1].split("-")[0])) {
                                devices.get(parts[1].split("-")[0]).setPin_In(devices.get(parts[0].split("-")[0]).getPin_Out());
                                this.devices.get(parts[1].split("-")[0]).updateDevice(this.devices.get(parts[1].split("-")[0]).getPin_In());
                            }
                        }
                    }
                }
            }
        }
    }
方法四:执行命令executeCommand(命令)
(根据对控制设备的调节命令,执行相应的功能)
这里展示详细代码:
点击查看代码
public void executeCommand(String command) {//执行命令
        Pattern pattern;
        Matcher matcher;
        pattern = Pattern.compile("#(K\\w+)");
        matcher = pattern.matcher(command);
        if (matcher.matches()) {
            String id = matcher.group(1);
            if (devices.containsKey(id) && devices.get(id) instanceof Switch) {
                ((Switch) devices.get(id)).toggle();
            }
            return;
        }
        pattern = Pattern.compile("#(F\\w+)(\\+|-)");
        matcher = pattern.matcher(command);
        if (matcher.matches()) {
            String id = matcher.group(1);
            if (devices.containsKey(id) &&devices.get(id) instanceof Grade_Governor) {
                if (matcher.group(2).equals("+")) {
                    ((Grade_Governor) devices.get(id)).increaseLevel();
                } else {
                    ((Grade_Governor) devices.get(id)).decreaseLevel();
                }
            }
            return;
        }
        pattern = Pattern.compile("#(L\\w+):([01]+(\\.\\d{2}))");
        matcher = pattern.matcher(command);
        if (matcher.matches()) {
            String id = matcher.group(1);
            double level = Double.parseDouble(matcher.group(2));
            if (devices.containsKey(id) && devices.get(id) instanceof Continuous_Governor ) {
                ((Continuous_Governor) devices.get(id)).setLevel(level);
            }
        }
    }
方法五:展示所有设备状态showDeviceStatuses()
(输出每一个设备的状态)
这里不展示详细代码
以上便是所有类的详细设计。
类图设计:(这一次老师也提前布置了自己设计类图和顺序图的作业,这里详细展示)
从我设计的类图可以看出,我的设计思路是,电路类对象中会存在大量的设备类对象,所以对象类与设备类的关系为聚合关系。

  踩坑心得
  由于是新题目集的第一次大作业,而且主要考察的是设计的合理性,所以难度不大,并没有太多的踩坑。
  第一次提交就已经得到了71分:

  这里可以看到还是有4个测试点未通过,前三个是受控设备单独存在于电路中。
所以这里引用测试样例(电路中只存在吊扇设备):
[VCC D2-1]
[D2-2 GND]
end
错误输出结果:
@D2:0
正常输出:
@D2:360
然后我进行调试,发现以下问题:

传输电压的方法存在于执行命令的判断语句中,这便会导致一种问题,如果电路中不存在控制设备,也就是说不存在开关或者调速器,那么就不会执行类似于#K、#F+之类的命令,那么就不会传输电压,所以受控设备单独存在时,它的状态一定为0。
修改之后的输出结果:

重新提交:

发现只剩一个测试点了。
  这个测试点是未考虑电路中存在多个开关的情况,当电路中存在两个及两个以上的开关时,需要考虑当所有的开关闭合后才能传输电压的情况,所以在传输电压的方法中需要先判断电路中所有的开关是否都已经闭合。
测试样例:
[VCC K1-1]
[K1-2 D2-1]
[D2-2 K2-1]
[K2-2 GND]
#K1
end
错误输出结果:
@K1:closed
@K2:turned on
@D2:360
这里发现,电路中明明只有一个开关闭合,但另一个开关是断开的,所以吊扇按理是没有分压的,所以他的转速应该为0。
在传输电压方法添加开关判断部分:
点击查看代码
List<Switch> list = new ArrayList<>();
        boolean temp = true;
        for (Device device:this.devices.values()) {
            if(device.getId().startsWith("K")){
                list.add((Switch) device);
            }
        }
        for (Switch aswitch:list) {
            if(aswitch.getStatus().equals("turned on")){
                temp=false;
                break;
            }
        }
添加后输出结果:
@K1:closed
@K2:turned on
@D2:0
最终提交结果:

  改进建议:
  我认为这次作业我的设计可以改进的地方有两点,第一点就是在我的主函数中,存放了较多的代码,这也是我之前也经常犯的一个错误,这是有违面向对象语言设计的原则的,所以在下一次作业的设计中我也将会设计一个系统类,专门处理输入与输出信息,第二点就是在有的方法中存在较多的if else语句,使得方法的圈复杂度较高,所以在接下来的设计中我也会将单个方法中的多个判断语句分组打包成一个小的方法,从而降低圈复杂度,使得我的设计更加合理。
一:家居强电电路模拟程序-2:
  设计与分析:
  这一次的设计是建立在家居强电电路模拟程序-1的基础上,这次题目新加入了一个并联电路,并新加入了一个新设备(落地扇),同时至此题目给每一个设备赋予了一个新的属性(电阻)。
  设备类的对象可以抽象理解为直接接在电路上,加入了并联电路后,就相当于一条大的串联电路上不但有各种设备,还有可能接入一个并联电路,而并联电路中又可能存在多个串联电路,一开始我的想法还是将设备类与电路类分隔开,他们只存在组合的关系,即电路类对象中存在设备类对象列表,但这样就会存在一个问题:在传输电压的方法中,无法将并联电路看作一个设备类对象来处理,这使得处理更加困难
  所以在这一次作业中我将电路类继承设备类,下面我也用一个简单的流程图来展示我的继承设计:

由于这一次作业的设计是在模拟程序-1的基础上,这里只详细介绍相对于上一次作业改变了的或者新添加的设计的地方:
1.设备类Device(抽象类)
属性(这里只展示新添加的属性):
设备电阻resistance(double类型)
方法(这里只展示新添加的方法):
计算分压calculate_Voltage(所获电流)
(将电流与该设备的电阻相乘,所得结果为该设备分压值)
这里不展示详细代码。
2.风扇类Fan(抽象类)
属性:风扇转速speed(double类型)
方法:获取设备状态getStatus()
这里不展示详细代码。
3.落地扇类Standing_Fan
属性:无特有方法
方法:更新设备状态updateDevice()
4.电路类Circuit(抽象类)
属性(这里只展示新添加的属性):
电路电流electricity(double类型)
方法(这里只展示新添加的方法):
方法一(抽象方法):集合电路中所有的设备gather_Devices()
方法二(抽象方法):添加电路连接信息addConnections(连接信息)
方法三(抽象方法):计算电路总电阻calculate_allResistances()
方法四(抽象方法):电路传输电压trans_voltage(输入电压,输出电压)
方法五:返回电路设备列表get_Devices()
这里不展示详代码。
5.串联电路类Series_Circuits
属性:无特有属性。
方法(这里只展示新添加的方法):
方法一:集合串联电路中的所有设备gather_Devices()
这里展示详细代码:
点击查看代码
public void gather_Devices(){
        for (String str:this.Connections) {
            if(!str.split(" ")[1].equals("OUT")) {
                this.addDevice(str.split(" ")[1].split("-")[0]);
            }
        }
    }
方法二:计算一条串联电路的总电阻calculate_allResistances()
这里不展示详细代码。
方法三:判断串联电路中的所有开关是否全部关闭if_allSwitch_closed()
这里展示详细代码:
点击查看代码
public boolean if_allSwitch_closed(){
        List<Switch> list = new ArrayList<>();
        boolean temp = true;
        for (Device device:this.devices.values()) {
            if(device.getId().startsWith("K")){
                list.add((Switch) device);
            }
        }
        for (Switch aswitch:list) {
            if(aswitch.getStatus().equals("turned on")){
                temp=false;
                break;
            }
        }
        return temp;
    }
6.并联电路类Multiple_Circuit
属性(这里只展示特有属性):
存放串联电路列表series_Circuits(Map类型)
方法(这里只详细介绍重要方法):
方法一:判断并联电路所有开关是否都断开if_allSwitch_open()
这里展示详细代码:
点击查看代码
public boolean if_allSwitch_open(){
        boolean temp = true;
        for (Series_Circuits circuit:this.series_Circuits.values()) {
            if(circuit.if_allSwitch_closed())
                temp = false;
        }
        return temp;
    }
方法二:传输电压trans_voltage(输入电压。输出电压)
(先判断每条串联电路中的所有开关是否闭合,若未闭合则不考虑传输,否则正常传输电压)
这里展示详细代码:
点击查看代码
public void trans_voltage(double input_voltage,double output_voltage){
        this.setPin_In(input_voltage);
        this.setPin_Out(output_voltage);
        for (Series_Circuits circuit:this.series_Circuits.values()) {
            circuit.trans_voltage(input_voltage,output_voltage);
        }
    }
7.复合电路类Compound_Circuit
属性(这里只展示特有属性):
并联电路multiple_circuit(Multiple_Circuit类型)
(这次的大作业每个复合电路中只有一个并联电路,所以这里直接将其作为属性)
存放除并联电路外的所有设备类对象列表devices_parts(Map类型)
方法(这里只详细介绍重要方法):
方法一:计算电路电阻calculate_allResistances()
(这里虽然并联电路类继承于设备类,但是并联电路中包括许多设备,这里区分计算)
这里展示详细代码:
点击查看代码
public void calculate_allResistances(){
        for (Device device:this.devices_parts.values()) {
            if(device.getId().charAt(0)=='M') {
                Multiple_Circuit circuit = (Multiple_Circuit)device;
                circuit.calculate_allResistances();
            }
            this.resistance+=device.getResistance();
        }
    }
方法二:判断复合电路中所有开关是否闭合if_allSwitch_closed()
(这里不但要考虑并联电路中是否存在通路,还要考虑除并联电路之外所有的开关是否闭合)
这里展示详细代码:
点击查看代码
public boolean if_allSwitch_closed(){
        List<Switch> list = new ArrayList<>();
        boolean temp = true;
        for (Device device:this.devices_parts.values()) {
            if(device.getId().startsWith("K")){
                list.add((Switch) device);
            }
        }
        for (Switch aswitch:list) {
            if(aswitch.getStatus().equals("turned on")){
                temp=false;
                break;
            }
        }
        if(this.multiple_circuit!=null) {
            if (this.multiple_circuit.if_allSwitch_open())
                temp = false;
        }
        return temp;
    }
8.处理系统类Center_System
属性:
存放输入的串联电路列表series_circuitsList(List类)
输入的并联电路类multiple_circuit(Multiple_Circuit类)
输入的复合电路类compound_circuit(Compound_Circuit类)
方法:
方法一:输入处理input()
(主要是对输入的所有信息进行处理)
这里不展示详细代码。
方法二:输出处理output()
(输出执行命令后所有的设备状态值)
这里不展示详细代码。
类图设计:这次的类图设计较为复杂,图片无法清晰的显示,这里就不详细展示了。
  踩坑心得
  这次的调试之旅可以说是非常艰难,因为老师没有给出具体的测试样例提示,所以需要自己不断摸索。
第一次提交只得了42分:

先不关注后面的测试点,这里的测试点显示非零返回,于是我就测试了一下,复合电路不存在并联电路的情况,只存在各种设备。
输入样例:
#T3:[VCC K1-1] [K1-2 D3-1] [D3-2 GND]
#K1
end
输出显示我非零返回,于是我重新改代码,考虑了当复合电路不存在并联电路的情况。
正确输出:
@K1:closed
@D3:360
这一次提交结果:


发现非零返回测试点全部通过,但是下面的很多测试点还没通过,然后!!我就在这个分数卡了好久,后来我去查阅资料,也看了之前同学的博客,发现了一个终极测试样例:
#T1:[IN K1-1] [K1-2 A1-1] [A1-2 OUT]
#T2:[IN K2-1] [K2-2 B2-1] [B2-2 A2-1] [A2-2 OUT]
#T3:[IN K3-1] [K3-2 D3-1] [D3-2 A3-1] [A3-2 OUT]
#M1:[T1 T2 T3]
#T4:[VCC F1-1] [F1-2 M1-IN] [M1-OUT R1-1] [R1-2 GND]
#K1
#K2
#K3
#F1+
#F1+
#F1+
#F1+
end
正确输出:
@K1:closed
@K2:closed
@K3:closed
@F1:3
@B2:73
@R1:180
@D3:0
@A1:260
@A2:80
@A3:0
这个测试样例救了我的“小命”,让我一下子变成了94分。
这个测试样例让我发现我的传输电压方法有问题,修改之后再提交:


发现已经到94分了,但还剩下两个测试点,就是这两个测试点!!!让我几度陷入绝望啊!!,如果不是我在最后一天问了我班上的大佬,我估计我调试一年都找不出来这个问题,这个问题就是!!!
计算并联电路总电阻时,精度不够!!!
是不是非常的奇怪,明明我已经把所有的涉及到数值的属性的类型设为double类型了,结果竟然出现了精度不够的问题。
于是我按照大佬的提示后修改代码,再次提交:

终于满分了!!!当时非常激动,因为我调试了好几天都没找出来这个错误,终于在最后一天晚上解决了,真的是被这个测试点恶心到了,呜呜呜~~
  改进建议:
  这一次的设计花了我两天半的时间,吸取了上一次题目的经验,我不但把电路类继承于设备类,还新设计了一个新的系统类来专门处理输入输出信息,这样的话在我的主函数中就只有短短几行代码,非常直观。
  但是这一次的代码量依旧很大,达到了七百多行,我觉得唯一可以改进的地方就是可以考虑最近在课堂上新学习的机中模式来融入到下一次大作业的设计中,使得我的设计更加的灵活多变,不会被某些地方约束。
  总结:
  对于这三次题目,我最大的收获就是,学会了如何通过调试寻找逻辑错误,因为编译软件控制台上直接显示的代码错误非常明显,非常容易改正,但是隐藏于设计中的逻辑错误却非常难找,这一点在家居强电电路模拟程序-2中我感悟最深,当出现逻辑错误的时候就需要找到需要设置断点的地方,然后进行调试,一步一步的步过,脑海中思考正确的逻辑输出,并于调试显示的内容进行对比,就这样一点一点的经历这个过程,最终找出问题所在,我可以说如果不会调试的话,接下来的两次作业将会非常困难,所以对我来说,除了在设计思维方面的提升,最大的收获就是锻炼了自己的调试能力。
  期待可以通过自己的努力顺利地完成后面的两次大作业!!!
posted on 2024-11-21 23:22 jkjkjkkjkjkj 阅读(30) 评论(0) 收藏 举报
                    
                
                
            
        
浙公网安备 33010602011771号