unable to produce random number? - java

Each object in my warehouseList contains a end stock, safety stock, and a required stock.
My aim to change the end stock of an object if lesser that 10% of the safety stock, and put it in range of -%10 to %5 of the safety stock. To do this im using a randomizer code:
Random random=new Random();
for(Warehouse obj:warehouseList){
double diff=obj.getEndStock()-obj.getSafetyStock();
if(((diff/obj.getSafetyStock())*100)<(-5)){
diff=Math.abs(diff)+(1.05*obj.getSafetyStock())-obj.getSafetyStock();
if(diff<0)
Logging.log(diff,"\n");
int randomNum=0;
double reqStock=0;
double end=obj.getEndStock();
while(((end-obj.getSafetyStock())*100)<(-5)){
randomNum=random.nextInt((int)diff);
reqStock+=randomNum;
end+=randomNum;
}
obj.setRequiredStock(reqStock);
obj.setEndStock(end);
}
}
}
Now to the problem: I'm checking if the diff variable even becomes negative as it doesnt as nothing prints on the console, However whenever i reach the the line randomNum=random.nextInt((int)diff);
the program throws the following error:
Exception in thread "main" java.lang.IllegalArgumentException: n must be positive
at java.util.Random.nextInt(Unknown Source)
at managing.Final.randomWay(Final.java:163)
at managing.Final.main(Final.java:252)
CAN ANYONE HELP?

This is rather simple. Look at these two lines:
double diff=obj.getEndStock()-obj.getSafetyStock();
...
randomNum=random.nextInt((int)diff);
Your diff contains a difference between end stock and safety stock. If your end stock is below safety stock, then diff will contain a negative number.
nextInt method requires a positive integer as a parameter. If your diff is negative, you'll get this error.
EDIT: In response to the comment I re-read the question carefully again and noticed the line I missed. With this line:
diff=Math.abs(diff)+(1.05*obj.getSafetyStock())-obj.getSafetyStock();
You actually can get a 0. (I am assuming that your getSafetyStock would always return a positive number - if it doesn't, then this may be your problem.)
In your code, you are checking whether diff is 0 - but are not doing anything about it, other than printing a log line.
On the whole, it may make sense to print the value of diff regardless of what it is before using it as a parameter for nextInt - for debugging purposes.

I see no check for negative value. Here:
if(diff==0)
Logging.log(diff,"\n");
You check for zero-equality, which is weird for double-typed variable anyway.

It seems I get what's wrong. nextInt method requires it's argument to be positive, but you are checking if it is non-negative. That's what causes the error.
This code prooves my point:
import java.util.Random;
public class RandomMain {
public static void main(String[] args) {
Random random = new Random();
System.out.println(random.nextInt(0));
}
}
it generates an exception:
Exception in thread "main" java.lang.IllegalArgumentException: n must be positive
at java.util.Random.nextInt(Random.java:300)
at RandomMain.main(RandomMain.java:6)

Related

Negative bound in Java

I'm making a program where I calculate a random number using a function named generarAleatorio.
public static int generarAleatorio(int l){
java.util.Random X = new java.util.Random();
return X.nextInt(l) ;
}
Then, I use that number to locate a value inside an array using the length of the array as the parameter for the generarAleatorio parameter
public static String generarFecha(){
int[] dias={1,2,3,4,5,6,7,8,9,10,
11,12,13,14,15,16,17,18,19,20,
21,22,23,24,25,26,27,28,29,30};
int[] mes={1,2,3,4,5,6,7,8,9,10,11,12};
return String.format("%d-%d",dias[generarAleatorio(dias.length)],
mes[generarAleatorio(generarAleatorio(mes.length))]);
}
The problem is that sometimes an Exception is showed that looks like this
Exception in thread "main" java.lang.IllegalArgumentException: bound must be positive
at java.util.Random.nextInt(Random.java:388)
at generadorregistros.GeneradorRegistros.generarAleatorio(GeneradorRegistros.java:70)
at generadorregistros.GeneradorRegistros.generarFecha(GeneradorRegistros.java:108)
at generadorregistros.GeneradorRegistros.main(GeneradorRegistros.java:48)
Java Result: 1
BUILD SUCCESSFUL (total time: 0 seconds)
It tells me that the Bound im sending its not positive, but as far as I know, the length of the Array is always the same and also positive.
What's the cause of this? Is the length of the array not always positive?
Is the length of the array not always positive?
It is in your case. However, the problematic call doesn't use the array length but a random number:
generarAleatorio( generarAleatorio(mes.length) )
Here the inner generarAleatorio(mes.length) may return 0 in which case the outer generarAleatorio(0) fails.
How to fix the problem depends on what you want to do. Both of the following changes would make the error go away -- but the behavior of your program will be very different.
mes[generarAleatorio(generarAleatorio(mes.length)+1)]
mes[generarAleatorio(mes.length)]

Changing Doubles To Ints

Im working on a homework assignment for my intro to computer science class and we are are inputting basic commands to get the percentage of people who drink a certain kind of energy drink. We used JOptionPane to make text boxes and you can input the amount of people and the computer has a set percentage to get the output. My problem is i set up my variables as doubles and my answers are very long decimals. I want to convert the answers to Ints so i can get whole numbers. I have tried to do this through casting but i keep getting the error message" EnergyDrink.java:14: error: variable citrusEnergyDrinkers might not have been initialized". What can i do?
This can't be solved without code. The error is not due to any problem with the conversion, but simply as the compiler-error says:
variable citrusEnergyDrinkers might not have been initialized
This means that the variable might not hold a value at the time you attempt to convert it, which results in undefined behaviour, which java-designers didn't allow for a reason.
The problem is as the error-message tells: citrusEnergyDrinkers gets its value inside some try-catch-block or a block that is only run under certain conditions, like if. One way to work around this would be to simply initialize citrusEnergyDrinkers as 0:
double citrusEnergyDrinkers = 0;.
Note though that this might produce incorrect results depending upon what happens when the value isn't set in case the above mentioned block of code isn't entered/breaks off before setting a value.
For the conversion:
Math.round(citrusEnergyDrinkers) is most likely preferable to a simple cast to int, since double most of the time has some imprecision due to the way it's stored in memory and round will actually round the value, while a cast will simply remove the frictional part. For example:
(int) 0.75 //produces 0
Math.round(0.75) //produces 1
You could multiply the double by 100 and then cast to an int:
double d = .77583495;
int perc = (int) Math.round( d );
I prefer to not cast like that, but it works.
Good luck.

Factorial of a number using recursion

I have the below recursive function to compute factorial of a number. The program works fine except when I remove the if condition. Can someone explain why?
This is the code that works fine --
public static long factUsingRecursion(int number) {
if (number == 1) {
return 1;
} else {
return number * factUsingRecursion(number - 1);
}
}
Without the if condition (Code that throws the error),
public static long factUsingRecursion(int number) {
return number * factUsingRecursion(number - 1);
}
I get the stack overflow error.
Exception in thread "main" java.lang.StackOverflowError
at birst.FactorialUsingRecursion.factUsingRecursion(FactorialUsingRecursion.java:10)
Request experts to please advise me why this is the case?
In recursion, there must always be a base case that stops the recursion. Without the if, you have no base case and nothing stops it. Eventually too many method calls are on the stack and a StackOverflowError results.
This line causing number variable to be decreased by 1
return number * factUsingRecursion(number - 1);
and it will handle all values of number except when it is 1
so this line of code is a break condition
if (number == 1) {
return 1;
}
and it prevent you to avoid stackoverflow exception
Recursion requires a base case. Without it, it will continue calling the function over and over and never stop. The if statement is the base case, which terminates the recursion. That is why if you remove it, you get a StackOverflowError.
Imagine what happens when you call:
factUsingRecursion(3);
With the if:
3*factUsingRecursion(2)
3*2*factUsingRecursion(1)
3*2*1
Without the if:
3*factUsingRecursion(2)
3*2*factUsingRecursion(1)
3*2*1*factUsingRecursion(0)
3*2*1*0*factUsingRecursion(-1)
3*2*1*0*-1*factUsingRecursion(-2)
3*2*1*0*-1*-2*factUsingRecursion(-3)
...
And so on... It will not stop until you encounter the StackOverflow error
It loses one of the things that makes a recursive function recursive in that it has no exit condition.
All recursive solutions must satisfy three rules or properties:
A recursive solution must contain a base case.
A recursive solution must contain a recursive case.
A recursive solution must make progress toward the base case.
From: Data Structures and Algorithms Using Python
The program will no longer work when you remove the if condition because you will just be left with return number * factUsingRecursion(number - 1); and the factUsingRecursion(number - 1) here would have the same return calling return number * factUsingRecursion(number - 1);. Your function constantly calls itself, never able to evaluate to anything. By setting the condition, you function is able to evaluate to a definitive value at some point in the recursive chain, and the first call can evaluate.
For every integer i, you are calling the function with i -1. Integersa are infinite, so you would never stop calling the function. eg: -1000 would call -1001 and this would keep going as long as JVM has some space in it's stack.

If or If-Else Statement Error

I am trying to write an If or If-Else Statement that protects the program when an integer value is not entered when prompted. I keep getting the error message: '.class' expected.
System.out.println("Type the name of your destination: ");
destination = keyboard.nextLine();
System.out.print(destination + " is how many miles away?");
miles = keyboard.nextInt();
if (miles != int);
{
System.out.println(miles + " is not valid. I will use 100 for the number of miles.");
}
This can not compile:
if (miles != int);
You are comparing a variable with int,which is a type. The compiler suggest you to add .class, so you can obtain the class object, but it is not correct either.
You want to know if an integer value is not entered, but in that case what would happen is that nexInt() would throw a InputMismatchException. What you should do is to check with hasNextInt() if the user is inputing an integer.
int is a keyword and cannot participate in conditional expressions.
There is also a spurious semicolon after your if statement, which acts as the controlled statement, so the following block is unconditional.
The syntax error that you are getting is because int is a keyword. You cannot use it as an identifier.
If you would like to check if a Scanner has an int ready for reading, use keyboard.hasNextInt() in your condition:
int miles;
while (!keyboard.hasNextInt()) {
System.out.println(keyboard.nextLine() + " is not valid. Please enter a different number.");
}
int miles = keyboard.nextInt();
you have a ; after the if statement.
You also have it checking what the user inputs to an int which is not a number. might want to fix that with a number and it should work... from what i can remember from class.
if (miles != int);
You can't test if a number is an int like that. You also have a semi colon at the end of this line (which should be removed). However, there's actually no reason to have that line at all. Because you wrote:
miles = keyboard.nextInt();
miles has to be an int. Otherwise an exception will be thrown by Scanner.
I'm going to start this by saying that you need to do a Java Tutorial. Your code is full of basic mistakes.
(Assuming that keyboard is an instance of Scanner ...)
Mistake 1 - You cannot use a type name or keyword (e.g. int) as a value.
Mistake 2 - You can only use == to compare integer values (like the value of miles) with other numbers.
Mistake 3 - You shouldn't put a semicolon after if (condition). What you have written will compile, but it actually means "if the condition is true, then execute the empty statement". Then you've followed that with a block ... that will be executed unconditionally.
Mistake 4 - In fact, if keyboard.nextInt() encounters something that isn't a valid integer, it will throw an exception; e.g. InputMismatchException. If you want to print out an error message, you need to catch that exception.
Mistake 5 - Obviously you didn't check the javadoc for the nextInt() method ...
To recap ... you are making so many mistakes because you haven't done the tutorial ... or you've been skipping lectures or something.

Basic imperial conversion problem

Coding a calculation tool for my android. On of the inputs is distance in Feet and Inches.
I have two inputs (input3 and input4) for feet and inches, respectively. In my calculation I am trying to convert these two inputs to a decimal number to be used in the rest of the equation. Here's the part of my code that does this:
private void doCalculation() {
// Get entered input value
String strValue3 = input3.getText().toString();
String strValue4 = input4.getText().toString();
// Perform a hard-coded calculation
double imperial1 = (Integer.parseInt(strValue3) + (Integer.parseInt(strValue4) / 12));
// Update the UI with the result to test if calc worked
output2.setText("Test: "+ imperial1);
}
My test values are 4 feet, 6 inches. The 4 comes across fine, but the 6 inches defaults to 0 when it is divided by 12. So my result is 4.0 I tried cutting the calculation down to JUST the division operation, and the result was 0.0
What am I doing wrong? (fyi: this is my first time using Java)
Your types are wrong. You're parsing them as ints when they really should be doubles.
Try:
double imperial1 = Double.parseDouble(strValue3) +
(Double.parseDouble(strValue4) / 12.0);
... what Eli said.
I just wanted to ask why your variables are called strValue3 and strValue4. I'm guessing that it's generated, but you should get into the habit of naming things well. I might go with "feet" and "inches" :)
Eli's answer will work fine. I'm just posting an answer to your question (comment) on Eli's answer.
Can you explain what a try-catch block is?
First you have to understand what an exception is. An exception is an event, which occurs during the execution of your program, that disrupts the normal flow of the program's instructions.
There are 3 kinds of exceptions in Java:
Runtime exceptions: An exception is referred to as a runtime exception if its data type is java.lang.RuntimeException or a subclass of it.
Checked exceptions: An exception is referred to as a checked exception if its data type is a child class of java.lang.Exception, but not a child class of RuntimeException.
Errors: An exception is referred to as an error if its data type is a child class of java.lang.Error. An error is associated with problems that arise outside of your application and typically do not attempt to recover from errors.
For a more detailed description on exceptions, read this.
In order to catch and handle these exceptions, you use try-catch blocks. For example, you use Double.parseDouble function. If the parameter in this function is not a valid number, for example if the user supply the string "NotANumber" you try to convert it to double, then a NumberFormatException will be thrown by Double.parseDouble. If you don't handle this error, your program will terminate unexpectedly.
So, you should write something like the following (including the positive numbers feature you want):
double imperial1 = 0.0;
try {
double firstNumber = Double.parseDouble(strValue3);
double secondNumber = Double.parseDouble(strValue4);
if(firstNumber < 0 || secondNumber < 0)
throw new NumberFormatException("numbers must be positive.");
imperial1 = firstNumber + secondNumber / 12.0;
} catch(NumberFormatException ex) {
// Handle the exception maybe by printing a message to the user that his inputs
// weren't valid numbers.
}

Categories

Resources