Home > Archive > Java Help > January 2006 > findAverage ()
You are viewing an archived Text-only version of the thread.
To view this thread in it's original format and/or if you want to reply to
this thread please [click here]
|
|
| Michael 2006-01-21, 9:57 pm |
| Hello, good day all. I had a question about getting an average value from an
array[]. I have the following piece of code below, for reference.
void findAverage(){
for(int i = 0; i<scores.length-1;i++){
sum += scores[i];
count++;
}
if(count>0){
average = (double)sum /(double) count;
System.out.println(average);
}else{
average=0;
}
}
Okay, I have figured that the problem lies within the sum variable. Since
the application only seems to be giving the average number of the last value
in the array. How do I allow for the suming of values in different elements
within the array. That is how do I add the values within the array to yield
the sum, and assign those summed values to the sum variable. My counter is
working fine, only the sum variable is not summing all of the requested
values. I see sum+=scores[i]; as the following sum= scores[0] + scores[1];
Please correct me if I am using the += operator incorrectly. Thanks again.
| |
| Allan Bruce 2006-01-21, 9:57 pm |
|
"Michael" <mbialowas@shaw.ca> wrote in message
news:z4zAf.192472$tl.39342@pd7tw3no...
> Hello, good day all. I had a question about getting an average value from
> an array[]. I have the following piece of code below, for reference.
>
> void findAverage(){
> for(int i = 0; i<scores.length-1;i++){
> sum += scores[i];
> count++;
> }
>
>
> if(count>0){
> average = (double)sum /(double) count;
> System.out.println(average);
> }else{
> average=0;
> }
> }
>
> Okay, I have figured that the problem lies within the sum variable. Since
> the application only seems to be giving the average number of the last
> value in the array. How do I allow for the suming of values in different
> elements within the array. That is how do I add the values within the
> array to yield the sum, and assign those summed values to the sum
> variable. My counter is working fine, only the sum variable is not summing
> all of the requested values. I see sum+=scores[i]; as the following sum=
> scores[0] + scores[1]; Please correct me if I am using the += operator
> incorrectly. Thanks again.
>
Where do you get your variables from? Here is a method that will return the
average given an array of doubles.
Allan
public double findAverage(double [] array)
{
double sum = 0.0;
for (int i=0; i<array.length; i++)
sum += array[i];
if (array.length == 0)
return 0.0;
else
return (sum/array.length);
}
| |
| Daniel Dyer 2006-01-21, 9:57 pm |
| On Sat, 21 Jan 2006 23:02:55 -0000, Michael <mbialowas@shaw.ca> wrote:
> Hello, good day all. I had a question about getting an average value
> from an
> array[]. I have the following piece of code below, for reference.
>
> void findAverage(){
> for(int i = 0; i<scores.length-1;i++){
> sum += scores[i];
> count++;
> }
This loop will miss out the last value in the array. Either lose the -1
or change the operator to <=.
> if(count>0){
> average = (double)sum /(double) count;
> System.out.println(average);
> }else{
> average=0;
> }
> }
Where are your variables (sum, average and count) declared? Are they
instance variables (declared outside of the findAverage method)? They
should probably be local variables (unless you have explicitly been told
to do it this way for the assignment). With your approach, if you call
findAverage more than once, the sum is never reset to zero.
> Okay, I have figured that the problem lies within the sum variable. Since
> the application only seems to be giving the average number of the last
> value
> in the array.
That code doesn't even look at the last value of the array. Are you sure
your diagnosis is correct?
> How do I allow for the suming of values in different elements
> within the array. That is how do I add the values within the array to
> yield
> the sum, and assign those summed values to the sum variable. My counter
> is
> working fine, only the sum variable is not summing all of the requested
> values.
It should work OK, except for the issues I mentioned. Your use of +=
seems to be correct.
Dan.
--
Daniel Dyer
http://www.dandyer.co.uk
| |
| Michael Redlich 2006-01-21, 9:57 pm |
|
Michael wrote:
> Hello, good day all. I had a question about getting an average value from an
> array[]. I have the following piece of code below, for reference.
>
> void findAverage(){
> for(int i = 0; i<scores.length-1;i++){
> sum += scores[i];
> count++;
> }
>
>
> if(count>0){
> average = (double)sum /(double) count;
> System.out.println(average);
> }else{
> average=0;
> }
> }
>
> Okay, I have figured that the problem lies within the sum variable. Since
> the application only seems to be giving the average number of the last value
> in the array. How do I allow for the suming of values in different elements
> within the array. That is how do I add the values within the array to yield
> the sum, and assign those summed values to the sum variable. My counter is
> working fine, only the sum variable is not summing all of the requested
> values. I see sum+=scores[i]; as the following sum= scores[0] + scores[1];
> Please correct me if I am using the += operator incorrectly. Thanks again.
Hi Michael:
I see a couple of minor things here.
(a) In your for loop, you aren't getting the last value of your array.
This is because you subtracted 1 from scores.length which only reaches
element n - 2. Iterating from 0 to n -1 elements is accomplished with
the '<' conditional that you used. I would also recommend that you
take the scores.length variable out of the for loop because it gets
computed n times. I would therefore change your for loop to:
int n = scores.length;
for(int i = 0; i < n; ++i)
{
//
}
(b) using a count variable is redundant since you already have
scores.length.
(c) I don't see sum being initialized to zero anywhere. Are scores and
sum global variables? I assume that the elements in the scores array
and sum are integers since you cast them in the average calculation.
(d) You are using the += operator properly.
(e) Why not return a double type as opposed to void in your method? I
would also pass in your scores array as a parameter. Your method can
be changed to:
public double findAverage(int[] scores)
{
int n = scores.length;
int sum = 0;
for(int i = 0; i < n; ++i) // also note the use of prefix increment
- it's more efficient...
sum += scores[i];
if(n > 0)
return (double)sum / (double) n;
return 0.0;
}
Hope this helps...
Sincerely,
Mike.
--- ACGNJ Java Users Group (http://www.javasig.org/)
| |
| Daniel Dyer 2006-01-21, 9:57 pm |
| On Sun, 22 Jan 2006 00:08:16 -0000, Michael Redlich <mike@redlich.net>
wrote:
> I would also recommend that you
> take the scores.length variable out of the for loop because it gets
> computed n times. I would therefore change your for loop to:
>
> int n = scores.length;
> for(int i = 0; i < n; ++i)
> {
> //
> }
Is there any performance improvement at all there? The length is not
computed, it's already known, so it's a direct access to a final field.
Dan.
--
Daniel Dyer
http://www.dandyer.co.uk
| |
| Eric Jacoboni 2006-01-21, 9:57 pm |
| "Michael Redlich" <mike@redlich.net> writes:
> int n = scores.length;
> for(int i = 0; i < n; ++i)
> {
> //
> }
You may even go further with a constant...
final int N = scores.length;
for (.....) { .... }
--
Eric Jacoboni, ne il y a 1441330013 secondes
| |
| Ian Mills 2006-01-21, 9:57 pm |
| sum += scores[i] is equivalent to sum = sum + scores[i].
how are you populating your array and what are the results you are getting
"Michael" <mbialowas@shaw.ca> wrote in message
news:z4zAf.192472$tl.39342@pd7tw3no...
> Hello, good day all. I had a question about getting an average value from
> an array[]. I have the following piece of code below, for reference.
>
> void findAverage(){
> for(int i = 0; i<scores.length-1;i++){
> sum += scores[i];
> count++;
> }
>
>
> if(count>0){
> average = (double)sum /(double) count;
> System.out.println(average);
> }else{
> average=0;
> }
> }
>
> Okay, I have figured that the problem lies within the sum variable. Since
> the application only seems to be giving the average number of the last
> value in the array. How do I allow for the suming of values in different
> elements within the array. That is how do I add the values within the
> array to yield the sum, and assign those summed values to the sum
> variable. My counter is working fine, only the sum variable is not summing
> all of the requested values. I see sum+=scores[i]; as the following sum=
> scores[0] + scores[1]; Please correct me if I am using the += operator
> incorrectly. Thanks again.
>
| |
| Michael Redlich 2006-01-21, 9:57 pm |
|
Daniel Dyer wrote:
> Is there any performance improvement at all there? The length is not
> computed, it's already known, so it's a direct access to a final field.
>
Hi Dan:
Good point. You're right, using the length field property shouldn't be
a major concern with regards to performance. I'm just so used to that
practice, especially when it involves a call to a method to get the
number of elements, e.g, scores.size(), like some of the Java
Collections have.
Thanks for pointing that out.
Sincerely,
Mike.
--- ACGNJ Java Users Group (http://www.javasig.org/)
| |
| Hal Rosser 2006-01-21, 9:57 pm |
|
"Michael" <mbialowas@shaw.ca> wrote in message
news:z4zAf.192472$tl.39342@pd7tw3no...
> Hello, good day all. I had a question about getting an average value from
an
> array[]. I have the following piece of code below, for reference.
>
> void findAverage(){
> for(int i = 0; i<scores.length-1;i++){
> sum += scores[i];
> count++;
> }
>
>
> if(count>0){
> average = (double)sum /(double) count;
> System.out.println(average);
> }else{
> average=0;
> }
> }
>
> Okay, I have figured that the problem lies within the sum variable. Since
> the application only seems to be giving the average number of the last
value
> in the array. How do I allow for the suming of values in different
elements
> within the array. That is how do I add the values within the array to
yield
> the sum, and assign those summed values to the sum variable. My counter is
> working fine, only the sum variable is not summing all of the requested
> values. I see sum+=scores[i]; as the following sum= scores[0] + scores[1];
> Please correct me if I am using the += operator incorrectly. Thanks again.
Try initializing sum and count to zero at the top of the method.
-- or just divide by scores.length instead of counting something you already
know.
and can we assume the variables you are using were appropriately scoped?
| |
| Michael 2006-01-22, 3:57 am |
| Thanks guys for the information; it is greatly appreciated. Basically I am
writing a worker class which has other methods() aswell. Then I am writing
an application class to instantiate this new object to test its methods. I
am implementing the Comparable interface from within the class which
contains the findAverage(). This class also uses a fillStudent() method that
is implemented using the StringTokenizer object. Also there is a
getName(),getAverage() ( both of which just return either a String name, or
a average which is of type double. And finally the compareTo(Obj) method.
And finally the toString() method to return all information from object.My
constructor for this class is initializing a array called scores to 5
slots.Also average is set to 0.0, and name is initilized to ""( an empty
string). When I run my application class I get the following.
Student's Name: mike
The average of the test mark scores is 1.8
The average should be 9.75 from the values of 10.0 10.0 9.5 9.5. So I am
still doing something wrong.
"Hal Rosser" <hmrosser@bellsouth.net> wrote in message
news:GgBAf.9104$TK2.6837@bignews1.bellsouth.net...
>
> "Michael" <mbialowas@shaw.ca> wrote in message
> news:z4zAf.192472$tl.39342@pd7tw3no...
> an
> value
> elements
> yield
>
> Try initializing sum and count to zero at the top of the method.
> -- or just divide by scores.length instead of counting something you
> already
> know.
> and can we assume the variables you are using were appropriately scoped?
>
>
| |
| Michael 2006-01-22, 3:58 am |
| Here is my method edited.
void findAverage(){
int sum = 0;
int n = scores.length;
for(int i = 0; i<n;i++){
sum += scores[i];
}
if(n > 0){
average = (double)sum /(double) n;
}else{
average=0;
}
}
"Michael" <mbialowas@shaw.ca> wrote in message
news:48IAf.305111$2k.229230@pd7tw1no...
> Thanks guys for the information; it is greatly appreciated. Basically I am
> writing a worker class which has other methods() aswell. Then I am writing
> an application class to instantiate this new object to test its methods. I
> am implementing the Comparable interface from within the class which
> contains the findAverage(). This class also uses a fillStudent() method
> that is implemented using the StringTokenizer object. Also there is a
> getName(),getAverage() ( both of which just return either a String name,
> or a average which is of type double. And finally the compareTo(Obj)
> method. And finally the toString() method to return all information from
> object.My constructor for this class is initializing a array called
> scores to 5 slots.Also average is set to 0.0, and name is initilized to
> ""( an empty string). When I run my application class I get the following.
>
> Student's Name: mike
>
> The average of the test mark scores is 1.8
>
> The average should be 9.75 from the values of 10.0 10.0 9.5 9.5. So I am
> still doing something wrong.
>
> "Hal Rosser" <hmrosser@bellsouth.net> wrote in message
> news:GgBAf.9104$TK2.6837@bignews1.bellsouth.net...
>
>
| |
| Andrew McDonagh 2006-01-22, 3:58 am |
| Michael wrote:
> Here is my method edited.
>
> void findAverage(){
> int sum = 0;
> int n = scores.length;
> for(int i = 0; i<n;i++){
> sum += scores[i];
> }
> if(n > 0){
> average = (double)sum /(double) n;
> }else{
> average=0;
> }
> }
A small but important point...
using letters for variable names is not a good habit to get into..
The case of 'n' above is a good example.
'n' is really the length of the scores array, so a good name for it
could be... numberOfScores, etc...
using meaningful names saves the readers (thats you, your colleagues,
us, others) from having to remember or mentally compile the code to
figure out what 'n' is.
Aside from that a different way to write the method....
public void findAverage(){
if (scores.length = 0) {
average = 0;
return;
}
int sum = 0;
for(int i = 0; i < scores.length;i++){
sum += scores[i];
}
average = (double)sum /(double) scores.length;
}
The first if test tells the read very clearly that if there is no
scores, then average is zero and theres nothing left to do, so return.
Its not there for any performance optimisation...its there for clarity.
HTH
Andrew
| |
| Michael 2006-01-22, 7:57 am |
| I think my findAverage() might indeed be working but, my fillStudent() is
where the problem maybe lies. I just edited some code now I get a compile
error. The error is the following.
Exception in thread "main" java.util.NoSuchElementException
at java.util.StringTokenizer.nextToken(StringTokenizer.java:332)
at Student.fillStudent(Student.java:32)
at StudentApp.main(StudentApp.java:27)
void fillStudent(String s){
StringTokenizer t = new StringTokenizer(s);
name = t.nextToken();
for(int i=0; i<scores.length;i++){
scores[i] += Double.parseDouble(t.nextToken());
}
}
I am somewhat on The StringTokenizer class. I know that since I
want to read in a name(which is a string), and then following this name will
be 4 test scores(real marks) I have to account for both strings and double.
That is way I am creating a new StringTokenizer object to hold all of these
values. Well I can just call t.nextToken() to get the next segment of the
string. I go this for name. But then to get a double value I extract the
token then try to parse that into a double. But for some reason, that aspect
of my code I don't think is working properly. Any suggestions, thanks again.
"Andrew McDonagh" <news@andrewcdonagh.f2s.com> wrote in message
news:dqvknq$ucg$1@news.freedom2surf.net...
> Michael wrote:
>
> A small but important point...
>
>
> using letters for variable names is not a good habit to get into..
>
> The case of 'n' above is a good example.
>
> 'n' is really the length of the scores array, so a good name for it could
> be... numberOfScores, etc...
>
> using meaningful names saves the readers (thats you, your colleagues, us,
> others) from having to remember or mentally compile the code to figure out
> what 'n' is.
>
>
> Aside from that a different way to write the method....
>
>
> public void findAverage(){
> if (scores.length = 0) {
> average = 0;
> return;
> }
>
>
> int sum = 0;
>
> for(int i = 0; i < scores.length;i++){
> sum += scores[i];
> }
>
> average = (double)sum /(double) scores.length;
> }
>
>
> The first if test tells the read very clearly that if there is no scores,
> then average is zero and theres nothing left to do, so return.
>
> Its not there for any performance optimisation...its there for clarity.
>
> HTH
>
> Andrew
| |
| Ian Mills 2006-01-22, 7:57 am |
| Michael wrote:
> I think my findAverage() might indeed be working but, my fillStudent() is
> where the problem maybe lies. I just edited some code now I get a compile
> error. The error is the following.
>
> Exception in thread "main" java.util.NoSuchElementException
>
> at java.util.StringTokenizer.nextToken(StringTokenizer.java:332)
>
> at Student.fillStudent(Student.java:32)
>
> at StudentApp.main(StudentApp.java:27)
>
> void fillStudent(String s){
> StringTokenizer t = new StringTokenizer(s);
> name = t.nextToken();
>
> for(int i=0; i<scores.length;i++){
> scores[i] += Double.parseDouble(t.nextToken());
> }
> }
>
> I am somewhat on The StringTokenizer class. I know that since I
> want to read in a name(which is a string), and then following this name will
> be 4 test scores(real marks) I have to account for both strings and double.
> That is way I am creating a new StringTokenizer object to hold all of these
> values. Well I can just call t.nextToken() to get the next segment of the
> string. I go this for name. But then to get a double value I extract the
> token then try to parse that into a double. But for some reason, that aspect
> of my code I don't think is working properly. Any suggestions, thanks again.
>
> "Andrew McDonagh" <news@andrewcdonagh.f2s.com> wrote in message
> news:dqvknq$ucg$1@news.freedom2surf.net...
>
>
>
>
This is a runtime error caused by the fact that your tokenizer has run
out of elements. Try modifying your code as follows:
int i=0;
while(t.hasMoreTokens())
{ scores[i]+=Double.parseDouble(t.nextToken());
i++
}
This should cure the problem
| |
| opalpa@gmail.com opalinski from opalpaweb 2006-01-22, 10:00 pm |
| Your code is broken down akwardly. Folks have suggested that you make
a function that takes as parameter numbers to be averaged and returns
an average. Similarly make a function that returns numbers after
reading them in. Having scores be a member variable and average be a
member variable is poor practice.
I think you're just learning (this is homework, right?).
You're creating scores variable somewhere else from where you are
reading it. How do you know that the scores array will not have too
many entries or too few entries for what you are reading? Extra zeros
at the end are going effect the average calculation.
Here is a tip: display the values contained in scores, see if they are
correct.
Opalinski
opalpa@gmail.com
http://www.geocities.com/opalpaweb/
| |
| Michael 2006-01-23, 3:59 am |
| Thanks guys for all the input. I think I figured it almost all out. However
I have been trying to convert to one decimal place. I believe once I can
round my average variable up; it should then be right on the money. I have
been looking at DecimalFormat class; but unsure how to use its methods in my
class. Hehe I'll play around with it. Thanks again. :)
<opalpa@gmail.com> wrote in message
news:1137940715.625061.269180@g47g2000cwa.googlegroups.com...
> Your code is broken down akwardly. Folks have suggested that you make
> a function that takes as parameter numbers to be averaged and returns
> an average. Similarly make a function that returns numbers after
> reading them in. Having scores be a member variable and average be a
> member variable is poor practice.
>
> I think you're just learning (this is homework, right?).
>
> You're creating scores variable somewhere else from where you are
> reading it. How do you know that the scores array will not have too
> many entries or too few entries for what you are reading? Extra zeros
> at the end are going effect the average calculation.
>
> Here is a tip: display the values contained in scores, see if they are
> correct.
>
> Opalinski
> opalpa@gmail.com
> http://www.geocities.com/opalpaweb/
>
| |
| Ian Mills 2006-01-23, 7:05 pm |
| Michael wrote:
> Thanks guys for all the input. I think I figured it almost all out. However
> I have been trying to convert to one decimal place. I believe once I can
> round my average variable up; it should then be right on the money. I have
> been looking at DecimalFormat class; but unsure how to use its methods in my
> class. Hehe I'll play around with it. Thanks again. :)
> <opalpa@gmail.com> wrote in message
> news:1137940715.625061.269180@g47g2000cwa.googlegroups.com...
>
>
>
>
You may also want to look at BigDecimal instead of double as yhis allows
you to specify the decimals and also the rounding method.
| |
| Michael 2006-01-23, 9:57 pm |
| Hello thanks again. I have tried to implement BigDecimal objects into my
code. However now I get a worst outcome, then without the BigDecimal object
instantiated.
Before I entered.
mike 10 10 9.5 9.5
and got the following
Student's Name: mike
The average of the test mark scores is 9.5
now with BigDecimal object used I get
Student's Name: mike
The average of the test mark scores is 8
I get a worst result. How do you specify to want decimal place you want and
rounding method.
snippet;
void findAverage(){
int sum = 0;
for(int i = 0; i < scores.length;i++){
sum += scores[i];
}
if(scores.length > 0){
//average = (double)sum /(double) numberOfScores;
BigDecimal exactSum = new BigDecimal(sum);
System.out.println(sum);
System.out.println(exactSum);
BigDecimal exactNumber=new BigDecimal(scores.length);
BigDecimal exactAverage= exactSum.divide(exactNumber);
avg=exactAverage;
}else{
average = 0;
}
}
Thanks again.
cheers!
"Ian Mills" <news@siteone.free-online.co.uk> wrote in message
news:43d53a21$0$2685$ed2619ec@ptn-nntp-reader02.plus.net...
> Michael wrote:
>
> You may also want to look at BigDecimal instead of double as yhis allows
> you to specify the decimals and also the rounding method.
| |
| Ian Mills 2006-01-24, 7:06 pm |
| Michael wrote:
> Hello thanks again. I have tried to implement BigDecimal objects into my
> code. However now I get a worst outcome, then without the BigDecimal object
> instantiated.
> Before I entered.
> mike 10 10 9.5 9.5
> and got the following
> Student's Name: mike
>
> The average of the test mark scores is 9.5
>
> now with BigDecimal object used I get
>
> Student's Name: mike
>
> The average of the test mark scores is 8
>
> I get a worst result. How do you specify to want decimal place you want and
> rounding method.
>
> snippet;
>
> void findAverage(){
> int sum = 0;
>
>
> for(int i = 0; i < scores.length;i++){
> sum += scores[i];
> }
>
>
> if(scores.length > 0){
> //average = (double)sum /(double) numberOfScores;
> BigDecimal exactSum = new BigDecimal(sum);
> System.out.println(sum);
> System.out.println(exactSum);
> BigDecimal exactNumber=new BigDecimal(scores.length);
> BigDecimal exactAverage= exactSum.divide(exactNumber);
> avg=exactAverage;
> }else{
> average = 0;
> }
>
> }
>
> Thanks again.
>
> cheers!
>
> "Ian Mills" <news@siteone.free-online.co.uk> wrote in message
> news:43d53a21$0$2685$ed2619ec@ptn-nntp-reader02.plus.net...
>
>
>
>
It's all in the javadoc for BigDecimaland much mor besides) but
basically you define the scale and rounding method required when calling
the divide method.
e.g exactSum.divide(exactNumber,2,BigDecimal.ROUND_HALF_UP) would give
you an answer to 4 decimals rounding normally (<5 rounds down >= 5
rounds up)
| |
| opalpa@gmail.com opalinski from opalpaweb 2006-01-24, 7:06 pm |
| FYI: In one branch of your if you assign to "avg" -- three letters. In
second branch of your if you assign to "average"-more letters. avg and
average are different names and, assuming the above code compiled for
you, different types.
All the best Mike. Maybe, in the future, you'll come back to this
thread and notice advice which would have prevented this mistake.
Cheers. Enjoy exploring programming
Opalinski
opalpa@gmail.com
http://www.geocities.com/opalpaweb/
| |
| opalpa@gmail.com opalinski from opalpaweb 2006-01-24, 7:06 pm |
| btw, in the line that prints the average, are you using the correct
variable? I mean do you decide between avg and average?
Opalinski
opalpa@gmail.com
http://www.geocities.com/opalpaweb/
| |
| Michael 2006-01-24, 9:58 pm |
| Thanks guys; it is much apreciated. I finally got it to work right using
DecimalFormat Class. I ued average instead of avg. Thanks for pointing that
out. ttyl
<opalpa@gmail.com> wrote in message
news:1138136707.764387.83980@z14g2000cwz.googlegroups.com...
> btw, in the line that prints the average, are you using the correct
> variable? I mean do you decide between avg and average?
>
> Opalinski
> opalpa@gmail.com
> http://www.geocities.com/opalpaweb/
>
|
|
|
|
|