The reason why I said better is subjective is because there are many ways to create a calculator program from a console perspective and from a GUI perspective as well.
I figured I'd take what I've learnt so far and try making a simple calculator program... It works, but I'm sure there most be a more straightforward way of doing this. Any advice / suggestions would be greatly appreciated.
So, you want to learn more. That is a good attitude!
1.) How about changing the if-else statements to a switch-case one? If you are using java 7 or higher, you can use Strings to pass into it. It is general to use it instead of ifs in a situation like this.
2.) You could try having the user only type in "3 + 12", in one line. Messing a bit with the scanner and its methods could work for that.
For a short program, it was nice and easy to read, so keep on the good work. I merely suggested these two enhancements because you asked for it! Up to the challenge?
Best regards, Dóri
Next, get everything out of the main() method. This may seem unnecessary for a short program, but it's a good habit to get into. See Main is a Pain.
Firstly, thank you for that link, Knute... I've done that now and understand why it's a good thing to do so will maintain that. However, I'm at a loss here. I'm fairly sure I am missing something very small somewhere...
This is the launcher (obviously):
This is the rest of the code in the separate file, but same package:
When I try to run it I'm getting the error: Exception in thread "main" java.lang.ClassFormatError: Duplicate field name&signature in class file calculator/Calculator. Erm...??? I looked up the error and it says about a bug in NetBeans? Is that right or am I doing something wrong here? Any help please :/
P.S. Dori, I'm also working on the switch-case, but want to get this lil problem sorted first
Exception in thread "main" java.lang.ClassFormatError: Duplicate field name&signature in class file calculator/Calculator
at java.lang.ClassLoader.defineClass1(Native Method)
at java.security.AccessController.doPrivileged(Native Method)
I've marked amendments:
The rest :
I'm not sure why, but prior to this working it was giving me the error that it couldn't find the main class... I checked right clicking on project > properties > run > Main Class and it said calculator.Calculator and when I tried to change it to calculator.CalculatorLauncher as I was expecting to find it wasn't in the list. Any ideas why that might be? Oh, it's working fine now
Hope all are well.
So, here's a calculator that the entire calculation would be on a single input, not number - enter - next number etc... This seems to work fine Any suggestions / advice? Took a lot longer for me to figure that one out and it turned out to be so simple! :O
Ok, looking at the "drunk - rewkjt" user input now Also, is there ever a need to use float instead of double? There seems no obvious reason to do so.
Ben Poland wrote:So, here's a calculator that the entire calculation would be on a single input, not number - enter - next number etc... This seems to work fine
Great work Ben! I particularly like the way you've worked through the problem gradually and come up with different "versions" that use different styles. If you keep up that level of effort, you're going to be a good programmer; and in the meantime, enjoy a cow!
However, do you notice that after nicely breaking up all your logic in your earlier versions, you're now back to having all of it in one place again with Calc? Personally, I'd say that's a step backwards - although I can understand why you did it.
Just one alternative might be a generic "binaryFunction" method, viz:and then in your run() method your can simply write:
System.out.println("Your answer is: " + binaryFunction(val1, function, val2));
However, there's arguably an even better way; and that's to use enums with a value for each operation you want to implement.
If you haven't got to them yet, don't worry about it; but if you have, have a think how you might use them.
HIH, and once again: Well done!
Ben Poland wrote:Also, is there ever a need to use float instead of double? There seems no obvious reason to do so.
Basically, the only reason you should ever use float is:
(a) When you've been told to.
(b) If another system that you have no control over is supplying them to yours.
You can, of course, convert the latter to a double; but it might give you a misleading sense of "accuracy", so you need to be careful about doing stuff like that.
Thank you for this feedback, I really appreciate it. The challenges, suggestions are a very good way to learn and it's very motivating, so really thank you very much for the help AND the cow Didn't know what you meant when I read that, then I read the description of "cows" here, really good idea, so whoever came up with it, GJ! I also agree about the code layout and will go back to how I'd done it before and keep that format moving forward.
I'll try the binary function suggestion, after I read about it that is And no, not got to enums yet, but as soon as I do I'll try that also. I'll also try to make this calc somewhat more "functional", include percent, square root, that sort of thing.
Again though, thank you so much for the help.
Ben Poland wrote:I'll try the binary function suggestion, after I read about it that is
Don't get too hung up on the name.
I simply called it 'binaryFunction()' to highlight the fact that it takes two values rather than one (or three, or four...). You could just call it 'function()' if you want.
All standard arithmetic operations are "binary" because they take two arguments - as opposed to 'log' or 'sin' or √, which only take one (they're called "unary").
Again though, thank you so much for the help.
You're most welcome.
Hope you're well...
So, I have the calc getting percentages, square roots and throwing exceptions for illegal characters etc, happy with that, but the problem now is if the user for example enters 3x3 it will error as it's not been entered as 3 x 3, same if characters are not entered in the right case. I've been digging around to find a way to stop this, but not having any luck OR not understanding what I'm finding. Could anyone point me in the right direction to solve this please? I'd rather not just be told how to do it.
Thank you in advance guys,
The "3+3" part is harder, but I'd look into regular expressions, which in Java is implemented with the Pattern and Matcher classes. Without giving too much away, you would want to do something like this:
If you want more clues about this I can give them to you.
Just read through the regex stuff, think I'll go back to that after sorting the case sensitive stuff I should have been a little clearer about what I was asking, but didn't think there was going to be such a difference here. It's only a char that I need to get taken as lower case... At the moment if I enter the character upper case, error, program ends... I saw the Character class and how that works, but doesn't work for this, well, doesn't seem to from what I've tried. Char variable is more than a single character, although the userInput is only a p or s. I tried adding it to the char declaration, the userInput, the System.out.println, but no joy on any. Hope that makes sense :/
Ben Poland wrote:if characters are not entered in the right case.
What "characters"? If you chose 'x' as meaning "multiply" then you've only got yourself to blame, because the Java standard is '*'.
And even if you did, you only have one character to worry about: 'x' (or 'X').
There are solutions that involve "regular expressions", but TBH, I'm not sure you need one just at the moment.
Have a think about WHAT you want your user to input: a "number", followed by an "operator", followed by another "number".
You already had a solution that was working, but it would appear that you now want them to be able to enter either 'x' or 'X' instead of '*' as an operator. Have a look at your switch statement, and see if you can't amend it to handle your two new cases.
Char variable is more than a single character, although the userInput is only a p or s.
A char variable can only be one character. I'd use a String and someString.toLower() but if you must have a char, I think Character.toLower(charVar) will work. Maybe show us your code now.
Ben Poland wrote:And worry not, Winston, I'm not using x instead of *, that was just me typing when over tired and forgetting that my brain needs a break sometimes
Unfortunately, it's starting to look a bit "monolithic" again because you have all your code in one place. Why not think about how you might break it up into "tasks", so that your run() code becomes a nice series of "do this...do that" calls to well named methods.
That way, anyone can read what's going on really easily - "oh, he's getting some input here...then he's calculating a result...then he's printing it out...".
It takes a bit of practice, but it usually results in cleaner, more flexible code that's much easier to read.
PS: Don't forget to save this "version" before you do - especially if it works.
So I am trying to figure this out, but suddenly realise what I wasn't understanding... And well, still don't, but playing, reading will address that fact
I usually before making changes to anything start a new program, type the whole thing up again (helps to get it firmly into my brain) and then make all changes so then it really doesn't matter if things break etc... I always have the original
So just to make sure I'm at least looking in the right direction, I should be writing another class and from within that class have methods running parts of the program and then refer back to it rather than writing line to line ("monolithic" ;) ) style code?
- X 3
Ben Poland wrote:So just to make sure I'm at least looking in the right direction, I should be writing another class and from within that class have methods running parts of the program and then refer back to it rather than writing line to line ("monolithic" ;) ) style code?
Kind of, but sorting out what classes (or objects) your program uses is slightly different.
First off, you need to understand what you're doing. Note: What, not how.
When you start out, there's a tendency to want to dive straight into code, because you think that's what you're supposed to be learning. It's also fun, and you get instant gratification when it works. However, most pros probably spend less than 20% of their time actually coding; the rest is spent analysing, designing, testing and just plain thinking.
So if you see an old warhorse like me sipping coffee and staring off blankly into space, don't assume that I'm slacking off...or having a 'senior' moment.
So, what is your program doing? I'd say it's doing a few things:
1. It's getting an "operator" from a user.
2. It's getting values for that operator to work on.
3. It's applying that operator to the value (or values) you got.
4. It's displaying the result back to the user.
Now there may be a few other things it's doing too: For example, #1 above may involve validating the operator, and repeating input requests until your "user" gets it right", but even that's starting to venture into the "how" (ie, the procedure), when what you really want to concentrate on is the "what".
So, if the above list seems reasonable, why not write some method signatures for it? Eg:
And now I can write a "draft" version of my run() method, viz:And now it "tells a story". Anyone looking at it can tell immediately what it's doing without all that "procedural clutter" - which, you may also note, I haven't even written yet.
However, I can be pretty confident that when I do, the program will probably work the way I want it to.
Like I say, it takes a bit of practice, and you'll probably develop your own techniques as you write more and more programs; but separating the "what" from the "how" is a really good place to start.
Ben Poland wrote:So just to make sure I'm at least looking in the right direction, I should be writing another class and from within that class have methods running parts of the program...
I should add that what I showed you above was a way of breaking down a program functionally into tasks. However, we've still only got one class, and I think part of your question was: Should I be writing any more classes?
And the answer to that (as with many things in CS) is: It depends. However, the mere fact you're thinking about it suggests that perhaps you should at least look into it. Java is an Object-Oriented language; and that means that it usually works best with objects (or classes).
However, my suggestion would be to tackle this (as you already have) bit by bit.
Come up with a nice, modular, "story telling" program first, and then we can delve into the business of "objects".
- X 2
Also, I started a project (will be calculator) from scratch, so aside the default stuff that displays it is just a blank canvas. I did that because I sat back and thought pretty much the way you said, I need to know WHAT I want to be happening rather than looking at what I already have and trying to fix something without understanding what it is exactly I want it to be doing, let alone how. So I'm going to slow down, back up a few steps and then approach the project in parts, break it down and get all the "whats" in order first, then approach the how, at which point I should better understand the dfferent things I will actually need to make the "whats" possible.
Really, I can't thank you guys enough for your help... I'd probably end up running into one of those "brain walls" soon enough, but this advice will ensure avoiding that situation.
So again, thank you very, very much,
* Remove all user input from the calculation. Put it in methods of a different class. This will set you up to start a GUI.
* Put a loop in run() so that the user can do several calculations, then type "q" to quit.
Now a note on your formatting. In general it looks really good except two things:
* Comments at the end of ends should be avoided, or be very short.
* Your lines should be shorter. The best way is to make them 80 characters or less. Here's the start of your class with the formatting suggestions:
Will get both done... Your suggestions are what I figured would have to be the next steps to get this project to a final working program, so now I have to implement them. I hadn't thought of the q to quit thing though, I like that idea a lot.
I really appreciate all the pointers, suggestions and general advice you guys have given me. I hope it continues And when I get good enough myself, hope to be able to do the same for other people...
Cheers guys, really glad I found this forum
P.S. Next version coming soon
Ben Poland wrote: is there ever a need to use float instead of double?
You would use float instead of double whenever you wanted to lose precision because your data does not warrant it. There are several ways that could occur:
Once, when I was a beginning programmer, I had access to a vector display in the room where I was working. Each day, upon completing work, I played on the vector display. I constructed an image of a windmill using two isosceles triangles point-to-point, among other graphics. When I made them rotate, they gradually became distorted. It did not matter whether I used double or float; they still got distorted. I clearly understood that a detailed analysis of error would have prevented the distortion. But I chose the easy way: every rotational cycle was computed in double. At the end of each cycle, all coordinates were truncated to float before starting the next cycle. By truncating to float, the errors accumulated during computation were lost, and everything started clean again. Errors accumulate because digital fractions do not evenly express decimal fractions. The more calculations you do before correcting them, the closer the errors become to the decimal point. After the change: rock solid images!!
That's very interesting actually, certainly not something I'd think about. Cetainly good to know. So float used more in an animation environment?
I'm working on this now, but just want to clarify I'm not ballsing this right up! I have another class setup with a bunch of methods for user input and the other class has methods for calculating those inputs... Soooo, it's kinda bouncing back and forth between those classes / methods? It's far from finished on even one yet, but I'll post what I have so far... Please let me know if I'm way off base. I tried something like this before, but was unable to get the final value to pass into another method, which is why I decided I'd take a step back first and just go the method route for now. I'll post the code I have now and then explain more what I mean. There are errors all over the place, but please ignore those unless there are BIG no no's, this is very much work in progress.
One class and second class:
So as you can see I've basically split user input into one class and calculations in another with each type of calculation in it's own method, far from finished as you'll see. I'm also probably going get rid of the switch statement for + - * / and just set a method for each, especially because of the loop and also wanting to be able to get a longer sum on a single line (3 * 3 + 3 / 2 for example), although that may well be better done in a single method.
Anyway's, there's what I have for now, am I going hideously wrong? :O
As far as I am concerned, a float is an affliction which should be avoided unless some API, e.g. this forces you to use it. I am also not convinced that changing doubles to floats improves precision. A better way to rotate images is (probably) to copy the Graphics object:-I have not had problems with rotation; it is shear that causes problems with arithmetic.
Ben Poland wrote:. . . Also, is there ever a need to use float instead of double? There seems no obvious reason to do so.