forked from adonovan/gopl.io
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
13 changed files
with
472 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
// Copyright © 2016 Alan A. A. Donovan & Brian W. Kernighan. | ||
// License: https://creativecommons.org/licenses/by-nc-sa/4.0/ | ||
|
||
// See page 8. | ||
//!+ | ||
|
||
// Dup1 prints the text of each line that appears more than | ||
// once in the standard input, preceded by its count. | ||
package main | ||
|
||
import ( | ||
"bufio" | ||
"fmt" | ||
"os" | ||
) | ||
|
||
func main() { | ||
counts := make(map[string]int) | ||
input := bufio.NewScanner(os.Stdin) | ||
for input.Scan() { | ||
counts[input.Text()]++ | ||
} | ||
// NOTE: ignoring potential errors from input.Err() | ||
for line, n := range counts { | ||
if n > 1 { | ||
fmt.Printf("%d\t%s\n", n, line) | ||
} | ||
} | ||
} | ||
|
||
//!- |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,48 @@ | ||
// Copyright © 2016 Alan A. A. Donovan & Brian W. Kernighan. | ||
// License: https://creativecommons.org/licenses/by-nc-sa/4.0/ | ||
|
||
// See page 10. | ||
//!+ | ||
|
||
// Dup2 prints the count and text of lines that appear more than once | ||
// in the input. It reads from stdin or from a list of named files. | ||
package main | ||
|
||
import ( | ||
"bufio" | ||
"fmt" | ||
"os" | ||
) | ||
|
||
func main() { | ||
counts := make(map[string]int) | ||
files := os.Args[1:] | ||
if len(files) == 0 { | ||
countLines(os.Stdin, counts) | ||
} else { | ||
for _, arg := range files { | ||
f, err := os.Open(arg) | ||
if err != nil { | ||
fmt.Fprintf(os.Stderr, "dup2: %v\n", err) | ||
continue | ||
} | ||
countLines(f, counts) | ||
f.Close() | ||
} | ||
} | ||
for line, n := range counts { | ||
if n > 1 { | ||
fmt.Printf("%d\t%s\n", n, line) | ||
} | ||
} | ||
} | ||
|
||
func countLines(f *os.File, counts map[string]int) { | ||
input := bufio.NewScanner(f) | ||
for input.Scan() { | ||
counts[input.Text()]++ | ||
} | ||
// NOTE: ignoring potential errors from input.Err() | ||
} | ||
|
||
//!- |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
// Copyright © 2016 Alan A. A. Donovan & Brian W. Kernighan. | ||
// License: https://creativecommons.org/licenses/by-nc-sa/4.0/ | ||
|
||
// See page 12. | ||
|
||
// Dup3 prints the count and text of lines that appear more than once | ||
// in the named input files. | ||
//!+ | ||
package main | ||
|
||
import ( | ||
"fmt" | ||
"io/ioutil" | ||
"os" | ||
"strings" | ||
) | ||
|
||
func main() { | ||
counts := make(map[string]int) | ||
for _, filename := range os.Args[1:] { | ||
data, err := ioutil.ReadFile(filename) | ||
if err != nil { | ||
fmt.Fprintf(os.Stderr, "dup3: %v\n", err) | ||
continue | ||
} | ||
for _, line := range strings.Split(string(data), "\n") { | ||
counts[line]++ | ||
} | ||
} | ||
for line, n := range counts { | ||
if n > 1 { | ||
fmt.Printf("%d\t%s\n", n, line) | ||
} | ||
} | ||
} | ||
|
||
//!- |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
// Copyright © 2016 Alan A. A. Donovan & Brian W. Kernighan. | ||
// License: https://creativecommons.org/licenses/by-nc-sa/4.0/ | ||
|
||
// See page 4. | ||
//!+ | ||
|
||
// Echo1 prints its command-line arguments. | ||
package main | ||
|
||
import ( | ||
"fmt" | ||
"os" | ||
) | ||
|
||
func main() { | ||
var s, sep string | ||
for i := 1; i < len(os.Args); i++ { | ||
s += sep + os.Args[i] | ||
sep = " " | ||
} | ||
fmt.Println(s) | ||
} | ||
|
||
//!- |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
// Copyright © 2016 Alan A. A. Donovan & Brian W. Kernighan. | ||
// License: https://creativecommons.org/licenses/by-nc-sa/4.0/ | ||
|
||
// See page 6. | ||
//!+ | ||
|
||
// Echo2 prints its command-line arguments. | ||
package main | ||
|
||
import ( | ||
"fmt" | ||
"os" | ||
) | ||
|
||
func main() { | ||
s, sep := "", "" | ||
for _, arg := range os.Args[1:] { | ||
s += sep + arg | ||
sep = " " | ||
} | ||
fmt.Println(s) | ||
} | ||
|
||
//!- |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
// Copyright © 2016 Alan A. A. Donovan & Brian W. Kernighan. | ||
// License: https://creativecommons.org/licenses/by-nc-sa/4.0/ | ||
|
||
// See page 8. | ||
|
||
// Echo3 prints its command-line arguments. | ||
package main | ||
|
||
import ( | ||
"fmt" | ||
"os" | ||
"strings" | ||
) | ||
|
||
//!+ | ||
func main() { | ||
fmt.Println(strings.Join(os.Args[1:], " ")) | ||
} | ||
|
||
//!- |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
// Copyright © 2016 Alan A. A. Donovan & Brian W. Kernighan. | ||
// License: https://creativecommons.org/licenses/by-nc-sa/4.0/ | ||
|
||
// See page 16. | ||
//!+ | ||
|
||
// Fetch prints the content found at a URL. | ||
package main | ||
|
||
import ( | ||
"fmt" | ||
"io/ioutil" | ||
"net/http" | ||
"os" | ||
) | ||
|
||
func main() { | ||
for _, url := range os.Args[1:] { | ||
resp, err := http.Get(url) | ||
if err != nil { | ||
fmt.Fprintf(os.Stderr, "fetch: %v\n", err) | ||
os.Exit(1) | ||
} | ||
b, err := ioutil.ReadAll(resp.Body) | ||
resp.Body.Close() | ||
if err != nil { | ||
fmt.Fprintf(os.Stderr, "fetch: reading %s: %v\n", url, err) | ||
os.Exit(1) | ||
} | ||
fmt.Printf("%s", b) | ||
} | ||
} | ||
|
||
//!- |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
// Copyright © 2016 Alan A. A. Donovan & Brian W. Kernighan. | ||
// License: https://creativecommons.org/licenses/by-nc-sa/4.0/ | ||
|
||
// See page 17. | ||
//!+ | ||
|
||
// Fetchall fetches URLs in parallel and reports their times and sizes. | ||
package main | ||
|
||
import ( | ||
"fmt" | ||
"io" | ||
"io/ioutil" | ||
"net/http" | ||
"os" | ||
"time" | ||
) | ||
|
||
func main() { | ||
start := time.Now() | ||
ch := make(chan string) | ||
for _, url := range os.Args[1:] { | ||
go fetch(url, ch) // start a goroutine | ||
} | ||
for range os.Args[1:] { | ||
fmt.Println(<-ch) // receive from channel ch | ||
} | ||
fmt.Printf("%.2fs elapsed\n", time.Since(start).Seconds()) | ||
} | ||
|
||
func fetch(url string, ch chan<- string) { | ||
start := time.Now() | ||
resp, err := http.Get(url) | ||
if err != nil { | ||
ch <- fmt.Sprint(err) // send to channel ch | ||
return | ||
} | ||
|
||
nbytes, err := io.Copy(ioutil.Discard, resp.Body) | ||
resp.Body.Close() // don't leak resources | ||
if err != nil { | ||
ch <- fmt.Sprintf("while reading %s: %v", url, err) | ||
return | ||
} | ||
secs := time.Since(start).Seconds() | ||
ch <- fmt.Sprintf("%.2fs %7d %s", secs, nbytes, url) | ||
} | ||
|
||
//!- |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,7 +1,16 @@ | ||
// Copyright © 2016 Alan A. A. Donovan & Brian W. Kernighan. | ||
// License: https://creativecommons.org/licenses/by-nc-sa/4.0/ | ||
|
||
// See page 1. | ||
|
||
// Helloworld is our first Go program. | ||
//!+ | ||
package main | ||
|
||
import "fmt" | ||
|
||
func main() { | ||
fmt.Println("Hello, 世界") | ||
} | ||
|
||
//!- |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,77 @@ | ||
// Copyright © 2016 Alan A. A. Donovan & Brian W. Kernighan. | ||
// License: https://creativecommons.org/licenses/by-nc-sa/4.0/ | ||
|
||
// Run with "web" command-line argument for web server. | ||
// See page 13. | ||
//!+main | ||
|
||
// Lissajous generates GIF animations of random Lissajous figures. | ||
package main | ||
|
||
import ( | ||
"image" | ||
"image/color" | ||
"image/gif" | ||
"io" | ||
//!-main | ||
"log" | ||
//!+main | ||
"math" | ||
"math/rand" | ||
//!-main | ||
"net/http" | ||
//!+main | ||
"os" | ||
) | ||
|
||
var palette = []color.Color{color.White, color.Black} | ||
|
||
const ( | ||
whiteIndex = 0 // first color in palette | ||
blackIndex = 1 // next color in palette | ||
) | ||
|
||
func main() { | ||
//!-main | ||
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), | ||
blackIndex) | ||
} | ||
phase += 0.1 | ||
anim.Delay = append(anim.Delay, delay) | ||
anim.Image = append(anim.Image, img) | ||
} | ||
gif.EncodeAll(out, &anim) // NOTE: ignoring encoding errors | ||
} | ||
|
||
//!-main |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
// Copyright © 2016 Alan A. A. Donovan & Brian W. Kernighan. | ||
// License: https://creativecommons.org/licenses/by-nc-sa/4.0/ | ||
|
||
// See page 19. | ||
//!+ | ||
|
||
// Server1 is a minimal "echo" server. | ||
package main | ||
|
||
import ( | ||
"fmt" | ||
"log" | ||
"net/http" | ||
) | ||
|
||
func main() { | ||
http.HandleFunc("/", handler) // each request calls handler | ||
log.Fatal(http.ListenAndServe("localhost:8000", nil)) | ||
} | ||
|
||
// handler echoes the Path component of the request URL r. | ||
func handler(w http.ResponseWriter, r *http.Request) { | ||
fmt.Fprintf(w, "URL.Path = %q\n", r.URL.Path) | ||
} | ||
|
||
//!- |
Oops, something went wrong.