I managed to make these two classess, but "score" has to have 7 digits after the dot. I cannot modify Main class. I think I should use String.format("%.7f", ...) but I don't know where. Please help.
MAIN:
public class Main {
public static void main(String[] args) {
Calc c = new Calc();
String score = c.doCalc(args[0]);
System.out.println(score);
}
}
CALC:
public class Calc {
public String doCalc(String cmd) {
ScriptEngineManager mgr = new ScriptEngineManager();
ScriptEngine engine = mgr.getEngineByName("JavaScript");
try {
return engine.eval(cmd).toString();
}
catch (ScriptException e) {
return "Invalid command to calc";
}
}
}
Instead of using system.out.println, you should use system.out.format or system.out.printf. See a short tutorial from Oracle on using it here. Why exactly can't you modify the main class? That seems to be where your score is being printed..
You can parse the string result back to Double and feed it to String.format:
try {
return String.format("%.7f", Double.valueOf(engine.eval(cmd).toString()));
}
catch (Exception e) {
return "Invalid command to calc";
}
You could of course feed the result directly to String.format without the toString and valueOf round trip, like so:
return String.format("%.7f", engine.eval(cmd));
But that only works when the eval result is a valid floating point number. To deal with other cases like integers or non-numbers, you'd have to put in a few type checks and make the code look more cluttered.
Related
I need to parse an input string into a new class object consisting of two floats. I do have a solution but it looks cumbersome. I wondered if there is a more elegant way to do it, esp. if the string splits only to 2 substrings and a cycle seems to be a bit of overkill?
my class:
public class Float2 {
public float width;
public float height;
}
my method to parse the input string into a class object:
public Float2 parseStringToFloat2(String inputstring) {
String[] stringarray = inputstring.split(",");
float[] floats = new float[2];
for (int i = 0; i <2; ++i) {
float number = Float.parseFloat(stringarray[i]);
floats[i] = number;
}
return new Float2(floats[0], floats[1]);
}
I do think the loop is an overkill if you know for sure there will by only 2 parts.
Maybe try this:
public Float2 parseStringToFloat2(String inputstring){
String[] stringarray = inputstring.split(",");
try {
return new Float2(Float.parseFloat(stringarray[0]), Float.parseFloat(stringarray[1]));
} catch (Exception e) {
// catch logic
}
return null;
}
As said in a comment, you should also use try catch logic in case of a conversion error.
Another solution would be to use a Scanner. It is a more flexible solution if you need Locale-specific parsing (it uses the default locale without setting it, which could be problematic if a , is a decimal separator there). Also if you use a regex delim, the pattern can be precompiled to be faster.
public static Optional<Float2> parseStringToFloat2(String inputstring) {
final Scanner in = new Scanner(inputstring).useLocale(Locale.US).useDelimiter(", ");
// in.useDelimiter(Pattern.compile("\\s*,\\s*"));
try {
return Optional.of(new Float2(in.nextFloat(), in.nextFloat()));
} catch (NoSuchElementException e) {
return Optional.empty();
}
}
I am trying to make a new command for the first time and was following this tutorial
which is slightly old but I believe will still work. After finishing it I tried running my mod and everything ran fine but my command did not exist. Here is my code:
public class MainRegistry {
#EventHandler
public void serverStart(FMLServerStartingEvent event) {
MinecraftServer server = MinecraftServer.getServer();
ICommandManager command = server.getCommandManager();
ServerCommandManager manager = (ServerCommandManager) command;
manager.registerCommand(new FireBall5());
}
}
And my actual CommandBase class:
public class FireBall5 extends CommandBase {
#Override
public String getCommandName() {
return "fireball 5";
}
#Override
public String getCommandUsage(ICommandSender var1) {
return "Shoots fireball with explosive power 5";
}
#Override
public void processCommand(ICommandSender icommandsender, String[] var2) {
if (icommandsender instanceof EntityPlayer) {
EntityPlayer player = (EntityPlayer) icommandsender;
World par2World = player.worldObj;
if (!par2World.isRemote)
par2World.spawnEntityInWorld(new PlayerFireBall(par2World, 5.0f));
}
}
}
It is calling an entity PlayerFireBall which I created myself and is simply a fireball with increased explosion power.
Commands cannot contain whitespaces. To implement your command, please follow the following:
#Override
public String getCommandName() {
return "fireball"; // Remove the argument - Leave the command only.
}
The argument has to be read like this instead:
{
if (sender instanceof EntityPlayer) {
final EntityPlayer player = (EntityPlayer) sender;
final World par2World = player.worldObj;
final float power;
// The "default" method:
// power = 5; // Write the default value here!
if (var2.length > 0) try {
power = Float.parseFloat(var2[0]); // Parse the first argument.
} catch(NumberFormatException ex) {}
// The "validation" method:
if (var2.length == 0) {
sender.sendMessage("You forgot to specify the fireball power.");
return;
}
if ( !var2[0].matches("\\d{2}")) { // Asserts this argument is two digits
sender.sendMessage("Incorrect.");
return;
}
power = Float.parseFloat(var2[0]);
if ( !par2World.isRemote)
par2World.spawnEntityInWorld(new PlayerFireBall(par2World, power));
}
}
Read more:
Reading arguments as Integer for a Bounty in a Bukkit plugin
See #Unihedron answer for the fix for the actual problem with this code. This answer simply cleans up his code even more.
CommandBase from which you inherit actually has several static methods that make parsing numbers and such from arguments much safer.
The ones you might want to use are:
CommandBase.parseDouble(ICommandSender, String) - Parses the given string and returns a double safely
CommandBase.parseDoubleWithMin(ICommandSender, String, int min) - Same as above, but with a required minimum value
CommandBase.parseDoubleBounded(ICommandSender, String, int min, int max) - Same as above, but with an upper limit as well
All these have an integer counterpart as well.
Also, not useful for your context, but maybe for future use is this:
CommandBase.parseBoolean(ICommandSender, String) - Parses the given string and returns a boolean safely
Look through the CommandBase class for many more useful static methods.
So for example, rather than this:
if (var2.length > 0) try {
power = Float.parseFloat(var2[0]); // Parse the first argument.
} catch(NumberFormatException ex) {}
Try this:
if(var2.length > 0){
//bounded because you don't want a size less than 0, could really be anything
power = CommandBase.parseDoubleWithMin(sender, var2[0], 0);
}
Minecraft will automatically tell the player if there is something wrong with there input and safely return the parsed value to you.
Good luck with your mod and have fun!
I am casting my String variables to integer and double. I want to check whether the String variable contains valid Integer or Double value at runtime.
I us following code but it not works for me.
String var1="5.5";
String var2="6";
Object o1=var1;
Object o2=var2;
if (o1 instanceof Integer)
{
qt += Integer.parseInt( var1);// Qty
}
if (o2 instanceof Double)
{
wt += Double.parseDouble(var2);// Wt
}
Try to parse the int and catch the exception if it fails:
String var1="5.5";
try {
qt += Integer.parseInt( var1);
}
catch (NumberFormatException nfe) {
// wasn't an int
}
You can use patterns to detect if a string is an integer or not :
Pattern pattern = Pattern.compile("^[-+]?\\d+(\\.\\d+)?$");
Matcher matcher = pattern.matcher(var1);
if (matcher.find()){
// Your string is a number
} else {
// Your string is not a number
}
You will have to find the correct pattern (I haven't used them for awhile) or someone could edit my answer with the correct pattern.
*EDIT** : Found a pattern for you. edited the code. I did not test it but it is taken from java2s site which also offer an even more elgant approach (copied from the site) :
public static boolean isNumeric(String string) {
return string.matches("^[-+]?\\d+(\\.\\d+)?$");
}
First of all, your if condition will certainly fail, because the object reference actually points to a String object. So, they are not instances of any integer or double.
To check whether a string can be converted to integer or double, you can either follow the approach in #Bedwyr's answer, or if you don't want to use try-catch, as I assume from your comments there (Actually, I don't understand why you don't want to use them), you can use a little bit of pattern matching: -
String str = "6.6";
String str2 = "6";
// If only digits are there, then it is integer
if (str2.matches("[+-]?\\d+")) {
int val = Integer.parseInt(str2);
qt += val;
}
// digits followed by a `.` followed by digits
if (str.matches("[+-]?\\d+\\.\\d+")) {
double val = Double.parseDouble(str);
wt += val;
}
But, understand that, Integer.parseInt and Double.parseDouble is the right way to do this. This is just an alternate approach.
Maybe regexps could suit your needs:
public static boolean isInteger(String s) {
return s.matches("[-+]?[0-9]+");
}
public static boolean isDouble(String s) {
return s.matches("[-+]?([0-9]+\\.([0-9]+)?|\\.[0-9]+)");
}
public static void main(String[] args) throws Exception {
String s1 = "5.5";
String s2 = "6";
System.out.println(isInteger(s1));
System.out.println(isDouble(s1));
System.out.println(isInteger(s2));
System.out.println(isDouble(s2));
}
Prints:
false
true
true
false
Integer.parseInt and Double.parseDouble return the integer/double value of the String. If the String is not a valid number, the method will thrown a NumberFormatException.
String var1 = "5.5";
try {
int number = Integer.parseInt(var1); // Will fail, var1 has wrong format
qt += number;
} catch (NumberFormatException e) {
// Do your thing if the check fails
}
try {
double number = Double.parseDouble(var1); // Will succeed
wt += number;
} catch (NumberFormatException e) {
// Do your thing if the check fails
}
There are some situation that I need to convert string to float or some other numerical data-type but there is a probability of getting some nonconvertible values such as "-" or "/" and I can't verify all the values beforehand to remove them.
and I want to avoid using try/catch for this matter , is there any other way of doing a proper conversion in java? something similar to C# TryParse?
The simplest thing I can think of is java.util.Scanner . However this approach requires a new Scanner instance for each String.
String data = ...;
Scanner n = new Scanner(data);
if(n.hasNextInt()){//check if the next chars are integer
int i = n.nextInt();
}else{
}
Next you could write a regex pattern that you use to check the String (complex to fail too big values) and then call Integer.parseInt() after checking the string against it.
Pattern p = Pattern.compile("insert regex to test string here");
String data = ...;
Matcher m = p.matcher(data);
//warning depending on regex used this may
//only check part of the string
if(m.matches()){
int i = Integer.parseInt(data);
}
However both of these parse the string twice, once to test the string and a second time to get the value. Depending on how often you get invalid strings catching an exception may be faster.
Unfortunately, there is no such method in Java. There is no out parameter in Java, so writing such a method would need to return a null Float to signal an error, or to pass a FloatHolder object which could be modified by the method:
public class FloatHolder {
private float value;
public void setValue(float value) {
this.value = value;
}
public float getValue() {
return this.value;
}
}
public static boolean tryParseFloat(String s, FloatHolder holder) {
try {
float value = Float.parseFloat(s);
holder.setValue(value);
}
catch (NumberFormatException e) {
return false;
}
}
This is an old question, but since all the answers fail to mention this (and I wasn't aware of it myself until seeing it in a merge request written by a colleague), I want to point potential readers to the Guava Floats and Ints classes:
With the help of these classes, you can write code like this:
Integer i = Ints.tryParse("10");
Integer j = Ints.tryParse("invalid");
Float f = Floats.tryParse("10.1");
Float g = Floats.tryParse("invalid.value");
The result will be null if the value is an invalid int or float, and you can then handle it in any way you like. (Be careful to not just cast it to an int/float, since this will trigger a NullPointerException if the value is an invalid integer/floating point value.)
Note that these methods are marked as "beta", but they are quite useful anyway and we use them in production.
For reference, here are the Javadocs for these classes:
https://google.github.io/guava/releases/snapshot-jre/api/docs/com/google/common/primitives/Ints.html
https://google.github.io/guava/releases/snapshot-jre/api/docs/com/google/common/primitives/Floats.html
Java does not provide some built in tryParse type of methods, on of the solutions you can try is to create your own tryParse Method and put try/catch code in this method and then you can easily use this method across your application very easily and without using try/catch at all the places you use the method.
One of the sample functions can have following code
public static Long parseLong(String value) {
if(isNullOrEmpty(value)) {
return null;
}
try {
return Long.valueOf(value);
}
catch (NumberFormatException e) {
}
return null;
}
Regular expressions helped me solve this issue. Here is how:
Get the string input.
Use the expression that matches one or more digits.
Parse if it is a match.
String s = "1111";
int i = s.matches("^[0-9]+$") ? Integer.parseInt(s) : -1;
if(i != -1)
System.out.println("Integer");
else
System.out.println("Not an integer");
Can i write sin(whatever) in Java and have it work?
public static void main(String[] args) {
try {
double check = Double.parseDouble(args[0]);
} catch (NumberFormatException e) {
System.exit(0);
}
sin(args[0]);
}
No it won't, you have to call sin with a number like this:
sin(Double.parseDouble(args[0]));
You can either import it statically from Math package or use the syntax
y = Math.sin(x);
with doubles x and y.
In your case x can be e.g. check but have to declare it outside the block.
no you have to pass in a double or something that can be implicitly converted to a double (no objects or Strings)
public static void main(String[] args) {
double check;
try {
check = Double.parseDouble(args[0]);
} catch (NumberFormatException e) {
System.exit(0);
}
System.out.println(Math.sin(check));
}
If you are running anything below Java 1.5, no. If you aren't, you can, using static imports; you can write import static java.lang.Math.*; and then sin(whatever); and this is OK. Be aware of the warning from Sun, though:
Q: So when should you use static imports?
A: Very Sparingly!
If you happen to be running something below Java 1.5, you can still write sin(whatever), but this method must be present...
public static double sin(double x) { Math.sin(x); }
Why would you want to? For example if your arg is "I wandered lonely as a cloud", what is the meaning of sin() of it? Check your input - that's a basic tenet of programming.