Gopl 练习题题解

说明

本文解答GOPL的主要练习题

第一章

1.5 李萨如图形改颜色

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
package main

import (
"image"
"image/color"
"image/gif"
"io"
"math"
"math/rand"
"os"
)

//!+main

var palette = []color.Color{color.Black, color.RGBA{0x00,0xff,0x00,0xff}}

const (
blackIndex = 0 // first color in palette
greenIndex = 1 // next color in palette
)

func main() {
//!-main
// The sequence of images is deterministic unless we seed
// the pseudo-random number generator using the current time.
// Thanks to Randall McPherson for pointing out the omission.
rand.Seed(time.Now().UTC().UnixNano())

if len(os.Args) > 1 && os.Args[1] == "web" {
//!+http
handler := func(w http.ResponseWriter, r *http.Request) {
lissajous(w)
}
http.HandleFunc("/", handler)
//!-http
log.Fatal(http.ListenAndServe("localhost:8000", nil))
return
}
//!+main
lissajous(os.Stdout)
}

func lissajous(out io.Writer) {
const (
cycles = 5 // number of complete x oscillator revolutions
res = 0.001 // angular resolution
size = 100 // image canvas covers [-size..+size]
nframes = 64 // number of animation frames
delay = 8 // delay between frames in 10ms units
)
freq := rand.Float64() * 3.0 // relative frequency of y oscillator
anim := gif.GIF{LoopCount: nframes}
phase := 0.0 // phase difference
for i := 0; i < nframes; i++ {
rect := image.Rect(0, 0, 2*size+1, 2*size+1)
img := image.NewPaletted(rect, palette)
for t := 0.0; t < cycles*2*math.Pi; t += res {
x := math.Sin(t)
y := math.Sin(t*freq + phase)
img.SetColorIndex(size+int(x*size+0.5), size+int(y*size+0.5),
greenIndex)
}
phase += 0.1
anim.Delay = append(anim.Delay, delay)
anim.Image = append(anim.Image, img)
}
gif.EncodeAll(out, &anim) // NOTE: ignoring encoding errors
}

//!-main

1.6 李萨如图形多彩颜色

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
package main

import (
"image"
"image/color"
"image/gif"
"io"
"log"
"math"
"math/rand"
"net/http"
"os"
)

var palette = []color.Color{
color.Black,
color.White,
color.RGBA{0x00, 0xff, 0x00, 0xff},
color.RGBA{0xff, 0x00, 0x00, 0xff},
color.RGBA{0x00, 0xff, 0xff, 0xff},
color.RGBA{0x0f, 0xff, 0x07, 0xff},
color.RGBA{0xf0, 0xf8, 0x09, 0xff},
color.RGBA{0x09, 0xfa, 0xcb, 0xff},
color.RGBA{0x0b, 0xb7, 0xb9, 0xff},
color.RGBA{0xc5, 0xa1, 0xb2, 0xff},
}

func main(){
if len(os.Args)>1 && os.Args[1] == "web"{
handler := func(w http.ResponseWriter,r *http.Request){
lissajous(w)
}
http.HandleFunc("/",handler)
log.Fatal(http.ListenAndServe("localhost:8000",nil))
}
file, _:= os.Create("1.gif")
lissajous(file)
file.Close()
}
func lissajous(out io.Writer) {
const (
cycles = 5 // number of complete x oscillator revolutions
res = 0.001 // angular resolution
size = 100 // image canvas covers [-size..+size]
nframes = 64 // number of animation frames
delay = 8 // delay between frames in 10ms units
)
freq := rand.Float64() * 3.0 // relative frequency of y oscillator
anim := gif.GIF{LoopCount: nframes}
phase := 0.0 // phase difference
for i := 0; i < nframes; i++ {
rect := image.Rect(0, 0, 2*size+1, 2*size+1)
img := image.NewPaletted(rect, palette)
colorIndex := uint8(rand.Intn(10))
for t := 0.0; t < cycles*2*math.Pi; t += res {
x := math.Sin(t)
y := math.Sin(t*freq + phase)
img.SetColorIndex(size+int(x*size+0.5), size+int(y*size+0.5),
colorIndex)
}
phase += 0.1
anim.Delay = append(anim.Delay, delay)
anim.Image = append(anim.Image, img)
}
gif.EncodeAll(out, &anim) // NOTE: ignoring encoding errors
}

1.7 io.Copy(dst,src)

1
2
3
4
5
6
7
8
9
10
func main(){
for _, url := range os.Args[1:]{
resp,_ := http.Get(url)
//body,_ :=ioutil.ReadAll(resp.Body)
_,err := io.Copy(os.Stdout,resp.Body)
if err!= nil{fmt.Fprintln(os.Stderr,"copy error")}
resp.Body.Close()
//fmt.Printf("%s",body)
}
}

1.8 fetch加http://前缀

1
2
3
4
5
6
7
8
9
10
11
func main(){
for _, url := range os.Args[1:]{
if !strings.HasPrefix(url,"http://"){
url = "http://" + url
}
resp,_ := http.Get(url)
body,_ :=ioutil.ReadAll(resp.Body)
resp.Body.Close()
fmt.Printf("%s",body)
}
}

1.9 fetch 输出HTTP状态

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
func main(){
for _, url := range os.Args[1:]{
if !strings.HasPrefix(url,"http://"){
url = "http://" + url
}
resp,err := http.Get(url)
if err!=nil{
fmt.Fprintf(os.Stderr,"fetch: %v\n",err)
}
fmt.Println("HTTP Status:",resp.Status)
body,err :=ioutil.ReadAll(resp.Body)
if err!=nil{
fmt.Fprintf(os.Stderr,"fetch:reading %s:%v\n",url,err)
}
resp.Body.Close()
fmt.Printf("%s",body)
}
}