junit.framework.AssertionFailedError - Incomplete Stack Trace Given - java

Full Disclosure: This was an assignment, it has been marked already, but I want to understand why I'm getting this error.
I'm having some issues understanding why junit.framework.AssertionFailedError is being thrown. Normally when errors occur I could at least look at the stack trace and see what is happening. In this case, the output console shows this:
Testcase: testIsCorrectMCQ(mr_3.myTester): FAILED
null
junit.framework.AssertionFailedError
at mr_3.MyTester.testIsCorrectMCQ(Assign03Tester.java:207)
testIsCorrectMCQ(mr_3.MyTester): FAILED
In the test result tab in NetBeans, copying the stack trace gives me:
junit.framework.AssertionFailedError
at mr_3.myTester.testIsCorrectMCQ(myTester.java:207)
In the tester file, I have this:
#Test
public void testIsCorrectMCQ() {
System.out.println("isCorrect of MCQ");
MCQuestion instance = new MCQuestion(1,"Capital city of Canada is", 'A',
"Ottawa", "Vancouver", "New York", "Toronto");
assertFalse(instance.isCorrect("B"));
assertTrue(instance.isCorrect("A")); // line 207
}
My isCorrect method is this:
#Override
public boolean isCorrect(Object guess) {
if (guess == null)
return false;
if (guess instanceof String) {
String userGuess = (String)guess;
return (userGuess.charAt(0) == this.getAnswer());
}
if (guess instanceof Character) {
Character userGuess = (Character)guess;
return (userGuess == this.getAnswer());
}
else return false;
}
Any help in understanding what is happening is greatly appreciated.
Edit 1 : My MCQuestion source code
public class MCQuestion extends Question {
private char answer;
private String[] options;
public MCQuestion() {
super();
questionType = QuestionType.MULTIPLE_CHOICE;
}
public MCQuestion(int id, String text, char answer, String... options) {
super(id, text);
setOptions(options);
setAnswer(answer);
questionType = QuestionType.MULTIPLE_CHOICE;
}
public String[] getOptions() {
String[] getOptions = new String[this.options.length];
System.arraycopy(this.options, 0, getOptions, 0, this.options.length);
return getOptions;
}
public void setOptions(String... options) {
if (options.length > 0) {
this.options = new String[options.length];
for (int i = 0; i < options.length; i++) {
if (options[i].isEmpty())
throw new IllegalArgumentException("You have nothing in this option");
else
this.options[i] = options[i];
}
}
else throw new IllegalArgumentException("You have no options set");
}
public char getAnswer() {
return this.answer;
}
public void setAnswer(char ans) {
ans = Character.toLowerCase(ans);
int index = ans - 97;
if (Character.isLetter(ans) && index >= 0 && index < this.options.length)
this.answer = ans;
else throw new IllegalArgumentException(ans + " is not a valid answer option");
}
#Override
public boolean isCorrect(Object guess) {
if (guess == null)
return false;
if (guess instanceof String) {
String userGuess = (String)guess;
return (userGuess.charAt(0) == this.getAnswer());
}
if (guess instanceof Character) {
Character userGuess = (Character)guess;
return (userGuess == this.getAnswer());
}
else return false;
}
#Override
public String toString() {
String option = "";
if (this.options.length == 0)
option = "No options added, yet!";
else {
char index = 'a';
for (String e: options)
option += index + ") " + e + "\n";
}
return (super.toString() + "\n" + option);
}
}

You execute ans = Character.toLowerCase(ans); for whatever reason in your setAnswer() method before saving it in this.answer. This means that (userGuess.charAt(0) == this.getAnswer()) will return false when you provide the answer in upper case, but compare it with the stored lower case character.
Depending on if you want case insensitive answers or not, you should add or remove the Character.toLowerCase() call to your isCorrect() method as well.

Related

Why am I not getting any values back?

When running the below method, I do not get anything back. Always getting terminated without any results. Could someone tell me why I am not getting any results back?
I hava adjusted according to the comments but havent worked. I have add the main method below;
public class ModuleGrader {
final int examID = 123;
String excellent =null;
String good=null;
String satisfactory=null;
String compensatableFail=null;
String outrightFail=null;
int grade;
public String gradeModule(int mark) {
String result = null;
if (mark>=70 && mark<=100)
{
result = excellent;
System.out.println(" ");
}
else if (mark>=60 && mark<=69)
{
result = good;
}
else if (mark>=50 && mark<=59)
{
result = satisfactory;
}
else if (mark>=40 && mark<=49)
{
result = compensatableFail;
}
else if (mark>=0 && mark<=39) {
result = outrightFail;
}
else {
System.out.println("Invalid entery, please insert an number between 100-0");
}
return result;
}
So I have add my invoking main method;
the method to call maybe the problem?
public static void main(String[] args) {
ModuleGrader mg=new ModuleGrader();
mg.gradeModule(100);
mg.gradeModule(66);}
You have assigned no values to String excellent;, String good;, so it fails because those values have not been initialized to anything when you call them.
How would you know that it is not working? You have no output of the final result to the console. I added System.out.println() to correct that.
You can't reference something which is not static from something which is static. Change public class ModuleGrader to public static class ModuleGrader.
Final Working Code
public class Main {
public static void main(String[] args) {
ModuleGrader mg=new ModuleGrader();
System.out.println(mg.gradeModule(100));
System.out.println(mg.gradeModule(66));
}
public static class ModuleGrader {
final int examID = 123;
String excellent = null;
String good = null;
String satisfactory = null;
String compensatableFail = null;
String outrightFail = null;
int grade;
public String gradeModule(int mark) {
String result = null;
if (mark >= 70 && mark <= 100) {
result = excellent;
System.out.println(" ");
} else if (mark >= 60 && mark <= 69) {
result = good;
} else if (mark >= 50 && mark <= 59) {
result = satisfactory;
} else if (mark >= 40 && mark <= 49) {
result = compensatableFail;
} else if (mark >= 0 && mark <= 39) {
result = outrightFail;
} else {
System.out.println("Invalid entery, please insert an number between 100-0");
}
return result;
}
}
}
You need to put quotes around the strings you want to assign.
result = excellent; should be result = "excellent"; and soforth for all your assignments to return
public class ModuleGrader {
final int examID = 123;
//String excellent=null;
//String good=null;
//String satisfactory=null;
//String compensatableFail=null;
//String outrightFail=null;
int grade;
public String gradeModule(int mark) {
String result = null;
if (mark>=70 && mark<=100)
{
result = "excellent";
System.out.println(" ");
}
else if (mark>=60 && mark<=69)
{
result = "good";
}
else if (mark>=50 && mark<=59)
{
result = "satisfactory";
}
else if (mark>=40 && mark<=49)
{
result = "compensatableFail";
}
else if (mark>=0 && mark<=39) {
result = "outrightFail";
}
else {
System.out.println("Invalid entery, please insert an number between 100-0");
}
return result;
}

Head First Java book battleship game

I am reading "Head First Java" book and I came across the problem in chapter 5 with the battleship game (with simple version). I knew that the book's code doesn't work and I tried my self fixing it, but it still didn't work.
So tried to google it and I found some post on this website but I still have a problem. The game isn't working properly as it should.
If a player enters any random number, the output is always "hit"...
This is the last version of the code:
DotCom class:
public class DotCom {
private ArrayList<String> locationCells = new ArrayList<>();
public void setlocationCells(int[] loc) {
if (loc != null)
for (int val : loc)
locationCells.add(String.valueOf(val));
}
public String checkYourself(String userInput) {
String result = "miss";
int index = locationCells.indexOf(userInput);
if (index >= 0) {
locationCells.remove(index);
}
if (locationCells.isEmpty()) {
result = "kill";
} else {
result = "hit";
}
System.out.println(result);
return result;
}
}
DotComGame class:
public class DotComGame {
public static void main(String[] args) {
int guessingTimes = 0;
DotCom dot = new DotCom();
GameHelperrr helper = new GameHelperrr();
int randomNum = (int) (Math.random() * 5);
int[] locations = { randomNum, randomNum + 1, randomNum + 2 };
dot.setlocationCells(locations);
boolean isAlive = true;
while (isAlive == true) {
String guess = helper.getUserInput("Enter a number");
String result = dot.checkYourself(guess);
guessingTimes++;
if (result.equals("kill")) {
isAlive = false;
System.out.println("You took " + guessingTimes + " guesses");
}
}
}
}
I would really appreciate to get a detailed and understandable answer, because I'm stuck and I couldn't move on with the book for a few days now.
int index = locationCells.indexOf(userInput);
This method will return -1 if the element doesn't exist in the collection.
So if you miss, it won't hit this condition:
if (index >= 0) {
locationCells.remove(index);
}
There are still elements in this collection because you didn't remove anything...
if (locationCells.isEmpty()) {
result = "kill";
} else {
result = "hit";
}
So on a miss, the result still shows "hit."
Try this instead:
if (locationCells.isEmpty()) {
result = "kill";
} else {
result = index == -1 ? "miss" : "hit";
}
If you haven't killed the opponents ships, then you either miss all ships or you hit a single ship.
I would guess the checkYourself-Method must be like this:
public String checkYourself(String userInput) {
String result = "miss";
int index = locationCells.indexOf(userInput);
if(index >= 0) {
locationCells.remove(index);
if (locationCells.isEmpty()) {
result = "kill";
}else {
result = "hit";
}
}
System.out.println(result);
return result;
}
In it's current form the ArrayList is never empty because you insert 3 Values but only remove 1 if the user-input is in the list so .isEmpty() is never TRUE.

Error: 'void' type not allowed here, within while loop (Java)

I keep getting the following error message in my method:
"Error: 'void' type not allowed here" on the line outEquation = outEquation + opSt.pop() + " ";.
The code I'm working on currently is a stacked linked list which takes in user input (in infix notation) and converts it to postfix. Any help would be appreciated.
import java.util.Scanner;
public class StackDemo
{
public static void main(String[] args)
{
final int right = 0;
final int left = 1;
final int ADD = 0;
final int MULT = 1;
final int EXP = 2;
final int PAR = -1;
}
public void UserPrompt()
{
Scanner keyboard = new Scanner(System.in);
String input = keyboard.nextLine();
System.out.println("Please select what type of conversion you would like to do: ");
System.out.println();
System.out.println("1) Infix to postfix \n2) Postfix to infix \n3) Print Equations \n4) Exit");
if(input == "1")
{
infix();
}
else if(input == "2")
{
postfix();
}
else if(input == "3")
{
print();
}
else if(input == "4")
{
System.exit(0);
}
else
{
System.out.println("That is not a correct input, please re-enter.");
UserPrompt();
}
}
public String infix()
{
String outEquation = "";
LinkedStackClass<String> opSt = new LinkedStackClass<String>();
Scanner keyboard = new Scanner(System.in);
System.out.println("Please enter the infix equation: ");
while(keyboard.hasNext())
{
String str = keyboard.next();
if(!isOperator(str))
{
outEquation = outEquation + str + " ";
}
else if(str.equals("("))
{
opSt.push(str);
}
else if(str.equals(")"))
{
while(!opSt.peek().equals("("))
{
outEquation = outEquation + opSt.pop() + " ";
}
opSt.pop();
}
else
{
while(opSt.size() > 0 && precede(opSt.peek(), str))
{
if(!opSt.peek().equals("("))
{
outEquation = outEquation + opSt.pop() + " ";
}
else
{
opSt.pop();
}
}
if(!str.equals(")"))
{
opSt.push(str);
}
}
while(opSt.size() > 0)
{
outEquation = outEquation + opSt.pop() + " ";
}
}
}
private static int getExpOrder(String op)
{
switch(op)
{
case "+":
case "-":
case "*":
case "/":
return left;
case "^":
return right;
//default
}
}
private boolean precede(String l, String r)
{
return (getPrec(l) > getPrec(r) || (getPrec(l) == getPrec(r) && getExpOrder(l) == left));
}
private int getPrec(String op)
{
switch(op)
{
case "+":
case "-":
return ADD;
case "*":
case "/":
return MULT;
case "^":
return EXP;
case "(":
case ")":
return PAR;
}
}
public static boolean isOperator(String op)
{
return (op.length() == 1 && "+-*/()".indexOf(op.charAt(0)) != -1);
}
public String toString()
{
return outEquation;
}
public void postfix()
{
System.out.println("Postfix");
}
public void print()
{
System.out.println("Print");
}
}
public class LinkedStackClass<T> extends UnorderedLinkedList<T>
{
public LinkedStackClass()
{
super();
}
public void initializeStack()
{
initializeList();
}
public boolean isEmptyStack()
{
return isEmptyList();
}
public boolean isFullStack()
{
return false;
}
public void push(T newElement)
{
insertFirst(newElement);
} //end push
public T peek() throws StackUnderflowException
{
if (first == null)
throw new StackUnderflowException();
return front();
} //end peek
public void pop()throws StackUnderflowException
{
if (first == null)
throw new StackUnderflowException();
first = first.link;
count--;
if (first == null)
last = null;
}//end pop
}
Ok, so the reason are you getting that error message is because your pop() function has a void return. Typically, in a stack implementation, the pop operation will remove the top item of the stack and return it. Your function only removes the element.
So change your pop() function to look as follows (I apologize in advanced, as Java is not my forté, and this may not even be correct, so you may need to tweak this):
public T pop() throws StackUnderflowException
{
if (first == null)
throw new StackUnderflowException();
// Get the top-most element
T top = peek();
first = first.link;
count--;
if (first == null)
last = null;
return top;
} //end pop
However as user Ashley Frieze stated, better to use an existing implementation if possible, rather than roll your own.

Return the position first position two strings are different

i can't figure out how i am supposed to return the first position org and check are different. Do i have to use substrings?
import acm.program.*;
public class CheckPasswords extends ConsoleProgram
{
public void run()
{
while(true)
{
String org = readLine("Enter Password: ");
String check = readLine("Confirm Password: ");
if(org.equals(check))
{
println("Password Confirmed");
}
else
{
println("Passwords do not Match");
//???
}
}
}
}
This is the easiest and clearest way
private int getPositionWhereTextDiffer(String a, String b) {
int position = 0;
while ( b.length() > position &&
a.length() > position &&
a.charAt(position) == b.charAt(position)) {
position++;
}
return position;
}
My solution would be:
static public int indexOfDiff(String one, String two) {
if(one!=null && two!=null) {
if(one==null || two==null) {
return 0;
}
else {
int ln=(one.length()<two.length() ? one.length() : two.length());
for(int xa=0; xa<ln; xa++) {
if(one.charAt(xa)!=two.charAt(xa)) { return xa; }
}
if(one.length()!=two.length()) {
return ln;
}
}
}
return -1;
}
This returns -1 if the strings are in fact equal (including if both are null), which generally should not be the case in practical use since the string will already be know to be different.
If you want to just check if they are equal or not , you can use:
int val = org.compareTo(check);
It will return 0 if they are equal, negative value if org is before check , else positive value if org is after check.
If you really want to return the first position where they are unequal, use this function:
int firstMismatch(String org, String check)
{
int limit = (org.length()>check.length())?org.length():check.length();
for(int i=0;i<limit;i++)
{
try{
if(org.charAt(i)!=check.charAt(i))
{
return i; //If one of the strings end, that's the position they are different, otherwise there is a mismatch. Either way, just return the index of mismatch
}
}
catch(Exception e)
{
if(org.length()!=check.length())
{
return(i); //Execution comes here only when length of strings is unequal
//Exception occurs because first string is smaller than
// the second or vice versa. Say if you use "fred" and"fredd" as org and check
//respectively, "fred" is smaller than "fredd" so accessing org[4] is not allowed.
//Hence the exception.
}
System.out.println("Problem encountered"); //Some other exception has occured.
return(-2);
}
}
return(-1); //if they are equal, just return -1
}
EDIT : And in your code, call as follows:
public class CheckPasswords extends ConsoleProgram
{
public void run()
{
while(true)
{
String org = readLine("Enter Password: ");
String check = readLine("Confirm Password: ");
int mismatchPosition = firstMisMatch(org,check);
if(mismatchPosition==-1)
{
println("Password Confirmed");
}
else
{
println("Passwords do not match from position "+mismatchPosition);
}
}
}
}
boolean isDifferent = false;
if(org!=null && check!=null) {
if(org.length()!=check.length()) {
System.out.println("String are diff at position, "+check.length()+1);
} else {
int mismatchPos = 0;
for(int i=0; i< org.length();i++) {
if(org.charAt(i)!=check.charAt(i)) {
isDifferent = true;
mismatchPos = i;
break;
}
}
if(isDifferent) {
System.out.println("String are diff at position, "+mismatchPos);
}
}
}

How to prevent my program from crashing due to a user's input

I am trying to implement an algorithm "recongnizng strings in a language "
L = {'w$w' : w is a possible empty string of characters other than $,
w' = reverse(w)}
my problem is whenever i input anything without having $, it crashes on the while loop. what will be the best way to prevent it from crashing?
public boolean isInLanguage(String inputString)
{
StackReferenceBased stack1 = new StackReferenceBased();
StackReferenceBased stack2 = new StackReferenceBased();
Object qItem;
Object sItem;
int index = 0;
if (inputString.length() == 0)
{
return false; // empty string not in L
}
else if (inputString.length() == 1)
{
return true;
}
**while (inputString.charAt(index) != '$')**
{
// save the first half of the string
stack1.push(inputString.charAt(index));
++index;
}
// index points to '$' or its value > than inputString.length()
while (index < inputString.length()-1)
{
// save the second half of the string
++index;
stack2.push(inputString.charAt(index));
}
do
{
// match the first half of the string with the second half
if ((stack1.isEmpty() && !stack2.isEmpty()) ||(!stack1.isEmpty() && stack2.isEmpty()))
{
return false;
}
qItem = stack1.peek();
sItem = stack2.peek();
if (qItem != sItem)
{
return false;
}
if (!stack1.isEmpty())
{
stack1.pop();
}
if (!stack2.isEmpty())
{
stack2.pop();
}
}while (!stack1.isEmpty() || !stack2.isEmpty());
if (stack1.isEmpty() && stack2.isEmpty())
{
return true;
}
else
{
return false;
}
}
Exception in thread "main" java.lang.StringIndexOutOfBoundsException:
String index out of range: 4 at java.lang.String.charAt(Unknown
Source) at
assignmnet5.StackReferenceBased.isInLanguage(StackReferenceBased.java:87)
at assignmnet5.Question3.main(Question3.java:19)
this is my main:
public static void main(String[]args)
{
StackReferenceBased stack = new StackReferenceBased();
String str;
boolean bool;
Scanner kb = new Scanner(System.in);
System.out.println( "Enter a string to be checked by the algorithm : ");
str = kb.next();
**bool = stack.isInLanguage(str);**
if (bool == true)
System.out.println( "The string is in language");
else
System.out.println("The string is not in language");
}
It sounds like this might suffice:
if (inputString == null || !inputString.contains("$")) {
return false; // empty string not in L
}
possible issue is a null pointer exception, try to add this line in the top of your function
public boolean isInLanguage(String inputString)
{
if(inputString == null){
return false;
}
...
...
complete your code
if you still have crashes, you will need to provide the error you've got when you run the code.

Categories

Resources