Returning value from method and "The Value Assigned Is Never Used" [duplicate] - java

This question already has answers here:
What does the "Assigned value is never used" warning mean?
(5 answers)
Closed 3 months ago.
I'm following Princeton's introductory computer science course (I'm not a student, just teaching myself). I working on this assignment.
Main is calling two methods: amplify and reverse, both of which return an array. Amplify multiplies all values in the array by a constant alpha. Reverse returns an array that lists the original array values in reverse order, ex. {1,2,3} -> {3,2,1}.
Amplify works fine, but nothing happens when I call reverse and I get a bug that states: The Value Assigned Is Never Used
public class audiocollage {
// Returns a new array that rescales a[] by a factor of alpha.
public static double[] amplify(double[] a, double alpha) {
for (int i = 0; i < a.length; i++) {
a[i] = a[i] * alpha;
}
return a;
}
// Returns a new array that is the reverse of a[].
public static double[] reverse(double[] a) {
double[] b = new double[a.length];
for (int i = a.length - 1, j = 0; i >= 0; i--, j++) {
b[j] = a[i];
}
return b;
}
// Creates an audio collage and plays it on standard audio.
public static void main(String[] args) {
double[] samples = StdAudio.read("cow.wav");
double alpha = 2.0;
samples = amplify(samples, alpha);
samples = reverse(samples);
}
}

It sounds like you have two questions:
Why doesn't anything happen when I call reverse(samples)?
The code you're showing does nothing with the result of reverse(samples) other than store it in the variable samples (overwriting its previous value). You will need to do something with samples after that to observe the new array (like printing samples, which should now appear to be reversed).
Which leads into the next question:
Why do I get a warning about "the value assigned to samples is never used"?
This is a warning saying that the code you wrote doesn't do anything.
Dead store to local variable is the first line of the warning, which describes what's happening: the value stored to samples is "dead" -- it is never used again, and so we may as well have skipped that line altogether. That causes your compiler (or extension) to give us a warning because it's almost certain that the code you wrote is not doing what you intended, so in many cases that warning can be helpful for spotting mistakes.
This warning can be resolved by using samples somehow, such as by printing it, calling another function with it, etc.
The previous line
samples = amplify(samples, alpha);
doesn't generate that warning because it's output is used in the following call to reverse():
samples = reverse(samples);
// ^ usage of `samples` variable!
This is made even clearer by using different variables for all your arrays:
public static void main(String[] args) {
// No warning; samplesRaw used later
double[] samplesRaw = StdAudio.read("cow.wav");
double alpha = 2.0;
// No warning; samplesAmplified used later
samplesAmplified = amplify(samplesRaw, alpha);
// WARNING! samplesReversed is never used!
samplesReversed = reverse(samplesAmplified);
}

If the hint is related to the last line, it means you have a local variables samples which has not used ( you assigned a value but never read it)

Related

Variable in for loop is giving a message that "The value of the local variable i is not used"

I wrote a for loop that is supposed to determine if there is user input. If there is, it sets the 6 elements of int[] valueArr to the input, a vararg int[] statValue. If there is no input, it sets all elements equal to -1.
if (statValue.length == 6) {
for (int i = 0; i < 6; i++) {
valueArr[i] = statValue[i];
}
} else {
for (int i : valueArr) {
i = -1;
}
}
I am using Visual Studio Code, and it is giving me a message in for (int i : valueArr) :
"The value of the local variable i is not used."
That particular for loop syntax is still new to me, so I may be very well blind, but it was working in another file:
for(int i : rollResults) {
sum = sum + i;
}
I feel that I should also mention that the for loop giving me trouble is in a private void method. I'm still fairly new and just recently started using private methods. I noticed the method would give the same message when not used elsewhere, but I do not see why it would appear here.
I tried closing and reopening Visual Studio Code, deleting and retyping the code, and other forms of that. In my short experience, I've had times where I received errors and messages that should not be there and fixed them with what I mentioned, but none of that worked here.
for (int i : valueArr) {
.... CODE HERE ...
}
This sets up a loop which will run CODE HERE a certain number of times. Inside this loop, at the start of every loop, an entirely new variable is created named i, containing one of the values in valueArr. Once the loop ends this variable is destroyed. Notably, i is not directly the value in valueArr - modifying it does nothing - other than affect this one loop if you use i later in within the block. It does not modify the contents of valueArr.
Hence why you get the warning: i = -1 does nothing - you change what i is, and then the loop ends, which means i goes away and your code hasn't changed anything or done anything, which surely you didn't intend. Hence, warning.
It's not entirely clear what you want to do here. If you intend to set all values in valueArr to -1, you want:
for (int i = 0; i < valueArr.length; i++) valueArr[i] = -1;
Or, actually, you can do that more simply:
Arrays.fill(valueArr, -1);
valueArr[i] = -1 changes the value of the i-th value in the valueArr array to -1. for (int i : valueArr) i = -1; does nothing.

Jave error: reached end of file while parsing (Not typical)

Im trying to create a method to find the common factors of 2 given numbers but I can not get the file to compile. All of my curly brackets are closed as I'm aware thats usually almost always the cause of this error. Hopefully someone can help me out!
import java.util.Scanner;
public class E1{
public static void main (String [] args){
Scanner kb = new Scanner(System.in);
double n1,n2;
System.out.println("Enter two numbers");
n1=kb.nextDouble();
n2=kb.nextDouble();
printCommonFactors(n1,n2);
}
//call a method that prints the positive shared factors of the 2 inputed numbers
public static void printCommonFactors(int n1,int n2){
//determining the max/min of the two inputed variables
int max,min;
max=Math.max(n1,n2);
min=Math.min(n1,n2);
//setting up 2 arrays to store the factors
int [] maxFactors = new int [max];
int [] minFactors = new int [min];
int counter1;
for (inti=0;i>max;i++)
if (i%max=0)
counter1++;
maxFactors[counter1]=i;
for (int i=0;i>min;i++)
if (maxFactors[i]%min=0)
maxFactors[i]=
}
}
This is the error I receive:
The reason you are seeing the "reached end of file while parsing" is that the parser expects to find a right-hand-side operand for the equals operator but fails to do so. You end your method with maxFactors[i]=. Binary operators always require right-hand-side operands. In this case, you must place a value after the equals-sign.
Also, it looks like you are trying to apply some principles to Java that you probably pulled from another language. The most obvious one here is that you use replace explicit blocks with white-space. This works for languages like Python, but does not work in Java. Indentation is not significant in Java and only has the effect of improving readability.
This is relevant for your for statements. Because you are not actually using blocks, these statements are actually equivalent:
for (inti=0;i>max;i++)
if (i%max=0)
counter1++;
maxFactors[counter1]=i;
for (inti=0;i>max;i++) {
if (i%max=0) {
counter1++;
}
}
maxFactors[counter1]=i;
This will cause issues with i being referenced out of its scope. The other issue with this is that the for initializer (inti=0;) is missing a space and should be int i = 0.
Other issues include trying to allocate arrays with a non-integer size (must be of type int) and using bad test expressions for your for-loops (i>min will invariably remain true if it is ever true due to your incrementor until an integer overflow is reached).

Getting back original signal using JTransform method realInverse

I was playing with JTransforms realForwardFull and RealInverse to test how they work.
My understanding is that after you pass say an audio signal to realForwardFull and then apply RealInverse, you should get back the same signal.
So here is what I am doing.
double[] a1 = getAudioSignal();
DoubleDDT_1D fft = new DoubleFFT_1D(a1.length);
double[] fftData = new double[a1.length * 2];
for(int i=0; i<fftData.length; i++) {
fftData[i] = a1[i]; // real part
fftData[fftData.length+i] = 0; // imaginary parts
}
fft.realForwardFull(fftData);
//Do an inverse to get back the signal
fft.realInverse(fftData, false);
My question is should the fftData after the inverse fft (realInverse) contain the same data as in a1, the original audio signal?
I tested this and checked if all the even indexes (real part) fftData[2k] was the same as indexes in a1, its not so.
for(int k=0; k<a1.length; k++) {
if(a[k] == fftData[2k]) {
printSame();
} else {
printDiff();
}
I see that the output in the array after realInverse is very different.
How do I get the original signal back?
As per the javadoc of realForwardFull you need to call complexInverse to recover the original signal. Since you want the original points you should enable scaling which will divide the values by N:
fft.realForwardFull(fftData);
//Do an inverse to get back the signal
fft.complexInverse(fftData, true);
Also your checking logic is broken. You cannot check double equality like that because of rounding errors. You should check it like this using an epsilon error tolerance:
for(int k=0; k<a1.length; k++) {
if(Math.abs(a1[k] - fftData[2*k]) < 1e-6) {
printSame();
} else {
printDiff();
}

Get random boolean in Java

Okay, I implemented this SO question to my code: Return True or False Randomly
But, I have strange behavior: I need to run ten instances simultaneously, where every instance returns true or false just once per run. And surprisingly, no matter what I do, every time i get just false
Is there something to improve the method so I can have at least roughly 50% chance to get true?
To make it more understandable: I have my application builded to JAR file which is then run via batch command
java -jar my-program.jar
pause
Content of the program - to make it as simple as possible:
public class myProgram{
public static boolean getRandomBoolean() {
return Math.random() < 0.5;
// I tried another approaches here, still the same result
}
public static void main(String[] args) {
System.out.println(getRandomBoolean());
}
}
If I open 10 command lines and run it, I get false as result every time...
I recommend using Random.nextBoolean()
That being said, Math.random() < 0.5 as you have used works too. Here's the behavior on my machine:
$ cat myProgram.java
public class myProgram{
public static boolean getRandomBoolean() {
return Math.random() < 0.5;
//I tried another approaches here, still the same result
}
public static void main(String[] args) {
System.out.println(getRandomBoolean());
}
}
$ javac myProgram.java
$ java myProgram ; java myProgram; java myProgram; java myProgram
true
false
false
true
Needless to say, there are no guarantees for getting different values each time. In your case however, I suspect that
A) you're not working with the code you think you are, (like editing the wrong file)
B) you havn't compiled your different attempts when testing, or
C) you're working with some non-standard broken implementation.
Have you tried looking at the Java Documentation?
Returns the next pseudorandom, uniformly distributed boolean value from this random number generator's sequence ... the values true and false are produced with (approximately) equal probability.
For example:
import java.util.Random;
Random random = new Random();
random.nextBoolean();
You could also try nextBoolean()-Method
Here is an example: http://www.tutorialspoint.com/java/util/random_nextboolean.htm
Java 8: Use random generator isolated to the current thread: ThreadLocalRandom nextBoolean()
Like the global Random generator used by the Math class, a ThreadLocalRandom is initialized with an internally generated seed that may not otherwise be modified. When applicable, use of ThreadLocalRandom rather than shared Random objects in concurrent programs will typically encounter much less overhead and contention.
java.util.concurrent.ThreadLocalRandom.current().nextBoolean();
Why not use the Random class, which has a method nextBoolean:
import java.util.Random;
/** Generate 10 random booleans. */
public final class MyProgram {
public static final void main(String... args){
Random randomGenerator = new Random();
for (int idx = 1; idx <= 10; ++idx){
boolean randomBool = randomGenerator.nextBoolean();
System.out.println("Generated : " + randomBool);
}
}
}
You can use the following for an unbiased result:
Random random = new Random();
//For 50% chance of true
boolean chance50oftrue = (random.nextInt(2) == 0) ? true : false;
Note: random.nextInt(2) means that the number 2 is the bound. the counting starts at 0. So we have 2 possible numbers (0 and 1) and hence the probability is 50%!
If you want to give more probability to your result to be true (or false) you can adjust the above as following!
Random random = new Random();
//For 50% chance of true
boolean chance50oftrue = (random.nextInt(2) == 0) ? true : false;
//For 25% chance of true
boolean chance25oftrue = (random.nextInt(4) == 0) ? true : false;
//For 40% chance of true
boolean chance40oftrue = (random.nextInt(5) < 2) ? true : false;
The easiest way to initialize a random number generator is to use the parameterless constructor, for example
Random generator = new Random();
However, in using this constructor you should recognize that algorithmic random number generators are not truly random, they are really algorithms that generate a fixed but random-looking sequence of numbers.
You can make it appear more 'random' by giving the Random constructor the 'seed' parameter, which you can dynamically built by for example using system time in milliseconds (which will always be different)
you could get your clock() value and check if it is odd or even. I dont know if it is %50 of true
And you can custom-create your random function:
static double s=System.nanoTime();//in the instantiating of main applet
public static double randoom()
{
s=(double)(((555555555* s+ 444444)%100000)/(double)100000);
return s;
}
numbers 55555.. and 444.. are the big numbers to get a wide range function
please ignore that skype icon :D
You can also make two random integers and verify if they are the same, this gives you more control over the probabilities.
Random rand = new Random();
Declare a range to manage random probability.
In this example, there is a 50% chance of being true.
int range = 2;
Generate 2 random integers.
int a = rand.nextInt(range);
int b = rand.nextInt(range);
Then simply compare return the value.
return a == b;
I also have a class you can use.
RandomRange.java
Words in a text are always a source of randomness. Given a certain word, nothing can be inferred about the next word. For each word, we can take the ASCII codes of its letters, add those codes to form a number. The parity of this number is a good candidate for a random boolean.
Possible drawbacks:
this strategy is based upon using a text file as a source for the words. At some point,
the end of the file will be reached. However, you can estimate how many times you are expected to call the randomBoolean()
function from your app. If you will need to call it about 1 million times, then a text file with 1 million words will be enough.
As a correction, you can use a stream of data from a live source like an online newspaper.
using some statistical analysis of the common phrases and idioms in a language, one can estimate the next word in a phrase,
given the first words of the phrase, with some degree of accuracy. But statistically, these cases are rare, when we can accuratelly
predict the next word. So, in most cases, the next word is independent on the previous words.
package p01;
import java.io.File;
import java.nio.file.Files;
import java.nio.file.Paths;
public class Main {
String words[];
int currentIndex=0;
public static String readFileAsString()throws Exception
{
String data = "";
File file = new File("the_comedy_of_errors");
//System.out.println(file.exists());
data = new String(Files.readAllBytes(Paths.get(file.getName())));
return data;
}
public void init() throws Exception
{
String data = readFileAsString();
words = data.split("\\t| |,|\\.|'|\\r|\\n|:");
}
public String getNextWord() throws Exception
{
if(currentIndex>words.length-1)
throw new Exception("out of words; reached end of file");
String currentWord = words[currentIndex];
currentIndex++;
while(currentWord.isEmpty())
{
currentWord = words[currentIndex];
currentIndex++;
}
return currentWord;
}
public boolean getNextRandom() throws Exception
{
String nextWord = getNextWord();
int asciiSum = 0;
for (int i = 0; i < nextWord.length(); i++){
char c = nextWord.charAt(i);
asciiSum = asciiSum + (int) c;
}
System.out.println(nextWord+"-"+asciiSum);
return (asciiSum%2==1) ;
}
public static void main(String args[]) throws Exception
{
Main m = new Main();
m.init();
while(true)
{
System.out.println(m.getNextRandom());
Thread.sleep(100);
}
}
}
In Eclipse, in the root of my project, there is a file called 'the_comedy_of_errors' (no extension) - created with File> New > File , where I pasted some content from here: http://shakespeare.mit.edu/comedy_errors/comedy_errors.1.1.html
For a flexible boolean randomizer:
public static rbin(bias){
bias = bias || 50;
return(Math.random() * 100 <= bias);
/*The bias argument is optional but will allow you to put some weight
on the TRUE side. The higher the bias number, the more likely it is
true.*/
}
Make sure to use numbers 0 - 100 or you might lower the bias and get more common false values.
PS: I do not know anything about Java other than it has a few features in common with JavaScript. I used my JavaScript knowledge plus my inferring power to construct this code. Expect my answer to not be functional. Y'all can edit this answer to fix any issues I am not aware of.

beginner java, help me fix my program?

I am trying to make a calculator for college gpa's. I cut out all like 20 if statements that just say what each letter grade is. I fixed my first program for anybody looking at this again. The program now works, but regardless of the letters i type in the gpa it returns is a 2.0 . If anybody sees anything wrong it would be very much appreciated...again. Thanks
import java.util.Scanner;
public class universityGPA {
public static void main(String args[]){
int classes = 4;
int units[] = {3, 2, 4, 4};
double[] grade = new double[4];
double[] value= new double[4];
int counter = 0;
double total = 0;
double gpa;
String letter;
while(classes > counter){
Scanner gradeObject = new Scanner(System.in);
letter = gradeObject.next();
if(letter.equalsIgnoreCase("A+") || letter.equalsIgnoreCase("A")){
grade[counter] = 4;
}
if(letter.equalsIgnoreCase("F")){
grade[counter] = 0;
}
value[counter] = grade[counter] * units[counter];
counter++;
}
for(int i = 0; i < classes; i++ ){
total += value[i];
}
gpa = total/classes;
System.out.println("You gpa is " +gpa);
}
}
You forgot to initialize grade. The NullPointerException is telling you that grade is null. The exception is thrown the first time you try to use grade, in the statment grade[counter] = 4;. Allocate as much space as you need with new.
Initialization of grade can be done statically as well dynamically:
double []grade = new double[4];
or
double []grade = new double[classes];
Do the same for value as well.
Here are a few pointers for cleaning up your code:
Try to be more consistent with your formatting. Make sure everything is properly indented and that you don't have lingering spaces at the beginnings or endings of lines (line 18).
You should declare variables as close to the first spot you use them as possible. This, along with making your code much more readable, minimizes the scope. For instance, on line 18, you initialize letter, but it is never used outside the scope of the while statement. You should declare the variable right there, along with the initializer (String letter = gradeObject.next()).
Declaring arrays in the type name[] form is discouraged. It is recommended to use the type[] name form instead.
Try to separate your program into distinguished sections. For instance, for this program, you can clearly see a few steps are involved. Namely, you first must grab some input, then parse it, then calculate the return value. These sections can be factored out into separate methods to clean up the code and promote reuse. While it may not seem to yield many benefits for such a simple program, once you start working on larger problems this organization will be absolutely mandatory.
NullPointerException means you are trying to access something that does not exist.
Since your grade[] is null, accessing it on line 21 by grade[counter] actually means you are accessing something that has yet to be created.
You need to initialize the array, so it actually has an instance.

Categories

Resources