Reputation: 147
I am trying to write a function to calculate the average in a simple math app. I am not getting any errors at all, but the code output is not showing up in the right sidebar in my Xcode playground. It outputs the two zeros in my code and stops there. Any thoughts on what's wrong?
func averageOf(numbers: Int...) -> Float {
var sum = 0
var numberTotal = 0
for number in numbers {
sum += number
numberTotal = numbers.count
}
return Float(sum / numberTotal)
}
averageOf()
averageOf(10, 56, 75, 90, 109)
Upvotes: 1
Views: 5943
Reputation: 1
func average(numbers: Int...) -> Float {
var sum = 0
var numberTotal = 0
for number in numbers {
sum += number
numberTotal = numbers.count
}
return Float(sum) / Float(numberTotal)
}
average(numbers: 5, 5, 5)
// this seemed to have worked
Upvotes: 0
Reputation: 70185
Of course, except as a learning exercise, averageOf()
is best implemented reusing existing functionality as:
func averageOf(_ head: Int, rest: Int...) -> Double {
return Double (rest.reduce (head, combine: +)) / Double (1 + rest.count)
}
27> averageOf (1, 2, 3)
$R6: Double = 2
The above avoids the 'how do you average no numbers' problem by requiring one argument. You also will want to be careful about your division use:
33> Double (3/2)
$R9: Double = 1
34> Double(3)/Double(2)
$R10: Double = 1.5
Also, the usefulness of optional arguments created with ...
is limited until there is an apply()
function like
var theAverage = apply (averageOf, someGiantArrayOfInts)
Upvotes: 3
Reputation: 7814
When you call averageOf()
, it seems to cause the playground to crash (division by zero, because numberTotal
is 0
).
For instance, if you called it like this:
averageOf(10, 56, 75, 90, 109)
averageOf(10, 20, 30)
averageOf()
averageOf(10, 20, 30)
you would get an output for the first two calls, but not for the second two.
UPDATE 3 (credits to @wumm) If you clicked on any of variables on the right panels or opened an assistant editor , you would see the error (rather strange one, though):
Playground execution failed: error: Execution was interrupted, reason: EXC_BAD_INSTRUCTION (code=EXC_I386_INVOP, subcode=0x0).
The process has been left at the point where it was interrupted, use "thread return -x" to return to the state before expression evaluation.
* thread #1: tid = 0x1c4a02, 0x000000010aff7e14, queue = 'com.apple.main-thread', stop reason = EXC_BAD_INSTRUCTION (code=EXC_I386_INVOP, subcode=0x0)
* frame #0: 0x000000010aff7e14
The solution is to check numberTotal in the end. And, by the way, there is no need to assign it inside the loop :) Here is a fixed version:
UPDATE: cheching numberTotal in the beginning is more reasonable indeed (credits to @kovpas):
UPDATE 2: changed the return
part. Credits to `@MartinR.
func averageOf(numbers: Int...) -> Float {
var numberTotal = numbers.count
if numberTotal == 0 {
return 0
}
var sum = 0
for number in numbers {
sum += number
}
return Float(sum)/Float(numberTotal)
}
averageOf(10, 56, 75, 90, 109)
averageOf(10, 20, 30)
averageOf()
averageOf(10, 20, 30)
Upvotes: 3
Reputation: 9593
You should first check if your array contains numbers. Otherwise you divide by 0.
func averageOf(numbers: Int...) -> Float {
if numbers.count == 0 {
return 0
}
var sum = 0
for number in numbers {
sum += number
}
return Float(sum / numbers.count)
}
Upvotes: 1