Beginner Java trouble with Parameters - java

I am currently learning Java, and have been having problems with parameters. I'm trying to create a program that takes age as input, and classifies the person based on said age.
Younger than 2 is a baby
Younger than 4 is a toddler
Younger than 13 is a child
Younger than 20 is a teenager
Younger than 35 is a young adult
Younger than 65 is middle aged
Younger than 100 is geriatric
100 and older is antique
It needs to return a string classifying the person. I wrote this:
String getMaturityLevel(int age) {
if (age < 2)
return ("a baby");
if (age < 4)
return ("a toddler");
if (age < 13)
return ("a child");
if (age < 20)
return ("a teenager");
if (age < 35)
return ("a young adult");
if (age < 65)
return ("middle aged");
if (age < 100)
return ("geriatric");
if (age >= 100)
return ("antique");
}
Which doesn't compile as it needs a return statement.
So my problem is, how do I effectively write the code? I don't know how to store the results. I tried something different with age < 2.
Any help would be appreciated.

I'm old school, so I believe in only one entry and exit point for a method or function...
The essence of your problem comes down to the compilers inability to guarantee that any one if statement "may" be meet (you and I know that the last one should be, but the compiler won't take that risk).
So instead of having a return for every condition, you could define a single return variable and change it's value based on your needs, for example...
String getMaturityLevel(int age) {
String maturity = "antique";
if(age < 2)
maturity = ("a baby");
else if(age < 4)
maturity = ("a toddler");
else if(age < 13)
maturity = ("a child");
else if(age < 20)
maturity = ("a teenager");
else if(age < 35)
maturity = ("a young adult");
else if(age < 65)
maturity = ("middle aged");
else if(age < 100)
maturity = ("geriatric");
return maturity;
}
Now, in this small piece of code, it may not make much difference, but when you deal with methods that are longer or have multiple compound if/loop statements, a single return statement anywhere in the code can ruin your understanding of what you think the method is doing...it's a nit pick, but anything that makes my life easier ;)
I would also encourage you to use {...} around your if statements, it will stop you from doing something like...
else if(age < 100)
maturity = ("geriatric");
maturity = "Why is the returned value for every condition?";

At the end where
if(age >= 100)
return("antique");
write
else
return("antique");
This is because the compiler thinks there's a possibility there is no return statement if they are all if's(imagine a scenario where everything is false).

Edit: Misread the question.
It appears you strictly have only if statements (no else if statements) therefore at the end of your last if statement, you need to add a return statement:
String getMaturityLevel(int age) {
if(age < 2)
maturity = ("a baby");
if(age < 4)
return("a toddler");
if(age < 13)
return("a child");
if(age < 20)
return("a teenager");
if(age < 35)
return("a young adult");
if(age < 65)
return("middle aged");
if(age < 100)
return("geriatric");
if(age >= 100)
return("antique");
return "no maturity level found";
}
It will only return "no maturity level found" if none of the previous if conditions are true.

Actually, even better, is end it with a return "Error" at the very end without removing anything. This "Error" should never, ever happen, but if it does, you know something went wrong. It's a little bit more robust, I think, and allows you to make the qualification for "antique" (>100) clear still without having to read a single other option.

I recommend using an Enum type (http://docs.oracle.com/javase/tutorial/java/javaOO/enum.html) that would enumerate your maturity levels. Each maturity would have a "value" that would be your string. You could then iterate over your Enum elements and make a single line or two of code... if each element also has a "maturityAge".
public enum MaturityEnum {
BABY (2, "A baby"),
// etc
private int maturityAge;
private String maturityMsg ;
// Accessors etc
}
public int getMaturityLevel(int age) {
for (MaturityEnum maturity : MaturityEnum.getValues()) {
if (maturity.getMaturityAge() > age)
return maturity.getMaturityMsg() ;
// only works if the values of MaturityEnum are in the good order
// to ensure this, you could make a function that gives the list of MaturityEnums
// in the good order :)
}
}

I would definitely change all of the if statements after the first to else if. Also I would recommend putting brackets around each else if / if statement.

Related

Does a simpler representation of this if condition exist?

I used the below conditional statement to ensure that the city name given is of valid length. Length of city should be greater than or equal to 3 and less than or equal to 20.
if(city.length()<3 || city.length()>20) return false;
else return true;
I am told that this conditional statement can be further simplified. Is that right? Then what is the simplified code?
return !(city.length() < 3 || city.length() > 20)
or
return city.length() >= 3 && city.length() <= 20
I simplified your code from IntelliJ IDEA IDE.
Actually it itself suggested to simplify when I used your code there. I recommend you to try IntelliJ IDEA.
return city.length() >= 3 && city.length() <= 20;
If you are already using the IDE, just move the cursor to the code with warning and press ALT+Enter and simplify it.
If city.length() is cheap, then write
return city.length() >= 3 && city.length() <= 20
else you ought to pre-compute city.length() to avoid the potential for two evaluations:
const auto&& /*assuming C++, for Java, you need to use the specific type*/ l = city.length();
return l >= 3 && l <= 20;

Initializing an int variable before if statement

When compiling i get an Error stating that my variable has not been initialized.
Code :
int number;
if (dotted==true)
{
if (input >= 1 && input <= 21)
{
number = 1;
System.out.print("True");
}
if (input >= 22 && input <= 40)
{
number = 2;
System.out.print("False");
}
if (input >= 41 && input <= 63)
{
number = 3;
System.out.print("False");
}
if (input >= 64 && input <= 82)
{
number = 4;
System.out.print("True");
}
}
else
{
if (input >= 2 && input <= 22)
{
number = 1;
System.out.print("True");
}
if (input >= 23 && input <= 41)
{
number = 2;
System.out.print("False");
}
if (input >= 42 && input <= 64)
{
number = 3;
System.out.print("False");
}
if (input >= 65 && input <= 83)
{
number = 4;
System.out.print("True");
}
}
System.out.print(number); // number is not initialized?
Why is number not initialized?
I put int number = 0;
But then when i print, no matter the value of input it stays at 0?
Love how people downvote this. A student new to java with a question gets downvoted. Nice site
You need to put int number = 0 because you can't be sure whether the IF statement is executed or not. That's a precaution for your code.
Also, if you think about it, if it keeps being 0, it means you're actually not entering into the IF statement.
Try to put that and check if the dotted variable is actually TRUE or not.
Check also your variable input, because it is the one that changes your number variable.
Why is number not initialized?
Simply, because if none of the if statements are executed then the number variable will never get initialised. Hence the variable will not have a value and that's why you get the following error:
When compiling i get an Error stating that my variable has not been
initialized.
Also, remember local variables must be initialized before the method exits.
with that in mind, you must at least give the variable below a default value:
int number = 0;
I put int number = 0; But then when I print, no matter the value of
input it stays at 0?
if that's the case then it means you're never entering into the if statement. So, you might have to consider your if statement expressions again.

Ternary Operators(Java)

I was recently introduced to ternary operators. I managed to make it through a year and a half of CS school without a professor ever mentioning ternary operators. This is my first quarter where my professor is using them regularly. They seem great for shortening code. So, this is a question that will help me understand the bounds of ternary operators and when/how they can be used. Is there a way to shorten the following code block using one long statements using a ternary operator?
if(age < 18){
minors+=1;
} else if(age < 65){
adults+=1;
}else{
seniors+=1;
}
You are updating three unique variables, one way to use ternaries here is something like
minors += (age < 18) ? 1 : 0;
adults += (age >= 18 && age < 65) ? 1 : 0;
seniors += (age >= 65) ? 1 : 0;
You can write it as a single statement:
int dummy = (age < 18) ? (minors += 1)
: (age < 65) ? (adults += 1)
: (seniors += 1);
The value of dummy is unused here. It's just a way to turn the expression into a statement.
Note that I wouldn't consider writing the logic like this in practice. There are multiple side-effects in the code, and that makes it hard to understand.
I think the intent of your current code is very clear as written. Ternary expressions have a tendency to make the code harder to read, in my experience.
The ternary operator is not a good fit for your code because you are changing 3 different variables. I would leave your code as it is.
Suppose, on the other hand, that you had this
if (age < 18) {
number += 1;
} else if (age < 65) {
number = 8;
} else if (age < 90) {
number += 2;
} else {
number = 13;
}
This could be rewritten to look like a kind of switch:
number = age < 18 ? number + 1 :
age < 65 ? 8 :
age < 90 ? number + 2 :
13;
I think this is an improvement on the if version. However, it is not common to nest ternary operators in this way, so you may confuse people looking at your code if you used this version.

Save values while inside a for loop

So I have the following code
for (int i = 0; i <= numberOfTickets; i++)
{
System.out.println("Please enter your age or if you are a student enter -1");
int age = input.nextInt();
if ((age < 10) && (age > 0))
{
cost = (cost / 4);
}
else if ((age < 16) && (age >= 10))
{
cost = (cost / 2);
}
else if (age > 60)
{
cost = (cost / 2.5);
}
else if (age == -1)
{
cost = (cost / (4/3));
}
System.out.println(cost);
}
the problem is say that initially the cost is £10 and the user enters an age of 12 I want the value of £5 to be saved as say int ticketCost1 before continuing the for loop but starting with 10 again.
In essence i want to at the end of the loop have all the costs of the tickets with the individual discounts applied and to be then able to dd them all together and have a final cost.
P.S. I intend to add more so that for every child i.e. age 0 to 10 then they go free with anyone over the age of 16.
In java.
Make a new double, for now lets call it sum. Now instead of writing:
cost = (cost/whatever);
do this:
sum+= (cost/whatever);
now you save all them in 1 number summed, and cost stays as 10; while all the discounts are applied. Just make sure you initialize sum to 0 OUTSIDE and before the for loop
If I understand you correctly, you have a group of people of varying ages, and you want to find the total cost of all the tickets purchased by the group. You can have two lists, then: one to store the ages, and one to store the ticket costs. The cost of the group will be the total cost stored in the second list.
static final TICKET_PRICE = 10;
int getTotalCost(List<Integer> ages) { // populated list of ages
List<Integer> costs = new ArrayList<>();
for (int i : ages)
costs.add(getTicketPrice(int age));
int totalCost = 0;
for (int curr_cost : costs)
totalCost += curr_cost;
return totalCost;
}
int getTicketPrice(int age) {
int price;
if (age > 60) price = TICKET_PRICE/2.5;
... // all the other conditions, e.g. for students, children under 10, etc.
else price = TICKET_PRICE; // if no special condition applies
return price;
}
For the more complicated conditions (e.g. a child under 10 goes free with another person over the age of 16), it's best if you have a separate method to compute the total cost. Keep in mind that as you increase these conditions that depend not just on the individual, but on the age-distribution of the whole group, the optimal cost computation will start to resemble quite a complex problem in and of itself.

Why I am getting an error to initialize letter and how do I fix it?

public static char determineGrade(float grade)
{
char letter;
if(grade>=90 && grade<=100)
{
letter='A';
}
else if(grade>=80 && grade<=89)
{
letter='B';
}
else if(grade>=70 && grade<=79)
{
letter='C';
}
else if(grade>=60 && grade<=79)
{
letter='D';
}
else if(grade<=59)
{
letter='F';
}
return letter;
}
The program keeps telling me to initialize letter but I do not understand why I need to. Thank you.
Why I am getting an error to initialize letter and how do I fix it?
The problem is that it is possible to reach the return statement without a value having been assigned to letter. (This happens when grade is greater than 100.0. While that might not make sense in the context of your application, the Java compiler cannot know that.)
People have suggested returning a "default" value. I think that is wrong, unless the API spec defines a default value. (And, IMO, it is bad API design to do that.)
I think that a better approach is to throw an exception (for example IllegalArgumentException) if the argument provided makes no sense.
public static char determineGrade(float grade) {
if (grade >= 90 && grade <= 100) {
return 'A';
} else if (grade >= 80 && grade <= 89) {
return 'B';
} else if (grade >= 70 && grade <= 79) {
return 'C';
} else if (grade >= 60 && grade <= 79) {
return 'D';
} else if (grade >= 0 && grade <= 59) {
return 'F';
} else {
throw new IllegalArgumentException("grade is out of range: " + grade);
}
}
The other design issue here is whether it is appropriate to use floating point numbers to represent grades. There is a risk that the computation that calculates the grades gives values that are a tiny bit "off" due to rounding error; i.e. 89.999998 instead of 90.0. If you are going to use a floating point type here, you need to use threshold comparisons rather than simple >= and <= against an integer value.
The problem is :
else if(grade<=59)
{
letter='F';
}
Should be
else
{
letter='F';
}
Because you have a series of if condition, so the compiler cannot know that whether a condition will be true in run time. So either you need to declare a default value for letter or the last else should not have any condition.
For grade over 100, there should be some check to handle this.
if grade over 100 is not acceptable, an exception should be thrown at the beginning of the method (as rule of thumb):
if(grade > 100){
throw new IllegalArgumentException("Invalid input"):
}
char letter simply declares a variable of type char. Initialising means assigning it an initial value, before the variable is acted upon elsewhere in the program.
In your case, if grade is not in any of the ranges that you explicitly check for, letter needs a default value that your method can return. Since this is a local variable in your method, compiler will not assign the standard default value for char, as mentioned in this excerpt from the documentation:
Local variables are slightly different; the compiler never assigns a default value to an uninitialized local variable. If you cannot initialize your local variable where it is declared, make sure to assign it a value before you attempt to use it. Accessing an uninitialized local variable will result in a compile-time error.
That is why you need to explicitly initialise it.
Try this,
public static char determineGrade(float grade) {
char letter = 0;
if (grade >= 90 && grade <= 100) {
letter = 'A';
} else if (grade >= 80 && grade <= 89) {
letter = 'B';
} else if (grade >= 70 && grade <= 79) {
letter = 'C';
} else if (grade >= 60 && grade <= 79) {
letter = 'D';
} else if (grade <= 59) {
letter = 'F';
}
return letter;
}
there is a situation where all if statements are not executing (when number >100 ). Then letter variable doesn't have a value.To prevent that the letter variable should be initialized with a default value.
Because the char is only given values in if statements the method does not know if it will ever be given a value (it assumes there is a chance that none of if statements will have a true condition) and therefore you are requested to give an initial value.
Another way around it would be by turning the last else if statement to just an else because it covers all if the remaining possibilities anyway.

Categories

Resources