How can I check an else statement correctly using &&? - java

Just a quick question, can i use this to include "left" "right"
back" and "forward" all together or do i have to do them separately?
An error came up, so if anyone knows how to include them all together then please help. Thanks
Scanner console = new Scanner(System.in);
for (int i = 0; i < 100; i++) {
System.out.println("Please type in either the word \"left\" or \"right\" or \"back\" or \"foward\": ");
String s = console.next();
if (s.equalsIgnoreCase("left")) {
myFinch.setWheelVelocities(90,90,S);
myFinch.setWheelVelocities(0,100,S);
} if (s.equalsIgnoreCase("right")) {
myFinch.setWheelVelocities(90,90,S);
myFinch.setWheelVelocities(100,0,S);
} if (s.equalsIgnoreCase("back")) {
myFinch.setWheelVelocities(-100,-100,S);
} if (s.equalsIgnoreCase("foward")) {
myFinch.setWheelVelocities(130,130,S);
} else if (s.equalsIgnoreCase != ("left" && "right" && "back" && "foward")) {
myFinch.quit();
}

I would go with a switch statement :
switch (s.toLowerCase()) {
case "left":
myFinch.setWheelVelocities(90,90,S);
myFinch.setWheelVelocities(0,100,S);
break;
case "right":
myFinch.setWheelVelocities(90,90,S);
myFinch.setWheelVelocities(100,0,S);
break;
}

First off to answer your question, in Java you should use String.equals to compare strings, or String.equalsIgnoreCase. This is because this example will fail:
String a = "a";
if (a == "a") {
// Will not be true because you are comparing the reference to the string "a"
} else if (a.equals("a")) {
// Will work because you are comparing on the value of the two strings
}
ref: == vs .equals
I noticed you did this in the first few statements, but on the last statement, the one in question, you did not.
While the statement you were trying to form was not necessary I find it would be useful to share the correct way to do it:
// OMITTED CODE
} else if (s.equalsIgnoreCase("left") && s.equalsIgnoreCase("right") && s.equalsIgnoreCase("back") && s.equalsIgnoreCase("foward") ) {
myFinch.quit();
}
You must make each boolean statement complete, in the sense that it must evaulate to a boolean.
s.equalsIgnoreCase != x// this is simply method so it could not be compared to anything using the != operator
("left" && "right" /* etc */ ) // "left", "right" are not booleans but simply strings.
Java is a very explicit language so shortcuts as the one you attempted are often far and few between.
Secondly you should use the format:
if (/* condition 1*/) {
// code if condition 1 is true
} else if (/* condtion 2 */) {
// code if condition 2 is true but condition 1 is false
} else {
// code if condition 1 and condition 2 are false
}
The else if statement is used to simplify code that would take the following format:
if (/* condition */) {
// code will run if condtion is true
} else {
if (/* sub-condition */) {
// code will run if sub-condition is true, but condition is false
} else {
if (/* sub-sub-condition */) {
// code will run if sub-sub-condition is true, but sub-condition and condition are false
} else {
// code will run if condition, sub-sub-condition, and sub-condition is false
}
}
}
To avoid long chains of such code:
if (/* condition */) {
// code will run if condtion is true
} else { if (/* sub-condition */) {
// code will run if sub-condition is true, but condition is false
} else { if (/* sub-sub-condition */) {
// code will run if sub-sub-condition is true, but sub-condition and condition are false
} else {
// code will run if condition, sub-sub-condition, and sub-condition is false
}}}
The formatting can be seen clearly from here to the current setup:
if (/* condition */) {
// code will run if condtion is true
} else if (/* sub-condition */) {
// code will run if sub-condition is true, but condition is false
} else if (/* sub-sub-condition */) {
// code will run if sub-sub-condition is true, but sub-condition and condition are false
} else {
// code will run if condition, sub-sub-condition, and sub-condition is false
}
These statements were created to read in a logical way:
If the first condtion is met follow the first set of instructions,
else if the first condition wasnt met then try the second condition and instructions,
else if the first two conditions failed try the third set!,
else Damn! Just resort to these instructions
Imagine a scenario where you are taking care of your friend's cat. You are unable to talk about how to care for the cat before your friend leaves but they left you a set of instructions:
Dear friend,
Thank you for looking after muffins. She is a very high maintenance cat.
She has four kinds of food and depending on her mood you should feed her one of
these four: "Purina Super Awesome Cat Time", "Cat Feast 2000", "Cat Chow", and
"Canned".
If you come over and she is waiting at the door give her the "Cat Fest 2000",
If she is not waiting at the door, but instead attacks your leg as you enter the
house you should give her the "Cat Chow",
If she is not at the door, and didn't attack you but is instead wearing a small hat
you should give her the "Purina Super Awesome Cat Time" and play a game of Bridge with
her.
If none of those things happened then give her the "Canned".
Thanks! See you Caturday!
Instead of sending yourself on this monstrous task, with clearly outlined danger, perhaps we want to write a very intelligent robot to go in and take care of the cat each day.
// Upon arrival
if ( Cat.isWaitingAtTheDoor() ) {
Cat.feed("Cat Fest 2000");
} else if ( Cat.didAttackWhenYouWalkedIn() ) {
Cat.feed("Cat Chow");
} else if ( Cat.isWearingSmallHat() ) {
Cat.feed("Purina Super Awesome Cat Time");
Cat.playBridgeWith(self);
} else {
Cat.feed("Canned");
}
So reformat your code to match that structure and you will find you don't need that last condition:
Scanner console = new Scanner(System.in);
for (int i = 0; i < 100; i++) {
System.out.println("Please type in either the word \"left\" or \"right\" or \"back\" or \"foward\": ");
String s = console.next();
if (s.equalsIgnoreCase("left")) {
myFinch.setWheelVelocities(90,90,S);
myFinch.setWheelVelocities(0,100,S);
} else if (s.equalsIgnoreCase("right")) {
myFinch.setWheelVelocities(90,90,S);
myFinch.setWheelVelocities(100,0,S);
} else if (s.equalsIgnoreCase("back")) {
myFinch.setWheelVelocities(-100,-100,S);
} else if (s.equalsIgnoreCase("foward")) {
myFinch.setWheelVelocities(130,130,S);
} else {
myFinch.quit();
}
}
The way you had it set up initially you essentially are not creating a branch structure.
consider this:
int i = 0;
if (i == 0) {
System.out.println("i = 0");
i = 1;
} if (i == 1) {
System.out.println("i = 1");
} else {
System.out.println("i is neither 1 or 0");
}
This will out put:
i = 0
i = 1
Not what we intended!
This is because the above code is equivalent to:
int i = 0;
if (i == 0) {
System.out.println("i = 0");
i = 1;
}
// Two separate statements altogether
if (i == 1) {
System.out.println("i = 1");
} else {
System.out.println("i is neither 1 or 0");
}
Whereas:
int i = 0;
if (i == 0) {
System.out.println("i = 0");
i = 1;
} else if (i == 1) {
System.out.println("i = 1");
} else {
System.out.println("i is neither 1 or 0");
}
Will give:
i = 0
What we wanted, now it is a branched statement, it checks the first if statement then all else if statements following and lastly if none were true resorts the else statement. This seems to be your intention since there is no space for variab;e reassignment between these if statements.

Since JDK 7 you can use strings in switches.
Means:
switch(s.toLowerCase()) {
case "left":
myFinch.setWheelVelocities(90,90,S);
myFinch.setWheelVelocities(0,100,S);
break;
case "right":
myFinch.setWheelVelocities(90,90,S);
myFinch.setWheelVelocities(100,0,S);
break;
case 'back':
myFinch.setWheelVelocities(-100,-100,S);
break;
case "foward"
myFinch.setWheelVelocities(130,130,S);
break;
/** .. and other cases **/
default:
myFinch.quit();
}

Related

For if loop wont loop: any pointers to why that might be?

This is supposed to loop 24 times; it does not, and I'm pretty confused as to why. Please help me various Kenobis out there :
private boolean simpleMove(Board bd)
{
int b = rn.nextInt(3);
for (int i = 0; i < 24; i++) {
if (bd.isVacant(i) && rul.isLegalMove(tigerLocs[b], i)) {
bd.swap(tigerLocs[b],i);
bd.setTiger(i);
tigerLocs[b] = i;
System.out.println(i);
return true;
}
else {
System.out.println(i);
}
}
System.out.println("invalid");
return false;
As the comments point out your loop will execute a maximum of 24 times.
But the return statement inside the if statement may cause it to return 'early'.
It looks like it's some kind of board game thing.
The board appears to have 24 'squares' and it makes the first legal move and returns true.
If it fails to find a legal move, it returns false.
I can't confirm the logic overall but that rationale seems sound:
If there's a move available, take it and return true.
If no move is available, make no move and return false.
If you expected it to continue, even after finding a "valid" move, then simply store the fact that a valid move has been found. This can be done in a separate boolean variable:
private boolean simpleMove(Board bd) {
int b = rn.nextInt(3);
boolean valid = false; // until proven otherwise below
for (int i = 0; i < 24; i++) {
if (bd.isVacant(i) && rul.isLegalMove(tigerLocs[b], i)) {
bd.swap(tigerLocs[b],i);
bd.setTiger(i);
tigerLocs[b] = i;
valid = true;
}
System.out.println(i); // why output HERE when we have a return value?
}
if (!valid) {
System.out.println("invalid"); // why output HERE when we have a return value?
}
return valid;
}
It's unclear if multiple "valid" moves could be found, and whether that would be a problem when you "swap" or not. If there is only ever one possible move, then there would be no need to continue iterating with the for loop; simply return in the body like you were doing.

How could we implement a garage door keeping track of what was its last moving direction?

I am doing the following programming exercise: Killer Garage Door. The statement is:
Situation
You have been hired by a company making electric garage doors.
Accidents with the present product line have resulted in numerous
damaged cars, broken limbs and several killed pets. Your mission is to
write a safer version of their controller software. Specification
We always start with a closed door. The remote control has exactly one
button, with the following behaviour.
If the door is closed, a push starts opening the door, and vice-versa
It takes 5 seconds for the door to open or close completely
While the door is moving, one push pauses movement, another push resumes movement in the same direction
In order to make the door safer, it has been equiped with
resistance-based obstacle detection. When the door detects an
obstacle, it must immediately reverse the direction of movement. Input
A string where each character represents one second, with the
following possible values.
'.' No event
'P' Button has been pressed
'O' Obstacle has been detected (supersedes P)
As an example, '..P....' means that nothing happens for two seconds,
then the button is pressed, then no further events. Output
A string where each character represents one second and indicates the
position of the door (0 if fully closed and 5 fully open). The door
starts moving immediately, hence its position changes at the same
second as the event. Example
..P...O..... as input should yield 001234321000 as output
I have written the following code:
public class Door {
public static String run(String events) {
System.out.println("\n\n\nevents: "+events);
int count = 0;
StringBuilder result = new StringBuilder();
boolean movingUp = false;
boolean movingDown = false;
for(char c : events.toCharArray()){
System.out.println("movingUp: "+movingUp);
System.out.println("movingDown: "+movingDown);
System.out.println("c: "+c);
System.out.println("count: "+count);
System.out.println("result: "+result);
if(c=='.'){
if(movingUp){
result.append(count < 5 ? ++count : 5);
}else if(movingDown){
result.append(count > 0 ? --count : 0);
}else{
result.append(count);
}
}else if(c=='P'){
if(count==5){
movingUp = false;
movingDown = true;
result.append(count > 0 ? --count : 0);
}else if(movingUp){
movingUp = false;
result.append(count);
}else if(movingDown){
movingDown = false;
result.append(count);
}else{
movingUp = true;
result.append(count < 5 ? ++count : 5);
}
}else if(c=='O'){
movingUp = false;
movingDown = true;
result.append(count > 0 ? --count : 0);
}
}
return result.toString();
}
}
I was wondering how could we handle, when there is a pause and then the door resumes again, to be able to keep it going up or down, as it was doing before the pause?
Here are some tests, the ones marked with →, are the ones where the pause or obstacle behaviour fails because of currently the code assumes that after a pause it should go upwards, and after an obstacle it should go downwards.
import static org.junit.Assert.*;
import org.junit.Test;
public class MainTest {
#Test
public void testNormalOperation() {
test("should stay closed unless button is pressed (no buttonpresses)", "..........", "0000000000");
test("should start opening on buttonpress", "P..", "123");
test("should open completely and stay open", "P....", "12345");
}
#Test
public void testPause() {
test("should start opening and pause on second buttonpress", "P.P..", "12222");
test("→ should resume closing on third buttonpress", ".....P......P.P..P....", "0000012345554333321000");
}
#Test
public void testObstacles() {
test("should reverse while opening", "P.O....", "1210000");
test("→ should reverse while closing", "P.O....", "12345554345555");
}
#Test
public void testObstaclePlusPause () {
test("→ should reverse while opening (and allow pause)", "P..OP..P..", "1232222100");
}
#Test
public void testExample() {
test("should start opening and reverse when obstacle", "..P...O.....", "001234321000");
}
private void test(String description, String events, String result) {
assertEquals(description ,result, Door.run(events));
}
}
I have also read:
https://users.cs.jmu.edu/bernstdh/web/common/lectures/summary_state_pattern.php
How could we implement a garage door keeping track of what was its last moving direction?
You're almost there. So in the interest of keeping your code intact I attempted
to introduce as few changes as needed.
However one correction is needed before proceeding - one of your test cases
is not correct, the 2nd test case in testObstacles is not valid.
Was:
test("→ should reverse while closing", "P.O....", "12345554345555");
// in the above the first 'P' would start it "12" and the first "O" should
// immediately reverse it (which would be reversing while opening) "1000"
So assuming the text is correct and the expected result is correct then the input should be:
test("→ should reverse while closing", "P.......P.O....", "12345554345555");
Short answer:
Introduce a boolean which records the previous up or down movement:
boolean lastUp = true; // default to true since we always assume initially CLOSED
The remaining changes are in th 'P' and 'O' case using lastUp:
else if (movingUp)
{
movingUp = false;
lastUp = true; // ADDED
result.append (count);
}
...
else if (movingDown)
{
movingDown = false;
lastUp = false; // ADDED
result.append (count);
}
... and update default case
else
{
movingUp = lastUp; // CHANGED
movingDown = !lastUp; // ADDED
result.append(movingUp ? ++count : --count); // CHANGED
}
And in 'O' case:
{
movingUp = !movingUp; // CHANGED
movingDown = !movingDown; // CHANGED
lastUp = !lastUp; // ADDED
result.append(movingUp ? ++count : --count); // CHANGED
}
Long Answer
Well, the long answer uses a different approach and this is essentially #grodzi 's answer (state then input) which has a great explanation but since it took me so long to enter it the point is moot.
I'll add it since it is in the language of your choice.:
public static class Door
{
enum DoorStates { OPEN, CLOSED, MOVINGUP, MOVINGDOWN, PAUSED }
public static String run (String events)
{
int count = 0;
StringBuilder result = new StringBuilder ();
DoorStates currentState = DoorStates.CLOSED;
DoorStates lastMovingState = DoorStates.MOVINGUP;
for (char c:events.toCharArray ())
{
switch (currentState)
{
case OPEN:
if (c == 'P') {
currentState = DoorStates.MOVINGDOWN;
count--;
}
// do nothing for O and .
break;
case CLOSED:
if (c == 'P') {
currentState = DoorStates.MOVINGUP;
count = 1;
}
// do nothing for O and .
break;
case MOVINGUP: // movingup
if (c == 'P') {
currentState = DoorStates.PAUSED; // paused
} else if (c == 'O') {
currentState = DoorStates.MOVINGDOWN; // movingdown
count--;
} else {
if (count < 5) {
count++;
}
if (count == 5) {
currentState = DoorStates.OPEN; // open
}
}
break;
case MOVINGDOWN:
if (c == 'P') {
currentState = DoorStates.PAUSED; // paused
} else if (c == 'O') {
currentState = DoorStates.MOVINGUP; // movingup
count++;
} else {
if (count > 0) {
count--;
}
if (count == 0) {
currentState = DoorStates.CLOSED;
}
}
break;
case PAUSED:
if (c == 'P') {
currentState = lastMovingState;
count = (currentState == DoorStates.MOVINGUP ? count+1 : count-1);
}
// do nothing for O and .
break;
} // end switch
if (currentState == DoorStates.MOVINGUP ||
currentState == DoorStates.MOVINGDOWN) {
lastMovingState = currentState;
}
result.append (count);
} // endfor
return result.toString();
} // end run
} // door class
An approach by using states.
We can list two trivial ones: closed and opened.
I will name them respectively idleUp, and idleDown.
transitions for idleUp:
P (user pushed the button): so you are now activeUp
transitions for activeUp:
P (user pushed another time): idleUp (keep the direction, but do nothing)
O: activeDown
End (door is fully opened): idleDown
transitions for activeDown:
P: idleDown
O: activeUp
End: idleUp
transitions for idleDown:
P (user pushed the button): so you are now activeDown
Something like graph below.
+----------+ P +--------+
| activeUp +<----->+ idleUp |
+----------+ +--------+
| ^ O ^
|End +---------+ |End
v v |
+----------+ P +------------+
| idleDown +<----->+ activeDown |
+----------+ +------------+
Notice the (somehow elegant) symmetry between activeUp-idleUp and activeDown-idleDown.
In your approach you are char first, then state. In below code we are state first, then char.
Instead of considering four states, we only "code" two: active and idle (but under the hood we indeed have four states, simply conditionned via variable instead of classes)
You sure can use a pattern state, but feels a bit tiresome.
function simu (str) {
let direction = 1 // 1 for up, -1 for down
let pos = 0 // initially closed
let active = false
let out = '' // the return string
for (let c of str) {
if (active) {
if (c === '.') {
pos += 1 * direction
if (pos <= 0 || pos >= 5) {// End
active = false
direction *= -1
}
}
else if (c === 'O') {
direction *= -1
pos += 1 * direction // instant change of direction
}
else if (c === 'P') {
active = false
}
} else { // idle
if (c === 'P') {
active = true
pos += 1 * direction // instant change too
}
}
out += pos
}
return out
}
function test(libel, s, exp) {
const out = simu(s)
if (out != exp) {
throw 'failed '+libel+' got '+out+' expect '+exp
}
console.log('OK', s, '->', out)
}
test("should stay closed unless button is pressed (no buttonpresses)", "..........", "0000000000")
test("should start opening on buttonpress", "P..", "123")
test("should open completely and stay open", "P....", "12345")
test("should start opening and pause on second buttonpress", "P.P..", "12222")
test("→ should resume closing on third buttonpress", ".....P......P.P..P....", "0000012345554333321000")
test("should reverse while opening", "P.O....", "1210000")
test("→ should reverse while closing", "P.......P.O....", "123455554345555") //thx Andy
test("→ should reverse while opening (and allow pause)", "P..OP..P..", "1232222100")
test("should start opening and reverse when obstacle", "..P...O.....", "001234321000")

Repeat an increment of loop

For my science fair project, I'm wanting to give a graphical update to a French-teaching program that's so old it's emulated in DosBOX. That's all well and good but I'm having problems. I'm writing the base logic of the program in a console application just to get that together. I've created a Question class that's in a array list/collection known as "test1".
I have a loop that iterates through the list and with each iteration, it runs another method called evaluate:
public static boolean evaluate(Question question, Scanner scanner)
{
System.out.println(question.getPhrase()); // prints the question
String answer = scanner.nextLine(); // gets the answer
if (answer.compareTo(question.getCorrectAnswer()) == 0)
return true; // compares the answer to the correct answer w/i the current instance of "Question"
else
return false; // if it's not right, returns "false" meaning the question wasn't correct
}
The loop looks as such:
for (Question question : test1)
{
if (evaluate(question, scan))
{
incorrect = 0;
continue;
}
else
{
incorrect++;
System.out.println(incorrect);
}
if (incorrect == 3)
System.out.println("you have failed");
break;
}
I want to make it so that if you answer a question incorrectly, it spits out the phrase again and increases "incorrect" by 1 and, if you hit 3, terminates the list (I think I've got this implemented correctly if I could just get it to repeat the question). Right now it moves to the next item in the list and thus the next question even if and I don't want that.
Sorry if my code is awful, I'm still relatively new to programming.
Create a while loop inside of the for loop that says if the question isn't answered correctly, then repeat so that way in each question the question will be asked until its correct. Keep everything inside the for loop in the while loop that you should create:
for (Question question : test1)
{
while(!evaluate(question, scan)) {
if (evaluate(question, scan))
{
incorrect = 0;
continue;
}
else
{
incorrect++;
System.out.println(incorrect);
}
if (incorrect == 3)
System.out.println("you have failed");
break;
}
}
Instead of doing a foreach loop the way you're doing it now, you can do the following:
for (int i = 0; i < test1.size(); i++) {
Question question = test1.get(i);
if (evaluate(question, scan)) {
...
} else {
incorrect++;
test1.add(question);
}
if (incorrect == 3) { ... }
}
This is assuming you're using a data structure that uses size() and add() as methods; you can adjust it to what you're using.
This will repeat questions later, though not immediately after. If you want to repeat it immediately after, just decrement i-- in the else case:
for (int i = 0; i < test1.size(); i++) {
Question question = test1.get(i);
if (evaluate(question, scan)) {
...
} else {
incorrect++;
i--;
}
if (incorrect == 3) { ... }
}
You can also nest a loop for the else case:
for (Question question : test1) {
boolean passed = True;
incorrect = 0;
while (!evaluate(question, scan)) {
incorrect++;
if (incorrect == 3) { passed = False; break; }
}
if (!passed) { System.out.println("you have failed"); break; }
}

how to jump from inner loop to outer loop

Here is the structure of my program:
for(loop1){
if(condition1)
{
for(loop2)
{
for(loop3)
{
if(condition1_3)
{
As condition1_3 is true continue with loop2's next iteration,
No need to execute loop3's remaining iteration
}
else
{
As condition1_3 is false no need to execute remaining part of loop3 and
loop 2 but continue with loop1's remaining part i.e. condition1_1
}
}
}
}
if(condition1_1)
{
some code here
}
}
I know I have to use continue and break statement but don't understand exactly how?
Please tell me how to achieve this mechanism?
If I understand your question, you could use the labeled continue,
loop1: for (;;) {
if (condition1) {
loop2: for (;;) {
loop3: for (;;) {
if (condition1_3) {
continue loop2;
} else {
continue loop1;
}
}
}
}
}
You can do as follows:
for(loop1){
if(condition1)
{
for(loop2)
{
boolean flag=false;
for(loop3)
{
if(condition1_3)
{
break;
}
else
{
flag=true;
break;
}
}
if(flag)
break;
}
}
if(condition1_1)
{
some code here
}
}
Do like the following -
for(loop1){
boolean flag = false;
if(condition1)
{
for(loop2)
{
if(flag == true)
break;
for(loop3)
{
if(condition1_3)
{
break;
}
else
{
flag = true;
break;
}
}
}
}
if(condition1_1)
{
some code here
}
}
An option would be to use variables - but you have to think about correct setting of values:
boolean runFor1 = true;
boolean runFor2 = true;
boolean runFor3 = true;
for(loop1 && runFor1)
{
for(loop2 && runFor2)
{
for(loop3 && runFor3)
{
setRunForX here to skip/unskip loops
}
}
}
}
Have a exit flags which is set when you want to exit a particular loop and check in each respective loops whether to continue or exit.
boolean exitLoop2 = false;
for(loop1){
if(condition1)
{
for(loop2)
{
for(loop3)
{
if(condition1_3)
{
//As condition1_3 is true continue with loop2's next iteration,
//No need to execute loop3's remaining iteration
break;
}
else
{
//As condition1_3 is false no need to execute remaining part of loop3 and
//loop 2 but continue with loop1's remaining part i.e. condition1_1
exitLoop2 = true;
break;
}
}
if(exitLoop2)
{
break;
}
}
}
if(condition1_1)
{
some code here
}
}
To break out and not continue the loop3 use break; if (condition1_3) break; The break; statement only breaks out of the current loop i think, not the loop it is nested in.
Edit: Missread the question
To break out of both loops you can make a boolean flag before both loops and at the end of both loops have an if (breakOut) break; This will solv the question
I'm not really shure what do you mean exactly. For me it simply looks like you want to jump out of the loops if a specific condition is satisfied. So you can either can define a label for your loops and use the continue labelLoopX; statement or you can satisfy the exit condition of loop3 if condition1_3==true resp. the exit condition of loop3 and loop2 if condition1_3==false. e.g. if loop3 looks like for ( int i = 0; i < 10; i++ ) like this:
if(condition1_3){
//do something important
i=10; //sets i to 10 and condition i < 10 is unsatified
}
else{
//do some other important stuff
i=10; //satify loop3's exitcondition
j=10; //satify loop2's exitcondition
}

For loop error, how do i fix this?

for(int x = 0;x<14;x++){
day[x]= theSheet.changeLetters(day[x]);
}
public String changeLetters(String entering){
if(entering.equalsIgnoreCase("a")){
entering = "10";
} else {
if(entering.equalsIgnoreCase("b")){
entering = "11";
} else {
if(entering.equalsIgnoreCase("c")){
entering = "12";
} else {
if(entering.equalsIgnoreCase("d")){
entering = "13";
} else {
if(entering.equalsIgnoreCase("e")){
entering = "14";
} else {
if(entering.equalsIgnoreCase("f")){
entering = "15";
} else {
if(entering.equalsIgnoreCase("g")){
entering = "16";
} else {
if(entering.equalsIgnoreCase("h")){
entering = "17";
}
}
}
}
}
}
}
}
return entering;
}
Says the error is here if(entering.equalsIgnoreCase("a")) and in the for loop I am using to run the method. I'm trying to change the letter put into the string into a number.
Can anyone explain to me where the error might be? I'm having trouble spotting the issue. it lets me enter the letters fine but it has an exception once it gets to this for loop and runs this method.
why don't you use
if (condition) {
// ...
} else if (condition2) {
// ...
} else if (condition3) {
// ...
}
// and so on
to make your code more readable. Your nested conditions are a mess. If you fix them, you might as well fix the error (if it's in the part of code you showed us).
Also add
System.out.println("Entering = '" + entering "'");
at the beginnig of your method to see if really receives what you are expecting it to receive.
Ok according to
Yes the code is being initialized in a for loop before that one using
for(int x =1;x<8;x++){ day[x-1] = JOptionPane.showInputDialog("Enter
hour pairs for day "+x +".\n Enter the first digit: "); day[x] =
JOptionPane.showInputDialog("Enter the second digit: "); } the letters
being put in the array are then changed into numbers using the for
loop posted earlier.
You have a logic error. You are overwriting previous entries and not filling the array up to 14 items. So items after 8 are left null, thus the NullPointerException.
Try this:
String[] day = new String[14];
for( int i = 0; i < 14; i+=2 ) {
day[i] = JOptionPane.showInputDialog("Enter hour pairs for day "+(i/2+1) +".\n Enter the first digit: ");
day[i+1] = JOptionPane.showInputDialog("Enter the second digit: ");
}
As a bonus, you can simplify the if-else code with:
public String changeLetters( String entering ) {
return String.valueOf(entering.toUpperCase().charAt(0) - 55);
}
As #jlordo already stated avoid nested if-statements with such a depth.
As an alternative you might use a switch statement in combination with an enum like this - although the following approach consists of more code it is more general and better suitable to be extended (e.g. using all letter of the alphabet and beyond) and it would make the code much more readable and more appropriate with respect to what you want to express.
Letter letter;
if (letter.equals("a")) letter = Letter.a;
if (letter.equals("A")) letter = Letter.A;
// and so on ...
switch (letter) {
case a : {
// do some code here ...
break;
}
case A : {
// do some code here ...
break;
}
// and so on ...
}
public enum Letter {
a (1),
A (2),
b (3),
B (4),
c (5),
C (6);
// and so on
private final int index;
Letter(int i) {
index = i;
}
public int getIndex () {
return index;
}
}
Note that if you're using Java 7 you can use the switch statement even without the enum since it accepts strings as well like this:
switch (entering) {
case "a" : {
// ...
}
// ...
}

Categories