Method not being called properly?! Calorie App [closed] - java

Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
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.
Closed 2 years ago.
Improve this question
package com.company;
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
//making values easier to change and also create global variables for gym comparison
Scanner scan = new Scanner (System.in);
System.out.println("How many calories did you consume today?>> ");
int actualIntake = scan.nextInt();
System.out.println("What is your BMR?>> ");
int BMR = scan.nextInt();
scan.close();
//this method is what is expected with deficit
calorieCalculation(actualIntake,BMR);
//this is what you actually ate
actualCalories(actualIntake,BMR);
//gym with protein
gym (30,40,50,100, actualIntake);
}
//testing method
testingMeth(actualIntake);
//What the user should be following
public static int calorieCalculation(int actualIntake, int BMR){
int calorieDifference = BMR - actualIntake;
if (calorieDifference <= 0 ){
calorieDifference = Math.abs (BMR - actualIntake);
System.out.println("You have went over your deficit, well done fatty = " + calorieDifference);
} else if (calorieDifference >= 0){
System.out.println("Expected calorie deficit should be " + calorieDifference);
}
return calorieDifference;
}
//What the user actually did
public static int actualCalories (int actualIntake, int BMR ) {
int deficitCalculation = actualIntake - BMR;
if (actualIntake > BMR ) {
System.out.println("You fat lard stop overeating you dumbass, " + "failed deficit of over " + deficitCalculation + " Calories.");
} else if (actualIntake < BMR ) {
System.out.println("Well done you created a deficit of " + deficitCalculation + " keep her going keep her movin." );
}
return deficitCalculation;
}
//How much did you burn in the gym
public static int gym (int treadMillCal, int rowingMachineCal, int weightsCal, int proteinShakeCal, int actualIntake) {
int totalGym = ((treadMillCal + rowingMachineCal + weightsCal) - proteinShakeCal);
if (totalGym >= 50 ) {
System.out.println("Well done you have burned more than 50 calories whilst drinking protein shake");
} else if (totalGym < 50 ) {
System.out.println("Whats the bloody point of drinking protein if your putting the calories back on fatty: " + totalGym + " calories is how much you lost");
}
int gymAndTotal = actualIntake - totalGym;
System.out.println("What you ate, plus minusing your workout along with the protein you consumed " + gymAndTotal);
return totalGym;
}
public static void testingMeth (int actualIntake) {
System.out.println(actualIntake);
}
}
//Take calories in then calculate BMR and compare, return value
So I am currently learning java, just learning and making random calorie deficit and BMR program. I created a new method called:
public static int testingMeth(actualIntake) {
System.out.println(actualIntake);
}
The issue is when i try to call the method after the gym method, it creates an error.
gym (30,40,50,100, actualIntake);
}
testingMeth(actualIntake);
If i was to delete the gym method from the main method, all my other methods has errors. I do not necessarily need a solution for this program but rather why am i receiving these errors? Just want to learn and improve! Thanks.
In other words, I can call the testingMeth before the Gym method and it works fine, but why not after the gym method? and if i get rid of the gym method, multiple errors occur amongst the other methods within the program?

If you see below code, i am able to run both method in any sequence and it's working fine as well.
You need to go through with basics of method declaration and method call.
It will help you.
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
//making values easier to change and also create global variables for gym comparison
Scanner scan = new Scanner(System.in);
System.out.println("How many calories did you consume today?>> ");
int actualIntake = scan.nextInt();
System.out.println("What is your BMR?>> ");
int BMR = scan.nextInt();
scan.close();
//this method is what is expected with deficit
calorieCalculation(actualIntake, BMR);
//this is what you actually ate
testingMeth(actualIntake);
actualCalories(actualIntake, BMR);
//gym with protein
gym(30, 40, 50, 100, actualIntake);
}
//testing method
//What the user should be following
public static int calorieCalculation(int actualIntake, int BMR) {
int calorieDifference = BMR - actualIntake;
if (calorieDifference <= 0) {
calorieDifference = Math.abs(BMR - actualIntake);
System.out.println("You have went over your deficit, well done fatty = " + calorieDifference);
} else if (calorieDifference >= 0) {
System.out.println("Expected calorie deficit should be " + calorieDifference);
}
return calorieDifference;
}
//What the user actually did
public static int actualCalories(int actualIntake, int BMR) {
int deficitCalculation = actualIntake - BMR;
if (actualIntake > BMR) {
System.out.println("You fat lard stop overeating you dumbass, " + "failed deficit of over " + deficitCalculation + " Calories.");
} else if (actualIntake < BMR) {
System.out.println("Well done you created a deficit of " + deficitCalculation + " keep her going keep her movin.");
}
return deficitCalculation;
}
//How much did you burn in the gym
public static int gym(int treadMillCal, int rowingMachineCal, int weightsCal, int proteinShakeCal, int actualIntake) {
int totalGym = ((treadMillCal + rowingMachineCal + weightsCal) - proteinShakeCal);
if (totalGym >= 50) {
System.out.println("Well done you have burned more than 50 calories whilst drinking protein shake");
} else if (totalGym < 50) {
System.out.println("Whats the bloody point of drinking protein if your putting the calories back on fatty: " + totalGym + " calories is how much you lost");
}
int gymAndTotal = actualIntake - totalGym;
System.out.println("What you ate, plus minusing your workout along with the protein you consumed " + gymAndTotal);
return totalGym;
}
public static void testingMeth(int actualIntake) {
System.out.println(actualIntake);
}
}
You need to understand for every opening braces of class/method/switch-case/or condition must have closing braces.
In your case you are try to call some method after closing braces of class, so those elements are not part of your class and that's why it's throwing an error.

Related

Having trouble with Java Scanner input and a while loop, with multiple if statements in it [duplicate]

This question already has answers here:
Scanner is skipping nextLine() after using next() or nextFoo()?
(24 answers)
Closed 3 years ago.
I wish to limit the input of an integer value, between certain values using a while loop, with a couple of if-else if-else statements inside it! It's kinda working, but not exactly as it should... thought of using a switch as well, but I'm too "green" to know how! If someone's up for it and knows how... I'd welcome the use of a switch as well! Even a nested switch if need be...
Here's my code:
public class OOPProject {
/**
* #param args the command line arguments
*/
public static void main(String[] args) {
// TODO code application logic here
Scanner sc = new Scanner(System.in);
Car Honda = new Car(2018, 20000, "Honda", "Civic", 200, 6, 0, 0);
System.out.println("Manufacturer is: " + Honda.maker + ", model: " + Honda.model +
", year of fabrication: " + Honda.year + ", price: " + Honda.price + "!");
System.out.println("Please start the engine of your vehicle, by typing in 'Yes' or 'Start' or 'Turn on'!");
System.out.print("Do you wish to start the engine?");
System.out.println(" ");
Honda.StartEngine(sc);
//System.out.println("Engine is on!");
System.out.println("Do you wish to depart? Shift in to the first gear then and accelerate!");
System.out.println("Type in the speed: ");
Honda.accelerate(sc);
System.out.println("We are departing! Shifting in to " + Honda.currentGear +
"st gear and accelerating to " + Honda.currentSpeed + " km per hour!");
}
Constructor & functions:
public class Car {
public int year;
public int price;
public String maker;
public String model;
public int maximumSpeed;
public int numberOfGears;
public int currentSpeed;
public int currentGear;
public boolean isEngineOn;
public Car(int year, int price, String maker, String model, int maximumSpeed,
int numberOfGears, int currentSpeed, int currentGear) {
this.year = year;
this.price = price;
this.maker = maker;
this.model = model;
this.maximumSpeed = maximumSpeed;
this.numberOfGears = numberOfGears;
this.currentSpeed = currentSpeed;
this.currentGear = currentGear;
}
public String StartEngine(Scanner in) {
while(in.hasNext()) {
String input = in.nextLine();
if(input.equals("Yes") || input.equals("Start") || input.equals("Turn on")) {
isEngineOn = true;
System.out.println("Engine is on!");
return input;
} else {
System.out.println("Your input is not correct! Please start the engine!");
}
}
return null;
}
public int accelerate(Scanner in){
while(in.hasNextInt()){
currentSpeed = in.nextInt();
if(isEngineOn && currentSpeed > 0){
currentGear++;
} else if(currentSpeed > 50){
System.out.println("We cannot accelerate to more than 50 km per hour, when shifting in the 1st gear!");
} else{
System.out.println("We cannot depart at 0 km per hour!");
}
}
return 0;
}
}
It's taking the input, but it's not going further with it as it should, neither does it give an error message or stop the app, what's my mistake?
Changing the order of your if statement will work.
In your current method:
if(isEngineOn && currentSpeed > 0)
Will always return true with any value that you enter.
Using this method will get you a little further, although I suspect it will still won't be what you are expecting, but I hope it helps you in the right direction.
public int accelerate(Scanner in){
while(in.hasNextInt()){
currentSpeed = in.nextInt();
if(currentSpeed > 50 && currentGear <= 1){
System.out.println("We cannot accelerate to more than 50 km per hour, when shifting in the 1st gear!");
} else if(isEngineOn && currentSpeed > 0){
currentGear++;
break; /* I've added this to break out of the method to progress in your flow */
} else{
System.out.println("We cannot depart at 0 km per hour!");
}
}
return 0;
}
}

Stack Overflow on Random Integers

Where the commented section is, it says that there is a StackOverflowError - null. I am trying to get it to make random numbers to match up with an inputted value. The goal of this code is to do the following:
Accept a top number (ie 1000 in order to have a scale of (1-1000)).
Accept an input as the number for the computer to guess.
Computer randomly guesses the first number and checks to see if it is correct.
If it is not correct, it should go through a loop and randomly guess numbers, adding them to an ArrayList, until it guesses the input. It should check to see if the guess is already in the array and will generate another random number until it makes one that isn't in the list.
In the end, it will print out the amount of iterations with the count variable.
Code:
import java.util.*;
public class ArrNumGuess
{
public static Integer top, input, guess, count;
public static ArrayList <Integer> nums;
public static void main ()
{
System.out.println("Please enter the top number");
top = (new Scanner(System.in)).nextInt();
System.out.println("Please enter the number to guess (1 - " + top + ")");
input = Integer.parseInt(((new Scanner(System.in)).nextLine()).trim());
nums = new ArrayList<Integer>(); //use nums.contains(guess);
guess = (new Random()).nextInt(top) + 1;
nums.add(guess);
System.out.println("My first guess is " + guess);
count = 1;
if(guess != input)
{
guesser();
}
System.out.println("It took me " + count + " tries to find " + guess + " and " + input);
}
public static void guesser()
{
boolean check = false;
while(!check)
{
guess = (new Random()).nextInt(top) + 1; //Stack Overflow - null
if(nums.contains(guess) && !(guess.equals(input)))
{
count--;
guesser();
}
else if(guess.equals(input))
{
check = true;
System.out.println("My guess was " + guess);
// nums.add(guess);
count++;
}
else
{
System.out.println("My guess was " + guess);
nums.add(guess);
count++;
}
}
}
}
In guesser() method, you're invoking itself:
if(nums.contains(guess) && !(guess.equals(input)))
{
count--;
guesser();
}
There is quite a possibility it will never end. But all that is in while loop, so why not get rid of recurrence and do this in an iterative style?
OK - a different approach to your guesser for fun. Enumerate a randomized sequence of numbers in specified range (1 to 'top') and find the guess in the list whose index is effectively the number of "attempts" and return.
(BTW - #Andronicus answer is the correct one.)
/** Pass in 'guess' to find and 'top' limit of numbers and return number of guesses. */
public static int guesser(int guess, int top) {
List<Integer> myNums;
Collections.shuffle((myNums = IntStream.rangeClosed(1, top).boxed().collect(Collectors.toList())), new Random(System.currentTimeMillis()));
return myNums.indexOf(guess);
}
You are making it more complicated than it needs to be and introducing recursion unnecessarily. The recursion is the source of your stack overflow as it gets too deep before it "guesses" correctly.
There is a lot of sloppiness in there as well. Here's a cleaned up version:
import java.util.*;
public class Guess {
public static void main(String args[]) {
System.out.println("Please enter the top number");
Scanner scanner = new Scanner(System.in);
int top = scanner.nextInt();
System.out.println("Please enter the number to guess (1 - " + top + ")");
int input = scanner.nextInt();
if (input < 1 || input > top) {
System.out.println("That's not in range. Aborting.");
return;
}
ArrayList <Integer> nums = new ArrayList<>();
Random rng = new Random(System.currentTimeMillis());
while(true) {
int guess = rng.nextInt(top) + 1;
if (!nums.contains(guess)) {
nums.add(guess);
if (nums.size() == 1) {
System.out.println("My first guess is " + guess);
} else {
System.out.println("My guess was " + guess);
}
if (guess == input) {
System.out.println("It took me " + nums.size() + " tries to find " + guess);
break;
}
}
}
}
}

Text based survival Game

So I just whipped up this quick little demo game in like 30 minutes and I was wondering 2 things:
How could I organize my code more?
Would you be willing to play a game like this?
I know that I could use classes but I'm a bit inexperienced them. I'm confused on how to get variables from specific classes. Would I need to import them into the main method class?
import java.util.Scanner;
public class mainGame
{
public static Scanner kboard = new Scanner(System.in);
public static boolean loop = true;
public static int treesInArea = 0;
public static int day = 0;
public static int wood = 0;
public static int woodCollected = 0;
public static int woodLevel = 0;
public static void main(String[] args)
{
System.out.println("__________________________________");
System.out.println(" Welcome to seul...Lets begin ");
System.out.println(" You woke up in the middle of ");
System.out.println(" a forest. Use the command walk ");
System.out.println(" in order to walk into a new area ");
System.out.println("__________________________________\n");
while(loop == true)
{
String choice = kboard.nextLine();
if(choice.equalsIgnoreCase("walk"))
{
treesInArea = (int)(Math.random() * 20);
System.out.println("__________________________________");
System.out.println("The number of trees in this area is");
System.out.println(treesInArea + " trees");
System.out.println("__________________________________\n");
day++;
System.out.println(" It is day " + day + " ");
System.out.println("__________________________________\n");
System.out.println(" Current usuable commands are : ");
System.out.println(" - Chop tree\n");
} else
if(choice.equalsIgnoreCase("choptree") || choice.equalsIgnoreCase("chop tree"))
{
if(treesInArea < 1)
{
System.out.println("There are no trees in this area.");
} else
{
woodCollected = (int)(Math.random() * 10);
treesInArea --;
wood += woodCollected;
woodLevel += (int)(Math.random() * 2);
System.out.println("__________________________________");
System.out.println(" You collected " + woodCollected + " wood");
System.out.println(" Your total wood = " + wood);
System.out.println(" Your total woodcutting level = " + woodLevel);
System.out.println("__________________________________\n");
}
}
}
}
}
You could improve your code in 4 main ways:
1 • Your code-indentation is not great, it should be a 4 space(or just press tab) indent after class name, loops, if statements etc. Example:
private methodName() {
for(int i = 0; i < 10; i++;) {
//do something
}
}
2 • It is easier to read your code when braces are right after methods/loops, and it takes less space, such as(5 lines of neat code):
if (condition = true) {
//do something
} else {
//do something else
}
Rather than(7 lines of messy code):
if (condition = true)
{
//do something
} else
{
//do something else
}
because when you have long if-else blocks, or long loops, it can become hard to read.
3 • You do not need to add spaces after a line, this does nothing. So this:
System.out.println(" It is day " + day + " ");
Can become this:
System.out.println(" It is day " + day);
4 • Lastly, the best way to organize code is by "dividing and conquering". This means make methods even if they're very short, to prevent repeat-code and save time. For example, you printed this line: System.out.println("__________________________________"); 7 times in your program. If you make a method like the one below, you can save time and space, by avoiding repeat-code, and simply call the method using printDivider(); wherever you used this line:
private static void printDivider() {
System.out.println("__________________________________");
}
Yes, I would play your game(in fact i did play your game), but you could improve it, by adding more possibilities, or different 'paths' to go down, ending in different results.

Return value executing a method?

import java.util.*;
public class Guess {
public static void main(String[] args) {
Scanner console = new Scanner(System.in);
Random r = new Random();
intro();
int numGames = 0;
int numGuesses = game(console, r);
int max = max(numGuesses);
String again = "y";
do {
game(console, r);
System.out.println("Do you want to play again?");
again = console.next();
System.out.println();
numGames++;
} while (again.startsWith("y") || again.startsWith("Y"));
stats(numGames, numGuesses, max);
}
public static void intro() {...}
public static int game(Scanner console, Random r) {
System.out.println("I'm thinking of a number between 1 and 100...");
int answer = r.nextInt(100) + 1;
System.out.println("answer = " + answer);
int guess = -1;
int numGuesses = 0;
while (answer != guess) {
System.out.print("Your guess? ");
guess = console.nextInt();
numGuesses++;
if (guess > answer) {
System.out.println("It's lower.");
} else if (guess < answer) {
System.out.println("It's higher.");
} else {
System.out.println("You got it right in " + numGuesses + " guesses");
}
max(numGuesses);
}
return numGuesses;
}
public static int max(int numGuesses) {
int max = numGuesses;
if (max > numGuesses) {
max = numGuesses;
}
return max;
}
public static void stats(int numGames, int numGuesses, int max) {
System.out.println("Overall results:");
System.out.println(" total games = " + numGames);
System.out.println(" total guesses = " + numGuesses);
System.out.println(" guesses/game = " + numGuesses / numGames / 1.0);
System.out.println(" best game = " + max);
}
}
So this is a small part of my program and the problem I'm having is that my initial int for numGuesses (int numGuesses = game(console, r);) is executing the game method shown below.
All I want from the game method is the return value of numGuesses so that I can forward the value into a different method called stats(numGames, numGuesses, max); . How do I make it so that the initial value isn't executing the method and only the do/while loop is?
Is the way I produce a return statement wrong? Also, my return values aren't saving in my stats method so when I run it, I get the wrong answers.
Then you should put the code that's responsible of generating numGuesses in another method that you will use on both main and game, for example:
public static int game(Scanner console, Random r) {
int numGuesses = getNumberOfGuesses(..);
//continue implementation here
}
public static void main(String[] args) {
int numGuesses = getNumberOfGuesses(..);
//use value
}
You should get familiar with class variables. At the top of your class, you can declare a variable and also give it a value. That is what you should do with numGuesses if you want to access it from different methods in your class. Here is the Foobar example:
class Foo {
private int bar = 0;
private void foobar(int arg) {...}
}
You just need to watch out that you don't do int numGuesses somewehere in a method as that would create a second local variable. The class variable can be accessed via just the name.
Next, you want to keep track of the total games played and the total guesses. You can guess now (hahaha), that you need to use class variables as well. If you need to keep track of the total guesses even when the program is restarted you will need to store these values in a file, but that will be for another time.
Finally, two more little things.
1.) The method max. I do not know what max should do, but at the moment it is just returning the value passed to it. Also the if statement will never execute (x can't be higher than x).
2.) You should maybe consider not making everything static. It obviously works that way, but that is not, what is called object-oriented programming.

How to find average mark of an array list that comes from a csv file (JAVA) [closed]

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Questions asking for code must demonstrate a minimal understanding of the problem being solved. Include attempted solutions, why they didn't work, and the expected results. See also: Stack Overflow question checklist
Closed 9 years ago.
Improve this question
I have a csv file that has a list with student id's, lastname, firstname, marks, phone number, etc. I have organized them into an array list so when you call stu[100].mark it will find the mark of the 100th student on the list of the csv file. There are 1000 students. I need to calculate the total overall average mark for all the students (each student only has one mark) I have put it in a loop, but it just prints out their mark. If you need more details, than I apologize.
Here is the code:
public class StudentRecs {
public static String user;
public int StuRec;
public static int numstu;
public static double average;
//public static StuRec[] stu;
static StuRec[] stu = new StuRec[1000];
public static void main(String[] args) throws IOException {
for (int i = 0; i < 1000; i++) {
stu[i] = new StuRec();
}
StuRec stu = new StuRec();
readFile(user);
menu();
}
public static String filename;
Scanner reader = new Scanner(filename);
public static Boolean readFile(String filename) throws IOException { //Constructor for filename
try {
Scanner userInput = new Scanner(System.in);
System.out.println("Type R To Read a File or Type Default for the default file");
user = userInput.nextLine();
if (user.equalsIgnoreCase("r")) {
user = userInput.nextLine();
}
filename = user;
if (user.equalsIgnoreCase("default")) {
filename = "newreg2.csv";
}
Scanner input = new Scanner(new FileReader(filename));
while (input.hasNext()) {
in(input.nextLine());
numstu++;
}
input.close();
return true;
} catch (IOException e) {
System.err.println(e.getMessage());
}
return false;
}
public static void in(String reader) {
String splitter[];
splitter = reader.split(",");
stu[numstu] = new StuRec();
stu[numstu].studentID = splitter[0];
stu[numstu].lastName = splitter[1];
stu[numstu].firstName = splitter[2];
stu[numstu].phoneNumber = splitter[3];
stu[numstu].courseCode = splitter[4];
stu[numstu].periodNumber = Integer.parseInt(splitter[5]); // parseInt turns a string of digits into an integer
stu[numstu].mark = Integer.parseInt(splitter[6]);
}
public static boolean menu() {
int total = 0;
String choice;
Scanner userInput = new Scanner(System.in);
System.out.println("=============================================");
System.out.println("Type R To Read Another File");
System.out.println("Type L To Print all File Records");
System.out.println("Type AA To Print The Average Of All The Marks");
choice = userInput.nextLine();
for (int i = 0; i < numstu; i++) {
if (choice.equalsIgnoreCase("L")) {
System.out.println(stu[i].lastName + ", " + stu[i].firstName + ", " + stu[i].studentID + ", " + stu[i].phoneNumber + ", " + stu[i].courseCode + ", " + stu[i].periodNumber + ", " + stu[i].mark);
}else if (choice.equalsIgnoreCase("R")){
} else if (choice.equalsIgnoreCase("AA")) {
total = total + stu[i].mark;
} else {
System.err.println("Unknown Key Try Again...");
}
average = total / 1000; // compute the average.
System.out.println(average);
} return menu();
}
}
Your average routine is computing incorrectly. It's simply taking the n'th mark and adding it to itself, divided by 1000. Since you're using integers, it will just round down, effectively giving you n'th mark + 0 for average on each iteration, leaving you with the last mark on the loop completion.
You need to keep adding to average, and divide by 1000 when you are done to get the value.
public static boolean menu() {
String choice;
Scanner userInput = new Scanner(System.in);
System.out.println("=============================================");
System.out.println("Type R To Read Another File");
System.out.println("Type L To Print all File Records");
System.out.println("Type AA To Print The Average Of All The Marks");
choice = userInput.nextLine();
for (int i = 0; i < numstu; i++) {
if (choice.equalsIgnoreCase("L")) {
System.out.println(stu[i].lastName + ", " + stu[i].firstName + ", " + stu[i].studentID + ", " + stu[i].phoneNumber + ", " + stu[i].courseCode + ", " + stu[i].periodNumber + ", " + stu[i].mark);
}else if (choice.equalsIgnoreCase("R")){
} else if (choice.equalsIgnoreCase("AA")) {
average += stu[i].mark; // keep adding to average
} else {
System.err.println("Unknown Key Try Again...");
}
}
// divide by zero protection
if ( numstu > 0 ) {
average = average/numstu; // compute the average. Always use the size in terms of a variable whenever possible.
System.out.println(average); // as noted below, if this is an integer value, < #of students computations will eval to 0.
// might be better to use double
}
else {
System.out.println("Oops! No students! :(");
}
return menu();
}
Note that your menu is a little inefficient, but the problem at hand should be solved.
Others have already pointed out the issue with not correctly calculating the sum of the scores, the numerator of the average calculation. I want to focus on the issue of the number of scores, the denominator of the average calculation.
Think real world. As others have mentioned, you cannot depend on the number of students in the file being fixed. File/class size can vary, so you cannot divide by a fixed number.
But neither can you depend on the number of scores being the same as the number of students, so you cannot simply divide by the number of students in that file. A student might not have a mark for a particular assignment (sickness, excused absence, or whatever). A good routine will account for the possibility of blanks (as well as invalid values), and thus I would expect you to need to count the valid, non-blank marks at the same time that you total them so that you can take the appropriate quotient at the end.
This statement is the problem
average = stu[i].mark + stu[i].mark / 1000;
This does not accumulate a total. Instead try
total = total + stu[i].mark;
And then at the end, outside the loop
average = total / 1000;

Categories

Resources