#RPN calculator

1 messages · Page 1 of 1 (latest)

dull orchid
#
 public class rpn {
    private Object[] array;
    
    
    public rpn(int n){
        array = new Object[n];
       for(int i=0;i<n;i++){
        array[i]=0;
       }
    }
     
     int calculator(Object[] n){
        int p=0;
        
        if(n.length == 1 ){
            return (int)n[0];
        }
           for(int i=0;i<n.length-2;i++){
            
            if (n[i] instanceof Integer && n[i + 1] instanceof Integer && n[i + 2] instanceof Character && ((char) n[i + 2] == '+' ||(char) n[i + 2] == '-'||(char) n[i + 2] == '*'||(char) n[i + 2] == '/'))  {
    ////////////////symbol check///////////////
                if(n[i+2] instanceof Character && ((char)n[i+2] == '+')){
                p=(int)n[i]+(int)n[i+1];
                }
                if(n[i+2] instanceof Character && ((char)n[i+2] == '-')){
                    p=(int)n[i]-(int)n[i+1];
                    }
                if(n[i+2] instanceof Character && ((char)n[i+2] == '*')){
                    p=(int)n[i]*(int)n[i+1];
                    }
                if( n[i+2] instanceof Character && ((char)n[i+2] == '/')){
                    if(n[i+1] instanceof Integer && ((int)n[i+1] == 0)){
                        break;
                    }
                    p=(int)n[i]/(int)n[i+1];
                    }
            //////////////////////////////////////////
                Object[] temparray = new Object[n.length-2];
                    for(int j=0;j<i;j++){
                        temparray[j]=n[j];
                    }
                 temparray[i]=p;
                    for(int j=i+3;j<n.length;j++){
                        temparray[j-2]=n[j];
                }
                    return calculator(temparray);
            }
            
            if(n[i] instanceof Character && n[i+1] instanceof Character && ((char)n[i]=='+'||(char)n[i+1]=='+')){
                System.out.println("your input is wrong");
                break;
            }
    }            return 0;
}
#
public static void main(String[] args) throws Exception {
    Object[] test = new Object[5];
    test[0] = 1;
    test[1] = 1;
    test[2] = 7;
    test[3] = '/';
    test[4] = '+';
    System.out.println(test.length);
    System.out.println(test[4] instanceof Integer);
    rpn peos = new rpn(5);
    int result = peos.calculator(test);
    System.out.println("Result: " + result);
}
}
#

so this is like the first version of the rpn

#

the question is if right now the calculator is good and how a programm should be (i have some conscernse about the class that has a private array and that i don't use it in my calculator function)

#

second question any features that you guys recomend

balmy grotto
#

Do you implement the shunting yard ?

In computer science, the shunting yard algorithm is a method for parsing arithmetical or logical expressions, or a combination of both, specified in infix notation. It can produce either a postfix notation string, also known as Reverse Polish notation (RPN), or an abstract syntax tree (AST). The algorithm was invented by Edsger Dijkstra and name...

#

I did an RPN algorithm once, for Grace actually 😂 - Implementing the shunting yard algo shortened the amount of code used and upped the speed

#

I haven't read how you did yours, but you should take a look

elfin onyx
#

I have a few comments for you but don't currently have time to write them. I'll send them once I have a few minutes.

balmy grotto
#

Oh

#

Oh silly me

elfin onyx
#

However, the shunting yard algorithm is indeed related to that. It allows you to parse infix notation to postfix notation, reverse polish notation (RPN) or an abstract syntax tree (AST)

dull orchid
#

man i want to make that the user just type the entire expression like 5+5

#

man i dont have the smallest idea on how to do this

dull orchid
elfin onyx
midnight mica
#
if(n.length == 1 ){
            return (int)n[0];
        }

This can crash with ClassCastException, pass '+' first

#

what about float / double / long ?

#

casting is not really proper

#

like you should cast to Number then nb.intValue()

dull orchid
#

i first done it using just the (int)n[i]

#

without n[i] instanceof Integer

midnight mica
#

which is really (int)(((Integer)n[i]).intValue())

#

you could get an NPE or CCE easily

#

like you don't even have try/catch 😂

dull orchid
#

man i really cant understand most of what you are telling me stunned

midnight mica
#

also your member array and constructor are useless

dull orchid
midnight mica
#
    test[0] = null;
    test[1] = null;
    test[2] = "+";
//OR

    test[0] = 3L;
    test[1] = 1.4d;
    test[2] = '+';
#

this.array not used anywhere

#

you should try an older JDK6 compiler, it would tell you what's wrong.

#

Problem with JDK8+ is implicit autoboxing and deboxing

#

so unless you use Java Free SpotBugs plugin, you won't know that there is an issue

dull orchid
midnight mica
#

then put your function static, and no need for constructor 😄

dull orchid
#

first time trying to make anything still clueless for a lot of things

midnight mica
#

then this becomes a procedural utility class

dull orchid
#

the programm returns 0 as it should do

midnight mica
#

Try:

test = new Object[] { null };

or

test = new Object[1];

dull orchid
#

ok so the problem is that the test[1] = null and i am trying to typecast to int but it is null and it can't do that

#

so just this can solve it right

 if(n.length == 1 ){
            if(n[0]==null){
                return 0;
            }
            return (int)n[0];
        }
dull orchid
midnight mica
#

just use instanceof Number

#

(null instanceof Number) == false

#

then you can cast to int, if it's Number
{ Double, Integer, Long, Float, BigDecimal, BigInteger, etc. }

#

if it's a instanceof CharSequence then s.toString().trim().charAt(0)

dull orchid
#

(i want for start just to use int numbers)

 if(n.length == 1 && n[0] instanceof Integer ){
           
            return (int)n[0];
        }
#

with this in main Object[] test = new Object[5];
test = new Object[1];
the program do return 0 as it should

midnight mica
#

yes, because instanceof checks for null

#

are you using maven or Eclipse ?

dull orchid
#

thanks very much for your comments fd26. Man i had to open like 5 tabs on google to just "translate" some words you told that i couldn't understand verysmiile

dull orchid
midnight mica
#

😬

#

try Eclipse with Maven and SpotBugs and Git/svn plugin

#

it's free

dull orchid
#

uni made us to download eclipse for java however i already had vs in my pc and it was like preety simple just to plug in java to vscode

midnight mica
#

also git init locally and git commit anything that compiles and run 😄

#

Eclipse let you debug and do major refactoring safely

dull orchid
midnight mica
#

amazing

#

are you on Windows or Linux or Mac

dull orchid
#

i am just hella bad

#

windows

midnight mica
#

OK did you install TortoiseGIT ?

#

and WinMerge ?

dull orchid
dull orchid
#

first time using git had a lot of problems understanding for some reason

midnight mica
#

you should makes your life WAY easier

#

and it's also free 😄

midnight mica
#

also you have some AIOBE exception 😂

#

doing n[i+2] without doing any array bound checks*

#

you are doing instanceof but not checking length

midnight mica
#

after some refactoring in Eclipse 😄

dull orchid
#

second of all you shouldn't spend your time trying to correct my code i feel bad

midnight mica
#

You are very much welcome 🙂

#

you said you didn't need Eclipse / TortoiseGit 😛

#

I was trying to show you that it helps a lot 😄

#

like trying to make a good point 😛

#

you see how the code on the right is much easier to read ?
at least to me

dull orchid
#

i start doing the project so i could get better so just like listing what to do in my code i think it would be better for you cause i really don't want to get a completed program and call it mine HOWEVER i can really learn from what you sent and even implement some things in my code but after i understand

midnight mica
#

like tools exist that once you got a working proof-of-concept right that mostly work

#

you use git and Eclispe refactoring to make it clean 😄

#

and ensure that you are 100% covered

#

I was going to show you how to use Eclipse and TortoiseGit, but i dunno

#

maybe I should create my own YouTube tutorial 😂 instead

dull orchid
#

i have actaully worked with eclipse in uni so i have some knowledge

#

isn't eclipse for java only?

midnight mica
#

in the beginning yes, nowadays no

#

it works also with C/C++/PHP also

#

and html/css/js and jsp

#

but the refactoring, I only do with Java

#

I use EditPlus instead of vscode for anything more write only 😂

#

vscode is now broken on Linux due to webview2

dull orchid
#

okey why you recomend eclipse more than vs? is there any reason

#

i think i found out why

midnight mica
#

the refactoring and debugging

#

for C/C++, use Visual Studio

dull orchid
#

so with winmerge you can just compare your 2 commits and see what you have changed ?

midnight mica
#

you can use WinMerge or TortoiseDiff

#

I use both, sometime it's easier with WinMerge than TortoiseGit, depends on the changes

dull orchid
#

so it also checks for bugs

midnight mica
#

YES !!!!

#

it's like jshint for JavaScript

#

or PCLint nt-lint.exe for C/C++

#

spotbugs works with mvn command line or Eclipse

#

does not work in IntelliJ or whatever

#

findbugs is the older version for JDK8-

#

and then it will "rewrite your code"

#

to make the code more concise

#

anyway try it and let me know 😄

dull orchid
#

pov me struggling to understand how the turtle works

#

idk i have to download 3 seperate things to do what i can do with just vscode in which i can have most of the features all of 3 apps give but in 1 place and more begginer friendly environnment

#

just to use the winmerge i have to go to my files and search for my commited files and then i can compare them

#

i still haven't figure out how to use the turtle1

dull orchid
#

i changed some things of the program cause as you guys said i didn't like that the constructor not array is being used in the program

#
public class rpn {
    private Object[] array;
    
    
    public rpn(int n){
        array = new Object[n];
       for(int i=0;i<n;i++){
        array[i]=0;
       }
    }
    public void setter(Object[] n){
        this.array = n;
    }
     
      int calculator(){
        int p=0;
        
        if(array.length == 1 && array[0] instanceof Integer ){
           
            return (int)array[0];
        }
        
           for(int i=0;i<array.length-2;i++){
            
            if (array[i] instanceof Integer && array[i + 1] instanceof Integer && array[i + 2] instanceof Character && ((char) array[i + 2] == '+' ||(char) array[i + 2] == '-'||(char) array[i + 2] == '*'||(char) array[i + 2] == '/'))  {
            ////////////////////symbol check////////////////////////////////


#
if(array[i+2] instanceof Character && ((char)array[i+2] == '+')){
                p=(int)array[i]+(int)array[i+1];
                }
                if(array[i+2] instanceof Character && ((char)array[i+2] == '-')){
                    p=(int)array[i]-(int)array[i+1];
                    }
                if(array[i+2] instanceof Character && ((char)array[i+2] == '*')){
                    p=(int)array[i]*(int)array[i+1];
                    }
                if( array[i+2] instanceof Character && ((char)array[i+2] == '/')){
                    if(array[i+1] instanceof Integer && ((int)array[i+1] == 0)){
                        break;
                    }
                    p=(int)array[i]/(int)array[i+1];
                    }
            ///////////////////////////////////////////////////////////////
                rpn temprpn = new rpn(array.length-3);
                Object[] temparray = new Object[array.length-2];
                    for(int j=0;j<i;j++){
                        temparray[j]=array[j];
                    }
                 temparray[i]=p;
                    for(int j=i+3;j<array.length;j++){
                        temparray[j-2]=array[j];
                }
                    temprpn.setter(temparray);
                    return temprpn.calculator();
            }
            
            if(array[i] instanceof Character && array[i+1] instanceof Character && ((char)array[i]=='+'||(char)array[i+1]=='+')){
                System.out.println("your input is wrong");
                break;
            }
    }
            return 0;
}
public static void main(String[] args) throws Exception {
    Object[] test = new Object[7];
    test[0] = 1;
    test[1] = 1;
    test[2] = '+';
    test[3] = 12;
    test[4] = 4;
    test[5] = '+';
    test[6] = '+';
    System.out.println(test.length);
    rpn peos = new rpn(5);
    peos.setter(test);
    int result = peos.calculator();
    System.out.println("Result: " + result);
}
}```
#

i changed a lot in the calculator function how it is been used

#

made a setter so i can change the array's values

#

so in the calculator method i won't call it using a parameter but i will call it from the class itself

#
  1. question is this better than it was?
#

2.i have in mind first to make some more changes in the calculator method so it can fix some bugs?(i don't know if there are any)

#
  1. to make the input of the user to be more like the whole expresion 5+5 and the program store it in the array
#

4.and final to make a gui are those good checkpoints? should i add some or remove some?

elfin onyx
#

Instead of addressing your points directly, I have a few general suggestions about to make your code easier to maintain and expand.

I lied, there is one of your point I will talk about. As I mentioned before, parting infix (ex. 5 + 5) expression is much harder than you might think and in my opinion no a priority to learn. Instead, I would recommend that you concentrate on building a proper stack calculator (with a GUI or not) before investing some time in learning how to parse expressions and you can easily add it once you built something strong.

What I want to talk about first is separation of concerns. Separation of concerns is dividing your software in different components that are responsible for a specific concern (task). Properly separating your program like that makes your program more maintainable, scalable and flexible. This means that, when properly done, you can easily extend your program without too much effort or changes. It also makes parts of your code much easier to reuse in different context (ex. using same code for CLI and GUI). This saves you a lot of code and prevents a lot of mistakes.

In your program there is 2 main concerns. The calculator and the inputs. The calculator can (and should) be completely separated from your input logic. You want to have a class that don't care about how it gets the data from the user or where the data comes from. It manages the stack and the calculation. That's it. Similarly, the code that handle the user input don't really want to know about the how the calculator work. It wants to concentrate on one thing and that's getting the user input. This would mean you'd have a very simple stack calculator class that would have a few methods, such as push that adds a value in the stack, add that add the 2 last numbers in the stack and puts it back and all the other arithmetic operations you want. The input logic would be located elsewhere and would use this other class instead of being intertwined.
.

#

If the picture isn't clear yet, this not only brings a better organization but also allows you to simplify all the parts of your code - no need to do that much complex input parsing) it makes your code easily extendable - you can use the same calculator code for a cli, gui, web app, api, etc.

If you need too, I can always show you some code examples.

On another note, it's important to follow a proper style convention when you write your code. Here's Java's style convention. I'd suggest to checkout the naming convention first. Another note on this, take a bit more time to name your variables. A lot of your variables are one letter or generic names. It makes it difficult to understand why they are used for. Ex. a variable called p doesn't tell much about what it is, but if it was called price you know instantly what it is and what it's used for. Having a good code hygiene is essential. It makes everything so much easier. Related to that, setters shouldn't be called setter. They should say what they set. Ex. setPrice.

dull orchid
# elfin onyx If the picture isn't clear yet, this not only brings a better organization but a...

thanks very much for the reply it means alot. So for the next step (you insist) to make my code more easy to read with better names for variables etc. maybe some comments and better spacing. Next, when i want to make the input method i should do it in a separate file? folder? class? (i would like a more step by step or what to search on yt/google to find how to do it) so each method would be in it's own so i can update or maintain the code more easy.I would also ask is the program that i know have good? Should i try make any repairs? thanks again

elfin onyx
# dull orchid thanks very much for the reply it means alot. So for the next step (you insist) ...

I don't really want to give you a step by step. Making you think about how to separate things is part of the process. If I'm giving a step by step it robs you from the learning process. Separate the calculator and the inputs. I gave lots of information that can help you determine how to do it. For now, you don't need to separate this in multiple files, but you definitely want to create a calculator class that is standalone. That said, the way java works, you could have the main there for the cli and testing. That's really your call. Obviously, eventually, file organization and classes becomes more important. Specially when you'll add a GUI.

yt/google to find how to do it
You can google "coupling and cohesion", "single responsibility principle" and "separation of concerns".

I would also ask is the program that i know have good?
Well, as I said, there's lot in term of design to improve. So, is it good, not really-ish. There's still lots to improve.

Should i try make any repairs?
I'm not completely sure what you mean by that but I think you mean "fix" stuff. Same thing, the design is to fix. There's lots of things that are complicated for no reason but lots of it is due to the overall design of your program.

dull orchid
#

for the fix i meant like is there anything that i can maybe improve in the code as code for example if i should add anything in the calculator method like checks for the length of input and if it is like 1 or 0 prints smthing. (maybe i will figure it out myself testing the program) and for the step by step i was talking about if i make like 2 files. first file the calculator and the second the input i have 0 clue how theese two files can be "connected" and one gives data to the other(maybe this i can also figure it out by searching my own and not get it done here)

elfin onyx
# dull orchid for the fix i meant like is there anything that i can maybe improve in the code ...

for the fix i meant like is there anything that i can maybe improve in the code as code for example if i should add anything in the calculator method like checks for the length of input and if it is like 1 or 0 prints smthing. (maybe i will figure it out myself testing the program)
I think you went over most of those with Fd26 so, I mainly looked at the code in terms of design and good practices.

for the step by step i was talking about if i make like 2 files. first file the calculator and the second the input i have 0 clue how theese two files can be "connected" and one gives data to the other(maybe this i can also figure it out by searching my own and not get it done
I understood and as I said, I don't want to give you any step by step. I want you to think about it. But, you don't have to separate this in multiple files for now.

dull orchid
#

okey thanks very much again

#

tomorrow you will prob see some changes

midnight mica
#

your constructor should be Object[] not int n

#

there is no reason to use OOP here

#

Procedural static utility function is actually better in here

#

If you want OOP, then your calculate could return a VO (Value Object) if you wanted, instead of just int

#

also you could return a BigDecimal to support all JDK Number types

#

Your code is too convoluted, too much repetition of the same stuff

#

that's why I praised you to use the Eclipse refactor feature

#

For TortoiseGit, you need to restart explorer.exe or reboot your computer, because it's a Windows Explorer shell extension

#

TortoiseGit won't work in folder which are OneDrive because OneDrive icons are stronger than GIT.

dull orchid
#

calculator is int cause it actaully do the math and in the end it returns 1 int so i don't know why i shouldn't be int

midnight mica
#

your constructor as is was useless

#
// better
 rpn peos = new rpn(test);
 int result = peos.calculator();
#

also class should be CamelCase

#

Even better:

 public rpn(final Object... n) { this.array = (n == null) ? new Object[] { 0 } : n; }
#

this way you can pass a list

#
public rpn(final Collection<? extends Object> n) { this.array = (n == null) ? new Object[] { 0 } : n.toArray(new Object[0]); }
#

Now you can write JDK8+

// Using constructor : new rpn(Object... n)
int r = new rpn(1, 1, '+', 12, 4, '+', '+').calculator();
#

Now you can write JDK5+

// Using constructor : new rpn(Collection n)
int r = new rpn(Arrays.asList(1, 1, '+', 12, 4, '+', '+')).calculator();
dull orchid
midnight mica
#

setter makes no sense here

#

Unless you want a Builder pattern

#

but you have only one argument, so why would you need a builder ?

#

;compile java

import java.util.*;

// JDK5+
public class RPN
{
 private Object[] array;

 public RPN(final Object... n)                    { this.array = (n == null) ? new Object[] { 0 } : n; }
 public RPN(final Collection<? extends Object> n) { this.array = (n == null) ? new Object[] { 0 } : n.toArray(new Object[0]); }

 public List<Object> toList()   { return Arrays.<Object>asList(this.array); }
 public String       toString() { return this.toList().toString(); }
 public Object[]     toArray()  { return Arrays.copyOf(this.array, this.array.length); }

 public int calculator() { return 0; }

 // Unsafe to AIOBE exception
 public Object get(final int i) { return this.array[i]; }
 public void   set(final int i, final Object o) { this.array[i] = o; }

 public static void main(String[] a)
 {
   // Using constructor : new rpn(Object... n)
   final RPN rpn1 = new RPN(1, 1, '+', 12, 4, '+', '+');
   final int r1 = rpn1.calculator();
   System.out.println(rpn1);
   System.out.println(r1);

   // Using constructor : new rpn(Collection n)
   final RPN rpn2 = new RPN(Arrays.asList(1, 1, '+', 12, 4, '+', '+'));
   final int r2 = rpn2.calculator();
   System.out.println(rpn2);
   System.out.println(r2);
   System.out.println(rpn2.toArray()[3]);
 }
}
tiny muralBOT
#
Program Output
[1, 1, +, 12, 4, +, +]
0
[1, 1, +, 12, 4, +, +]
0
12
midnight mica
#

Vararg seems to be since JDK5 😛

#

is this more OOP to you ?

dull orchid
#

so the new program after some adjustments :i added a switch method so it can check the operation

#

i tried first of all to make it cleaner by naming some variables better and not just p.I also modified the way the temparray is made in the for loop by combine the before 2 for loops into 1 and also some errors messages

#

i think now it actually a lot more readable and also i can modify it way easier

dull orchid
dull orchid
elfin onyx
#

If I go on my computer later I'll try to show you an example

midnight mica
# dull orchid

continue refactoring you are far from my answer 😄
but at least you are getting there 👍

dull orchid
#

for example no clue what final is

midnight mica
#

final is like const in C++, which means that variable reference won't change

#

so if you are not re-assigning this variable later in the code, it's more readable to declare it final to instruct the user that the reference won't change, and create a compilation error if you try to do so.

#

Furthermore, if you use closure later in the code, then anything used inside the closure pointing to the outer closure MUST be final