I am currently writing a program that will read through a designated text file that checks the transaction values of each buy/sell/summary and checks the arithmetic such that if the transactions from the buy and sell statements do not equal the total transaction amount that was given in the summary then it outputs an error and closes the program. But currently my method scanMoneyValue has an error that says it's not returning a double, when in fact it is. Is there a different way I should go about returning the values from my method? Here is my code for reference:
import java.io.File;
import java.io.IOException;
import java.util.Scanner;
import javax.swing.JFileChooser;
import javax.swing.JOptionPane;
public class RecurrsionFileChecker {
public static void main(String[] args) {
int result;
//File Chooser Window
JFileChooser chooser = new JFileChooser("/home/nick/workspace/CS 1410-001/src/assignment03");
chooser.setDialogTitle("Please choose a file to be checked");
result = chooser.showOpenDialog(null);
//User Cancelled the chooser
if (result == JFileChooser.CANCEL_OPTION)
return;
File inputfile = chooser.getSelectedFile();
try
{
Scanner in = new Scanner(inputfile);
//Call Method to look at next transaction
scanNextTransaction(in);
}
catch (IOException e)
{
System.out.println("Could not read file: " + inputfile);
}
}
/**
* Returns double if the parameter Scanner has an error that does,
* not match the summary before it.
*
* #param s Any scanner
* #return double if Summaries don't match.
*/
public static double scanNextTransaction(Scanner s)
{
String buy, sell, summary, date;
double amount = 0, referenceValue, total = 0;
summary = s.next();
date = s.next();
referenceValue = scanMoneyValue(s);
while (s.hasNext())
{
if (s.next() == "Buy")
{
date = s.next();
amount = scanMoneyValue(s);
}
if(s.next() == "Sell")
{
date = s.next();
amount = scanMoneyValue(s);
}
if(s.next() == "Summary")
{
amount = scanSubSummary(s);
}
//add the transactions
total = total + amount;
}
return total;
}
public static double scanMoneyValue(Scanner in)
{
String dollar = in.next();
if(dollar.charAt(0) == '$')
{ //convert string to a double
String amount = dollar.substring(1);
double complete = Double.parseDouble(amount);
complete = complete * 100;
return complete;
}
}
public static double scanSubSummary(Scanner sub)
{
String summaryDate, transDate, transType;
int summarySubEntries, count = 0;
double transValue, summaryValue = 0, totalValue = 0, summaryAmount;
summaryDate = sub.next();
summaryAmount = scanMoneyValue(sub);
summarySubEntries = sub.nextInt();
while (count != summarySubEntries)
{
transType = sub.next();
if (transType == "Summary")
{
summaryValue = scanSubSummary(sub);
}
transValue = scanMoneyValue(sub);
totalValue = transValue + totalValue + summaryValue;
count++;
}
if (totalValue != summaryAmount)
{
System.out.print("Summary error on " + summaryDate + ".");
System.out.println("Amount is $" + summaryAmount + ", " + "should be $" + totalValue + ".");
}
return totalValue;
}
}
public static double scanMoneyValue(Scanner in)
{
String dollar = in.next();
if(dollar.charAt(0) == '$')
{ //convert string to a double
String amount = dollar.substring(1);
double complete = Double.parseDouble(amount);
complete = complete * 100;
return complete;
}
}
If the if condition fails then there's no return statement. You have a return inside of the condition but not outside. You'll need to add a return statement at the end, or throw an exception if not having a dollar sign is an error.
Okay, looking at the only relevant part of your code:
public static double scanMoneyValue(Scanner in)
{
String dollar = in.next();
if(dollar.charAt(0) == '$')
{ //convert string to a double
String amount = dollar.substring(1);
double complete = Double.parseDouble(amount);
complete = complete * 100;
return complete;
}
}
You do return a value if dollar starts with a $... but what do you expect to happen if it doesn't start with $? Currently you reach the end of the method without returning anything, which isn't valid.
You should probably throw an exception, if this is unexpected data that you can't actually handle.
Additionally, you shouldn't really use double for currency values anyway, due to the nature of binary floating point types. Consider using BigDecimal instead.
public static double scanMoneyValue(Scanner in)
{
String dollar = in.next();
if(dollar.charAt(0) == '$')
{ //convert string to a double
String amount = dollar.substring(1);
double complete = Double.parseDouble(amount);
complete = complete * 100;
return complete;
}
//NEED RETURN STATEMENT HERE
}
The error you get is because when you write a function all branches of that function must return a value of the correct type. In your case, if the if-statement fails it hits the end of the function without returning anything.
Its better to change it on
public static double scanMoneyValue(Scanner in)
{
String dollar = in.next();
String amount = dollar.replaceAll("[^\\d.]+", "")
double complete = Double.parseDouble(amount);
complete = complete * 100;
return complete;
}
link on explain - Parsing a currency String in java
Related
I am in need of some guidance. I am not sure how to go about reading in the sample text file into an array of objects. I know that the work needs to be in the while loop I have in main. I just do not know what I need to accomplish this.
I understand that I need to read in the file line by line (that's what the while loop is doing), but I don't know how to parse that line into an object in my array.
I know all of you like to see what people have tried before you help, but I honestly don't know what to try. I don't need a hand out, just some guidance.
Sample Text File:
100 3
120 5
646 7
224 9
761 4
Main:
public static void main(String[] args) {
Weight[] arrWeights = new Weight[25];
int count = 0;
JFileChooser jfc = new JFileChooser(FileSystemView.getFileSystemView().getHomeDirectory());
int returnValue = jfc.showOpenDialog(null);
if (returnValue == JFileChooser.APPROVE_OPTION) {
File selectedFile = jfc.getSelectedFile();
System.out.println(selectedFile.getAbsolutePath());
BufferedReader inputStream = null;
String fileLine;
inputStream = new BufferedReader(new FileReader(selectedFile.getAbsoluteFile()));
System.out.println("Weights:");
// Read one Line using BufferedReader
while ((fileLine = inputStream.readLine()) != null) {
count++;
System.out.println(fileLine);
}
System.out.println("Total entries: " + count);
}
}
Weight Class:
public class Weight {
private int pounds;
private double ounces;
private final int OUNCES_IN_POUNDS = 16;
public Weight(int pounds, double ounces) {
this.pounds = pounds;
this.ounces = ounces;
}
public boolean lessThan(Weight weight) {
return toOunces() < weight.toOunces();
}
public void addTo(Weight weight) {
this.ounces += weight.toOunces();
normalize();
}
public void divide(int divisor) {
if (divisor != 0) {
this.ounces = (this.toOunces() / divisor);
this.pounds = 0;
normalize();
}
}
public String toString() {
return this.pounds + " lbs " + String.format("%.3f", this.ounces) + " oz";
}
private double toOunces() {
return this.pounds * OUNCES_IN_POUNDS + this.ounces;
}
private void normalize() {
if (ounces >=16) {
this.pounds += (int) (this.ounces /OUNCES_IN_POUNDS);
this.ounces = this.ounces % OUNCES_IN_POUNDS;
}
}
}
I don't remember how to do that exactly in Java but I think this general guidance could help you:
In the while loop -
Parse the line you input from the read line using split function, you can use this as reference(first example can do the trick): http://pages.cs.wisc.edu/~hasti/cs302/examples/Parsing/parseString.html
Take the parsed line values, cast them to desired values per your class and create your object.
Append the created object to your list of objects: arrWeights
I am new in java and I have to use the code below but the code it does work because I have to specifying the path for input data and output data. The code is got it from the internet. please help me
class Svm_scale
{
private BufferedReader rewind(BufferedReader fp, String filename) throws IOException
{
fp.close();
return new BufferedReader(new FileReader(filename));
}
private void output_target(double value)
{
LnCount++;
if(y_scaling)
{
if(value == y_min)
value = y_lower;
else if(value == y_max)
value = y_upper;
else
value = y_lower + (y_upper-y_lower) *
(value-y_min) / (y_max-y_min);
}
formatterscaled.format(value+" ");
System.out.println(" Line Number "+LnCount + " ");
}
private void output(int index, double value)
{
count++;
double Threshold1=0,Threshold2=0;
Threshold1= Avg[index]+(STDV[index]/2);
Threshold2= Avg[index]-(STDV[index]/2);
if(value > Threshold1 )
value = 2;
else if(value < Threshold2 )
value = -2;
else
value = 0;
formatterscaled.format( formatter.format(value) + ",");
// System.out.println(" Counter "+count);
// }
}
String save_filename =Save1; // = null?
String restore_filename =null;
String scale_data_filename =Disc; // set this to the path where the output should be stored, e.g. = "C:\\temp\\scaled";
String data_filename =Libsvm; // set this to the path where the input can be get, e.g. = "C:\\temp\\inputdata"
These are the Strings you need to adapt in order that the program can read and write. Save1, Disc, Libsvm are not in your code, so it can only be guessed where they come from.
data_filename and scale_data_filename are required. save_filename seems to be optional and may be set to null.
I don't want to solve an equation and my question is not about Graphs and Trees Data Structures. I am trying to generate Data Points for graph from an equation given by user. I want efficient algorithm, easy to use and easy to maintain data structures. I have two solutions in mind
1: This is trivial and I have seen in many Applications.
String expr = "2*x+3*x";
Evaluator evaluator = new Evaluator();//I have this class
for (int i = start; i < end; i += step)
{
evaluator.setConstant("x", i);
double ans = evaluator.evaluate(expr);
}
This is very slow because each time every step is repeated like tokenzing, verifying, conversion to RPN, preparing stacks and queues and at last result calculation. The possible solution to this problem is somehow caching all stacks and queues but after that a comparison would be required between current expression and previous expression to use last stored state.
2: Currently I am developing second solution. The purpose of this is efficiency and would be used in Symbolic calculation in future.
So far my implementation
Variable.java
import java.text.DecimalFormat;
public class Variable
{
private final double pow;
private final double coefficient;
private final String symbol;
public Variable(String symbol)
{
this.symbol = symbol;
this.pow = 1.0;
this.coefficient = 1.0;
}
public Variable(String symbol, double coefficient, double pow)throws IllegalArgumentException
{
if (coefficient == 0.0)throw new IllegalArgumentException("trying to create variable with coefficient 0");
if (pow == 0.0)throw new IllegalArgumentException("trying to create variable with exponent 0");
this.symbol = symbol;
this.pow = pow;
this.coefficient = coefficient;
}
public final String getSymbol()
{
return this.symbol;
}
public final double getPow()
{
return this.pow;
}
public final double getCoefficient()
{
return this.coefficient;
}
#Override
public String toString()
{
StringBuilder builder = new StringBuilder();
DecimalFormat decimalFormat = new DecimalFormat("#.############");
if (coefficient != 1.0)builder.append(decimalFormat.format(this.coefficient));
builder.append(this.symbol);
if (this.pow != 1.0)builder.append("^").append(decimalFormat.format(this.pow));
return builder.toString();
}
/*
* Stub Method
* Generate some unique hash code
* such that chances of key collision
* become less and easy to identify
* variables with same power and same
* symbol*/
#Override
public int hashCode()
{
return 0;
}
}
Equation.java
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
public class Equation
{
private final ArrayList<Boolean> operations;
private final HashMap<String, Variable> variableHashMap;
private int typesOfVariables;
public Equation(Variable variable)
{
this.variableHashMap = new HashMap<>();
this.operations = new ArrayList<>();
this.typesOfVariables = 1;
this.variableHashMap.put(variable.getSymbol(), variable);
}
/*Stub Method*/
public void addVariable(Variable variable, boolean multiply)
{
/*
* Currently not covering many cases
* 1: Add two variables which have same name
* and same pow.
* 2: variable which are wrapped inside functions e.g sin(x)
* and many other.*/
if (multiply && variableHashMap.containsKey(variable.getSymbol()))
{
Variable var = variableHashMap.get(variable.getSymbol());
Variable newVar = new Variable(var.getSymbol(), var.getCoefficient() * variable.getCoefficient(), var.getPow() + variable.getPow());
/*
* Collision chances for variables with same name but
* with different powers*/
this.variableHashMap.replace(var.getSymbol(), newVar);
}
else
{
++this.typesOfVariables;
this.variableHashMap.put(variable.getSymbol(), variable);
}
this.operations.add(multiply);
}
/*Stub Method
*Value for every variable at any point will be different*/
public double solveFor(double x)
{
if (typesOfVariables > 1)throw new IllegalArgumentException("provide values for all variables");
Iterator<HashMap.Entry<String, Variable>> entryIterator = this.variableHashMap.entrySet().iterator();
Variable var;
double ans = 0.0;
if (entryIterator.hasNext())
{
var = entryIterator.next().getValue();
ans = var.getCoefficient() * Math.pow(x, var.getPow());
}
for (int i = 0; entryIterator.hasNext(); i++)
{
var = entryIterator.next().getValue();
if (this.operations.get(i))ans *= var.getCoefficient() * Math.pow(x, var.getPow());
else ans += var.getCoefficient() * Math.pow(x, var.getPow());
}
return ans;
}
#Override
public String toString()
{
StringBuilder builder = new StringBuilder();
Iterator<HashMap.Entry<String, Variable>> entryIterator = this.variableHashMap.entrySet().iterator();
if (entryIterator.hasNext())builder.append(entryIterator.next().getValue().toString());
Variable var;
for (int i = 0; entryIterator.hasNext(); i++)
{
var = entryIterator.next().getValue();
if (this.operations.get(i))builder.append("*").append(var.toString());
else builder.append(var.toString());
}
return builder.toString();
}
}
Main.java
class Main
{
public static void main(String[] args)
{
try
{
long t1 = System.nanoTime();
Variable variable = new Variable("x");
Variable variable1 = new Variable("x", -2.0, 1.0);
Variable variable2 = new Variable("x", 3.0, 4.0);
Equation equation = new Equation(variable);
equation.addVariable(variable1, true);//2x+x
equation.addVariable(variable2, true);
for (int i = 0; i < 1000000; i++)equation.solveFor(i);//Calculate Million Data Points
long t2 = System.nanoTime();
System.out.println((t2-t1)/1000/1000);
System.out.println(equation.toString());
}
catch (Exception e)
{
System.out.println("Error: " + e.getMessage());
}
}
}
Am I going in right direction?
Is there any commonly used Algorithm for this problem?
My main goal is efficiency, code cleanness and code maintainability.
Note: I am not native English speaker so please ignore any grammatical mistake.
Thanks.
I do not see any problem with your first code. Yes may be at every step your code "repeat like tokenzing, verifying, conversion to RPN, preparing stacks and queues and at last result calculation", but in the end all of this is just linear number of steps. So I fail to see how it can make it really slow.
One of the biggest screens I have seen was 2560x1440 pixels, which means that most of the time you would need less than 2500 points to draw your graph there.
If you point is code cleanness and code maintainability, then most probably a code consisting of 5 lines is better than the code consisting of 200.
I have to write a program to convert between linear units in, ft, mi, mm, cm, m, km. I know there are easier and better ways to do this. I think we'ere just trying to fully understand if else if statements. But this is what I have so far. I'm just trying to figure out if I am on the right track. I've tried to write out some pseudocode but it just seems like a lot going on so I find it a bit overwhelming. Next I'm going to add a method to convert form in or mm to whatever is selected by the user.
When I test the program i get this: UnitConversion#76c5a2f7 (EDIT: THIS ISSUE WAS FIXED)
Ok I made the suggested changes and that allowed the first part of the program to run properly. I have now added my second method to convert from in/mm to the other measurements.. I was having issues but I figured it out.
Here is my main method;
public class LinearConversion
{
public static void main(String[] args)
{
UnitConversion newConvert = new UnitConversion("km", "m", 100);
System.out.println(newConvert);
}
}
Any suggestions? What am I missing or not understanding about doing this sort of program?
public class UnitConversion
{
private String input;
private String output;
private double value;
private double temp;
private double in, ft, mi, mm, cm, m, km;
private final double inch_feet = 12;
private final double inch_miles = 63360;
private final double inch_millimeters = 25.4;
private final double inch_centimeters = 2.54;
private final double inch_meters = 0.0254;
private final double inch_kilometers = 0.0000254;
private final double millimeters_inch = 0.0393701;
private final double millimeters_feet = 0.00328084;
private final double millimeters_miles = 0.000000622;
private final double millimeter_centimeters = 10;
private final double millimeter_meters = 1000;
private final double millimeter_kilometers = 1000000;
public UnitConversion(String in, String out, double val)
{
input = in;
output = out;
value = val;
}
public String toString()
{
if (input.equals("mi"))
{
in = value * inch_miles;
input = "in";
}
else if (input.equals("ft"))
{
in = value * inch_feet;
input = "in";
}
else
{
in = value;
input = "in";
}
if (input.equals("km"))
{
mm = value * millimeter_kilometers;
input = "mm";
}
else if (input.equals("m"))
{
mm = value * millimeter_meters;
input = "mm";
}
else if (input.equals("cm"))
{
mm = value * millimeter_centimeters;
input = "mm";
}
else
{
mm = value;
input = "mm";
}
return value + input + " " + output;
}
public double getUnit()
{
if (input.equals("in"))
{
if (output.equals("ft"))
{
ft = in * inch_feet;
System.out.println(ft + "ft");
}
else if (output.equals("mi"))
{
mi = in * inch_miles;
System.out.println(mi + "mi");
}
else if (output.equals("mm"))
{
mm = in * inch_millimeters;
System.out.println(mm + "mm");
}
else if (output.equals("cm"))
{
cm = in * inch_centimeters;
System.out.println(cm + "cm");
}
else if (output.equals("m"))
{
m = in * inch_meters;
System.out.println(m + "m");
}
else if (output.equals("km"))
{
km = in * inch_kilometers;
System.out.println(km + "km");
}
else
{
System.out.println(in + "in");
}
}
else
{
if (output.equals("cm"))
{
cm = mm * millimeter_centimeters;
System.out.println(cm + "cm");
}
else if (output.equals("m"))
{
m = mm * millimeter_meters;
System.out.println(m + "m");
}
else if (output.equals("km"))
{
km = mm * millimeter_kilometers;
System.out.println(km + "km");
}
else if (output.equals("in"))
{
in = mm * millimeters_inch;
System.out.println(in + "in");
}
else if (output.equals("ft"))
{
ft = mm * millimeters_feet;
System.out.println(ft + "ft");
}
else if (output.equals("mi"))
{
mi = mm * millimeters_miles;
System.out.println(mi + "mi");
}
else
{
System.out.println(mm + "mm");
}
}
}
Basically, you need/want to give a String argument to System.out.println in order to display it.
Thus, when you use System.out.println with an Object (that is not a String) as the argument, Java actually outputs the result of the toString method on that object.
If you haven't overridden it, the Object class' implementation of toString is used: this is what gives you your current output: UnitConversion#76c5a2f7.
To learn more about how is this default toString implementation generating that String, you can refer to the javadoc entry for Object#toString.
Base on your output, and your provided code, yes! Rename String getInput() to String toString() and your current main() will work, or change your current main()
System.out.println(newConvert.getInput()); // <-- added .getInput()
I am new to Java and am still getting used to the minor difference so please excuse any mistakes you may find ridiculous.
I am trying to write a program that stores temperature and can be used to call that temperature in Celsius or in Fahrenheit. My only issue comes with the command line arguments, after successfully compiling my program I enter the following:
java Driver 0.0C 32.0F
And then I get this:
Exception in thread "main" java.lang.NumberFormatException: For input string:
"0.0C"
at sun.misc.FloatingDecimal.readJavaFormatString(FloatingDecimal.java:1241)
at java.lang.Float.parseFloat(Float.java:452)
at Driver.main(Driver.java:47)
My program is still not completely polished up so I know that the getters can be written to be much for efficient and that the driver program doesn't even call the temperature class, but this is not my concern at the moment. My Driver is supposed to take in the input and determine from the 'C' or 'F' character whether the value is in Celsius or Fahrenheit. It then parses the string and truncates the C or F and stores the values contained in the strings as floats. I am using Eclipse and the program is object oriented, this is my code:
public class Temperature {
private float temperature;
private char scale;
// default constructor
Temperature() {
this.temperature = 0;
this.scale = 'C';
}
Temperature(float temperatureIn) {
this.temperature = temperatureIn;
this.scale = 'C';
}
Temperature(char scaleIn) {
this.temperature = 0;
this.scale = scaleIn;
}
Temperature(float temperatureIn, char scaleIn) {
this.temperature = temperatureIn;
this.scale = scaleIn;
}
float degreesC(float degreesF) {
float degreesC = (5 * (degreesF - 32)) / 9;
return degreesC;
}
float degreesF(float degreesC) {
float degreesF = (9*(degreesC / 5)) + 32;
return degreesF;
}
void setTemperature(float temperatureIn) {
temperature = temperatureIn;
}
void setScale(char scaleIn) {
scale = scaleIn;
}
void setBothValues(float temperatureIn, char scaleIn) {
temperature = temperatureIn;
scale = scaleIn;
}
int compareTemps(Temperature temp1, Temperature temp2) {
// both values will be compared in Farenheit
Temperature temp1temp = temp1;
if (temp1temp.scale == 'C') {
temp1temp.temperature = degreesF(temp1temp.temperature);
temp1temp.scale = 'F';
}
Temperature temp2temp = temp2;
if (temp2temp.scale == 'C') {
temp2temp.temperature = degreesF(temp2temp.temperature);
temp2temp.scale = 'F';
}
if (temp1temp.temperature == temp2temp.temperature) {
return 0;
}
if (temp1temp.temperature > temp2temp.temperature)
return 1;
if (temp1temp.temperature < temp2temp.temperature)
return -1;
return 0;
}
}
And the main driver program:
public class Driver {
public static void main(String[] args) {
// ints to hold the temperature values
float temp1Value = 0;
float temp2Value = 0;
// strings to hold the scale types
char temp1Scale = 'C';
char temp2Scale = 'C';
// declare objects of type temperature
Temperature firstTemp = null;
Temperature secondTemp = null;
// copy scale values of temperatures
int scaleIndex = 0;
int scaleIndex2 = 0;
if (args.length > 0) {
if (args[0].indexOf('C') != -1)
{
scaleIndex = args[0].indexOf('C');
temp1Scale = args[0].charAt(scaleIndex);
}
else if (args[0].indexOf('F') != -1)
{
scaleIndex = args[0].indexOf('F');
temp1Scale = args[0].charAt(scaleIndex);
}
if (args[1].indexOf('C') != -1)
{
scaleIndex = args[1].indexOf('C');
temp2Scale = args[1].charAt(scaleIndex2);
}
else if (args[1].indexOf('F') != -1)
{
scaleIndex = args[1].indexOf('F');
temp2Scale = args[1].charAt(scaleIndex2);
}
}
// parse the values to exclude scales and copy to strings holding temperature values
if (args.length > 0) {
temp1Value = Float.parseFloat(args[0].substring(0, scaleIndex));
temp2Value = Float.parseFloat(args[1].substring(0, scaleIndex2));
}
}
}
the exception you are getting is beacuse you passed '0.0C' to the float parser at:
tempValue = Float.parseFloat(args[1].substring(0, scaleIndex));
that is beacuse you do
scaleIndex = args[1].indexOf('F');
effectively overwriting the scaleIndex instead of setting scaleIndex2
please be open minded with my following recommendations:
object oriented means you create classes which will take up responsibility
your Temperature class stores temp in celsius and in fahrenheit too..which might be easier, but storing only for example Kelvins would mean you have a strong inner concept inside the class
when someone asks for C or F it calculates from the K
after that the Temperature class's constructor should be responsible for parsing '0.0C' and '42.0F'
It is better you take inputs as <temp1> <unit1> <temp2> <unit2>. This way you'll get all the parameter you need in the desired format. You can now parse args[0] and args[2] for tempValues and the other two parameter for the units. Even better, just take <temp1> <temp2> as you command line arguments and decide that <temp1> is in degC and <temp2> is in F.