// 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