Server-Side Scripting/Arrays/Go
Appearance
routes/lesson6.go
[edit | edit source]// This program reads a user-selected text file of countries
// and Celsius temperatures. It displays the data in Celsius
// and Fahrenheit sorted in descending order by temperature.
//
// File format:
// Country,MaximumTemperature
// Bulgaria,45.2 °C
// Canada,45 °C
//
// References:
// https://www.mathsisfun.com/temperature-conversion.html
// https://golang.org/doc/
// https://tutorialedge.net/golang/go-file-upload-tutorial/
// https://golangbyexample.com/append-slice-array-golang/
package routes
import (
"html/template"
"io/ioutil"
"net/http"
"mime/multipart"
"path/filepath"
"sort"
"strconv"
"strings"
)
func Lesson6(response http.ResponseWriter, request *http.Request) {
response.Header().Set("Content-Type", "text/html; charset=utf-8")
type Data struct {
Table template.HTML
}
result := ""
switch request.Method {
case "GET":
result = ""
case "POST":
file, handler, err := request.FormFile("file")
result = "<h2>" + handler.Filename + "</h2>"
if err != nil {
result += err.Error()
} else {
result += processFile6(file);
}
default:
result = "Unexpected request method: " + request.Method
}
data := Data{template.HTML(result)}
path := filepath.Join("templates", "lesson6.html")
parsed, _ := template.ParseFiles(path)
parsed.Execute(response, data)
}
func processFile6(file multipart.File) string {
bytes, err := ioutil.ReadAll(file)
if (err != nil) {
return err.Error()
}
text := string(bytes)
text = strings.TrimSpace(text)
lines := strings.Split(text, "\n")
if strings.Index(lines[0], "Country,MaximumTemperature") == 0 {
// remove heading line
lines = lines[1:]
}
var table [][]string
for _, line := range lines {
slice := processLine6(line)
table = append(table, slice)
}
sort.Slice(table, func(a, b int) bool {
return table[a][1] > table[b][1]
})
result := formatTable6(table)
return result
}
func processLine6(line string) []string {
slice := strings.Split(line, ",")
if len(slice) != 2 {
return []string{"Invalid file format: " + line, "", ""}
}
index := strings.Index(slice[1], " °C")
if index < 0 {
return []string{"Invalid file format: " + line, "", ""}
}
celsius, err := strconv.ParseFloat(slice[1][0:index], 64)
if err != nil {
return []string{err.Error(), "", ""}
}
slice[1] = strconv.FormatFloat(celsius, 'f', 1, 64)
fahrenheit := celsius * 9 / 5 + 32
slice = append(slice, strconv.FormatFloat(fahrenheit, 'f', 1, 64))
return slice
}
func formatTable6(table [][]string) string {
result := "<table><tr><th>Country</th>"
result += "<th>Celsius</th><th>Fahrenheit</th></tr>"
for _, slice := range table {
result += "<tr><td>" + slice[0] + "</td>"
result += "<td>" + slice[1] + "° C</td>"
result += "<td>" + slice[2] + "° F</td></tr>"
}
result += "</table>"
return result
}
templates/lesson6.html
[edit | edit source]<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Lesson 6</title>
<link rel="stylesheet" href="styles.css">
<style>
p {
min-height: 1em;
}
</style>
</head>
<body>
<h1>Temperature Conversion</h1>
<p>Select a file of Celsius temperatures for conversion:</p>
<form method="POST" enctype="multipart/form-data">
<input type="file" id="file" name="file">
<input type="submit">
</form>
{{.Table}}
</body>
</html>
Try It
[edit | edit source]See Server-Side Scripting/Routes and Templates/Go to create a test environment.