How can I use this method in conjunction with another method? - java

I am trying to finish this code off and get it working, but I cannot figure out why it is not working, the program is using methods to compute a grade from an exam mark input and pring out a pass/fail string. I have been putting the program together well until now, the last method won't function or compile. The copiler says:
error: cannot find symbol
gradeMessage(examGrade);
^
However, as my program shows, the method is there. So what am I doing wrong? A word of warning, as this is an assessment, the main method must have the four statements only, nothing else.
import java.util.Scanner;
public class GradeClassifier
{
public static void main(String[] args) {
titleString();
int examMark = getMark();
examGrade(examMark);
gradeMessage(examGrade);
}
/**
Prints title of the program
#param title the string with dashed underline
*/
public static void titleString() {
// Print Title
System.out.println("Grade Classifier\n****************");
}
/**
Gets the exam mark for the user
#param getMark from scanner
#return the mark
*/
public static int getMark() {
// Declare and create a Scanner to read input values
Scanner in = new Scanner(System.in);
System.out.println("");
System.out.print("Enter exam mark :> ");
int mark = in.nextInt();
return mark;
}
/**
Determine the grade
#param mark
#return string grade
*/
public static String examGrade(int mark) {
// Print out grade
String grade;
if (mark <= 100 && mark >=70) {
grade = "A";
} else if (mark <= 69 && mark >= 60) {
grade = "B";
} else if (mark <= 59 && mark >= 50) {
grade = "C";
} else if (mark <= 49 && mark >= 40) {
grade = "D";
} else {
grade = "F";
}
return grade;
}
/**
Display grade message
#param result to find pass or fail
*/
public static void gradeMessage(String result) {
// Compute if grade leads to pass or fail
String message;
if (result == "F") {
System.out.println("Unfortunately, you have a Grade F, so you have"
+ " failed this exam");
} else {
System.out.println("Congratulations, you are awarded a Grade"
+ message + " Pass");
}
}
}

First of all I noticed in your last method gradeMessage you create a String variable message and try to print it out rather than trying to print out the result parameter passed into your method. For example your last method should look like this:
public static void gradeMessage(String result) {
// Compute if grade leads to pass or fail
if (result == "F") {
System.out.println("Unfortunately, you have a Grade F, so you have failed this exam");
}
else {
System.out.println("Congratulations, you are awarded a Grade" + result + " Pass");
}
}
Now if you want to use the method in conjunction with one another you would end up with a main method looking like so:
public static void main(String[] args) {
titleString();
int examMark = getMark();
gradeMessage(examGrade(examMark));
}
In this main method we call the examGrade method and pass in the parameter examMark. The String value returned from the examGrade method is then passed into the gradeMessage method.

Related

What is the best method to get the index of a String or Char Array?

I would like to know what is the best way to get the index of a specific letter in a word. The reason i am doing this, is because i am making and modifying a Hangman game. I am already done with the game and it works good, however i want to implement a score based system. I created a method called keepScore() that takes a boolean value to see if the answer is right or wrong. If it is right, i am going to add 10 points for each letter found. If its wrong, i will deduct 10 points. My method keepScore() is implemented incorrectly any help?
Hangman.java
import Game.Game;
import Prompter.Prompter;
/* This class is the main class that starts the game.
* It instantiates the Game and Prompter objects.
*/
public class Hangman {
public static void main(String[] args) {
//Check if an argument has been passed, we expect the answer to be passed
if(args.length == 0) {
System.out.println("Expected: Java Hangman <answer>");
System.err.println("Answer is required!");
System.exit(1);
}
System.out.println("Welcome to Hangman!");
//Create an instance of our game
Game game = new Game(args[0]);
//Create an instance of our prompter
Prompter prompter = new Prompter(game);
//Starts the game
while (game.getRemainingTries() > 0 && !game.isWon()) {
prompter.displayProgress();
prompter.promptForGuess();
}
//Displays the outcome of the game
prompter.displayOutcome();
}
}
Game.java
package Game;
/* This class is responsible for implementing the game
* logic.
*/
public class Game {
//Declare our member variables
public final static int TOTAL_TRIES = 3;
public final static int MAX_SCORE_POINTS = 10;
private String mAnswer;
private String lettersHit;
private String lettersMissed;
private int score;
//Default constructor
public Game(String answer) {
//Initialize our member variables
mAnswer = answer.toLowerCase();
lettersHit = "";
lettersMissed = "";
}
//This method checks to see if the letter was a hit or a miss
public boolean checkLetter(char letter){
letter = validateGuess(letter);
boolean isHit = mAnswer.indexOf(letter) != -1;
//If correct
if (isHit) {
//Add the letter to the lettersHit pool
lettersHit += letter;
keepScore(isHit);
System.out.println("Hit! Score: " + score);
}else {
//Add the letter to the lettersMissed pool
lettersMissed += letter;
keepScore(isHit);
System.out.println("Missed! Score: " + score);
}
return isHit;
}
private void keepScore(boolean isHit) {
if(isHit) {
for (int i = 0; i < lettersHit.length(); i++) {
score += MAX_SCORE_POINTS;
}
} else {
for (int i = 0; i < lettersMissed.length(); i++ ) {
score -= MAX_SCORE_POINTS;
}
}
}
/*
This method handles an empty string input. For example,
if the user were to press enter on input a 0 length String
will cause the program to crash.
*/
public boolean checkLetter(String letters) {
if (letters.length() == 0) {
throw new IllegalArgumentException("No letter entered");
}
return checkLetter(letters.charAt(0));
}
//This method validates the user guess
private char validateGuess(char letter) {
//If the character is not a letter
if (!Character.isLetter(letter)) {
//Ask user for a valid letter
throw new IllegalArgumentException("A letter is required!");
}
//If entry was valid, convert character to lowercase
letter = Character.toLowerCase(letter);
//Check if the letter has been guessed already
if (lettersHit.indexOf(letter) != -1 || lettersMissed.indexOf(letter) != -1) {
throw new IllegalArgumentException("The letter " + letter + " has already been guessed");
}
return letter;
}
//This method keeps track of the user's game progress
public String getCurrentProgress() {
String progress = "";
//For each character in the array of strings of mAnswer
for (char letter : mAnswer.toCharArray()) {
char display = '-';
if (lettersHit.indexOf(letter) != -1){
display = letter;
}
progress += display;
}
return progress;
}
//Get the current remaining tries
public int getRemainingTries() {
return TOTAL_TRIES - lettersMissed.length();
}
//Get the current answer
public String getAnswer() {
return mAnswer;
}
//This method checks if the game is won.
public boolean isWon() {
return getCurrentProgress().indexOf('-') == -1;
}
public int getScore(){
return score;
}
}
Prompter.java
package Prompter;
import Game.Game;
import java.util.Scanner;
/* This class is responsible for displaying instructions and information to the user
* regarding the game.
*/
public class Prompter {
//The game object
private Game mGame;
private boolean isHit;
private boolean acceptable;
//Default constructor
public Prompter(Game game) {
//Get the instance of our game
mGame = game;
isHit = false;
acceptable = false;
}
//This method prompts the user for a guess
public boolean promptForGuess() {
//Create an instance of scanner
Scanner scanner = new Scanner(System.in);
//Loop for input
do {
System.out.println("Please enter a letter: ");
String guess = scanner.nextLine();
try {
isHit = mGame.checkLetter(guess);
acceptable = true;
}catch (IllegalArgumentException iae) {
System.out.printf("%s. Please try again!%n", iae.getMessage());
}
} while (!acceptable);
return isHit;
}
//This method displays the progress
public void displayProgress() {
System.out.printf("You have %d tries to guess the answer" +
" before you are taken to the gallows. Try to solve: %s%n", mGame.getRemainingTries(),
mGame.getCurrentProgress());
}
//This method displays the outcome of the game
public void displayOutcome() {
if( mGame.isWon()) {
System.out.printf("Congratulations! you won with %d tries remaining.%n" +
"Your total score: %d%n", mGame.getRemainingTries(), mGame.getScore());
}else {
System.out.printf("Bummer! The answer was: %s", mGame.getAnswer());
}
}
}
Look at this method of yours:
private void keepScore(boolean isHit) {
if(isHit) {
for (int i = 0; i < lettersHit.length(); i++) {
score += MAX_SCORE_POINTS;
}
} else {
for (int i = 0; i < lettersMissed.length(); i++ ) {
score -= MAX_SCORE_POINTS;
}
}
}
It doesn't add MAX_SCORE_POINTS times the number of good letters you just found, it does so with the number of good letters in lettersHit. Now, what is in lettersHit ? Well, there is all the letters you found since the start.
So you'll have :
word to guess: anaconda
letter: a
lettersHit = "a", score += (lettersHit.length * 10) = 10
letter: c
lettersHit = "ac", score += (lettersHit.length * 10) = 30
You could just use StringUtils.countMatches(mAnswer, letter); to get the number of occurence, hence the score.

Arrays with for loop and if statements

So when i i have tried to save and compile everything works fine until I run it. There seems to be an issue with my array syntax. Could someone help me find it?When I do run this program the grades()method outputs "AAA" . What I'm trying to do in this program is read text from a txt file and list each line, outputting a student name and score. Now in the grades() method I am trying to output calculate a letter grade for each of the students grades and make that go into a loop until the last score has been read.
public class ReadData
{
private static String[] names = new String[3];
private static int line;
private static int[] scores = new int[3];
private static float mean;
private static double stdDeviation;
public static void readData() throws FileNotFoundException
{
File file = new File("data.txt");
Scanner scanner = new Scanner(file);
int l = 0;
// float sum = 0 ;
while (scanner.hasNextLine()) {
String line = scanner.nextLine();
String [] words = line.split("\t");
names[l] = words[0];
scores[l] = Integer.parseInt(words[1]);
// sum+=scores[l];
System.out.println(" name: " + names[l] + ", score: " + scores[l]);
l++;
}
// System.out.println(scores[0]+ " " + scores[1]+ " " + scores[2]);
}
public static void fndMean()
{
float mean = ((25+65+89)/3);
System.out.println(" The mean is: " + mean);
}
public static void fndStandard() throws FileNotFoundException
{
double stdDeviation = Math.sqrt(((Math.pow(25-59, 2)+(Math.pow(65-59,2))+
(Math.pow(89-59, 2))))/3);
System.out.println("The Standard Deviation is: " + stdDeviation);
}
Grades method
public static void grades()
{
for(int i = 0; i < (scores.length); i++)
{
if(mean + stdDeviation <= scores[i])
{
System.out.print("A");
}
else if( (scores[i] >= mean+(stdDeviation/3)) &&
(mean +stdDeviation)> scores[i])
{
System.out.print("B");
}
else if( (scores[i] >= mean-(stdDeviation/3)) &&
(mean +(stdDeviation/3))> scores[i])
{
System.out.print("C");
}
else if( (scores[i] >= mean-(stdDeviation)) &&
(mean - (stdDeviation/3))> scores[i])
{
System.out.print("D");
}
else
{
System.out.println("F");
}
}
}
You are re-declaring your variables in methods like fndMean() and fndStandard() when you do the following
double stdDeviation = Math.sqrt(((Math.pow(25-59, 2)+(Math.pow(65-59,2))+
(Math.pow(89-59, 2))))/3);
float mean = ((25+65+89)/3);
You already declare them up top and don't need to do it again, otherwise it will only set the local variables inside the methods and not inside your class. you should do
stdDeviation = Math.sqrt(((Math.pow(25-59, 2)+(Math.pow(65-59,2))+
(Math.pow(89-59, 2))))/3);
mean = ((25+65+89)/3);
Which will set those variables to what you were expecting when you call those methods BEFORE calculating the grades.
This is what fndMean and fndStandard methods print:
The mean is: 59.0
The Standard Deviation is: 26.407069760451147
Sum of mean and stdDeviation is 85.40706976045115.
Now, the condition if(mean + stdDeviation <= scores[i]) checks whether that sum is less than equal to score[i] and if yes, prints 'A'. It can be true in either of these two cases:
Values in second column (tab) in txt files are all more than 85
score array gets altered between two method calls
Printing score value before those conditions should give you some more idea.

Is there a way to make this user validation code more efficient and/or easier to read?

I'm trying to validate the user input such that the program will loop back to the first question of asking the user for the grade if it is NOT an int and the int is not within the ranges of 9 - 12, inclusive. Is there a "better" way of writing this code?
do
{
if (userGrade < 9 || userGrade > 12)
{
System.out.println("That is not a valid grade!");
}
System.out.printf("Grade (9-12): ");
while(!enterInfo.hasNextInt())
{
System.out.println("That is not a number! Enter in a valid number.");
enterInfo.next();
}
userGrade = enterInfo.nextInt();
} while (userGrade < 9 || userGrade > 12);
To make the code cleaner you can use encapsulation based on classes and
methods (encapsulation is btw the main reason for OOP).
So you divide everything into smaller parts as methods or classes as long as possible, every method has just one simple purpose then. This way the whole program is easier to read, understand and maintain.
Notice for example how the scanner object is just used in the local context of the readInput method.
import java.util.InputMismatchException;
import java.util.Scanner;
public class KillerLoop {
private boolean notReady;
private int grade;
public static void main(String[] args) {
new KillerLoop();
}
/**
* the default constructor calls the doStuff method
* which contains the main loop of the program
*/
public KillerLoop() {
this.notReady = true;
doStuff();
}
/**
* the programs main loop
*/
private void doStuff() {
while (this.notReady) {
int input = this.readInput();
this.verifyInput(input);
}
System.out.println("Grade " + this.grade + " is a correct grade!");
}
/**
* verifies a users input
* if the input is correct, notReady will be set
* to false so that the programs main loop is left
* (you could also use an if construct with break for this purpose)
* #param userGrade the users input
*/
private void verifyInput(int userGrade) {
if (userGrade < 9 || userGrade > 12) {
System.out.println("That is not a valid grade!\n" + "Grade (9-12): ");
} else {
this.grade = userGrade;
this.notReady = false;
}
}
/**
* this method reads input from the command line
* and returns an integer if successful
* #return the users input as integer
*/
private int readInput() {
Scanner scanner = new Scanner(System.in);
System.out.println("enter a grade");
int userGrade = 0;
try {
userGrade = scanner.nextInt();
} catch (InputMismatchException e) {
System.out.println("That is not a number! Enter in a valid number.");
this.readInput(); //this recursion might not always be a good idea ;)
}
return userGrade;
}
}
Basically I would read System.in and while there is something, first I would try to convert to Integer and then check if that Integer is in correct range:
package trial;
import java.util.Scanner;
public class TestScan {
public static void main(String[] args) {
// TODO Auto-generated method stub
try {
System.out.println("Please introduce a number:");
Scanner sc = new Scanner(System.in);
while(sc.hasNext()){
String input=sc.next();
Integer inputInt;
try{
inputInt=Integer.parseInt(input);
}catch(Exception e){
System.out.println("You must introduce a number");
continue;
}
if(inputInt<9 || inputInt>12){
System.out.println("Number must be between 9 and 12 (inclusive)");
continue;
}
System.out.println("Correct!");
}
sc.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
It is worth noting, because of reading from System.in, this program can be executed from your IDE, so you will have to execute it outside your IDE:
1.-go to TestScan folder and compile it: javac TestScan.java
2.- specify this class in your classpatch to execute it. E.g. if you are in C: you could use something like
C:>java -classpath C:\workspace\StackOverflow\src trial.TestScan
if (userGrade < 9 || userGrade > 12)
{
System.out.println("That is not a valid grade!");
} else {
do {
System.out.printf("Grade (9-12):
");
while(!enterInfo.hasNextInt())
{
System.out.println("That is not a number! Enter in a valid number.");
enterInfo.next();
}
userGrade = enterInfo.nextInt();
} while (userGrade < 9 || userGrade > 12)}

How to invoke multiple method signatures within a main method?

So I have three required codes I have already figured out. They are the codes for a quadratic formula, codes for an ISBN checker, and a code for Newtons Method. I'm supposed to make a menu with options 1, 2, and three each containing these codes respectively.
I guess this means I need different methods for this right? I was never really taught - I was told we had to always put in public class void main (String []args){ for everything, and I was just told there were variations to this?
For Quadratics formula, the information is : Return - void and parameters of three doubles, Newtons method: Return - double and parameters of 1 double, and ISBN checker: Return: Boolean and Parameters of 1 string. I don't really understand the parameters thing either. Help would be appreciated. I know this aesthetically looks horrible, but because my codes for now are relatively short I just edit the style when I' done. I know a lot of things are wrong in this too and I've spent time trying to figure them out.
import Java.util.Scanner;
public class HelperMethod{
public static void main(String[] args) {
Scanner userInputScanner = new Scanner (System.in);
System.out.println ("You have three options. press one for the quadratic Formula, 2 for the newtons Method, and 3 for an ISBN checker.");
int input = userInputScanner.nextInt();
if (input = 1){
}else if (input = 2) {
private class NewtonsMethod {
public static void NewtonsMethod(String[] args) {
Scanner userInputScanner = new Scanner (System.in);
double guess, fX, fPrimeX, newGuess;
System.out.println ("enter in a value give");
guess = userInputScanner.nextDouble();
System.out.println ("Your guess is " + guess);
while (true) {
fX = (6 * Math.pow (guess,4)) - (13 * Math.pow (guess,3)) - (18 * Math.pow (guess,2)) + (7 * guess) + 6;
fPrimeX = (24 * Math.pow (guess,3)) - (39 * Math.pow (guess,2)) - 36 * guess + 7;
newGuess = guess - (fX / fPrimeX);
System.out.println ("A possible root is " + newGuess);
if (Math.abs(newGuess - guess) < 0.00001) {
break;
} else {
guess = newGuess;
}
}
System.out.println ("The root is: " + newGuess);
}
}
}else{
private class BookNumber {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
char f;
int e, g, h;
int result = 0;
System.out.println ("Pleas enter a thirteen digit number");
String a = scanner.nextLine();
if (a.length() == 13){
for (int i = 0; i < 13; i ++) {
f = a.charAt(i);
e = Character.digit(f, 10);
if (i % 2 == 0) {
g = e * 1;
result = result + g;
} else {
g = e * 3;
result = result + g;
}
}
System.out.println ("The added sum of you numbers is " + result);
if (result % 10 == 0) {
System.out.println ("This combination IS a ISBN number");
} else {
System.out.println ("This is NOT an ISBN number");
}
} else {
System.out.println ("This combination is not thirteen digits long");
}
}
}
}
}
}
First of all, right now you're setting input to 1 in your first if statement. To compare input to 1 instead, use the == operator, i.e. if (input == 1) {.... Secondly, you don't really need to use classes, you can simply have methods NewtonsMethod(), BookNumber() etc. and run them when the input is correct.
public class HelperMethod{
public static void main(String[] args) {
int input;
//Handle user input
switch (input) {
case 1:
newtonsMethod();
break;
case 2:
bookNumber();
break;
case 3:
anotherMethod();
break;
}
}
public static void newtonsMethod() {
//Your code
}
public static void bookNumber() {
//Your code
}
public static void anotherMethod() {
//Your code
}
}
Methods should never be inside one another. That is what classes are for. A method is an element within a class. For example, in your case your class was named "HelperMethod". Your methods need to begin after the main method's code block is closed with a curly brace "}"
as an example
// This would be your main method.
public static void main(String args[]) {
// Your method is CALLED here.
someMethod();
{
// Then this is where your next method would start.
public static void someMethod() {
// Your code for the method of course goes here.
}
Of course you need your class setup and needed imports ABOVE the main method but you have that setup correctly already. With this setup, it makes it easy to call public methods that are in other classes. Your private methods are not really needed unless you intend to use more than one class, at which point you will need to import that class and then call the method like so
SomeClass.someMethod();

Why doesn't my program call my methods?

java methods statithing but I can't seem to get my while statement on line 56 to call my methods properly. Is there something that I'm doing wrong? I am very new to Java so any sort of help would be appreciated! Thanks in advance!
Here is my code:
import java.util.*;
import javax.swing.*;
import java.io.*;
public class GradeCalculator {
static String fileInput;
static double totalGrade;
static int scoreCount= 0;
static double classAverage;
static double score;
static double testScore;
static double averageScore;
static int numberOfStudents = 0;
static char letterGrade;
static String fileOutput;
static String nameOfStudent;
static int numberCount;
static int numberCalculatedStudents;
static double average = 0;
public static void main (String[] args) throws FileNotFoundException {
//Welcome
JOptionPane.showMessageDialog(null,"Welcome to the Grade Calculator! This program will\n" +
" calculate the average percentage of 5 test scores that\n"+
" are given in a given file once these scores are\n"+
" averaged it will give the student a letter grade.","Welcome!",JOptionPane.PLAIN_MESSAGE);
fileInput = JOptionPane.showInputDialog(null, "Please enter the name of the input file you wish to use for this program."
,"Input File",JOptionPane.PLAIN_MESSAGE);
fileOutput = JOptionPane.showInputDialog(null, "Please enter the name of the output file you wish to use for this program."
,"Output File",JOptionPane.PLAIN_MESSAGE);
//preparing text files
PrintWriter outFile = new PrintWriter (fileOutput);
File inFile = new File (fileInput);
Scanner reader = new Scanner(new FileReader(fileInput));
outFile.println("Student Name Test1 Test2 Test3 Test4 Test5 Average Grade");
while(reader.hasNextLine()) {
nameOfStudent = reader.next();
outFile.printf("%n%n%s",nameOfStudent);
numberOfStudents++;
score = reader.nextDouble();
calculateAverage(score);
calculateGrade(averageScore);
outFile.printf(" %.2f ", averageScore);
outFile.println(" "+letterGrade);
}
classAverage = classAverage/numberCalculatedStudents;
outFile.print("\n\n\n\n\n\n\n\n\n\n\n\nClass average for "+ numberCalculatedStudents + "of" + numberOfStudents + "is" + classAverage);
JOptionPane.showMessageDialog(null,"The report has successfully been completed and written into the file of " + fileOutput +"."
+" The class average is " + classAverage + ". Please go to the output file for the complete report.");
outFile.close();
}
public static void calculateAverage(double score) throws FileNotFoundException {
Scanner reader = new Scanner(new FileReader(fileInput));
PrintWriter outFile = new PrintWriter (fileOutput);
while (reader.hasNextDouble() && numberCount <= 5 ) {
score = reader.nextDouble();
numberCount++;
if (score >= 0 & score <= 100) {
outFile.printf("%10.2f",score);
scoreCount++;
average = score + average;
}
else
outFile.printf(" **%.2f",score);
}
if (average!=0){
numberCalculatedStudents++;
average = average/scoreCount;
averageScore = average;
classAverage = average + classAverage;
}
average = 0;
}
public static char calculateGrade (double averageScore) {
if (averageScore >= 90 && averageScore <= 100)
letterGrade = 'A';
else if (averageScore < 90 && averageScore >= 80)
letterGrade = 'B';
else if (averageScore < 80 && averageScore >= 70)
letterGrade = 'C';
else if (averageScore < 70 && averageScore >= 60)
letterGrade = 'D';
else if (averageScore < 60 && averageScore >= 0)
letterGrade = 'F';
else
letterGrade =' ';
return letterGrade;
}
}
Without knowing what line the problem is arising on, two issues jump out at me:
At the top of the while loop:
if (score >= 0 & score <= 100)
{ outFile.printf("%10.2f",score);
scoreCount++;
average = score + average;
}
else
outFile.printf(" **%.2f",score);}
You have a close bracket (}) after the else statement, but no open bracket. So that close bracket looks like its exiting the while loop before you want it to.
Second, it looks like you're trying to return something (namely a char) in your CalculateGrade method, but you have specified a return type of void on it, which means that even though you have a return statement, nothing gets returned when you call it. You don't show where you're calling that method, so I can't be sure this is causing a problem, but its certainly suspect. It seems like you want to use:
public static char calculateAverage(double score) throws FileNotFoundException{
instead of public static void calculateAverage(double score)...
Also, is there a reason why all of these methods are static? Do you know what making something static means?
EDIT (based on your comment):
No. making a variable static makes it a "class variable", which means that only one of them exists for all objects of that class. To illustrate:
If you have a class like this:
class test {
static int id;
}
And you run the following code:
test t1 = new test();
test t2 = new test();
t1.id = 4;
t2.id = 8;
System.out.println(t1.id);
it will print 8. This is because, since id is a static variable changing it on any object of the class will cause it to change for every other object of the class.
This is as opposed to an "instance variable" one of which exists for every object of the class. To make id an instance variable, simply remove the static keyword. If you do so and run the same code, it will print 4, because changing an instance variable of t2 has no effect on t1.
Make sense?

Categories