I'm currently working on an Android app. This is my code:
FieldSolution.setText("y =","(Double.toString(m))","x + ", "(Double.toString(b))");
I'm trying to print "y = mx + b" whereas m and b are doubles. Somehow I'm getting exceptions.
Where lies my mistake?
fieldSolution.setText("y =" + Double.toString(m) + " x + " + Double.toString(b));
or simply
fieldSolution.setText("y =" + m + " x + " + b);
Aside: Use Java naming conventions for variable names
You can use String.format:
FieldSolution.setText(String.format("y = %fx + %f", m, b));
You can use modifiers on the %f format specifier to control precision and width of the output. You can also, if appropriate, supply a locale as an argument to format().
Related
I'm building a simple calculator Android app in Java that will receive 2 numbers as inputs and when the user presses one of the 4 action buttons (+, -, *, /) the exercise and it's solution will appear in the bottom of the screen inside a TextView in this format:
{num1} {action} {num2} = {solution}
I tried to declare a string and form the exercise's string in it and in the end I used "setText" to change the TextView but instead of showing the full exercise when I run the app it shows something like "androidx.appcompat.widget.AppCom".
Here is an example for the string I form when the user clicks on the + button:
exerciseStr = etNum1.toString() + " + " + etNum2.toString() + " = " + String.valueOf(Integer.valueOf(etNum1.getText().toString())+Integer.valueOf(etNum2.getText() + ""));
Does anybody know what the issue may be?
You should call getText() befor calling toString():
exerciseStr = etNum1.getText().toString() + " + " + etNum2.getText().toString() + " = " + String.valueOf(Integer.valueOf(etNum1.getText().toString())+Integer.valueOf(etNum2.getText() + ""));
Change it to like this.
exerciseStr = etNum1.getText().toString() + " + " + etNum2.getText().toString() + " = " + String.valueOf(Integer.valueOf(etNum1.getText().toString())+Integer.valueOf(etNum2.getText() + ""));
Is it possible to set length of field padding in the same line as setting the decimal precision? I want firstPlaceTime to display with 3 decimal points, like 8.250 instead of 8.25. Perhaps something like %8s%3f or %8s.3f?
System.out.format("%-10s%1s%-18s%1s%8s%1s%16s%-10s","Level " + level, "| ", firstPlaceName, "| ", firstPlaceTime + "s ", "|", timeGain + "s ahead |", " " + numberOfRunners + " runners");
This code shows an approach to building the format String as well as using the %8.3f to display a double.
public static void main(String[] args)
{
String level = "Beginning";
String firstPlaceName = "TheWinner!";
double firstPlaceTime = 180.234534D;
double timeGain = 10.2D;
int numberOfRunners = 10;
StringBuilder sb = new StringBuilder();
sb.append("Level %-10s"); //the level
sb.append("|"); //divider
sb.append("%-18s"); //name of winner
sb.append("|"); //divider
sb.append("%8.3f s "); //winning time
sb.append("|"); //divider
sb.append("%8.3f s ahead"); //time gain
sb.append("|"); //divider
sb.append("%5d runners"); // # of runners
System.out.format(sb.toString(),
level,
firstPlaceName,
firstPlaceTime,
timeGain,
numberOfRunners);
}
Output:
Level Beginning |TheWinner! | 180.235 s | 10.200 s ahead| 10 runners
Edit: to elaborate on a question in the comment. The OP indicated an attempt to use %8.3f and received a format error. firstPlaceTime is a double. However, the parameter was specified as:
...,firstPlaceTime + "s ",...
When the + "s " was provided as a parameter, it would have been converted to a String, and then passed to the .format(). As a String, it would not be a double to format via the %8.3f specification. It is part of the reason for suggesting moving the text into the format specification rather than attempting
the various String concatenations in the parameters.
This question already has answers here:
Why am I getting InputMismatchException?
(5 answers)
Closed 6 years ago.
Whenever I try to compile it, it keeps giving me an exception:
This is my source code:
Scanner input = new Scanner(System.in);
DecimalFormat df = new DecimalFormat("#.##");
System.out.print("Gaji Pokok (x 10.000) : ");
double gaji = input.nextDouble();
System.out.print("Lama Tahun Kerja : ");
int th = input.nextInt();
System.out.print("Lama Bulan Kerja : ");
float bl = input.nextFloat();
if ( bl > 12)
{
System.out.println("Inputan bulan anda salah");
System.out.print("Masukkan kembali bulan yang benar : ");
float blnnew = input.nextFloat();
float tukar = blnnew;
bl = tukar;
}
float fak_peng;
fak_peng = Float.valueOf(df.format((th+(bl/12))*2.5));
System.out.print("Jumlah Faktor Penghargaan : " );
System.out.println(fak_peng + " %");
System.out.println("Nilai Sekarang : 1.0000000 " );
float per_mppeg;
per_mppeg = Float.valueOf(df.format(gaji*(fak_peng/100)*1));
System.out.print("Perhitungan MP Pegawai : " );
System.out.println(gaji + " x " + fak_peng + "% x " + " 1.0000000 = Rp." + (per_mppeg) + "(x 10.000)");
System.out.print("MP Perbulan : " );
System.out.println(per_mppeg + " + 100% = Rp." + (per_mppeg) + "(x 10.000)");
System.out.println("MP sekaligus 100% : ");
float peserta;
peserta = Float.valueOf(df.format(100.6650*per_mppeg));
float jd;
jd = Float.valueOf(df.format(14.4820*per_mppeg*0.8));
float anak;
anak = Float.valueOf(df.format(0.6090*per_mppeg*0.8));
float jml;
jml = Float.valueOf(df.format(peserta+jd+anak));
System.out.println(" Peserta = 100.6650 x "+ per_mppeg + " = " + peserta + "(x 10.000)");
System.out.println(" Jd/Dd = 14.4820 x "+ per_mppeg + " x 80% = " + jd + "(x 10.000)" );
System.out.println(" Anak = 0.6090 x "+ per_mppeg + " x 80% = " + anak + "(x 10.000)");
System.out.println("Jumlah Total = "+ jml);
float mpdua;
mpdua = Float.valueOf(df.format (jml*0.2)) ;
float mpdel;
mpdel = Float.valueOf(df.format(per_mppeg*0.8)) ;
System.out.println("MP Sekaligus 20% = "+ mpdua + "(x 10.000)");
System.out.println("MP sekaligus 80% = "+ mpdel + "(x 10.000)");
Your exception is not a compile-time error/exception; it is a runtime exception. It is thrown because the thing the scanner is reading cannot be converted to the type you are asking for (e.g., the next thing the scanner should read is "hello" but you are using scanner.nextInt(), as "hello" cannot be converted to an integer it will raise a InputMismatchException).
In your case the exception is raised when asking for a double. Probably you are using the wrong syntax. You should check which syntax your system uses to represent doubles. On some systems, for example, the fractional and the integer part of a double should be separated with a , and on other systems with a .. So one-half on the first type of system should be written as 0,5 but on the second as 0.5.
In Java the syntax the scanner uses is defined with a Locale instance.
You can check which-one your scanner uses with the locale() method and change it with useLocale() method.
So you should recheck what you give as input.
Besides your problem with the format of double you are creating your DecimalFormat on a discommanded way (see last quote below) and there is another line that may rise an exception ( NumberFormatException ), if you do not pay attention to the Locale instance you are using:
fak_peng = Float.valueOf(df.format((th+(bl/12))*2.5));
As you are using your own format to parse the decimal (new DecimalFormat("#.##");) the string that will be passed to the Float.valueOf method will depend on the Locale instance used to create the DecimalFormat object df (in the code sample you didn't use a specific Locale instance so your systems default Locale instance is used). But Float.valueOf expects its argument to use a specific syntax defined by The Java™ Language Specification regardless to your system as written in the Java API for Float.valueOf:
[...] where Sign, FloatingPointLiteral, HexNumeral, HexDigits, SignedInteger and FloatTypeSuffix are as defined in the lexical structure sections of The Java™ Language Specification, except that underscores are not accepted between digits. If s does not have the form of a FloatValue, then a NumberFormatException is thrown.
(The complete text was too big too include here. Follow this link or the one above to have more info about what Sign, FloatingPointLiteral, HexNumeral, HexDigits, SignedInteger, FloatTypeSuffix and FloatValue exactly represent)
If you want to change the Locale instance used in your DecimalFormat object, read the API for the DecimalFormat class.
To obtain a NumberFormat for a specific locale, including the default locale, call one of NumberFormat's factory methods, such as getInstance(). In general, do not call the DecimalFormat constructors directly, since the NumberFormat factory methods may return subclasses other than DecimalFormat.
In the API (follow link just before quote) they give an example of how you should correctly create an instance of a NumberFormat.
Good luck!
I'm writing a program that should be able to read and parse chess moves (SAN).
Here's an example of possible accepted moves:
e4
Nf3
Nbd2
Nb1c3
R1a3
d8=Q
exd5
Nbxd2
...
I first wrote the NFA, then converted it to grammar and then I converted it to a regular expression.
With my conventions, this is how it looks
pln + plxln + plnxln + plnln + plln + pxln + lxln=(B+R+Q+N) + lxln + lnxln=(B+R+Q+N) + lnxln + lnln=(B+R+Q+N) + lnln + ln=(B+R+Q+N) + ln + pnxln + pnln
where:
p is a character of set {B,R,Q,N,K} (or think it as (B+R+Q+N+K) = [BRQNK]
l is a character among [a-h] interval (case sensitive)
n is a number among [1-8] interval
+ represents Union operation... if I got it right, (B+R+Q+N) is [BRQN] in regex's programming languages.
= is just a normal character... in chess moves it's used in promotion (ex. e8=Q)
x is a normal character too... used when by moving your piece in that location you're taking an opponent's one.
(/): Like in math
I tried to parse first part pln as: [BRQN][a-h][1-8] in an online java regex tester and worked for a move like Nf3. I didn't get well how to do the union thing for composite expression (like pln+plxln)... also how can I label to parts of regex so that when it's detected, I get all the infos? I tried to read docs about it but didn't figure out.
Any advice?
The + in your notation is | in regexes. So you could use the regex
[BRQNK][a-h][1-8]|[BRQNK][a-h]x[a-h][1-8]|[BRQNK][a-h][1-8]x[a-h][1-8]|[BRQNK][a-h][1-8][a-h][1-8]|[BRQNK][a-h][a-h][1-8]|[BRQNK]x[a-h][1-8]|[a-h]x[a-h][1-8]=(B+R+Q+N)|[a-h]x[a-h][1-8]|[a-h][1-8]x[a-h][1-8]=(B+R+Q+N)|[a-h][1-8]x[a-h][1-8]|[a-h][1-8][a-h][1-8]=(B+R+Q+N)|[a-h][1-8][a-h][1-8]|[a-h][1-8]=(B+R+Q+N)|[a-h][1-8]|[BRQNK][1-8]x[a-h][1-8]|[BRQNK][1-8][a-h][1-8]
This is, clearly, a bit ugly. I can think of 2 possible ways to make it nicer:
With the COMMENTS flag, you can add whitespace.
Combine the possibilities together in a nicer way. For example, [BRQNK][a-h]x[a-h][1-8]|[BRQNK][a-h][1-8]x[a-h][1-8] can be rewritten as [BRQNK][a-h][1-8]?x[a-h][1-8].
I also know of one other improvement which isn't available in java. (And maybe not many languages, but you can do it in Perl.) The subexpression (?1) (likewise (?2), etc) is a bit like \1, except that instead of matching the exact string that matched the first capture group, it matches any string that could have matched that capture group. In other words, it's equivalent to writing the capture group out again. So you could (in Perl) replace the first [BRQNK] with ([BRQNK]), then replace all subsequent occurrences with (?1).
/^([NBRQK])?([a-h])?([1-8])?(x)?([a-h][1-8])(=[NBRQK])?(\+|#)?$|^O-O(-O)?$/
.
.
.
.
This was unit tested against 2599 cases. See below for unit tests
describe('Importer/Game', function() {
let Importer, Game;
beforeEach(function() {
Importer = require(`${moduleDir}/import`).Importer;
Game = require(`${moduleDir}/import`).Game;
});
describe('moveRegex', function() {
describe('non-castling', function() {
// ([NBRQK])? ([a-h])? ([1-8])? (x)? ([a-h][1-8]) (=[NBRQK])? (+|#)?/
// unitType? startFile? startRank? capture? end promotion? checkState?
for(let unitType of ['', 'N', 'B', 'R', 'Q', 'K']) {
for(let startFile of ['', 'b']) {
for(let startRank of ['', '3']) {
for(let capture of ['', 'x']) {
for(let promotion of ['', '=Q']) {
for(let checkState of ['', '+', '#']) {
//TODO: castling
const dest = 'e4';
const san = unitType + startFile + startRank + capture + dest + promotion + checkState;
testPositive(san);
//TODO: negative substitutions here.
testNagative('Y' + startFile + startRank + capture + dest + promotion + checkState);
testNagative(unitType + 'i' + startRank + capture + dest + promotion + checkState);
testNagative(unitType + startFile + '9' + capture + dest + promotion + checkState);
testNagative(unitType + startFile + startRank + 'X' + dest + promotion + checkState);
testNagative(unitType + startFile + startRank + capture + 'i9' + promotion + checkState);
// testNagative(unitType + startFile + startRank + capture + '' + promotion + checkState);
testNagative(unitType + startFile + startRank + capture + dest + '=' + checkState);
testNagative(unitType + startFile + startRank + capture + dest + 'Q' + checkState);
testNagative(unitType + startFile + startRank + capture + dest + promotion + '++');
}
}
}
}
}
}
});
describe('castling', function() {
testPositive('O-O');
testPositive('O-O-O');
testNagative('OOO');
testNagative('OO');
testNagative('O-O-');
testNagative('O-O-O-O');
testNagative('O');
});
function testPositive(san) {
it(`should handle this san: ${san}`, function(done) {
const matches = san.match(Importer.moveRegex);
assert(matches);
done();
});
}
function testNagative(san) {
it(`should not match this: ${san}`, function(done) {
const matches = san.match(Importer.moveRegex);
assert(!matches);
done();
});
}
});
});
Re: /^([NBRQK])?([a-h])?([1-8])?(x)?([a-h][1-8])(=[NBRQK])?(\+|#)?$|^O-O(-O)?$/
It's both underinclusive and overinclusive.
It excludes the possibly legal moves O-O+, O-O-O+, O-O#, and O-O-O#.
It includes many strings that can never be legal: e8=K, Kaa4, Nf5=B, Qa1xb7
and so on.
I've made this one:
/(^([PNBRQK])?([a-h])?([1-8])?(x|X|-)?([a-h][1-8])(=[NBRQ]| ?e\.p\.)?|^O-O(-O)?)(\+|\#|\$)?$/
Includes: O-O+, O-O-O+, O-O# and O-O-O#
Also: e.p., N-f6 or NXf6 and Pe4 or Pe5xd6
Update:
Thanks #Toto for improving my version of regex above:
^([PNBRQK]?[a-h]?[1-8]?[xX-]?[a-h][1-8](=[NBRQ]| ?e\.p\.)?|^O-O(?:-O)?)[+#$]?$
I have been using this for a while in my web portal.
[BRQNK][a-h][1-8]| [a-h][1-8]|[BRQNK][a-h][a-h][1-8]|O-O|0-0-0|[BRQNK]x[a-h][1-8]|[a-h]x[a-h][1-8]|1\/2-1\/2|1\/-O|O-\/1
I'm developing an application in Java and found this strange behaviour:
if the regional settings format is set to Hungarian (system default) via the Control Panel, I get this exception, but if I set it to an English one, it works perfectly. Also works on a virtual Mandriva where I'm developing the program in the first place.
This is the code snippet that causes the problem:
public String stattxt(){
double dt = time_avg();
double bpm = (Double.compare(dt, 0) == 0) ? 0 : msec2bpm(dt);
String s = "<html>Number of control points: " + timestamps.size() + "<br>Average dt: " +
Double.valueOf(new DecimalFormat("#.####").format(dt).toString()) + " ms<br>" +
"Average BPM: " + Double.valueOf(new DecimalFormat("#.####").format(bpm).toString()) + "<br> </html>";
return s;
}
where both time_avg() and msec2bpm return double (not Double by any chance) values.
How could I make this work regardless to regional settings? Any help would be appreciated.
It seems like you're using
Double.valueOf(new DecimalFormat("#.####").format(dt).toString())
to round a number to 4 decimal places, but this looks like a hack to me and will fail due to regionalization settings (Hungary probably uses a decimal comma, not a decimal point.)
So, instead round doubles using something like:
rounded = Math.round(original * 10000)/10000.0;
And, if you want to create a string which is a double rounded to 4 decimal places, use String.format()
String.format("%.4f", original);
It looks like you should just skip the Double.valueOf:
public String stattxt(){
double dt = time_avg();
double bpm = (Double.compare(dt, 0) == 0) ? 0 : msec2bpm(dt);
String s = "<html>Number of control points: " + timestamps.size() + "<br>Average dt: " +
new DecimalFormat("#.####").format(dt) + " ms<br>" +
"Average BPM: " + new DecimalFormat("#.####").format(bpm) + "<br> </html>";
return s;
}
Why are you converting String to Double and then again to String? Do it like this:
public String stattxt(){
double dt=time_avg();
double bpm=(Double.compare(dt, 0)==0)?0:msec2bpm(dt);
String s="<html>Number of control points: "+timestamps.size()+"<br>Average dt: "+
new DecimalFormat("#.####").format(dt).toString()+" ms<br>"+
"Average BPM: "+Double.valueOf(new DecimalFormat("#.####").format(bpm).toString())+"<br> </html>";
return s;
}