How to compare two double numbers in Selenium - java

I have some trouble to write test script where I have to check if discount and prices on the website are correct. I wrote something like that:
#Test
public void discountOnTheDress() {
WebElement dressLink = driver.findElement(By.cssSelector("#block_top_menu > ul > li:nth-child(2) > a"));
dressLink.click();
List<WebElement> listOfDresses = driver.findElements(By.cssSelector("div.product-container"));
for (WebElement e: listOfDresses) {
double endPrice = 0;
if(e.getText().contains("%")) {
String priceWithDollarBeforeDiscount = driver.findElement(By.xpath("//*[#id=\"center_column\"]/ul/li[3]/div/div[2]/div[1]/span[2]")).getText();
String priceWithoutDollarBeforeDiscount = priceWithDollarBeforeDiscount.replace("$", "");
double priceBeforeDiscount = Double.parseDouble(priceWithoutDollarBeforeDiscount);
String priceWithDollarAfterDiscount = driver.findElement(By.xpath("//*[#id=\"center_column\"]/ul/li[3]/div/div[2]/div[1]/span[1]")).getText();
String priceWithoutDollarAfterDiscount = priceWithDollarAfterDiscount.replace("$", "");
double priceAfterDiscount = Double.parseDouble(priceWithoutDollarAfterDiscount);
String discountWithPercent = driver.findElement(By.xpath("//*[#id=\"center_column\"]/ul/li[3]/div/div[2]/div[1]/span[3]")).getText();
String discountWithoutPercent = discountWithPercent.replaceAll("[^0-9]", "");
double discount = Double.parseDouble(discountWithoutPercent);
endPrice = ((discount / 100) * priceBeforeDiscount) + priceAfterDiscount;
Assert.assertEquals(priceAfterDiscount, endPrice);
}
}
}
It doesn't work and I don't know how to handle that. Does someone have any idea how to write it correctly?
Thanks for your help.

From the top of my head, I can think of two easy ways -
First - ==
if(priceAfterDiscount == endPrice) {
//Double values are same
}
Second - java.lang.Double.compare()
if(Double.compare(priceAfterDiscount, endPrice) == 0) {
//Double values are same
}

Related

Round Double datatype upto 3 digits

I am trying to calculate the value a field which represent Interest rate for that I have to round up the value to 3 digits.
Below is code which I am using :
double bigAmt1 = Double.parseDouble(amount);
bigAmt = (intsign*bigAmt1)/div;
bigAmt=Math.round(bigAmt*1000d)/1000d;
amount = 4048500
intsign = 1
div = 6
it returns = 4.048
I need it return = 4.049
if I change the value of amount to 4048600 then it return 4.049 so I think it is rounding up values where last digit after division is greater than 5 but It should be if last digit equal or greater than 5 then It should round up to next digit.
Below is my test class --
package test;
import java.math.BigDecimal;
import java.math.MathContext;
import java.math.RoundingMode;
import java.text.DecimalFormat;
public class Test {
public static void main(String[] args) {
// TODO Auto-generated method stub
System.out.println(divideAndConvertToString1("4048100","6","1"));
//System.out.println("---> 3 places "+Math.round(3.5));
//Math.round(3.7)
/*double value = 12.3457652133;
value =Double.parseDouble(new DecimalFormat("##.####").format(value));
System.out.println("---> 3 places "+value);*/
}
public static String divideAndConvertToString(String amount, String decml, String sign) {
double bigAmt = 0.00;
int div = 0;
double d =0;
if (!isStringEmpty(decml)) {
d = Double.parseDouble(decml);
}
double d1 = Math.pow(10, d);
div = (int)d1;
int intsign = Integer.parseInt(sign);
if (amount != null && !"".equalsIgnoreCase(amount)) {
//BigDecimal bigAmt1 = new BigDecimal(amount);
double bigAmt1 = Double.parseDouble(amount);
bigAmt = (intsign*bigAmt1)/div;
bigAmt=Math.ceil(bigAmt*1000d)/1000d;
//bigAmt = new BigDecimal((intsign*bigAmt1.doubleValue())/div);
return String.valueOf(bigAmt);
}
else {
bigAmt = bigAmt;
}
System.out.println("inside divideAndConvertToString");
return String.valueOf(bigAmt);
}
public static String divideAndConvertToString1(String amount, String decml, String sign) {
BigDecimal bigAmt = null;
int div = 0;
double d =0;
if (!Util.isStringEmpty(decml)) {
d = Double.parseDouble(decml);
}
double d1 = Math.pow(10, d);
div = (int)d1;
int intsign = Integer.parseInt(sign);
if (amount != null && !"".equalsIgnoreCase(amount)) {
BigDecimal bigAmt1 = new BigDecimal(amount);
bigAmt = new BigDecimal((intsign*bigAmt1.doubleValue())/div);
}
else {
bigAmt = new BigDecimal("0");
}
System.out.println("inside divideAndConvertToString1");
return String.valueOf(bigAmt.setScale(3, RoundingMode.CEILING));
//System.out.println(b.setScale(0, RoundingMode.CEILING));
}
public static boolean isStringEmpty(String input) {
if (input == null || input.trim().length() == 0 || "".equalsIgnoreCase(input)) {
return true;
}
return false;
}
}
Math.round should work however I usual do this like this:
bigAmt=Math.floor((bigAmt*1000d)+0.5d)/1000d;
Your problem however lies elsewhere:
bigAmt1 = Double.parseDouble(amount);
bigAmt = (intsign*bigAmt1)/div;
bigAmt=Math.round(bigAmt*1000d)/1000d;
So using your values:
amount = 4048500
intsign = 1
div = 6
bigAmt1 = 4048500;
bigAmt = (1*4048500)/6 = 674750;
bigAmt= round(674750*1000)/1000 = round(674750000)/1000 = 674750;
However in your example You wrote: it returns = 4.048 I need it return = 4.049 So do you have the same div value?
If the div is 1000000 instead then:
bigAmt1 = 4048500;
bigAmt = (1*4048500)/1000000 = 4.048500;
bigAmt= round(4.048500*1000)/1000 = round(4048.500)/1000 = 4.049;
However there is a big problem because floating point might round your 4.048500 number to something like 4.048499999999. It is safer to use integer rounding directly:
1000* ((amount+500)/1000)
1000* ((4048500+500)/1000)
1000* ((4049000 )/1000)
1000* (4049)
4049000
So you add half of the rounding value, divide by rounding value and then multiply by rounding value. All done on integers
Why won't you use Math.ceil(), instead of Math.round(), I think that's what it's for.

Extracting digit values from before and after decimal points in Java

I have 2 values
String latitude = "37.348541";
String longitude = "-121.88627";
I would like to extract like the values as below with out any rounding up the values.
latitude = "37.34";
longitude = "-121.88";
I tried using DecimalFormat.format, but it does some round up and I want to extract an exact value.
You can define a function using String#substring and String#indexOf as shown below:
public class Main {
public static void main(String[] args) {
// Tests
System.out.println(getNumberUptoTwoDecimalPlaces("37.348541"));
System.out.println(getNumberUptoTwoDecimalPlaces("-121.88627"));
System.out.println(getNumberUptoTwoDecimalPlaces("-121.8"));
System.out.println(getNumberUptoTwoDecimalPlaces("-121.88"));
System.out.println(getNumberUptoTwoDecimalPlaces("-121.889"));
}
static String getNumberUptoTwoDecimalPlaces(String number) {
int indexOfPoint = number.indexOf('.');
if (indexOfPoint != -1 && number.length() >= indexOfPoint + 3) {
return number.substring(0, indexOfPoint + 3);
} else {
return number;
}
}
}
Output:
37.34
-121.88
-121.8
-121.88
-121.88
For example:
String latitude = "37.348541";
int i = latitude.indexOf(".");
if(i > 0 && i < latitude.length()-2) latitude = latitude.substring(i, i+2);
You can use the BigDecimal class and the ROUND_DOWN option. So the code could look like this:
BigDecimal number = new BigDecimal("123.13298");
BigDecimal roundedNumber = number.setScale(2, BigDecimal.ROUND_DOWN);
System.out.println(roundedNumber);
Otherwise you can also use the native double and the Math.floor or the Math.ceil method:
double number = 123.13598;
double roundedNumber = (number < 0 ? Math.ceil(number * 100) : Math.floor(number * 100)) / 100;
System.out.println(roundedNumber);

finding the minimum value in circular array queue

public class CanadaTour {
private CircularArrayQueue<City> cityQueue;
private Map map;
private City startCity;
public CanadaTour (String fileName) {
map = new Map();
cityQueue = new CircularArrayQueue<City>();
loadData(fileName);
}
private void loadData (String file) {
MyFileReader reader = new MyFileReader(file);
reader.readString(); // First line of headers.
String cityName = null;
int locX = 0;
int locY = 0;
double earnings = 0;
int cityID = 0;
while (!reader.endOfFile()) {
cityName = reader.readString();
locX = reader.readInt();
locY = reader.readInt();
earnings = reader.readDouble();
cityID ++;
City city = new City(cityID, cityName, locX, locY, earnings);
if (cityID == 1) {
startCity = city;
}
cityQueue.enqueue(city);
map.addCity(city);
}
}
public City findNextCity (City currCity, double currMoney) {
double distance = 0;
City result = cityQueue.dequeue();
if (result != currCity || result.isMarkedInStack()
|| result.isMarkedOutOfStack()) //add other conditionals
distance = distBetweenCities(result, currCity);
cityQueue.enqueue(result);
double distance1;
for (int i = 1; i < cityQueue.getLength(); i ++) {
City result1 = cityQueue.dequeue();
if (result1 != currCity || result1.isMarkedInStack()
|| result1.isMarkedOutOfStack()) { //add other conditionals
distance1 = distBetweenCities(result1, currCity);
if (distance1 < distance) {
distance = distance1;
return result1;
}
cityQueue.enqueue(result1);
}
}
return result;
}
public double distBetweenCities (City city1, City city2) {
double result = Math.sqrt(Math.pow(city2.getX() - city1.getX(), 2) +
Math.pow(city2.getY() - city2.getY(), 2) * 1.0);
return result;
}
public double calcFlightCost (double distance) {
double flightCost;
if (distance < 100.0) {
flightCost = 127.00;
} else {
flightCost = (1.25 * distance) + 32.0;
}
return flightCost;
}
This is what I have thus far, but logically my answer seems wrong for the findNextCity method. and additionally, I don't even know how to approach the second part of the question (below).
I am supposed to go through each element in the cityQueue to determine which one is the
closest to the current city (from the first parameter) using the Euclidean distance
calculated in the next method (distBetweenCities). I must omit cities that already
marked in or out of the stack and the current city itself (otherwise a city will always be
the closest city to itself!). If the found city (with the smallest distance to current city) is
null, return null. Calculate the flight cost to this city and determine if it is affordable with
the band's current money. If so, return the city, but if it is not affordable then return null.
Without providing a complete solution, here are several pointers you might like to consider:
You seem to be dequeuing and enqueuing for the purpose of viewing the head of the queue. If your CircularArrayQueue implements Queue it should have a peek method that views the head without removing it.
The or operators in your filter condition should probably be and (&&) if I'm reading your requirements correctly
As you mention, your logic is pretty flaky in findNextCity it kinda seems to look for the first city that is smaller than the distance to the next city or something like that
You probably need something like:
City closestCity = null;
for (City testCity: cityQueue) {
if (testCity != currCity
&& !testCity.isMarkedInStack() && !testCity.isMarkedOutOfStack()
&& (closestCity == null || distance(currCity, closestCity) > distance(currCity, testCity))
closestCity == testCity;
}

How to check if the string is equal to or greater than something?

I want to check if strCurrentSpeed is greater than or equal to "10".
how do i do that? i am getting error- "The operator >= is undefined for the argument type(s) String, int" i know this is pretty basic but i couldn't find a workaround
public void updateSpeed(CLocation location)
{
float nCurrentSpeed = 0;
if( location!=null )
{
location.setUseMetricUnits(this.useMetricUnits());
nCurrentSpeed = location.getSpeed();
}
Formatter fmt = new Formatter(new StringBuilder());
fmt.format(Locale.US, "%5.1f", nCurrentSpeed);
String strCurrentSpeed = fmt.toString();
strCurrentSpeed = strCurrentSpeed.replace(' ', '0');
String strUnits = "miles/hour";
if (this.useMetricUnits())
{
strUnits = "meters/second";
}
TextView txtCurrentSpeed = (TextView) this.findViewById(R.id.txtCurrentSpeed);
txtCurrentSpeed.setText(strCurrentSpeed + " " + strUnits);
if (strCurrentSpeed >= 10){
//do action
}}
Use Explicit Conversion :
if(Integer.parseInt(strCurrentSpeed) >=10)
{
// Do you stuff
}

what is the best way to handle double value while split?

String x = "39.33";
String result ;
Double x1 = new Double(x);
System.err.println("value :"+ x1);
String[] parts = x1.toString().split("\\.");
if(parts != null )
{
if((Integer.parseInt(parts[1])) > 0)
{
result =x1;
}
else
{
result= parts[0];
}
}
please let me know the best way to format/split the value:
my need is....
if x is 39
so x1 is 39.0
so i need result =39
if x is 39.33
so x1 is 39.33
so i need result =39.33
i dont want to use split or condition checking if((Integer.parseInt(parts[1])) > 0).. please let me know the best way for this?
Try this:
Double d = Double.parseDouble("35.0");
String result = NumberFormat.getNumberInstance().format(d.doubleValue())
System.out.println(result);
if you convert your double to an int the decimal places are ignored.
for this problem it would be something like that:
String result;
String x = "39.33";
Double x1 = new Double(x);
int xPre = x1.intValue();
if ( x1 > xPre) {
result = x1;
} else {
result = Integer.toString(xPre);
}
All you need to do is to read the number as a double and cast it to an int, which will effectively truncate the number.
You can do
String x = "39.33";
long l = (long) Double.parseDouble(x); // == 39
This will result in l being the whole number part of the double. (provided the number is less than 9 billion billion)
If you really want to use split you can do the following which will be slightly slower but will throw an exception if the number is too large.
long l = Long.parseLong(x.split("\\.")[0]);
public static void main(String[] args) {
Double x = new Double("39.33");
Double y = new Double("39.0");
printDouble(x);
printDouble(y);
}
public static void printDouble(Double dbl){
System.out.println(dbl.toString().replaceAll("[0]*$", "").replaceAll(".$", ""));
}

Categories