首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >等级统计

等级统计
EN

Code Review用户
提问于 2021-12-01 16:52:14
回答 1查看 115关注 0票数 1

我现在正在MOOC中学习Java,这是我练习成绩统计的解决方案。

这是一项工作:

在本练习中,我们创建了一个用于打印课程中点数的统计数据的程序。该程序接收点数(整数从0到100)作为输入,并在此基础上打印有关年级的统计数据。当用户输入数字-1时,输入的读取停止。在计算统计数据时,不应考虑不在间隔0-100内的数字。第1部分:平均值,编写一个程序,读取来自用户的表示课程点数总和的整数。0-100之间的数字是可以接受的,数字-1结束输入的读取.其他数字是错误的输入,应该忽略。当用户输入数字-1时,程序应该打印输入点总数的平均值。第二部分给出及格分数的点平均值扩展了程序,这样除了给出所有总分的点平均值外,还提供了给出及格分数的点平均值。一个及格的分数是通过获得至少50个课程的分数。您可以假设用户总是在0-100之间提供至少一个整数。如果没有给出及格分数的数字,程序应该打印一行"-“在那里的平均值。第3部分传递百分比扩展了程序的前一部分,因此它也打印了通过率。通过率是使用公式100 *传递/参与者计算的。第4部分扩展了程序的等级分布,使得它还打印出了基于上表的年级distribution.Each点数总数转换为一个等级。如果一个点总数不在0-100中,则应该忽略它。等级分布被打印成星星。如果五年级有一个总分,那么它应该打印第5行:*。如果没有一个特定等级的点数总数,那么就不应该为它打印任何星星。在下面的样本中,这对四年级的学生来说是正确的。

这是我的解决办法:

Main.java:

代码语言:javascript
复制
import java.util.Scanner;

public class Main {

    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
    
        // Write your program here -- consider breaking the program into 
        // multiple classes.
        UserInterface ui = new UserInterface(scanner);
        ui.start();
    }
}

PointsStatistics.java:

代码语言:javascript
复制
import java.util.ArrayList;

public class PointsStatistics {

    private ArrayList<Integer> allpoints;
    private ArrayList<Integer> passingpoints;

    public PointsStatistics() {
        this.allpoints = new ArrayList<>();
        this.passingpoints = new ArrayList<>();
    }

    public void add(int points) {
        if (points > 0 && points >= 50 && points <= 100) {
            this.passingpoints.add(points);
        }
        if (points > 0 && points <= 100) {
            this.allpoints.add(points);
        }
    }

    public double pointsAverage() {
        double sum = 0.0;
        for (Integer points : this.allpoints) {
            sum += points;
        }
        return sum / this.allpoints.size();
    }

    public double possingPointsAverage() {
        double sum = 0.0;
        for (Integer points : this.passingpoints) {
            sum += points;
        }
        return sum / this.passingpoints.size();
    }

    public double passingPercentage() {
        double percentage = (this.passingpoints.size() * 1.0) / this.allpoints.size();
        return percentage * 100;
    }

    public void gradeDistribution() {
        ArrayList<Integer> grades = new ArrayList<>();
        for (Integer points : this.allpoints) {
            if (points < 50) {
                grades.add(0);
            } else if (points < 60) {
                grades.add(1);
            } else if (points < 70) {
                grades.add(2);
            } else if (points < 80) {
                grades.add(3);
            } else if (points < 90) {
                grades.add(4);
            } else if (points <= 100) {
                grades.add(5);
            }
        }

        for (int i = 5; i >= 0; i--) {
            System.out.print(i + ": ");            
            for(Integer grade : grades) {
                if (grade == i) {
                    System.out.print("*");
                }                
            }
            System.out.println("");            
        }        
    }
}

UserInterface.java

代码语言:javascript
复制
import java.util.Scanner;

public class UserInterface {
    private PointsStatistics points;
    private Scanner scanner;

    public UserInterface(Scanner scanner) {
        this.points = new PointsStatistics();
        this.scanner = scanner;
    }

    public void start() {
        System.out.println("Enter point totals, -1 stops: ");
        while(true) {
            int enterPoints = Integer.valueOf(scanner.nextLine());
        
            if( enterPoints == -1) {
                break;
            }
        
            this.points.add(enterPoints);            
        }
        System.out.println("Point average (all): " + this.points.pointsAverage());
        System.out.println("Points average (passing): " + this.points.possingPointsAverage());
        System.out.println("Pass percentage: " + this.points.passingPercentage());
        points.gradeDistribution();
    }
}

你怎么看?它有效,但它是一个最佳的解决方案吗?谢谢你。

EN

回答 1

Code Review用户

发布于 2021-12-01 17:58:38

包名

Java代码应该放在一个名为“避免与其他开发人员冲突”的包中。最好的做法是对你拥有的一些域/帐户/电子邮件进行反向读取。

代码语言:javascript
复制
package com.stackexchange.codereview.srxxx.grading;

命名约定

对遵循典型的Java命名约定表示赞赏。

名称

在引入变量名称时要非常小心,使它们尽可能地自我解释.

一个改进:在passingPercentage()中,您有一个名为percentage的变量,但它不在与该单词关联的0..100范围内,而是在0到1之间。所以,我将它称为比率,而不是百分比。

这听起来像是吹毛求疵,但相信我,无论是在一个团队工作,还是在一个长期存在的软件项目中,这都是最重要的技能。

分离计算与用户界面

您主要遵循计算(类PointsStatistics)和用户界面(类UserInterface)之间的关注点分离。

只对gradeDistribution()来说,您可以在PointsStatistics中执行System.out.print()。您应该更改方法以返回年级列表(grades变量),并从UserInterface类执行打印循环。

记录您的类和方法

为公共类和方法编写文档注释(Javadoc样式),记录他们的任务(而不是他们如何完成任务)。

要获得好的Javadoc示例,请看一下Java类,您肯定会在Java8 8平台规范这样的网页上使用HTML生成的文档结果。在Java开发的20+年中,我很少需要研究Java源代码,Javadocs很好地解释了所有预先存在的Java类和方法。

使用大多数泛型类型

声明变量

你应该换衣服

代码语言:javascript
复制
ArrayList<Integer> grades = new ArrayList<>();

成为

代码语言:javascript
复制
List<Integer> grades = new ArrayList<>();

一般规则是使用提供所需方法和行为的最一般类型(或接口)声明变量,并使用您(当前)希望使用的具体类对其进行初始化。

为什么?要么相信我,这是最好的做法,或阅读以下冗长的解释。

所有代码都将用于任何类型的List,可能是LinkedList或包装为List的数组(使用Arrays.asList())。也许,稍后您会发现一个超酷的新List实现,您希望将ArrayList与该类交换。然后,您只需将初始化部分交换到现在读取。

代码语言:javascript
复制
List<Integer> grades = new SuperCoolList<>();

一切都是一样的,只是很酷。

您可能会问,为什么不同时进行初始化和声明:

代码语言:javascript
复制
SuperCoolList<Integer> grades = new SuperCoolList<>();

风险在于,使用初始声明ArrayList<Integer> grades,没有什么可以阻止您调用例如grades.trimToSize(),它不是List接口的一部分,而是特定于ArrayList。有两种可能的情况:

  • 很可能,SuperCoolList不会有这样的方法,从而导致编译错误。您会看到错误,花费一些时间来替换方法调用,或者发现您无法使用SuperCoolList并返回到ArrayList
  • 更糟糕的是,SuperCoolList可能有这样的方法,但却在做一些不同的事情。然后,程序将在没有得到编译器任何提示的情况下不正常运行。

使用

代码语言:javascript
复制
List<Integer> grades = new ArrayList<>();

这是不可能的。在grades变量上调用的每个方法都将出现在每种List实现中,并且行为都是相同的。您不能意外地使用grades.trimToSize()方法,因为这不是List接口的一部分。这样,编译器就可以保证以后更改为不同的List实现的自由。

票数 3
EN
页面原文内容由Code Review提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://codereview.stackexchange.com/questions/270585

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档