small java exercise

R

ros

Hi,

I am working on this exercise and would be thankful if you folks
comment on it.

The requirement was as follows:

Create a MovieRating class that contains a private map with rating as
the key and minimum age as the value, populate this map when the class
is instantiated. Also include a method which takes two parameters,
rating and age and checks the minimum age in the map and returns true
or false to indicate whether or not a human with the specified age is
allowed to watch a movie with the specified rating.

My attempt is pasted below. I get a compiler error that says that I
have a missing return statement in getStatus. The return statements
that I have are in the if/else block. How can I solve this issue?
Also I am not sure about the Map?

Thanks
Ros

import java.util.HashMap;
import java.util.Map;

public class MovieRating {

private Map humanMap = new HashMap();

public MovieRating(){
humanMap.put("G", 18);
humanMap.put("PG", 16);
}

public boolean getStatus(String rating, int age){

int minAge;
minAge = Integer.getInteger((String) humanMap.get("PG"));

if (age < minAge ){
return false;
}
else if (age >= minAge){
return true;
}

}

}
 
I

Ingo R. Homann

Hi,
public class MovieRating {

private Map humanMap = new HashMap();

public MovieRating(){
humanMap.put("G", 18);
humanMap.put("PG", 16);
}

public boolean getStatus(String rating, int age){

int minAge;
minAge = Integer.getInteger((String) humanMap.get("PG"));

if (age < minAge ){
return false;
}
else if (age >= minAge){
return true;
}

}

}

Several issues. In the first step I would do it like this:

public class MovieRating {
private int g=18; // perhaps also 'static final'?
private int pg=16;// perhaps also 'static final'?
public boolean getStatus(int age) {
return age>=pg;
}
}

In the second step - I suppose that's what you want to do - you can take
into account the parameter 'rating'. After all, I think it could be
better like this (it all depands on the rest of your architecture and
your requirenments):

public class MovieRating {
private int age;
public MovieRating(int age) {
this.age=age;
}
public boolean getStatus(int age) {
return age>=this.age;
}
}

Ciao,
Ingo
 
V

vishist

Hi,

I am working on this exercise and would be thankful if you folks
comment on it.

The requirement was as follows:

Create a MovieRating class that contains a private map with rating as
the key and minimum age as the value, populate this map when the class
is instantiated. Also include a method which takes two parameters,
rating and age and checks the minimum age in the map and returns true
or false to indicate whether or not a human with the specified age is
allowed to watch a movie with the specified rating.

My attempt is pasted below. I get a compiler error that says that I
have a missing return statement in getStatus. The return statements
that I have are in the if/else block. How can I solve this issue?
Also I am not sure about the Map?

Thanks
Ros

import java.util.HashMap;
import java.util.Map;

public class MovieRating {

private Map humanMap = new HashMap();

public MovieRating(){
humanMap.put("G", 18);
humanMap.put("PG", 16);
}

public boolean getStatus(String rating, int age){

int minAge;
minAge = Integer.getInteger((String) humanMap.get("PG"));

if (age < minAge ){
return false;
}
else if (age >= minAge){
return true;
}

}

}

Ros:
You also may want to try this,

import java.util.HashMap;
import java.util.Map;

public class MovieRating {

private Map humanMap = new HashMap();
public MovieRating(){
humanMap.put("G", new Integer(18));
humanMap.put("PG", new Integer(16));
}

public boolean getStatus(String rating, int age){

Integer ratingAge = (Integer)humanMap.get(rating);
if(ratingAge != null)
{
int minAge = ratingAge.intValue();
if (age < minAge ){
return false;
}
else{
return true;
}
}
return false;
}
}

The problem with your code is that you are trying to 1. add basic data
types to map (Map takes only references to Objects) 2. the "if/else
if" conditions has no "else" condition. For the compiler, it doesn't
know whats the default return is going to be in case if/elseif fails
3. Also, you have hardcoded the rating in access function.

Once you got this working, I guess you may want to add additional
condition checks for non-null method arguments.

V.
 
B

bcr666

public boolean getStatus(String rating, int age){

Integer ratingAge = (Integer)humanMap.get(rating);
if(ratingAge != null)
{
int minAge = ratingAge.intValue();
if (age < minAge ){
return false;
}
else{
return true;
}
}
return false;
}

I am a big believer in one exit point for a method, so I would do the
following

public boolean getStatus(String rating, int age) {
boolean value = false;

Integer ratingAge = (Integer)humanMap.get(rating);
if(ratingAge != null) {
int minAge = ratingAge.intValue();
value = (age >= minAge);
}

return value;
}
 
P

Patricia Shanahan

bcr666 said:
I am a big believer in one exit point for a method, so I would do the
following

Why one exit point per method?

[I used to believe that, but most of the logical reasons I can
articulate are covered by try-finally. I'm curious about whether there
is a better reason I'm missing.]

Patricia
 
R

ros

Ros:
You also may want to try this,

import java.util.HashMap;
import java.util.Map;

public class MovieRating {

private Map humanMap = new HashMap();
public MovieRating(){
humanMap.put("G", new Integer(18));
humanMap.put("PG", new Integer(16));
}

public boolean getStatus(String rating, int age){

Integer ratingAge = (Integer)humanMap.get(rating);
if(ratingAge != null)
{
int minAge = ratingAge.intValue();
if (age < minAge ){
return false;
}
else{
return true;
}
}
return false;
}

}

The problem with your code is that you are trying to 1. add basic data
types to map (Map takes only references to Objects) 2. the "if/else
if" conditions has no "else" condition. For the compiler, it doesn't
know whats the default return is going to be in case if/elseif fails
3. Also, you have hardcoded the rating in access function.

Once you got this working, I guess you may want to add additional
condition checks for non-null method arguments.

V.

Thank you so much Vishist for the help. It makes sense.
Ros
 
B

bcr666

Why one exit point per method?

[I used to believe that, but most of the logical reasons I can
articulate are covered by try-finally. I'm curious about whether there
is a better reason I'm missing.]

Patricia

Maybe it is my opinion, but It makes it easier to debug, and it is
easier to change later on without breaking it or introducing errors.
 
L

Lew

bcr666 said:
Why one exit point per method?

[I used to believe that, but most of the logical reasons I can
articulate are covered by try-finally. I'm curious about whether there
is a better reason I'm missing.]

Patricia

Maybe it is my opinion, but It makes it easier to debug, and it is
easier to change later on without breaking it or introducing errors.

I disagree. The single-exit anal retention makes it harder to debug, and
harder to change later on, especially when it forces you into ridiculous
levels of nesting and extraneous conditionals, not to mention the introduction
of superfluous "retVal" variables. I'd stick with Patricia's insights; she's
one of the god(desse)s of Java.

Seriously, Patricia - you provide some of the sharpest, most succinct,
to-the-point and informative posts on the topic that there are.

Ignore her advice at your peril. (Not that she's infallible, but I have yet
to find her in error in this forum.)
 
P

Patricia Shanahan

Lew said:
bcr666 said:
Why one exit point per method?

[I used to believe that, but most of the logical reasons I can
articulate are covered by try-finally. I'm curious about whether there
is a better reason I'm missing.]

Patricia

Maybe it is my opinion, but It makes it easier to debug, and it is
easier to change later on without breaking it or introducing errors.

I disagree. The single-exit anal retention makes it harder to debug,
and harder to change later on, especially when it forces you into
ridiculous levels of nesting and extraneous conditionals, not to mention
the introduction of superfluous "retVal" variables. I'd stick with
Patricia's insights; she's one of the god(desse)s of Java.

Seriously, Patricia - you provide some of the sharpest, most succinct,
to-the-point and informative posts on the topic that there are.

Ignore her advice at your peril. (Not that she's infallible, but I have
yet to find her in error in this forum.)

BLUSH! And thanks. However, two points:

1. In this case, I am not so much giving advice as asking for insight.
Are there advantages in Java to pushing for single exit that outweigh
the cost of making the code more complicated, for example by requiring a
"retVal"? If so, what are they?

I believe that there is a significant gain in ease of debug and change
for languages without try-finally or equivalent. I am just not convinced
for Java.

2. Even when I am giving advice, I really want anyone who is interested
in the topic and not convinced by my arguments to question and challenge
what I am saying. Maybe I'll get to learn something that way.

Patricia
 
P

Patricia Shanahan

bcr666 said:
Why one exit point per method?

[I used to believe that, but most of the logical reasons I can
articulate are covered by try-finally. I'm curious about whether there
is a better reason I'm missing.]

Patricia

Maybe it is my opinion, but It makes it easier to debug, and it is
easier to change later on without breaking it or introducing errors.

Can you explain why?

Thanks,

Patricia
 
D

Daniel Pitts

Hi,

I am working on this exercise and would be thankful if you folks
comment on it.

The requirement was as follows:

Create a MovieRating class that contains a private map with rating as
the key and minimum age as the value, populate this map when the class
is instantiated. Also include a method which takes two parameters,
rating and age and checks the minimum age in the map and returns true
or false to indicate whether or not a human with the specified age is
allowed to watch a movie with the specified rating.

My attempt is pasted below. I get a compiler error that says that I
have a missing return statement in getStatus. The return statements
that I have are in the if/else block. How can I solve this issue?
Also I am not sure about the Map?

Thanks
Ros

import java.util.HashMap;
import java.util.Map;

public class MovieRating {

private Map humanMap = new HashMap();

public MovieRating(){
humanMap.put("G", 18);
humanMap.put("PG", 16);
}

public boolean getStatus(String rating, int age){

int minAge;
minAge = Integer.getInteger((String) humanMap.get("PG"));

if (age < minAge ){
return false;
}
else if (age >= minAge){
return true;
}

}

}


if (age < minAge) isn't true, then age >= minAge MUST be true, so
after for it again doesn't make sense so what you're really trying to
do is
if (age < minAge) {
return false;
} else { // age >= minAge
return true;
}

Also, when the difference in outcome of an if/else statement is only a
boolean value, you can replace the if/else with just the boolean
value. So you end up with this:
// return true if the age is acceptable.
return age >= minAge;
 
D

Daniel Pitts

bcr666 said:
Why one exit point per method?
[I used to believe that, but most of the logical reasons I can
articulate are covered by try-finally. I'm curious about whether there
is a better reason I'm missing.]
Patricia
Maybe it is my opinion, but It makes it easier to debug, and it is
easier to change later on without breaking it or introducing errors.

I disagree. The single-exit anal retention makes it harder to debug, and
harder to change later on, especially when it forces you into ridiculous
levels of nesting and extraneous conditionals, not to mention the introduction
of superfluous "retVal" variables. I'd stick with Patricia's insights; she's
one of the god(desse)s of Java.

Seriously, Patricia - you provide some of the sharpest, most succinct,
to-the-point and informative posts on the topic that there are.

Ignore her advice at your peril. (Not that she's infallible, but I have yet
to find her in error in this forum.)

I also find that avoiding multiple exit points leads to variable
reuse, which is a far worse practice. Actually, I think that it makes
sense for a method to possible have multiple exit points, as long as
it only has one entry point :) Can you imagine debugging a method
who's entry point could be in one of three places?
 
L

Lew

Daniel said:
I also find that avoiding multiple exit points leads to variable
reuse, which is a far worse practice. Actually, I think that it makes
sense for a method to possible have multiple exit points, as long as
it only has one entry point :) Can you imagine debugging a method
who's entry point could be in one of three places?

Imagine? I can remember. I used to work on systems that allowed multiple
entry points in a routine. I agree that single entry point is much nicer.
 
S

Stefan Ram

Patricia Shanahan said:
In this case, I am not so much giving advice as asking for
insight. Are there advantages in Java to pushing for single
exit that outweigh the cost of making the code more
complicated, for example by requiring a "retVal"? If so, what
are they?

The usual benefits of »structured programming«.

- With a single exit at the end, if I would want to add a
call to be done once before the method exits, I would add
it in front of this exit point. Otherwise, one would need
to find all exit points and add this call in front of
each one.

- A kind of »referential transparency« of blocks. By this
(ignoring parameters and return values for simplicity),
a methode declaration

m(){ ... { ... } ... }

can always be refactored to

m1(){ ... } // = the »{ ... }« block from above

m(){ ... m1(); ... }

Thus, a block can always be replaced by a call to this
block after it has been given a name by a method
declaration.

This is not possible anymore, when this block contains
an exit (»return«).

- Improved readability. In

{ ...
{ ... }
f();
... }

I know that »f();« will be executed whenever the whole
block is executed if the block is written according to
structured programming rules. I do not have to analyze the
inner block to make this assertion. When jump-statements,
like »return;« are allowed, one can not make such
assertions with the same ease.

Once I have read that in certain C++ implementations multiple
returns can speed up a function, which would be slowed down by
an enforcement of the single-exit rule. This would be one of
the cases, where I would refrain from enforcing a single exit:
If code needs to be optimized for runtime speed. In general,
I like and apply the single-exit rule.
 
L

Lew

Patricia said:
BLUSH! And thanks. However,

Note that when I suggest that one ignores your advice at peril, it doesn't
mean that I endorse uncritically /following/ your advice. One should
carefully consider anyone's input, particularly those known to be
knowledgeable, but that confers no obligation to follow it afterward.
 
M

Martin Gregorie

Patricia said:
Lew said:
bcr666 said:
Why one exit point per method?

[I used to believe that, but most of the logical reasons I can
articulate are covered by try-finally. I'm curious about whether there
is a better reason I'm missing.]

Patricia

Maybe it is my opinion, but It makes it easier to debug, and it is
easier to change later on without breaking it or introducing errors.

I disagree. The single-exit anal retention makes it harder to debug,
and harder to change later on, especially when it forces you into
ridiculous levels of nesting and extraneous conditionals, not to
mention the introduction of superfluous "retVal" variables. I'd stick
with Patricia's insights; she's one of the god(desse)s of Java.

Seriously, Patricia - you provide some of the sharpest, most succinct,
to-the-point and informative posts on the topic that there are.

Ignore her advice at your peril. (Not that she's infallible, but I
have yet to find her in error in this forum.)

BLUSH! And thanks. However, two points:

1. In this case, I am not so much giving advice as asking for insight.
Are there advantages in Java to pushing for single exit that outweigh
the cost of making the code more complicated, for example by requiring a
"retVal"? If so, what are they?
I tend to end up with a single-exit solution, but than I also tend to
lard my code fairly liberally with debugging statements (and
multi-valued debugging switches). I find that this is generally easier
to set up and works better with a single exit. This is a
language-agnostic position on my part: I use the same approach in any
language. It was proven in IDMS/COBOL systems, carried through to C and
now to Java.

I should add that I don't go to this trouble merely to debug the methods
in a particular class, but do it this way because I find the tracing
useful as I add successive classes and hierarchies of classes to a
complex process. It continues to be useful when system testing starts to
integrate intercommunicating processes.

Last but not least, it remains useful in debugging live code: a
well-thought out tracing system can, for instance, help to
distinguish between a user who didn't type what (s)he thought (s)he typed
when entering data and a genuine bug or to diagnose problems if the data
feed
from an upstream system changes in unexpected ways.
I believe that there is a significant gain in ease of debug and change
for languages without try-finally or equivalent. I am just not convinced
for Java.
I don't find much difference, but then my philosophy is to restrict
throwing exceptions to potentially fatal situations. I generally do not
use them to signal expected non-fatal conditions such as end of file in
the grounds that the higher level classes must detect and act on them
without undue contortions, tangled logic or data loss.
 
P

Patricia Shanahan

Stefan said:
The usual benefits of »structured programming«.

- With a single exit at the end, if I would want to add a
call to be done once before the method exits, I would add
it in front of this exit point. Otherwise, one would need
to find all exit points and add this call in front of
each one.

My question is specific to Java, so I could wrap the multi-exit code in
a try-finally and do the call in the finally block. This used to be one
of the most convincing arguments, but I'm not sure it still applies.
- A kind of »referential transparency« of blocks. By this
(ignoring parameters and return values for simplicity),
a methode declaration

m(){ ... { ... } ... }

can always be refactored to

m1(){ ... } // = the »{ ... }« block from above

m(){ ... m1(); ... }

Thus, a block can always be replaced by a call to this
block after it has been given a name by a method
declaration.

Not always, in Java, given the lack of call-by-reference:

m(){int x=0; int y = 0; ... { ... x = 5; y = 20; ... } ... }

cannot be refactored as above without changing the handling of x and y.
Passing them as parameters does not get the changed values back to the
surrounding block.

And one of the standard techniques for obtaining a single exit function
involves using an extra outer block variable, modified at each logical
exit point, to represent the return value.

This is not possible anymore, when this block contains
an exit (»return«).

- Improved readability. In

{ ...
{ ... }
f();
... }

I know that »f();« will be executed whenever the whole
block is executed if the block is written according to
structured programming rules. I do not have to analyze the
inner block to make this assertion. When jump-statements,
like »return;« are allowed, one can not make such
assertions with the same ease.

I'm not convinced the single exit rule does always aid readability. In
some cases, for example, I think getting one or two special cases
completely out of the way before starting the main work leads to more
readable code. It makes it easier to be sure that nothing else in the
method needs to handle the special cases, and that the special case
decision will not be overridden later on.

This is especially the case for recursive methods.

int factorial(int n){
if(n < 0){
throw something;
}
if(n == 0){
return 1;
}
return n * factorial(n-1);
}

int factorial(int n){
int fact;
if(n < 0){
throw something;
}
if(n == 0){
fact = 1;
}else{
fact = n * factorial(n-1);
}
return fact;
}

I think the multi-exit version makes it easier to identify the base case
and be sure its handling is non-recursive.

Note that I am not denying the existence of many methods for which the
single exit version will be the most readable version, and should be
used. I just feel that there are cases in which multiple exit is clearer
than single exit, and that multiple exit should be used in those cases.

Possibly the difference is whether it is more important to be sure some
code is always executed, or to be sure some code is not executed in
particular cases.

Patricia
 
P

Patricia Shanahan

Martin said:
Patricia Shanahan wrote: ....
I don't find much difference, but then my philosophy is to restrict
throwing exceptions to potentially fatal situations. I generally do not
use them to signal expected non-fatal conditions such as end of file in
the grounds that the higher level classes must detect and act on them
without undue contortions, tangled logic or data loss.

try-finally does not require any use of exceptions. It just provides a
way of having the finally block run on completion of the try block.

I thought single exit was a very good idea when I was programming in
assembly languages and later in C. Is it a good idea in Java, or just a
habit?

Patricia
 
L

Lew

Patricia said:
try-finally does not require any use of exceptions. It just provides a
way of having the finally block run on completion of the try block.

I thought single exit was a very good idea when I was programming in
assembly languages and later in C. Is it a good idea in Java, or just a
habit?

Very interesting discussion. What I like about Patricia's suggestion is a
sense of flexibility - she seems to express a bias for single-exit structure,
but violates that principle when there is a compelling argument that another
way is clearer.

This is one of those areas where I would leave it to the practitioner, if
everyone is thinking as carefully as the respondents in this thread.
Arguments in both directions were founded on the same basic principles of code
clarity and maintainability. Whichever decision you make is likely to be
elegant for some values of elegant, if you work from such sound first principles.

If I were reviewing, say, Martin's or Patricia's code, I would not ding either
for the decisions they described here. Both would be based on intelligent
goals and clear thinking; the difference is a matter of style at that point.

At some threshold one must recognize that coding is an art, and some rules
should not become repressive. There is room for individual style.
 
P

printdude1968

I am a big believer in one exit point for a method, so I would do the
following

Why one exit point per method?

[I used to believe that, but most of the logical reasons I can
articulate are covered by try-finally. I'm curious about whether there
is a better reason I'm missing.]

Patricia

Having come from a procedural language background, I was always taught
5 rules that could not be broken:
1) Single Entry Point
2) Single Exit Point
3) No GOTO's allowed
4) No self-modifying code.
5) One procedure, one function

Having been trying to learn Java, I am now of the opinion that one can
still write well structured programs yet not be regimented by the
above rules, more over numbers 1 and 2.
I found this site http://ivan.truemesh.com/archives/000611.html
which appears to agree with me. And just to quote a section of the
above site,

Longer functions that use the "single exit
point" rule can get really convoluted and difficult
to understand. Having a function return as
soon as it can improves the clarity because it
improves the "locality" of the code.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,744
Messages
2,569,484
Members
44,903
Latest member
orderPeak8CBDGummies

Latest Threads

Top