0

I'm working through "The Swift Programming Language" and the associated playground file.

I have one section where I am asked: Write a function that calculates the average of its arguments.

Given the context, this is my solution

func averageOf(numbers: Int...) -> Int {
    var sum = 0
    var countOfNumbers = 0
    for number in numbers {
        sum += number
        countOfNumbers += 1
    }
    var result: Double = Double(sum) / Double(countOfNumbers)
    return result
}

averageOf()
averageOf(10, 20, 30)

As you can see I had to call the result as a Double (thats the sum / countOfNumbers).

However, I can't return result in this case because I get an error about converting return expression of type "Double".

So then I tried to return Double(result) without success.

Why does this not work and how can I best understand what I am doing wrong here?

Dan Beaulieu
  • 19,406
  • 19
  • 101
  • 135
mutantChickenHer0
  • 223
  • 1
  • 4
  • 14
  • not variadic arguments but I think you should take a look at http://stackoverflow.com/questions/28288148/making-my-function-calculate-average-of-array/28288619#28288619 – Leo Dabus Jan 21 '16 at 23:46

4 Answers4

3

Just looking at your code (and not giving you another, out of many neat ways, to calculate this): your function expects return type Int, but you return Double.

Below follows your code with commented corrections:

func averageOf(numbers: Int...) -> Double {
    var sum = 0                  // ^ note the return type here
    var countOfNumbers = 0
    for number in numbers {
        sum += number
        countOfNumbers += 1
    }
    /* Note here: you declare 'result' to be of type Double */
    var result: Double = Double(sum) / Double(countOfNumbers)
    return result /* and return 'result'; hence returning a Double */
}

averageOf(10, 20, 30) // 20.0 <-- a Double
dfrib
  • 70,367
  • 12
  • 127
  • 192
  • 1
    no need for the `var countOfNumbers` you can access `numbers.count`. – Leo Dabus Jan 21 '16 at 23:48
  • A single line would do it all `return Double(numbers.reduce(0, combine: +)) / Double(numbers.count)` – Leo Dabus Jan 21 '16 at 23:49
  • Thank you - I suppose these are the difficulties a novice will face having only "programmed" in python. – mutantChickenHer0 Jan 21 '16 at 23:50
  • 2
    @LeoDabus Thanks for feedback; although this is just a minimal fix to describe to OP why his original code didn't work. (Note my statement/disclaimer: _"and not giving you another, out of many neat ways, to calculate this"_). Since OP is working out the first parts of Swift Programming Language, I think it'd be best to wait with the functional approach, for now :) – dfrib Jan 21 '16 at 23:50
  • 1
    @mutantChickenHer0 Happy to help. Welcome to Swift! – dfrib Jan 21 '16 at 23:50
  • 2
    @mutantChickenHer0 Note also the comments here by Leo Dabus, in particular the first one (and look at the second one once you feel a bit more comfortable with swift!): you needn't actually count the number of variadic parameters, but can get this number using the `.count` property; so after your loop, `countOfNumbers` has the same value as this pre-existing property, `numbers.count`. – dfrib Jan 21 '16 at 23:54
1

If you look at your function definition, it is return an Int (the return parameter is after the ->.

func averageOf(numbers: Int...) -> Int

Change it to Double if you want to return the Double or cast your result to an Int before returning

Laurent Rivard
  • 509
  • 4
  • 13
1

In Swift 3...

Using variadic parameter:

func averageOf(_ n: Int...) -> Double {
    return Double(n.reduce(0, +)) / Double(n.count)
}

averageOf() // nan
averageOf(0) // 0
averageOf(1, 2, 3, 4) // 2.5

Using array parameter (guarding for empty array):

func averageOf(_ n: [Int]) -> Double {
    guard n.count > 0 else { return 0 }
    return Double(n.reduce(0, +)) / Double(n.count)
}

averageOf([Int]()) // 0
averageOf([1, 2, 3, 4]) // 2.5
Scott Gardner
  • 8,603
  • 1
  • 44
  • 36
0

Your function is declared as returning an Int:

func averageOf(numbers: Int...) -> Int {

You can't return a Double because it doesn't match this signature. You could either convert back to an Int before returning, or change the function signature.

jtbandes
  • 115,675
  • 35
  • 233
  • 266