.. highlight:: go 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