| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110 |
- // statistics.go
- package main
- import (
- "fmt"
- "log"
- "net/http"
- "sort"
- "strconv"
- "strings"
- )
- type statistics struct {
- numbers []float64
- mean float64
- median float64
- }
- const form = `<html><body><form action="/" method="POST">
- <label for="numbers">Numbers (comma or space-separated):</label><br>
- <input type="text" name="numbers" size="30"><br />
- <input type="submit" value="Calculate">
- </form></html></body>`
- const error = `<p class="error">%s</p>`
- var pageTop = ""
- var pageBottom = ""
- func main() {
- http.HandleFunc("/", homePage)
- if err := http.ListenAndServe(":9001", nil); err != nil {
- log.Fatal("failed to start server", err)
- }
- }
- func homePage(writer http.ResponseWriter, request *http.Request) {
- writer.Header().Set("Content-Type", "text/html")
- err := request.ParseForm() // Must be called before writing response
- fmt.Fprint(writer, pageTop, form)
- if err != nil {
- fmt.Fprintf(writer, error, err)
- } else {
- if numbers, message, ok := processRequest(request); ok {
- stats := getStats(numbers)
- fmt.Fprint(writer, formatStats(stats))
- } else if message != "" {
- fmt.Fprintf(writer, error, message)
- }
- }
- fmt.Fprint(writer, pageBottom)
- }
- func processRequest(request *http.Request) ([]float64, string, bool) {
- var numbers []float64
- var text string
- if slice, found := request.Form["numbers"]; found && len(slice) > 0 {
- //处理如果网页中输入的是中文逗号
- if strings.Contains(slice[0], ",") {
- text = strings.Replace(slice[0], ",", " ", -1)
- } else {
- text = strings.Replace(slice[0], ",", " ", -1)
- }
- for _, field := range strings.Fields(text) {
- if x, err := strconv.ParseFloat(field, 64); err != nil {
- return numbers, "'" + field + "' is invalid", false
- } else {
- numbers = append(numbers, x)
- }
- }
- }
- if len(numbers) == 0 {
- return numbers, "", false // no data first time form is shown
- }
- return numbers, "", true
- }
- func getStats(numbers []float64) (stats statistics) {
- stats.numbers = numbers
- sort.Float64s(stats.numbers)
- stats.mean = sum(numbers) / float64(len(numbers))
- stats.median = median(numbers)
- return
- }
- func sum(numbers []float64) (total float64) {
- for _, x := range numbers {
- total += x
- }
- return
- }
- func median(numbers []float64) float64 {
- middle := len(numbers) / 2
- result := numbers[middle]
- if len(numbers)%2 == 0 {
- result = (result + numbers[middle-1]) / 2
- }
- return result
- }
- func formatStats(stats statistics) string {
- return fmt.Sprintf(`<table border="1">
- <tr><th colspan="2">Results</th></tr>
- <tr><td>Numbers</td><td>%v</td></tr>
- <tr><td>Count</td><td>%d</td></tr>
- <tr><td>Mean</td><td>%f</td></tr>
- <tr><td>Median</td><td>%f</td></tr>
- </table>`, stats.numbers, len(stats.numbers), stats.mean, stats.median)
- }
|