Is there any way to do this easier? [closed] - java

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 3 years ago.
Improve this question
I'm new to java, i do study from udemy.
My question is...at the end of learning java i will find out there are n better ways to do the same thing ? (i just want to accelerate the process of learning)
There is my code if some one can give me an example of a better way so i can understand. Thank you !!
public static void main(String[] args) {
toMillesPerHour(50);
toMillesPerHour(90);
toMillesPerHour(100);
toMillesPerHour(130);
toMillesPerHour(-20);
}
public static void toMillesPerHour(double kilomettersPerHour) {
//return round value
if(kilomettersPerHour >= 0) {
kilomettersPerHour = (int) kilomettersPerHour / 1.60934;
int roundKm = (int) kilomettersPerHour;
System.out.println("You travel with speed of: " + roundKm +" Miles");
}else {
System.out.println("Negative value detected");
}
}
You travel with speed of: 31 Miles
You travel with speed of: 55 Miles
You travel with speed of: 62 Miles
You travel with speed of: 80 Miles
Negative value detected

I assume a typical Java developer with some experience would do these things:
change the return type to double (int if you need to round the result);
throw an exception when kilomettersPerHour < 0;
print the results in the main.
For example,
public static double toMillesPerHour(double kilomettersPerHour) {
if (kilomettersPerHour < 0) {
throw new IllegalArgumentException("Negative value detected");
}
return kilomettersPerHour / 1.60934;
}

You could make the change steven35 suggest, but also in your toMilesPerHour method you shouldn't use the parameter variable to store the result of divison. Instead of that you should do something like:
int milesPerHour = (int)kilometersPerHour / 1.60934
This way you don't need to make any additional variables to round your result. Also it's bad practice to modify parameter variables.

You could just define the values in an array and iterate over them. Then every time you add a new value, you don't have to call toMillesPerHour() again.
double[] values = { 50.0, 90.0, 100.0, 130.0, -20.0 };
for (double value : values) {
toMillesPerHour(value);
}

You can use Math.round() for more accurate result.
public static void main(String[] args) {
toMillesPerHour(50);
toMillesPerHour(90);
toMillesPerHour(100);
toMillesPerHour(130);
toMillesPerHour(-20);
}
public static void toMillesPerHour(double kilomettersPerHour) {
//return round value
if(kilomettersPerHour >= 0) {
kilomettersPerHour = kilomettersPerHour / 1.60934;
int roundKm = (int) Math.round( kilomettersPerHour );
System.out.println("You travel with speed of: " + roundKm +" Miles");
}else {
System.out.println("Negative value detected");
}
}

My single biggest issue with this code is that the name toMilesPerHour(50); only tells half the story. 50 what? Don't make me look inside to figure that out.
Not convinced? Ok now I need a method that converts feet per second to miles per hour. What am I supposed to name it that won't cause confusion?
If your method was hanging off a type named KilometersPerHour this name would be fine but as is this name makes the abstraction fail. I have to look inside to know what it means.

You could use varargs. - It allows you to remove alot of code.
You do not need double.
Using parameters as local variables is not so good approach.
Have a look at:
class Printer {
public static void main(String[] args) {
toMillesPerHour(50, 90, 100, 130, -20);
}
public static void toMillesPerHour(int... kilomettersPerHour) {
Arrays.stream(kilomettersPerHour).forEach(Printer::printRound);
//return round value
}
private static void printRound(int kmPerHour) {
String message = (kmPerHour >= 0) ? calculate(kmPerHour) : "Negative value detected";
System.out.println(message);
}
private static String calculate(int kmPerHour) {
int roundKm = (int) (kmPerHour / 1.60934);
return "You travel with speed of: " + roundKm + " Miles";
}
}

Related

Frustrating Syntax Issues with passing values into methods [closed]

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Closed 5 years ago.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Improve this question
I needed to rewrite a java program I had already completed to now include a class I would be able to test with using JUnit4. Unfortunately I can't even get to that point because I'm receiving an error. It's a really simple program where I ask the user for 3 numbers, pass those values into a function that does some calculations and should return a print statement with the value back. I made it work without the function and I'm having trouble with the syntax and fully understanding what I can and can't do with methods.
Here it is:
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner kybd = new Scanner(System.in);
System.out.println("Given ax^2 + bx^2 + c = 0");
System.out.println("Please enter 'a', 'b', and 'c' to determine if there are any roots: ");
float numA = kybd.nextFloat();
float numB = kybd.nextFloat();
float numC = kybd.nextFloat();
quadraticAnswer(numA, numB, numC);
}
public static void float quadraticAnswer (float numA, float numB, float numC){
float discriminant = ((numB*numB)-(4*numA*numC));
if (discriminant < 0){
System.out.println("The Equation has no roots!");
}
else if (discriminant ==0) {
float root = (-numB + Math.sqrt(discriminant))/(2*numA);
System.out.println("The Equation has one root: "+ root);
}
else {
float root1 = (-numB + Math.sqrt(discriminant))/(2*numA);
float root2 = (-numB - Math.sqrt(discriminant))/(2*numA);
System.out.println("The Equation has two roots: " + root1 + " and " + root2 + ".");
}
}
}
Change the invalid syntax of
public static void float quadraticAnswer
to
public static void quadraticAnswer
as you are not returning anything.
If you use an IDE like Eclipse it will quickly highlight such errors

Calling a method for calculation [duplicate]

This question already has answers here:
How to get the user input in Java?
(29 answers)
Closed 6 years ago.
So I made a class that is supposed to calculate the number of beers needed to become intoxicated. My class receives User Input for the name of the beer, the alcohol content, and then the user's weight to make the calculation.
Here's my whole Beer class
public class Beer {
private String name;
private double alcoholContent;
//Default apple values (Constructors)
public Beer()
{
this.name = "";
this.alcoholContent = 0.0;
}
//Accessors
public String getName()
{
return this.name;
}
public double getAlcoholContent()
{
return this.alcoholContent;
}
//Mutators
public void setName (String aName)
{
this.name = aName;
}
public void setAlcoholContent (double aAlcoholContent)
{
if (aAlcoholContent < 0 || aAlcoholContent > 1)
{
System.out.println("That is an invalid alcohol content");
return;
}
this.alcoholContent = aAlcoholContent;
}
//Methods
public double Intoxicated (double aWeight)
{
double numberOfDrinks = (0.08 + 0.015) * aWeight / (12 * 7.5 * this.alcoholContent);
return numberOfDrinks;
}
This is specifically my intoxicatedmethod in the class (I think it's right):
public double Intoxicated (double aWeight)
{
double numberOfDrinks = (0.08 + 0.015) * aWeight / (12 * 7.5 * this.alcoholContent);
return numberOfDrinks;
}
This is what the output window is supposed to look like, receiving User Input for the weight and then performing the calculation to see how many beers it would take based on the user's input when previously defining two beers to be considered intoxicated:
What’s the weight of the person consuming said beverages?
185
It would take 3.166 "firstBeerName" beers to become intoxicated.
It would take 1.979 "secondBeerName" beers to become intoxicated.
The intoxicated formula was given to me, I don't know how to properly set up my class testing main method file which calls this class to reflect that output.
You need to write a testing class, that contains a main method. In the main method you can create several Beer-Objects.
By iterating over your Beers, you can get the wanted results.
Look here to get information about how to set up a main method.
Create an Array of Beer-Objects in that method with different alcohol content
Get the user input for the weight and then
Iterate over your Array, call intoxicated() and print the results
You are going to want to create a main method which does the following:
1) Prints the prompt for the beer values (name and % alcohol)
2) Takes in user input for those beer values
3) Prints the prompt for the user's weight
4) Takes in the user input for the weight
5) Calculates and prints the result
For printing prompts, you will most likely want to use System.out.println("Some prompt here!");
For taking input, you will most likely want to use a Scanner. You can search around on this website and others, as well as read the documentation, for how to take input with using that class.
Here is an example of a main method:
public static void main(String[] args) {
Beer blueMoon = new Beer("Blue Moon", 5.4);
Beer hoegaarden = new Beer("Hoegaarden", 4.9);
System.out.println("Enter your weight: ");
Scanner input = new Scanner();
Double weight = input.nextLine();
double value = beer1.Intoxicated(weight);
System.out.println("It would take " + value + " of " + blueMoon.getName() + " to become intoxicated.");
}
I would suggest renaming your Intoxicated method to intoxicated, as method names are generally camelCased in Java.
I am not going to give you the exact code because this seems like homework and I already graduated, but that should be enough to get you started. My advice would be to search around for any specific questions you come up with.
You can write a main method like this:
public static void main(String [ ] args)
{
Beer beer1 = new Beer().
beer1.setName("firstBeerName");
beer1.setAlcoholContent(3.166);
Scanner reader = new Scanner(System.in); // Reading from System.in
System.out.println("What’s the weight of the person consuming said beverages?");
double weight = reader.nextDouble();
double answer = beer1.Intoxicated(weight);
System.out.println("It would take "+answer+" "+beer1.getName()+" beers to become intoxicated.")
// similar for beer2
}
I would encourage you to throw IllegalArgumentException when checking condition in setter:
public void setAlcoholContent(double aAlcoholContent) {
if (aAlcoholContent < 0 || aAlcoholContent > 1) {
throw new IllegalArgumentException("Alcohol content can't be more than 1 or less than 0");
}
this.alcoholContent = aAlcoholContent;
}
And for your question you can test it like this:
public static void main(String[] args) {
List<Beer> beers = new ArrayList<>();
beers.add(new Beer("firstBeerName", 0.04));
beers.add(new Beer("secondBeerName", 0.06));
Scanner reader = new Scanner(System.in);
System.out.println("What’s the weight of the person consuming said beverages?");
double weight = reader.nextDouble();
DecimalFormat decimalFormat = new DecimalFormat("0.000");
for(Beer beer : beers){
System.out.println("It would take " + decimalFormat.format(beer.Intoxicated(weight)) + " " + beer.getName() +" beers to become intoxicated.");
}
}
Also you can use loop for creating new beers, just ask user for amount of beers that he can obtain result for, and then create for loop.

Beginner Java Issues [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 9 years ago.
Improve this question
EDIT: I am using BlueJ. When I right click my class I am supposed to enter the values for a and b there rather than the actual code. Is there a way to do that?
Hello I am trying to write a basic program that will let me enter 2 numbers and then automatically calculate the sum, difference, division and remainder, and then print the results to the output. Here is what I have so far. It compiles but I get this error
java.lang.ArithmeticException: / by zero
at Q1A3.DoTheCalculation(Q1A3.java:33)
at Q1A3.<init>(Q1A3.java:24)
when I try to run it. I have no java experience and this is my first time trying anything on the computer other than emailing. Please be gentle! Can you point out my errors and guide me toward fixing them? Thank you.
/*
This program accepts two numbers from the user. Finds out the sum, diff, division and
remainder of the two numbers, and prints the results on the screen
*/
public class Q1A3
{
//instant variables - replace the example below with your own
private int a;
private int b;
private int sum;
private int difference;
private int division;
private int remainder;
//-----------------------------------------
//The following is the constructor that takes the input from the user
//and stores it in the system
public Q1A3(int a, int b)
{
DoTheCalculation ( );
PrintTheResults ( );
}
//-------------------------------------------------------------
//The following routine does all of the required calculations.
public void DoTheCalculation ( )
{
sum = (a+b);
difference = (a-b);
division = (a/b);
remainder = (a%b);
}
//----------------------------------------------------------------------------
//The following routine prints all of the information including the calculated
//items on the screen
public void PrintTheResults ( )
{
System.out.println("The value of “a” is:");
System.out.println("The value of “b” is:");
System.out.println("The sum is:" );
System.out.println("The difference is:");
System.out.println("The division is:");
System.out.println("The remainder is:");
}
}
You don't assign any values to a or b. try this:
private int a = 5;
private int b = 7;
(1) Make sure that private member variables are initialized from constructor parameters.
(2) Make sure to assign variables to string outputs.
Please observe the proposed changes in the following source code:
public Q1A3(int a, int b)
{
this.a = a;
this.b = b;
DoTheCalculation ( );
PrintTheResults ( );
}
public void PrintTheResults ( )
{
System.out.println("The value of 'a' is:"+a);
System.out.println("The value of 'b' is:"+b);
System.out.println("The sum is:" +sum);
System.out.println("The difference is:"+difference);
System.out.println("The division is:"+division);
System.out.println("The remainder is:"+remainder);
}
public static void main(String [] args)
{
Q1A3 obj = new Q1A3(8,4);
}
Your answer is in the first line of the error code "/ by zero". You cannot divide by zero (it'd implode the universe or something.) Try an if statement to test if 0 is being passed, and reject, or skip it.
You cannot divide by zero (it'd implode the universe or something.)
~ Andrew
No, it creates black holes. Or something :P
The question has been answered. BUT:
A good way to find the mistake yourself (next time) would have been a good debugger or systematic outputs, e.g. System.out.println("var a:"+a) to see what values which variables have at the time, before the error occurs.

Using Java, how would I find a time behind using modulo? [closed]

It's difficult to tell what is being asked here. This question is ambiguous, vague, incomplete, overly broad, or rhetorical and cannot be reasonably answered in its current form. For help clarifying this question so that it can be reopened, visit the help center.
Closed 9 years ago.
I'm building a table of runners and their times. I need to find the time behind the previous runner in minutes and seconds using modulo. the first 2 records are
Runner: 198
Minutes: 29
Seconds: 05
Runner: 419
Minutes: 30
Seconds: 01
Time behind runner #1?
Here is my code so far:
import java.io.*;
import java.text.*;
public class read3
{
public static void main(String[] args)throws IOException
{
DataInputStream in=new DataInputStream(new FileInputStream("c:\\java\\chapter13\\sheet2\\program2.jdat2"));
int id;
int mins;
int secs;//,num3;
double calc=0,calc2=0;
char chr;
double tcalc=0;
double t1=0,t2=0,t3=0;
NumberFormat money=NumberFormat.getCurrencyInstance();
System.out.println("Runner\tTotal \tTotal \tTime");
System.out.println("Number\tMinutes\tSeconds\tBehind\n");
try
{
while(true)
{
id=in.readInt();
in.readChar();
mins=in.readInt();
in.readChar();
secs=in.readInt();
in.readChar();
System.out.println(id+"\t "+mins+"\t "+secs+"\t"+calc);
}
}
catch(EOFException e)
{
//Hi
}
in.close();
}
}
I just need to know the equation for finding minutes/seconds (in separate variables) using modulo. Can anybody help?
int time1=nbMinutes1*60+nbSeconds1;
int time2=nbMinutes2*60+nbSeconds2;
int differenceInMinutes = (time2-time1)/60;
int differenceinSeconds = (time2-time1)%60;
EDIT:
To apply it to your code, I would do the following :
Integer duration=null;
while(true)
{
id=in.readInt();
in.readChar();
mins=in.readInt();
in.readChar();
secs=in.readInt();
in.readChar();
Integer newDuration=60*mins+secs;
//duration is null for the first one.
if(duration!=null){
System.out.println(id+"\t "+(newDuration-duration)/60+"\t "+secs+"\t"+(newDuration-duration)%60);
}
duration = newDuration;
}
Your problem here is only tangentially associated with knowing how to use modulus. You have one master function doing a mess of things: initializing variables, opening files, iterating through rows, and figuring out display parameters. This is known as procedural programming, and bad procedural programming at that: you want to leverage object oriented programming here.
//note the standards regarding class names: Capitalize Class Names!
//also, pick names that make it clear what you're doing.
public class DisplayTimes
{
DataInputStream in;
//This is not actually the correct way to do this, but it's lightweight enough for this example
List<Integer> runnerIds = new ArrayList<Integer>();
List<Integer> runnerMinutes = new ArrayList<Integer>();
List<Integer> runnerSeconds = new ArrayList<Integer>();
//note that your main method should not throw an exception. Nothing can catch it!!
//also note that this is just an entry point; it probably shouldn't do any work
public static void main(String[] args)
{
DisplayTimes display = new DisplayTimes("c:\\java\\chapter13\\sheet2\\program2.jdat2");
display.readAndDisplay();
}
//constructors are the proper way to initialize object variables
public DisplayTimes(String inputFile) {
//see how much easier this next line is to read?
this.in = new DataInputStream(new FileInputStream(fileName));
}
public void readAndDisplay() {
processData(); //offload processing somewhere else
System.out.println("Runner\tTotal \tTotal \tTime");
System.out.println("Number\tMinutes\tSeconds\tBehind\n");
for (int idx = 0; idx++; idx<runnerIds.size()) {
String output = runnerIds.get(idx)+"\t";
output = output + runnerMinutes.get(idx)+"\t";
output = output + runnerSeconds.get(idx)+"\t";
output = output + calculateDifference(idx)+"\t";
System.out.println(output);
}
}
private void processData() {
boolean moreData = true;
while (moreData) { //offload the work of the loop to another method
moreData = processRunner();
}
}
private boolean processRunner() {
try {
int id=in.readInt();
in.readChar();//how is this file formatted that you need to skip a char?
int mins=in.readInt();
in.readChar();
int secs=in.readInt();
//Here you should really sanity-check your values
//Instead we'll just store them
this.runnerIds.add(id);
this.runnerMinutes(mins);
this.runnerSeconds(secs);
return isFinished();
} catch (EOFException e) {
//Exceptions should NOT be used for program control.
//They should be used when there is bad data.
System.out.println("There was an unexpected termination of the datafile.");
}
}
private boolean isFinished() {
in.mark(1);
if (in.read == -1) {//checks cleanly if we're at the end of the file.
return false;
} else {
in.reset();//moves you back to mark
return true;
}
}
private String calculateDifference(int idx) {
if (idx == 0) { return "\t"; } //First runner is first!
int previousTimeInSeconds = (runnerMinutes.get(idx-1) * 60) + runnerSeconds.get(idx-1);
int nextTimeInSeconds = (runnerMinutes.get(idx) * 60) + runnerSeconds.get(idx);
int delta = (nextTimeInSeconds - previousTimeInSeconds);
return (delta / 60) + "min " + (delta % 60) + "sec \t";
}
}
The main thing you should take away here is that the problem you came here with - calculating the difference between runner a and b - is only a small part of the code you presented. You couldn't present a Short, Self Contained, Correct (Compilable), Example because your code was improperly tangled with other code. By writing clean code you can focus on the one function (calculateDifference()) that you actually needed help with. While I understand you may be beginning and working out of a book (based on what was presented), the most fundamental thing you can learn is how to break down a problem into the smallest pieces possible. Utilize the language to help you with this; don't fight it.

Class to count variables design issue

I'm new to OO programing and having a bit of trouble with the design of my program to use the concepts. I have done the tutorials but am still having problem.
I have a recursion that takes a value of items(could be anything in this example, stocks) and figures out what number of them are needed to equal a specific value(in this code 100). This part works but I want to know if a stock's weighting exceeds a threshold. Originally I approached this problem with a method that did a for loop and calculated the entire list of values but this is super inefficient because its doing it on every loop of the recursion. I thought this would be a good time to try to learn classes because I could use a class to maintain state information and just increment the value on each loop and it'll let me know when the threshold is hit.
I think I have the code but I don't fully understand how to design this problem with classes. So far it runs the loop each step of the recursion because I'm initially the class there. Is there a better way to design this? My end goal is to be notified when a weighting is exceeded(which I can somewhat already do) but I want to do in way that uses the least bit of resources(avoiding inefficient/unnecessary for loops)
Code(Here's the entire code I have been using to learn but the problem is with the Counter class and its location within the findVariables method):
import java.util.Arrays;
public class LearningClassCounting {
public static int[] stock_price = new int[]{ 20,5,20};
public static int target = 100;
public static void main(String[] args) {
// takes items from the first list
findVariables(stock_price, 100, new int[] {0,0,0}, 0, 0);
}
public static void findVariables(int[] constants, int sum,
int[] variables, int n, int result) {
Counter Checker = new Counter(stock_price, variables);
if (n == constants.length) {
if (result == sum) {
System.out.println(Arrays.toString(variables));
}
} else if (result <= sum){ //keep going
for (int i = 0; i <= 100; i++) {
variables[n] = i;
Checker.check_total_percent(n, i);
findVariables(constants, sum, variables, n+1, result+constants[n]*i);
}
}
}
}
class Counter {
private int[] stock_price;
private int[] variables;
private int value_so_far;
public Counter(int[] stock_price, int[] variables) {
this.stock_price = stock_price;
this.variables = variables;
for (int location = 0; location < variables.length; location++) {
//System.out.println(variables[location] + " * " + stock_price[location] + " = " + (variables[location] * stock_price[location]) );
value_so_far = value_so_far + (variables[location] * stock_price[location]);
}
//System.out.println("Total value so far is " + value_so_far);
//System.out.println("************");
}
public void check_total_percent(int current_location, int percent) {
// Check to see if weight exceeds threshold
//System.out.println("we are at " + current_location + " and " + percent + " and " + Arrays.toString(variables));
//System.out.println("value is " + stock_price[current_location] * percent);
//formula I think I need to use is:
if (percent == 0) {
return;
}
int current_value = (stock_price[current_location] * percent);
int overall_percent = current_value/(value_so_far + current_value);
if (overall_percent > 50 ) {
System.out.println("item " + current_location + " is over 50%" );
}
}
}
What you're describing sounds like a variant of the famous knapsack problem. There are many approaches to these problems, which are inherently difficult to calculate.
Inherently, one may need to check "all the combinations". The so-called optimization comes from backtracking when a certain selection subset is already too large (e.g., if 10 given stocks are over my sum, no need to explore other combinations). In addition, one can cache certain subsets (e.g., if I know that X Y and Z amount to some value V, I can reuse that value). You'll see a lot of discussion of how to approach these sort of problems and how to design solutions.
That being said, my view is that while algorithmic problems of this sort may be important for learning how to program and structure code and data structures, they're generally a very poor choice for learning object-oriented design and modelling.

Categories