numstats2.goΒΆ

// numstats2.go

// To run at the command line:
//    $ go run numstats2.go

package main

import (
    "bufio"
    "fmt"
    "os"
    "sort"
    "strconv"
)

func sum(nums []int) int {
    result := 0
    for _, n := range nums {
        result += n
    }
    return result
}

func mean(nums []int) float64 {
    return float64(sum(nums)) / float64(len(nums))
}

func min(nums []int) int {
    if len(nums) == 0 {
        panic("can't take min of empty slice")
    }

    result := nums[0]
    for _, n := range nums[1:] {
        if n < result {
            result = n
        }
    }
    return result
}

func max(nums []int) int {
    if len(nums) == 0 {
        panic("can't take max of empty slice")
    }

    result := nums[0]
    for _, n := range nums[1:] {
        if n > result {
            result = n
        }
    }
    return result
}

func median(nums []int) int {
    n := len(nums)
    if n == 0 {
        panic("can't take median of empty slice")
    }
    // make a copy of nums
    tmp := make([]int, len(nums))
    copy(tmp, nums)
    sort.Ints(tmp)
    return tmp[n/2]
}

func main() {
    // numbers.txt is assumed to have one integer per line
    file, err := os.Open("numbers.txt")

    // deferred statements are run after the function ends, even if the
    // function ends unexpectedly (e.g. by a call to panic)
    defer file.Close()

    // if err is not nil, then something went wrong opening the file
    // and so we immediately end the program by calling panic
    if err != nil {
        panic("couldn't open numbers.txt")
    }

    // read all the numbers into a slice
    nums := []int{} // nums is initially empty
    scanner := bufio.NewScanner(file)
    for scanner.Scan() {
        line := scanner.Text()
        n, err := strconv.Atoi(line)
        if err == nil {
            nums = append(nums, n)
        } else { // err != nil
            fmt.Printf("Couldn't convert \"%v\" to an int (skipping)\n", line)
        }
    } // for

    //
    // print some statistics about the numbers
    //
    fmt.Println(nums)
    fmt.Printf("   min: %v\n", min(nums))
    fmt.Printf("  mean: %0.3v\n", mean(nums))
    fmt.Printf("median: %v\n", median(nums))
    fmt.Printf("   max: %v\n", max(nums))
    fmt.Println(nums)
} // main