Win a copy of Kotlin in Action this week in the Kotlin forum!
  • Post Reply Bookmark Topic Watch Topic
  • New Topic

Sentinel won't work.  RSS feed

 
Karen Guffey
Ranch Hand
Posts: 87
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I have spent over 6 hours just trying to get the program to terminate when I want it to.

Forgive me; I'm so tired. Good afternoon. How are you?

This is a course assignment, & it's supposed to be, essentially, a 4-function calculator. I need to ask for an operation & then get two operands. I have to account for input that's not one of the 4 operation choices, & I have to give an option to quit the program. Everything works except the sentinel, which is 0 in my program. When the user enters it, the program responds as if it's one of the 4 & asks for two operands. Whatever they are, the answer is 0.0 (0 is supposed to end the program & doesn't have an operation to perform), & the program proceeds as normal, accepting 0 or one of the four operations, asking for operands, & performing the operations correctly.

Why won't it stop???


 
Tapas Chand
Ranch Hand
Posts: 614
9
BSD Java
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Because "break" is not the way to quit from a method/program.
It just skips the loop and continues with the next statement after the loop.
 
Tapas Chand
Ranch Hand
Posts: 614
9
BSD Java
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Moreover you need to put braces in loops and if-statements even if they contain only one line of code.
This is considered to be a good programming practice and helps avoiding silly mistakes.
 
Karen Guffey
Ranch Hand
Posts: 87
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
OK...so how do I quit? The only other thing I've been able to find is "system.exit," which, as I understand it, can only come at the very end of a program.
 
Tapas Chand
Ranch Hand
Posts: 614
9
BSD Java
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
There are various ways.
You can keep your logic in a if-statement and have an else for illegitimate inputs.
Or better if you can return from that point where you face illegitimate input using "return" and show a user friendly message.
Or you can throw exception(if you have already learnt).
 
Karen Guffey
Ranch Hand
Posts: 87
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Thank you. I'll try that. No, I haven't learned exceptions yet.

*sigh* I feel like I'm freezing & about to jump back into the deep end of a very cold pool.
 
Tapas Chand
Ranch Hand
Posts: 614
9
BSD Java
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Try and comeback if you find any more difficulties, comeback and post the code if you are able to solve it
 
Campbell Ritchie
Marshal
Posts: 55751
163
  • Likes 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
It is a bit unfair to call a 0 illegitimate input.

I would suggest you go farther with dividing into little methods. If you have multiple choices, have you come across the switch statement?Alternative for case 0:
case 0:
    // do nothing
    break;

That means if your option is 0, your method will return 0. You can of course wrap your switch in a loop. Maybe a do loop is a good idea.

Did you know you can do arithmetic with an enum? I like that idea because it is more object‑oriented. You can have an ADD object, SUBTRACT, etc. Now, where have I seen anything like that? Not the faintest idea. Scroll down to fig 8.9.3-3.

And don't spend six hours over something that short without asking for help.
 
Karen Guffey
Ranch Hand
Posts: 87
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Thank you. I do know how to use "switch," but we haven't done classes or objects in my class yet. I know what they are but am rusty on using them. I think Java is at least as bad as if not worse than a natural language in that "what you don't use, you lose"!

I actually understood everything you said, CR--which is definitely not the case with everything I read about Java, even with stuff on my level--but it's going to take a bit to wrap my head around it & put it together. Thank you & please keep talking down to me!
 
Junilu Lacar
Sheriff
Posts: 11155
160
Android Debian Eclipse IDE IntelliJ IDE Java Linux Mac Spring Ubuntu
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

What you have here is a failure to communicate. The instructions you wrote don't match what you really wanted the computer to do. The break statement will abort the enclosing while loop that starts on line 22. This doesn't make sense logically because that's like telling somebody: "Ok, keep running until I say 'STOP!'" and then immediately saying "STOP!"

What you really want to say is: "If the operation is 0, then exit from this method"

In this case, an if-statement is more appropriate instead of a while-loop and a return statement instead of break.
 
Karen Guffey
Ranch Hand
Posts: 87
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Oh man oh man oh man, Junilu!!! I still need to run some more tests, but for the first time since I began this daggone program hours & hours & hours ago, it terminates!!! I had that return has the effect of terminating the program, & I still don't quite get that, but it worked! I THINK I've gotten the idea of passing to parameters, which is one of the Java pieces I absolutely needed to get, so maybe this will start me on my way to understanding "return"! But better yet, I think you've saved my sanity! (Or what's left of it.) Thank you!
 
Karen Guffey
Ranch Hand
Posts: 87
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Ta da! A program that runs EXACTLY as it's supposed to!



But I don't think I'm ready to quit my day job. Thanks for all the help!
 
Campbell Ritchie
Marshal
Posts: 55751
163
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Well done

But why are you using recursion rather than a loop?
 
Junilu Lacar
Sheriff
Posts: 11155
160
Android Debian Eclipse IDE IntelliJ IDE Java Linux Mac Spring Ubuntu
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Campbell Ritchie wrote:
But why are you using recursion rather than a loop?

My guess is that the indirect recursion is unintentional.

Karen, recursion is when you call the same method again either directly or indirectly before it has a chance to exit. Even if the call is the last statement of the method, execution of the method is still not complete until after it has been fully exited. In this case, you are doing indirect recursion:

perform(int) --> perform(int, double, double) --> perform(int) --> perform(int, double, double) --> ....

If you run this program long enough without selecting 0 for operation, you will get a StackOverflowError.

 
Campbell Ritchie
Marshal
Posts: 55751
163
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
On the average PC you will have to run it several thousand times before you start running out of stack space.
 
Karen Guffey
Ranch Hand
Posts: 87
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I actually had a couple of reasons for using recursion.

First, as I was writing the program & came to the end of the method, I realized I'd already written what I needed to come next, so the easiest thing just seemed to make the last thing in the method a call to the method I needed.

Second, the lesson on it in chapter 20 of our books was something we had to read along with methods in Chapter 5, so I figured my professor might be impressed if I used it.

Sooo...recursion somehow uses up more RAM than loops? Or more whatever-it-is that holds the program, so that it fills up &, um, overflows? Just asking for confirmation, not an explanation. My book has something about finding program steps in stacks, & I haven't been able to process THAT yet.

I have my mid-term a week from tomorrow, & I'm not going to do well. One thing we have to do is read a program & tell what the outcome will be, & as counter-intuitive as it seems to me as a linguist, since reading & writing come more easily than writing & speaking, reading a program is much more difficult for me than writing one. Is that normal? It's like I have to write it to understand it. And, quite honestly, since I test it as I go along, I sometimes make a small change to see if it will make the program work, & it does, but I'm really not sure why!
 
Tapas Chand
Ranch Hand
Posts: 614
9
BSD Java
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Karen Guffey wrote:...reading a program is much more difficult for me than writing one. Is that normal?

After few years of doing job as a Java programmer I still feel the same.
And I do not know whether this is normal.
I always prefer debugging a program to understand it (if there is no documentation available).
Anyways understanding a code only by reading has been getting better since I am hanging out with Ranch.
 
Campbell Ritchie
Marshal
Posts: 55751
163
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Agree; it can be difficult to read a program. That is why we complain about poorly‑indented code and incorrect naMing conVentions, which make the code even harder to read.

Use the following instruction on your .class file:-
javap -c Assignment4_main
and you get a printout of what the bytecode means. You probably won't understand it, but you will be able to count the lines. Each line pushes an instruction onto the stack, and probably other details, e.g. value of an operand, memory location of an object as an operand. So a method which takes 30 lines to print out probably puts 100 things onto the stack. I suspect the last thing on the stack is an address to return to, i.e. which instruction called that method. So let's have a stack pointer pointing to address 1234567890(decimal). You call method foo() and the pointer now points to 1234567990. Then foo recursively calls itself and you are at 1234568090. Then foo recursively calls itself and you are at 1234568190. Then foo recursively calls itself and you are at 1234568290. Then foo recursively calls itself and you are at 1234568390. …

That is why you must have a means of limiting recursion; each recursive call has a slightly smaller argument that the previous one and eventually you get to something which terminates altogether, e.g.
return i == 0 ? 1 : i * factorial(i - 1);
You can see what a nice simple way that is to calculate factorials. Each time you call it, the argument is 1 smaller, and it terminates by returning 1 when you reach 0. At that point the stack space becomes available for reuse. If however you try calculating −1! (which, I beleive, does not actually exist) that method will run out of stack space long before you reach 0.
Your recursive call has a different means of limiting itself. You call the method by hand, so it only increases its recursive depth by 1 whenever you enter an option. You will most probably enter 0 for the termination condition long before you run out of stack space.
 
Winston Gutkowski
Bartender
Posts: 10573
65
Eclipse IDE Hibernate Ubuntu
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Karen Guffey wrote:First, as I was writing the program & came to the end of the method, I realized I'd already written what I needed to come next, so the easiest thing just seemed to make the last thing in the method a call to the method I needed.
Second, the lesson on it in chapter 20 of our books was something we had to read along with methods in Chapter 5, so I figured my professor might be impressed if I used it.

Reasonable logic; however, it violates one of the Golden Rules of programming, which has two parts:
1. Do one thing at a time.
2. When faced with two (or more) choices, or options, for how to proceed: choose the simplest one first.

Apart from possibly mathematicians - who are trained in things like induction, which help a lot - most people find recursive logic quite hard. I've been at this lark for more than 35 years, and I still find it tough. Now that's not to say I don't use it; but I always keep plenty of paper and pencils around when I do.

So, faced with your situation, I would have probably written a simple program with a basic loop, and got that working first. Then - if I still had time - I would have tried for the brownie points and re-written it as a recursive function (making sure I kept a copy of my "basic" one first of course ).

One thing we have to do is read a program & tell what the outcome will be, & as counter-intuitive as it seems to me as a linguist ... reading a program is much more difficult for me than writing one. Is that normal? It's like I have to write it to understand it...

It's perfectly normal. When you write a program, you know what you're thinking (hopefully). When you read one, you have to try and reverse-engineer what the writer was thinking when they wrote it.

And that's just one of the reasons why it's so important to Write Dumb Code. If I write a program that is hard for other people to read, I've just insured that it will probably be consigned to File 13 very quickly.

So: write clearly; use descriptive names everywhere (but within that constraint, keep them as short as possible); DontWriteLongLines; and stick to normal Java conventions.
Also: Learn about Javadoc, and use it. Everywhere.

And, quite honestly, since I test it as I go along, I sometimes make a small change to see if it will make the program work, & it does, but I'm really not sure why!

I suspect because you still don't understand the problem (or the solution you've written to it). Coding should be the last thing you do, and ONLY when the process is pretty much a mechanical one. As most of the contributors here are probably bored with hearing me saying:
      You cannot write a decent program in Java until to you can describe what it does in English (or your native language).

You might also want to read the StopCoding (←click→) and WhatNotHow pages, which exapnd on some of these points.

Good luck. Hope it helps.

Winston
 
Karen Guffey
Ranch Hand
Posts: 87
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Campbell--Thank you! That helps me visualize what's happening behind the scenes.

Winston--Since I broke rule 1, recursion was the simplest solution, so I really only violated half the principle! I do test as I go along, but I don't think I'm seeing the program in bits (& I don't mean binary digits here). I'm doing a bit (gotta find a better, non-computing word) better since Campbell told me to use several methods rather than one big one, but it's not something that comes naturally to me.

I read "Write Dumb Code," but I think I'm still to dumb to understand all of it. I get the meaning, but I don't see how I could possibly know enough right now to write anything but dumb code!

I think my "let's try this" approach is because I don't completely understand what the program is doing &, sometimes, because I'm not so great at math. Like, one time I switched two statements, & that fixed the problem. They needed to be executed in that order, & they had math in them, so... And if there's anything worse than math, it's examples with letters representing numbers! Put a number in there, & then I'll figure out how to do it with other numbers! I'm chomping at the bit to get to Strings!

 
  • Post Reply Bookmark Topic Watch Topic
  • New Topic
Boost this thread!