How to calculate using a for-loop with odd numbers and print only average

Viewed 98

I need some help with a problem.

Problem: Using a for loop, compute the average of the first 20 odd numbers. Print only the average.

I have figured out how to count the first 20 odd numbers in the for loop but I can't figure out how to get the average where it only prints the average. Right now it is printing the total of all the odd numbers of 400.

Any help would be greatly appreciative. Also, if you could explain in simple terms as I am a beginner. Thanks!

{
$avg=0
    for ($i =1 ; $i –le 39 ; $i+=2) {
    $avg = $avg +$i 
}
echo $avg
}
3 Answers

The average (or arithmetic mean) is defined as the sum of the data divided by the number of items in the data set.

therefore you must divide the final sum of odd numbers by two.

$sum=0

for ($i =1 ; $i –lt 20 ; $i+=2) {
    $sum = $sum + $i 
}

$avg = $sum / 20

echo $avg

To complement henry groves' helpful answer:

The Measure-Object cmdlet has an -Average switch that automatically calculates the average of all numbers it receives via the pipeline and reports it in the .Average property of the [Microsoft.PowerShell.Commands.GenericMeasureInfo] instance it outputs:

(
  & { for ($i =1 ; $i –le 39 ; $i+=2) { $i } } | Measure-Object -Average
).Average

This outputs 20. (To assign the result to variable $avg, simply prepend $avg = to the entire command.)

Note that for, as a language statement, cannot directly participate in a pipeline, hence its invocation via a script block ({ ... }) called with &.


As an aside:

For looping over a range of integers with an increment of 1 (or -1), PowerShell offers .., the convenient range operator; e.g. 1..3 is effectively the same as
for ($i=1; $i -le 3; ++$i) { $i }; 3..1 works analogously.

It would be great if .. also supported specifiable increments (stepping), such as 2 in your case, which isn't supported as of PowerShell 7.2.x.

GitHub issue #7928 proposes adding such support in the future, which could take the following form.

# WISHFUL THINKING as of PowerShell 7.2.x
# If implemented, would be the equivalent of:
#   for ($i =1 ; $i –le 39 ; $i += 2) { $i }
1..39..2

While there are many correct ways to solve a problem, let me give you a recommendation on your loop: As your task basically just consists of having 20 iterations, you should use a more readable and intuitive way to describe 20 iterations. Your loop could look like this, for example:

for ($i = 0; $i -lt 20; $i++) {
    $sum += 2 * $i + 1
}
$avg = $sum / 20
echo $avg

In programming/scripting you will encounter, that you most often start counting/indexing at 0. So my recommendation is: Get used to it, don't start at 1, if it is not necessary. Secondly, I define my iteration with default step size 1 and a break condition of $i -lt 20, which clearly contains 20, which we already know from your task. I could achieve the same result with $i -le 19, but then I would loose the direct relation to your task again.

Don't get me wrong, ($i =1 ; $i –le 39 ; $i+=2) is absolutely correct and deterministic with no randomness involved, but it is a little harder to understand than ($i = 0; $i -lt 20; $i++), for example.

You might ask now, why am I telling you all this? Well, there is the quite popular off-by-one error. And with your technique, you will sooner or later become a victim of this error. Maybe you already did while trying to develop your loop condition.

Related