Method returns 0 - java

I've made a program that generates a random number but every time it gives back 0.0
Program:
import java.util.*;
public class RandomNumber {
public static void main(String args[]){
double QuantityColors = 5;
double Mastermind = 0;
Random(QuantityColors, Mastermind);
System.out.println(Mastermind);
}
public static double Random(double QuantityColors, double Mastermind){
Mastermind = Math.random();
Mastermind = Mastermind * QuantityColors;
Mastermind = (int) Mastermind;
return Mastermind ;
}
}
I've been searching where the problem is, but the problem is in the return.

a) you are doing nothing with the result of "Random".
b) you can not modify Java argument. See change a functions argument's values?

First of all, you can use a builtin function to generate a next integer with a certain upper bound: Random.nextInt(int). For instance:
Random rand = new Random();
int masterMind = rand.nextInt(QuantityColors);
Instead of writing a Random method yourself.
It is nearly always better to use builtins since these have been tested extensively, are implemented to be rather fast, etc.
Next you seem to assume that Java uses pass-by-reference. If you perform the following call:
Random(QuantityColors, Mastermind);
Java will make a copy of the value of MasterMind. Setting the parameter in a method has no use. The only way to set a value - not encapsulated in an object - is by returning value. So:
MasterMind = Random(QuantityColors, Mastermind);
To make a long story short: the method does not return 0, you simply don't do anything useful with it.
A better solution would thus be to drop the Random method and use:
import java.util.*;
public class RandomNumber {
public static void main(String args[]){
int quantityColors = 5;
Random rand = new Random();
int mastermind = rand.nextInt(QuantityColors);
System.out.println(mastermind);
}
}
Further remarks
In your random method:
public static double Random(double QuantityColors, double Mastermind){
the MasterMind parameter is rather useless since you immediately set it with another value, so you better remove it and use a local variable instead.
Furthermore Java standards say that the name of classes, interfaces, etc. start with an uppercase; the names of methods and variables with lowercase.
Finally it is unclear why you use doubles since all the values you calculate are clearly integral.

It looks like your code would work if you wrote
Mastermind = Random(QuantityColors, Mastermind);
...because Java is pass by value, so calling a function will not change the variable you passed in.

Related

Java Random.nextInt() repeating numbers only in a loop

I am trying to procedurally generate a world on a 2D grid. For the random numbers generation I am using a single global java.utils.Random Instance and a seed.
Like this:
public class Game {
private static final int SEED = 1111;
private static final Random RANDOM = new Random(SEED);
private static final int roomsCount = generateRandomNumberOfRooms();
}
Everything worked just fine untill I wrote this method:
public ArrayList<XYCoords> generateRandomCoordinates(){
ArrayList<XYCoords> coords = new ArrayList<>(roomsCount);
for(int i = 0; i < roomsCount; i+=1) {
XYCoords xy = new XYCoords(RANDOM.nextInt(WIDTH), RANDOM.nextInt(HEIGHT));
coords.add(xy);
}
return coords;
}
When I execute it I get the list of XYCoordinates but they all have the same two X and Y values, for example (11,20) or (12, 5)... etc. and all the rooms land on the same spot. It looks to me like the call to RANDOM.nextInt() in the for loop doesn't update the state of the instance RANDOM.
In all other functions that I call RANDOM.nextInt() it works fine. Some of them use for loops too. The problem is only with this function. It is used once directly in main() and not nested anywhere.
Does anyone have any sense of where the problem might be? I can upload more code if you need, but I think it is irrelevant.
Unwanted behaviour 1: each application run generates the same values in the same order. The reason is your RANDOM object which is instantiated with a seed. Try the following adaption: (Removing the seed, allowing Random to give you random values):
public class Game {
private static final Random RANDOM = new Random();
private static final int roomsCount = generateRandomNumberOfRooms();
}
If you need the seed for some reason, you could try to update the seed at each startup.
Clarification what the seed actually does:
(Note that the seed is also set from the constructor if you provide a seed)
setSeed
public void setSeed(long seed)
Sets the seed of this random
number generator using a single long seed. The general contract of
setSeed is that it alters the state of this random number generator
object so as to be in exactly the same state as if it had just been
created with the argument seed as a seed. The method setSeed is
implemented by class Random by atomically updating the seed to (seed ^
0x5DEECE66DL) & ((1L << 48) - 1) and clearing the haveNextNextGaussian
flag used by nextGaussian(). The implementation of setSeed by class
Random happens to use only 48 bits of the given seed. In general,
however, an overriding method may use all 64 bits of the long argument
as a seed value.
Parameters: seed - the initial seed
Unwanted behaviour 2: the cords are all the same after the loop. The XYCoords class probably declares the x and y as static variables. Solution: Remove the static declaration. As the values are static, the objects share these values as they are bound to the class. The last values which are set are the values you will get if you iterate over all of your XYCoords objects.
In general it is a mixture of both things which lead to the result that you get the same values all the time.

How do I pass these integers to the method below it?

I'm confusing myself here. My goal was to make a simple program that took the number of values the user wants to average, store them in an array (while adding them together) and finally giving the average of these numbers.
My thing is, I am trying to understand the concept of multiple classes and methods as I am new so I tried using another class just do do all the work, while the Main class would just create the object from the other class, and then run their methods. Maybe I am asking something impossible. Take a look at my code.
This is my Main class:
public class Main
{
public static void main(String[] args)
{
System.out.println("Please enter numbers to average together");
OtherClass averages = new OtherClass();
averages.collectNumbers();
averages.AverageNumbers();
}
}
Now I am not sure if anything goes in those parameters, or if I can even use "averages.AverageNumbers();" without creating another object with "OtherClass" called something else? I am pretty sure it's legal though.
Here is my other class for this project entitled "OtherClass"
import java.util.Scanner;
public class OtherClass // using this to name obj
{
public void collectNumbers() //name of our method that does things
{
Scanner sc = new Scanner(System.in);
System.out.println("how many integers would you like to average? ");
int givenNum = sc.nextInt();
System.out.println("Alright, I will average " + givenNum + " values. \nPress enter after each:");
int[] numCollect = new int[givenNum];
int sum = 0;
for (int i = 0; i < numCollect.length; i++)
{
numCollect[i] = sc.nextInt();
sum = sum + numCollect[i];
}
System.out.println(sum);
}
public int AverageNumbers(int givenNum, int sum)
{
int average = sum / givenNum;
System.out.println(average);
return average;
}
}
So when I run this now with the the method AverageNumbers, it does not work. I am suspecting that maybe I am passing in the integers wrong? I have been toying with it for about an hour now, so I am asking for help. How do I make this work?
This will work if you declare sum and givenNum as fields of your OtherClass, instead of as local variables. So, before the collectNumbers method, write
private int sum;
private int givenNum;
and remove the declarations of these two variables inside collectNumbers. So, for example, instead of
int givenNum = sc.getInt();
you'll just have
givenNum = sc.getInt();
because the variable already exists. Also change the declaration of the averageNumbers method to
public int averageNumbers()
because you no longer need to pass those two values in to this method.
This is the archetypical example of using the objects of a class to carry a small amount of data around, instead of just using a class as a way to group methods together. The two methods of this class work with sum and givenNum, so it makes sense to store these in each object of this class.
Lastly, in your averageNumbers method, you have an integer division, which will automatically round down. You probably want a floating point division instead, so you could write
double average = (double) sum / givenNum;
which converts sum to a double-precision floating point number before the division, and therefore does the division in floating point, instead of just using integers. Of course, if you make this change, you'll need to change the return type of this method to double too.

Methods in java (grade calculator)

We've been learning about methods in java (using netbeans) in class and I'm still a bit confused about using methods. One homework question basically asks to design a grade calculator using methods by prompting the user for a mark, the max mark possible, the weighting of that test and then producing a final score for that test.
eg. (35/50)*75% = overall mark
However, I am struggling to use methods and I was wondering if someone could point me in the right direction as to why my code below has some errors and doesn't run? I don't want any full answers because I would like to try and do it best on my own and not plagiarise. Any help would be greatly appreciated :)! (Also pls be nice because I am new to programming and I'm not very good)
Thanks!
import java.util.Scanner;
public class gradeCalc
{
public static void main(String[] args)
{
Scanner in = new Scanner(System.in);
scoreCalc();
System.out.print("Your score is" + scoreCalc());
}
public static double scoreCalc (int score1, int maxMark, double weighting, double finalScore)
{
Scanner in = new Scanner(System.in);
System.out.print("Enter mark");
in.hasNextInt();
score1 = in.nextInt();
System.out.print("Enter Max mark");
in.hasNextInt();
maxMark = in.nextInt();
System.out.print("Enter weighting as a decimal (eg. 75% = 0.75)");
in.hasNextInt();
weighting = in.nextInt();
finalScore = (score1/maxMark)* weighting;
return finalScore;
}
}
You are calling your method scoreCalc() without passing the parameters you defined.
When you are calling it, it was defined as having 3 parameters.
scoreCalc(7, 10, 3.0, 8.0);
Also, when creating a class, start it with upper case, GradeCalc
As you can see scoreCalc method needs a set of parameters, but you call it without parameters.
The second: there is no need in Scanner in = new Scanner(System.in); into your main(String[] args) method. You are calling it into scoreCalc method.
Third: you are calling scoreCalc twice. The first call is before System.out.println, the second is into System.out.println. And your application will ask user twice to enter values.
store result value in a variable and show it later:
double result = scoreCalc(.... required params .....);
System.out.println("Your score is: " + result);
To start :
1) Follow coding conventions. (Class name should start with a capital letter).
2) In your context, you don't need Scanner in = new Scanner(System.in); in main() because you are not using it.
3) You are a calling the method scoreCalc() without parameters. Whereas, the method needs to be called with parameters.
4) A method,is a module. It as block of code which increases re-usability. So I suggest that accept the values from user in main() method and then pass them to the method for calculation.
A couple of things spring to mind:
You execute scoreCalc() twice. Probably you want to execute it once and save the result in a double variable like: double score = scoreCalc().
Speaking of scoreCalc(): Your definition takes 4 parameters that your don't have as input for that method. You should remove those from your method definition, and instead add score1, maxMark, weighting and finalScorevariable declarations in the method-body.
In your main function, you declare and instantiate a Scanner object you don't use.
Be careful with arithmetic that mixes int and double.
Some mistakes/errors to point out are:-
1) You do not need this statement Scanner in = new Scanner(System.in); in your main() , as you are not taking input from user through that function.
2) Your function scoreCalc (int score1, int maxMark, double weighting, double finalScore) takes parameters, for example its call should look like scoreCalc(15, 50, 1.5, 2.7), but you are calling it as scoreCalc(), that is without paramters from main().
Edit:- There is one more serious flaw in your program, which might work , but is not good coding. I wont provide code for it , and will leave implementation to you. Take input from user in the main() (using scanner) , assign the result to a temp variable there, and then pass that variable as parameter to the function scoreCalc()
//pseudocode in main()
Scanner in = new Scanner(System.in);
int score= in.nextInt();
.
.
.
scoreCalc(score,...);
Or you can make your scoreCalc function without parameters, and take user input in it (like present), and finally return just the result to main().
Both approaches seem appropriate and you are free to choose :)
As opposed to other answers I will start with one other thing.
You forgot about the most important method - and that is the Constructor.
You have to create a grade calculator, so you create a class(type) that represents objects of grade calculators. Using the Java convention this class should be named GradeCalculator, don't use abbreviations like Calc so that the name is not ambiguous.
So back to the constructor - You have not created your Calculator object. It may not be needed and you may achieve your goal not using it, but it's not a good practice.
So use this method as well - this way, you'll create actual Calculator object.
It can be achieved like that:
public static void main(String[] args)
{
GradeCalculator myCalculator = new GradeCalculator();
}
And now you can imagine you have your calculator in front of you. Whan can you do with it?
Getting a mark would be a good start - so, what you can do is:
myCalculator.getMark()
Now you'll have to define an method getMark():
private void getMark() { }
In which you would prompt the user for the input.
You can also do:
myCalculator.getMaxMark() { }
and that way get max mark (after defining a method).
The same way you can call method myCalculator.getWeighting(), myCalculator.calculateFinalResult(), myCalculator.printResult().
This way you'll have actual object with the following mehtods (things that it can do):
public GradeCalculator() { } //constructor
private void getMark() { } //prompts user for mark
private void getMaxMark() { } //prompts user for max mark
private void getWeighting() { } //prompts user for weighting factor
private void calculateFinalResult() // calculates the final result
private void printResult() // prints the result.
And that I would call creating a calculator using methods - and that I would grade highly.
Try to think of the classes you are creating as a real objects and create methods representing the behaviour that objects really have. The sooner you'll start to do that the better for you.
Writing whole code in one method is not a good practice and in bigger applications can lead to various problems. So even when doing small projects try to do them using best practices, so that you don't develop bad habbits.
Edit:
So that your whole program can look like this:
import java.util.Scanner;
public class GradeCalculator
{
//here you define instance fields. Those will be visible in all of your classes methods.
private Scanner userInput; //this is the userInput the calculator keypad if you will.
private int mark; //this is the mark the user will enter.
private int maxMark; //this is the mark the user will enter.
private int weightingFactor; //this is the weighting factor the user will enter.
private int result; //this is the result that will be calculated.
public static void main(final String args[])
{
Scanner userInput = new Scanner(System.in); //create the input(keypad).
GradeCalculator calculator = new GradeCalculator(userInput); //create the calculator providing it with an input(keypad)
calculator.getMark();
calculator.getMaxMark();
calculator.getWeightingFactor();
calculator.printResult();
}
private GradeCalculator(final Scanner userInput)
{
this.userInput = userInput; //from now the provided userInput will be this calculators userInput. 'this' means that it's this specific calculators field (defined above). Some other calculator may have some other input.
}
private void getMark() { } //here some work for you to do.
private void getMaxMark() { } //here some work for you to do.
private void getWeightingFactor() { } //here some work for you to do.
private void printResult() { } //here some work for you to do.
}
Please mind the fact that after constructing the Calculator object you don't have to use methods that are static.

Class Random only Generates 0

Okay
I have The problem that i want to generate 64 numbers between 0 and 1 (that means 0 or 1)
the function i have currently is:
public static int randNr(int max) {
Random r = new Random();
int o = r.nextInt(max);
return o;
}
But it always returns 0.
Is there any way to make that it generates also a 1 ?
EDIT:
the function is located in a different java file than when i calling it!
Two issues:
1) nextInt(max); generates a number from 0 and up to but not including max. My guess is that you're passing 1 as max. Pass 2 and all will be well.
2) Creating a new generator object each time ruins the statistical properties of the generator. You should create one Random instance and (i) either pass into the function or (ii) have the instance stored as a member variable.
This function works fine. You are probably calling it with the wrong arguments. It should be:
randNr(2)
Why? Because it's using the Random#nextInt(max) method, which will return a random integer in the range [0, max-1] (including 0 and max-1).
Note: It's not recommended to create a new Random object each time you call the function. One solution would be to declare the Random object as an static member of the class:
public class Test
{
private static Random r = new Random();
// ...
}
Another solution would be to use the static method Math.random()1:
int o = (int) Math.round(Math.random());
1: Could someone confirm if this method is faster than the OP's one?

Extend java.util.Random to control generation of numbers

Hello I have the following tasks:
First, I am given this code that uses a method to generate random numbers 100 times:
public class Q3 {
public static void printDiceRolls(Random randGenerator) {
for (int i = 0; i < 100; i++) {
System.out.println(randGenerator.nextInt(6) + 1);
}
}
public static void main(String[] args) {
Random man = new Random();
printDiceRolls(man);
}
}
Second, I am asked to make a class LoadedDice that extends the Random class:
public class LoadedDice extends Random {
// instance variables - replace the example below with your own
public int nextInt(int num) {
// code right here
return 3;
}
}
Then I am asked to override the public int nextInt ( int num ) and do the following
Override the public int nextInt(int num) method such that with a 50%
chance, the new method always returns the largest number possible
(i.e., num-1), and with a 50% chance, it returns what the Random's
nextInt method would return
I do not quite understand what my overridden method should do in this case.
Suggestions?
Use another Random instance to give you a 50% chance (e.g. nextInt(100) >= 50) then based on that return a constant or a real random.
I guess one way to do this is to use (another?) random number generator with a uniform distribution and set it to return 0 or 1. The 0/1 would be the 50% for you to make your decision upon.... either returning super.nextInt or the max number.
To me, it looks like the nextInt(int) function comes up with a number between 1 and the input. In the root Random class, this function finds a random number within that range. What they want you to do is change that so that half the time it will return a random number in the range, but the other half the time it will give the maximum number.
In the example they gave, you're rolling a dice, so the range is 1-6. Normally, nextInt will find a random number between 1 and 6. But your new function will only do that half the time. The other half the time, it will return 6.
I have an idea on how you can implement that, but it seems like it would be cheating to go that far. ^^;
if(super.nextBoolean())
return num-1;
return super.nextInt(num);
if num<Integer.MAX/2, we can
int x = super.nextInt(num*2);
return Math.min(x, num-1);

Categories