Add numbers with the word "add" - java

I am writing to offer an application in Java right now and instead of using the operator "+", the user of the application can literally use the word "add" to add two numbers together.
I'm quite stuck on how to do this because I can't really use a method in order to complete the function considering I'd have to type "add()" rather than just "add". Unless there is a way to execute a method without the parentheses. Would I have to write a completely new class or is there an easier way to do this?

Just a little explanation on what you could do based on what the user enters:
int x = get it from the user;
int y = get it from the user;
string operation = get it from the user;
Create separate methods for the operations (i.e add(int x, int y), multiply(int x, int y), etc..)
Then create a method thag gets the values (x, y, string) say.. you can call it calculate(int x, int y, string operation)
Then in the calculuate method have a switch statement:
switch(operation)
{
case "add":
add(x,y);
break;
case "multiply":
multiply(x,y);
break;
etc...
}
Well, got you something to think about :).

There's no way to do this in Java. You have two options:
1)Use a preprocessor.
2)Write it in a different language. You can write things in other languages and still have it compatible with Java classes and libraries.

The consensus in comments seems to be 'Why would you want to do this? It is slow and cumbersome'. While the latter part is true, it is commonly done. See ScriptEngine as an example. Here is a demo of the JavaScript ScriptEngine in an applet.
The reader might note that ScriptEngine is an interface, suggesting an answer of 'implement your own script engine, based on the rules required'. Whether or not it is a good idea to create another scripting language, is left as an exercise for the reader.

(An expansion on the idea presented by user710502)
You can use reflection.
double a = Double.parseDouble(some user input);
double b = Double.parseDouble(some user input);
String operation = some user input; // i.e. "add", "subtract"
Method operator = Calculations.class.getMethod(operation, double.class, double.class);
// NoSuchMethodException is thrown if method of operation name isn't found
double result = (Double) operator.invoke(null, a, b);
In some sort of calculations class:
public static double add(double a, double b) {
return a + b;
}
public static double subtract(double a, double b) {
return a - b;
}
// and so forth

Related

How to replace the overridden methods with a Recursive implementation

I want to use recursion in order to collapse the overridden add() methods in the code and allow the user to provide any number of terms.
I've made a couple of changes to my code, but I'm not getting the desired result.
Examples of user input and expected output.
Output (for input 3 + 4)
7.0
Output (for input 3 + 4 + 5)
12.0
The code I have:
import java.util.*;
public class Recursion {
public static void main(String args[]) {
Scanner input = new Scanner(System.in);
String exp = input.nextLine();
System.out.println(solver(exp.split(" ")));
}
public static double solver(String[] expression) {
double result = 0;
if (expression.length == 3) {
result = add(Double.parseDouble(expression[0]), Double.parseDouble(expression[2]));
}
else if (expression.length == 5) {
result = add(Double.parseDouble(expression[0]), Double.parseDouble(expression[2]),
Double.parseDouble(expression[4]));
}
else if (expression.length == 7) {
result = add(Double.parseDouble(expression[0]), Double.parseDouble(expression[2]),
Double.parseDouble(expression[4]), Double.parseDouble(expression[6]));
}
else if (expression.length == 9) {
result = add(Double.parseDouble(expression[0]), Double.parseDouble(expression[2]),
Double.parseDouble(expression[4]), Double.parseDouble(expression[6]),
Double.parseDouble(expression[8]));
}
else if (expression.length == 11) {
result = add(Double.parseDouble(expression[0]), Double.parseDouble(expression[2]),
Double.parseDouble(expression[4]), Double.parseDouble(expression[6]),
Double.parseDouble(expression[8]), Double.parseDouble(expression[10]));
}
return result;
}
public static double add(double a, double b) {return a + b;}
public static double add(double a, double b, double c) {return a + b + c;}
public static double add(double a, double b, double c, double d) {return a + b + c + d;}
public static double add(double a, double b, double c, double d, double e) {return a + b + c + d + e;}
public static double add(double a, double b, double c, double d, double e, double f) {return a + b + c + d + e + f;}
}
That's doable with recursion.
But before diving into recursive implementation, it's worth to find out how to solve this problem iteratively because it'll give you a better understanding of what the recursion does.
Firstly, I want to point out at issues with the code you've provided.
Your existing solution is brittle since it depends on the consistency of the user input, and it will fail because of the single additional white space or if a white space will be missing.
Another draw-back is that you have a lot of methods and with them, you are able to handle only a limited number of arguments in the given expression. Let's fix it.
Since your code is intended to perform the arithmetical addition, I think it'll be better to split the input on the plus symbol + and give a user a bit of freedom with white spaces.
For that, we need to pass the following regular expression into the split() method:
"\\s*\\+\\s*"
\s* - implies 0 or more white spaces;
\+ - plus symbol has a special meaning in regular expressions and needs to be escaped with a back-slash.
And since there's more than one arithmetical operation (and you also might want to implement others letter on). It's better to extract your the logic for splitting the user input into a separate method:
public static double add(String expression) {
return addIteratively(expression.split("\\s*\\+\\s*"));
}
expression.split() will return an array of numeric strings that will allow to substitute all your methods with a single method that expects a string array String[] or varargs String... expression (which will allow you to pass as an argument either an array of strings or arbitrary number of string values).
public static double addIteratively(String[] operands) {
double result = 0;
for (String next: operands) {
result += Double.parseDouble(next);
}
return result;
}
Now, when it's clear how to deal with this task iteratively (remember every problem and could be addressed using iteration is also eligible for recursion and vice versa) let's proceed with a quick recap on recursion.
Every recursive method consists of two parts:
Base case - that represents a simple edge-case (condition when recursion terminates) for which the outcome is known in advance.
Recursive case - a part of a solution where recursive calls are made and where the main logic resides.
To process the given array recursively, we can track the position in the array by passing it with each method call.
The base case will represent a situation when there's no more elements left in the array, i.e. current position is equal to the array's length. Since there's no element under the given position, the return is 0.
In the recursive case we need to parse the number under the current position and add the result of the recursive call with position incremented by 1 to it. That will give us the return value.
The recursive implementation might look that:
public static double addAsDouble(String[] operands, int pos) {
if (pos == operands.length) { // base case
return 0;
}
// recursive case
return Double.parseDouble(operands[pos]) + addAsDouble(operands, pos + 1);
}
Method responsible for splitting the user input.
public static double add(String expression) {
return addAsDouble(expression.split("\\s*\\+\\s*"), 0); // recursion starts at position 0
}
main() - here, you just need to call the add() providing a string inter by the user and bother of what is happening inside add. That makes code cleaner and easier to read.
public static void main(String args[]) {
Scanner input = new Scanner(System.in);
String exp = input.nextLine();
System.out.println(add(exp));
}
Output
3 + 4 +5
12.0
You are not passing the correct indexes to the various add methods. For example, if you want to add three numbers, you should do the following:
result = add(Double.parseDouble(expression[0]), Double.parseDouble(expression[1]), Double.parseDouble(expression[2]));

Converting a binary string to integer using a basic mathematical operator

Main:
public class Main{
public static void main(String[] args){
System.out.println(Convert.BtoI("10001"));
System.out.println(Convert.BtoI("101010101"));
}
}
Class:
public class Convert{
public static int BtoI(String num){
Integer i= Integer.parseInt(num,2);
return i;
}
}
So I was working on converters, I was struggling as I am new to java and my friend suggested using integer method, which works. However, which method would be most efficient to convert using the basic operators (e.g. logical, arithmetic etc.)
.... my friend suggested using integer method, which works.
Correct:
it works, and
it is the best way.
However, which method would be most efficient to convert using the basic operators (e.g. logical, arithmetic etc.)
If you are new to Java, you should not be obsessing over the efficiency of your code. You don't have the intuition.
You probably shouldn't optimize this it even if you are experienced. In most cases, small scale efficiencies are irrelevant, and you are better off using a profiler to validate your intuition about what is important before you start to optimize.
Even if this is a performance hotspot in your application, the Integer.parseint code has (no doubt) already been well optimized. There is little chance that you could do significantly better using "primitive" operations. (Under the hood, the methods will most likely already be doing the same thing as you would be doing.)
If you are just asking this because you are curious, take a look at the source code for the Integer class.
If you want to use basic arithmetic to convert binary numbers to integers then you can replace the BtoI() method within the class Convert with the following code.
public static int BtoI(String num){
int number = 0; // declare the number to store the result
int power = 0; // declare power variable
// loop from end to start of the binary number
for(int i = num.length()-1; i >= 0; i--)
{
// check if the number encountered is 1
/// if yes then do 2^Power and add to the result
if(num.charAt(i) == '1')
number += Math.pow(2, power);
// increment the power to use in next iteration
power++;
}
// return the number
return number;
}
Normal calculation is performed in above code to get the result. e.g.
101 => 1*2^2 + 0 + 1*2^0 = 5

Guava iterators for nested foreach

I want to use guava iterator or java8 foreach(may be lambda expression) nested for loop and process some statements and return a long variable. Here is my code in native java. Please excuse my code may not efficient. I read over net accessing non final variables inside new java 8 foreach is not possible.
Long x = Long.valueOf(0);
Long y = Long.valueOf(0);
for(FirstLevel first : Levels)
{
if(first.getSecondLevels() == null)
{
x= x + getSomeValue(first);
}
for (SecondLevel second : first.getSecondLevels())
{
y = y + getSomeValue(second);
}
}
return x + y;
I have tried but unable to return the values. Thanks in advance for help!
Couple things:
Before approaching "refactoring" like that one you ask, I really strongly recommend learning more "pure" Java (which I assume is the case here, #javalearner). For example you can use long literals instead of manually boxing values:
long x = 0L;
long y = 0L;
Anyway...
using Guava won't help here - this is the imperative way of doing it, and with Java 7 + Guava you'd have to write awkward anonymous classes (i.e. Functions), which without language support is painful. Which brings me to...
Java 8 and Streams. This is probably the best way to go, but first you have to fix (?) your code and define actual problem - for example this statement x= x + getSomeValue(x); evaluates x each time and does not take FirstLevel into account (same is true for y and SecondLevel), so I assume what you really meant was x =+ getSomeValue(firstLevel);.
Having all that said - please be more specific what your problem really is.
EDIT:
After your clarification, using streams your code could look like this:
final long sum = levels.stream()
.mapToLong(first -> getSomeValue(first) + first.getSecondLevels().stream().mapToLong(this::getSomeValue).sum())
.sum();
or with some helper method:
final long s = levels.stream()
.mapToLong(first -> getSomeValue(first) + getSecondLevelSum(first))
.sum();
private long getSecondLevelSum(final FirstLevel first) {
return first.getSecondLevels().stream().mapToLong(this::getSomeValue).sum();
}
First of all, there is no sense in using boxed Long values and even if you once need a boxed value, you don’t need to invoke Long.valueOf, Java already does that for you when converting a long primitive to a boxed Long object.
Further, since adding long values does not depend on the order of summands, there is no reason to maintain two variable throughout the operation, when you will add them at the end anyway:
long result=0;
for(FirstLevel first: Levels) {
result += getSomeValue(first);
for(SecondLevel second: first.getSecondLevels()) {
result += getSomeValue(second);
}
}
return result;
Note that the operator += does the same as result = result + … here, but avoids the repetition of the target operand.
Assuming that both, Levels and the result of getSecondLevels, are collections you can write the same as Stream operation as
return Levels.stream()
.mapToLong(first ->
getSomeValue(first) + first.getSecondLevels().stream()
.mapToLong(second -> getSomeValue(second)).sum())
.sum();
or, alternatively
return Levels.stream()
.flatMapToLong(first -> LongStream.concat(
LongStream.of(getSomeValue(first)),
first.getSecondLevels().stream().mapToLong(second -> getSomeValue(second))))
.sum();
If Levels is an array, you have to replace Levels.stream() with Arrays.stream(Levels) and likewise, if getSecondLevels() returns an array, you have to replace first.getSecondLevels().stream() with Arrays.stream(first.getSecondLevels())

Custom functions in Processing Language

doing some uni work on 'Processing' Programming language (a form of java).
So my question is 'Write a function called twoNumbers(int a,int b) which takes in two parameters a and b. If a is greater than b, then the two numbers are added together and the string 'the sum of a and b is sum' is displayed in the console window, where a and b and the sum are the values of a, b and their sum. Finally, the function should return the sum.'
..soo here is my attempt at the code, if I put (int a,int b) after the customer function, it just says that my other int a = number, is a duplicate, which is true, but im not sure how I am ment to give a and b a number without it thinking its a duplicate? Should I be putting it out of a void setup tag? as im unsure if this would then cause too many { brackets...
/* Question 1 */
int twoNumbers(){
int a = 30;
int b = 20;
if (a > b) {println(a+b);}
println("The sum of a and b is sum");
int sum;
sum = a+b;
println(sum);
}
Any help would be massively helpful in getting this and the other questions done :)
Thanks!!
Also your function is not returning a value, which will give you an error. It looks like you are confusing things. Either declare it a void or return a value of declared type (that last is what your assignment calls for). Either way a function, or a method, needs to be called to execute, and you are not calling it! So the code inside your the function is not being run!!
The following:
void imAMethod()
{
println("hello");
}
It is a valid method, but will do nothing, you need to call it, like:
imAMethod();// calling your method
void imAMethod()
{
println("hello");
}
But this won't work also, will give you the error "It looks like you're mixing "active" and "static" modes". Thats because to use a function in Processing you need to have at least a setup() method in the sketch, so:
void setup()
{
imAMethod();
}//end of setup
void imAMethod()
{
println("hello");
}
will work as expected.
But you need a function, so as Jesper pointed you will have to do something like:
int a = 30; // those are global variables to pass to your function
int b = 20;
void setup()// this is a builtin basic Processing method
{
//call your function
println("The sum of " + a + " and " + b + " is "+ twoNumbers(a, b));
}
int twoNumbers(int a, int b)
{
//do your math and tests here
return result;
}
There is another thing not clear in the assignment. A function must return something, so it is not clear what the function should return if a is not greater than b. You will have to handle this case, or compiler will complain. You may want to move this test out of the function to make things easier, like:
if (a < b)
println("The sum of " + a + " and " + b + " is "+ twoNumbers(a, b));//call your function
else
println(a + " is smaller than " + b);
and in the function just do the sum. But this may be not what the assignment requires... Anyway you will need to return something even if a is not greater than b. Note that the printing to console can be done inside the function also.
Hummm, re reading the assignment a think what is expected is: Aways return the sum, and just print if a is greater than b, which makes more sense and is easier, something like:
int twoNUmbers(int a, int b)
{
if (a < b){/*print the string*/}
return a + b;
}
Just a note for jlordo. In Processing.org you don't have a main, or better, it is transparent/hidden from user. Processing is like a "dialect" of java. So the code above would run as it is. There are two basic builtin functions: setup() and draw(). If the user do not use none of them the IDE will warps it in a setup() function, that will call the main() somewhere else. It will run once. Draw() instead loops forever.
'Write a function called twoNumbers(int a,int b) which takes in two parameters a and b.
That's not what your code looks like. Your method twoNumbers doesn't take two parameters a and b. Your code should start like this (exactly as mentioned in the assignment):
int twoNumbers(int a, int b) {
Remove the next two lines, int a = 30; and int b = 20;. Those lines declare two local variables named a and b. You should use the a and b that are passed in as parameters instead.
This also looks wrong:
if (a > b) {println(a+b);}
println("The sum of a and b is sum");
Carefully look at what the assignment says:
If a is greater than b, then the two numbers are added together and the string 'the sum of a and b is sum' is displayed in the console window, where a and b and the sum are the values of a, b and their sum.
That's not what your code is doing. Take it step by step, carefully think about what is meant in the assignment.

Making java wait until a property is called for?

I recently started working with JOGL, so I made a vector class. Inside this class, I used the line
public Vector unit=new Vector(x/length,y/length,z/length);
To find the unit vector. And of course, this causes a stackoverflow. Is there any way to make java wait for unit to be called before running this or will I have to make unit a method?
I woukld personally create a second constructor, which calculates the unit vector and sets its own unit vector to itself. You should ideally use private values and a get method as Ernest suggests. The reason for this is that otherwise other classes can simply overwrite the x,y,z, etc. values if they have access to one of your objects. Java has a tradition of using final classes for pure data storage. See the String class for example. You can't modify an existing String, only create a new String. Once created, a String remains the same. For your purposes it might not matter much, but in a different context it may cause your application to misbehave, if your class is used by someone who doesn't have a clue. It might even be a security risk in some cases.
You could simply ignore this and access the variables directly, and enjoy the less cluttered code and small performance increase. But I would still suggest knowing what the problem is for the future.
Anyway, below is my suggested code for solving the unit vector problem, minus getter methods.
import java.lang.Math;
class Vector{
public double x,y,z,length;
public Vector unit;
public static void main(String[]s){
new Vector(5,5,5);
}
public Vector(double x, double y, double z){
this.length = Math.sqrt(x*x + y*y + z*z);
this.x=x;
this.y=y;
this.z=z;
this.unit = new Vector(x/length, y/length, z/length, true);
}
private Vector(double x, double y, double z, boolean isUnitVector){
// Temp variable for calculating the length
double length = Math.sqrt(x*x + y*y + z*z);
if (isUnitVector){
this.length = 1;
this.x=x/length;
this.y=y/length;
this.z=z/length;
this.unit = this;
}else{
this.length = Math.sqrt(x*x + y*y + z*z);
this.x=x;
this.y=y;
this.z=z;
this.unit = new Vector(x/length, y/length, z/length, true);
}
}
}
I'm not entirely happy with the code duplication between the constructors that follows from the boolean argument. In practice, I would probably create a factory class, VectorFactory with one static method, whose only job is to create Vector objects. Or maybe just use Java's own javax.vecmath.Vector3d and related classes.
Yes, this is easy enough, but you'll need to fix your design a bit. Most importantly, as is almost always the case with all member variables, unit should be private, and all access to it should be through a method named something like getUnit(). Then, you simply write getUnit() to check whether unit has been initialized or not:
public synchronized Vector getUnit() {
if (unit == null)
unit = new Vector(x/length,y/length,z/length);
return unit;
}
I've made this method synchronized so that you'll avoid any problems if two different threads call getUnit() at around the same time, and unit hasn't been initialized yet.
I propose a constructor which decides itself whether it is a unit vector or not. If it is a unit vector, then unit points to itself. This will break the recursion of the constructor.
The only problem might be numbers where length is not exactly 1.0 due to rounding errors.
public class Vector {
public double x, y, z;
public Vector unit;
public Vector(double x, double y, double z){
this.x = x;
this.y = y;
this.z = z;
double length = calcLength(x, y, z);
if( length == 1.0 ) // perhaps add a little fuzz factor.
this.unit = this;
else
this.unit = new Vector(x/length, y/length, z/length);
}
}

Categories

Resources