我写了以下程序:数学测验。这是来自“Java的艺术与科学”一书的第5章第6章的编程练习。
这个计划似乎正在起作用。不过,我希望能就我能改进的任何领域(任何坏习惯等)提出任何建议。
如果有任何更有效或优雅的方式随机选择符合下面所列标准的两个数字,我也会感到欣慰。
该方案应满足以下要求:
·它应该提出一系列五个问题--算术问题--编码为一个命名常数。
每个问题都应该包含一个简单的加法或减法问题,只涉及两个数字。
每个问题都应随机选择加法或减法。
·所涉及的数字,包括答案,都不应小于0或大于20 --在这些限制条件下,程序应随机选择数字。
·这个项目应该给学生三次回答每个问题的机会。如果学生给出正确的答案,程序应该以某种适当的祝贺方式表明这一事实。
·如果学生在三次尝试中没有得到答案,程序应该给出答案,然后再继续处理另一个问题。
/*
* File: MathQuiz.java
* ---------------------
*/
import acm.program.*;
import acm.util.*;
public class MathQuiz extends ConsoleProgram {
private static final int NUMBER_OF_QUESTIONS = 5;
public void run() {
println("Welcome to MathQuiz");
// Starts a function which will ask questions
for (int i=0; i < NUMBER_OF_QUESTIONS; i++) {
// Draws a random number between 0 and 20
int x = getRandomX();
// Draws a random sign - plus or minus with a probability of 50 per cent
String sign = getPlusOrMinus();
// Initializes a second variable which will be used for second random number
int y = 0;
// Initializes a variable where the good answer to the arithmetic problem will be kept
int goodanswer = 0;
// Draws a second random number between 0 and 20-x (method getRandomYPlus) if the drawn sign is + or between 0 and x (method getRandomYMinus) if the drawn sign is -
// I have created two methods because that numbers have to be such so that the answer will not be greater than 20 or less than zero
if (sign == "+") {
y = getRandomYPlus(x);
goodanswer = x + y;
} else {
y = getRandomYMinus(x);
goodanswer = x-y;
}
// Poses an arithmetic problem with the two random numbers and a random sign
int answer = readInt("What is " + x + sign + y + "? ");
// Initializes a variable which will count the number of answers
int count = 0;
// Students gets three chances to give a correct answer
while (answer != goodanswer && count !=3) {
answer = readInt("That`s incorrect - try a different answer: ");
count ++;
}
if (answer == goodanswer) {
println("You got it!");
// After three wrong answers program gives a correct answer and moves to another problem
} else {
println ("No, the answer is " + goodanswer + ".");
}
}
}
// Method which draws a random number between 0 and 20
private int getRandomX() {
int x = 0;
x = rgen.nextInt(0,20);
return x;
}
// Method which draws a random sign - plus or minus - with a probability of 50 per cent
private String getPlusOrMinus() {
String sign = null;
sign = rgen.nextBoolean() ? "+" : "-";
return sign;
}
// Draws a second random number between 0 and 20-x (method getRandomYPlus) if the drawn sign is + or between 0 and x (method getRandomYMinus) if the drawn sign is -
// I have created two methods because that numbers have to be such so that the answer will not be greater than 20 or less than zero
private int getRandomYPlus(int x) {
int y = 0;
y = rgen.nextInt(0,20-x);
return y;
}
private int getRandomYMinus(int x) {
int y = 0;
y = rgen.nextInt(0,x);
return y;
}
// Creates an instance variable for random number generator
private RandomGenerator rgen = new RandomGenerator();
}发布于 2018-07-06 12:20:17
最大的问题是,您有硬编码的最大数目大小(20)在多个地方。就像子弹的数量一样,这应该是一个常数。
你应该取消使用通配卡的进口。始终只导入要使用的特定类。否则,当两个包声明了同名类时,您将很难计算出名称冲突。
将RandomGenerator的初始化移到类的开头,这样人们就不需要猜测变量rgen是什么。您还可以将其设置为final和static,因为它不会改变,您(可能)可以对类的所有实例使用相同的实例。
应避免将变量初始化为不使用的值:
private int getRandomX() {
int x;
x = rgen.nextInt(0,20);
return x;
}或
private int getRandomX() {
int x = rgen.nextInt(0,20);
return x;
}甚至在某项功能中:
private int getRandomX() {
return rgen.nextInt(0,20);
}这样的话,人们就不需要弄清楚零的含义。它还有助于调试,因为如果忘记执行实际初始化,代码将不会编译。
例如,这段代码不会编译,因为goodanswer没有在else块中初始化。
int y;
int goodanswer;
if (sign == "+") {
y = getRandomYPlus(x);
goodanswer = x + y;
} else {
y = getRandomYMinus(x);
}如果您已经离开了int goodanswer = 0;,那么代码将编译并运行,但是不能正常工作,您将不得不花时间查找错误。
发布于 2018-07-06 13:37:24
==进行比较。始终使用equals()。!=3应该是!= 3。int i=0应该是int i = 0。this.rgen.nextInt(min, max)可以放在行内。您不需要为此声明三个单独的包装方法。final来减少读者的认知负荷。goodAnswer,而不是goodanswer)y和goodAnswer都依赖于符号,但我认为它们是分开的计算。为了清楚起见,最好用不同的方法来处理。20是一个幻数,应该是一个常量。count应该更具描述性--也许是attempts?<而不是!=是惯例,以防某些东西指定count大于3,如果它大于3,那么循环就会永远持续下去。count,因为您在分配count之前第一次询问。如果我尝试重构您的代码以包含上面的想法,它可能如下所示:
public final class MathQuiz extends ConsoleProgram {
private static final int NUMBER_OF_QUESTIONS = 5;
private static final int BIGGEST_POSSIBLE_NUMBER = 20;
private final RandomGenerator rgen = new RandomGenerator();
public void run() {
this.println("Welcome to MathQuiz");
for (int i = 0; i < NUMBER_OF_QUESTIONS; i++) {
final int x = this.rgen.nextInt(0, BIGGEST_POSSIBLE_NUMBER);
final String sign = this.rgen.nextBoolean() ? "+" : "-";
final int y = this.computeY(x, sign);
final int goodAnswer = this.computeAnswer(x, sign, y);
int answer = this.readInt("What is " + x + sign + y + "? ");
int attempts = 1;
while ((answer != goodAnswer) && (attempts < 3)) {
answer = this.readInt("That`s incorrect - try a different answer: ");
attempts++;
}
if (answer == goodAnswer) {
this.println("You got it!");
} else {
this.println ("No, the answer is " + goodAnswer + ".");
}
}
}
/**
* @return a value {@code y} such that {@code y} and the correct answer to the mathematical
* operation are both less than {@link BIGGEST_POSSIBLE_NUMBER}.
*/
private int computeY(final int x, final String sign) {
return sign.equals("+") ? this.rgen.nextInt(0, BIGGEST_POSSIBLE_NUMBER - x) : this.rgen.nextInt(0, x);
}
private int computeAnswer(final int x, final String sign, final int y) {
return sign.equals("+") ? x + y : x - y;
}
}发布于 2018-07-09 12:41:17
已经有很好的答案了。我补充一点:
sign == "+"是一个(潜在的)错误。请参阅字符串等于Java
最好是将符号存储在boolean (isPlus)中,或者更好地使用显式enum。
例如:
enum Sign
{
PLUS, MINUS
}然后,您有一个显式类型,这是您的符号,您可以使用
if (sign == Sign.PLUS)https://codereview.stackexchange.com/questions/197944
复制相似问题