diff options
| author | Michael Manring <michael@manring> | 2022-05-21 10:38:19 +0700 |
|---|---|---|
| committer | Michael Manring <michael@manring> | 2022-05-22 08:48:14 +0700 |
| commit | 6135f628b7af9e1d6933908776d54eb6a2f336b7 (patch) | |
| tree | 6d5fe1b1579803b2b35217194847a1e8eda88d1d | |
| parent | 7e035a8e8d9342dc33f33a68cae10acfd972aea2 (diff) | |
| download | perlweeklychallenge-club-6135f628b7af9e1d6933908776d54eb6a2f336b7.tar.gz perlweeklychallenge-club-6135f628b7af9e1d6933908776d54eb6a2f336b7.tar.bz2 perlweeklychallenge-club-6135f628b7af9e1d6933908776d54eb6a2f336b7.zip | |
Improve input handling and add option to start http.Server to show the result
| -rw-r--r-- | challenge-165/pokgopun/go/ch-1.go | 136 | ||||
| -rw-r--r-- | challenge-165/pokgopun/go/ch-2.go | 30 |
2 files changed, 106 insertions, 60 deletions
diff --git a/challenge-165/pokgopun/go/ch-1.go b/challenge-165/pokgopun/go/ch-1.go index cace8187e2..d8caec8cf2 100644 --- a/challenge-165/pokgopun/go/ch-1.go +++ b/challenge-165/pokgopun/go/ch-1.go @@ -3,28 +3,37 @@ go run ch-1.go -Enter 'x1,y1' for a point or 'x1,y1,x2,y2' for a line, or '0' to end this +Enter 'x1,y1' for a point or 'x1,y1,x2,y2' for a line, or 'done' when done 53,10 53,10,23,30 23,30 -0 +done <?xml version="1.0" encoding="UTF-8" standalone="yes"?> <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.0//EN" "http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd"> <svg height="60.000000" width="106.000000" xmlns="http://www.w3.org/2000/svg" xmlns:svg="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"> <g id="lines" stroke="#369" stroke-width="4"><line x1="53.000000" x2="23.000000" y1="10.000000" y2="30.000000" /></g><g fill="#f73" id="points"><circle cx="53.000000" cy="10.000000" r="3" /><circle cx="23.000000" cy="30.000000" r="3" /></g></svg> -### Pass points and line data via STDIN and output to file ch-1.svg: +### Pass point and line data via STDIN and output to file ch-1.svg: + +echo -e "53,10\n53,10,23,30\n23,30" | go run ch-1.go ch-1.svg + +### Pass point and line data via STDIN and start http.Server at localhost:8080 to show the result: + +go run ch-2.go | go run ch-1.go :8080 -echo -e "53,10\n53,10,23,30\n23,30\n0" | go run ch-1.go ch-1.svg */ package main import ( "bufio" + "bytes" "fmt" "io" "log" + "net/http" "os" + "regexp" + "time" ) type point struct{ x, y float64 } @@ -54,54 +63,89 @@ func (svg *Svg) updateHW() { } } -func (svg *Svg) input() { - var x1, y1, x2, y2 float64 - guide := "Enter 'x1,y1' for a point or 'x1,y1,x2,y2' for a line, or '0' to end this" - //fmt.Println(guide) - for { - n, err := fmt.Scanf("%f,%f,%f,%f\n", &x1, &y1, &x2, &y2) - //fmt.Println("n =>", n, "err =>", err) - switch n { - case 2: - svg.points = append(svg.points, point{x1, y1}) - case 4: - svg.lines = append(svg.lines, line{point{x1, y1}, point{x2, y2}}) - default: - if err == io.EOF || n == 1 && x1 == 0 { - goto done +func (svg *Svg) input(r io.Reader) { + var ( + x1, y1, x2, y2 float64 + text string + ) + guide := "Enter 'x1,y1' for a point or 'x1,y1,x2,y2' for a line, or 'done' when done" + scanner := bufio.NewScanner(r) + for scanner.Scan() { + text = scanner.Text() + if text == "done" { + break + } else { + n, err := fmt.Sscanf(text, "%f,%f,%f,%f\n", &x1, &y1, &x2, &y2) + if err != nil { + _, err := fmt.Sscanf(text, "%f,%f\n", &x1, &y1) + if err != nil { + fmt.Fprintln(os.Stderr, guide) + continue + } + } + if n == 4 { + svg.lines = append(svg.lines, line{point{x1, y1}, point{x2, y2}}) + } else { + svg.points = append(svg.points, point{x1, y1}) } - fmt.Fprintln(os.Stderr, guide) - continue } - //fmt.Println("svg =>", svg) } -done: + svg.updateHW() } -func main() { - w := bufio.NewWriter(os.Stdout) - if len(os.Args) > 1 { - f, err := os.Create(os.Args[1]) - if err != nil { - log.Fatal(err) - } - defer f.Close() - w = bufio.NewWriter(f) - } - var data Svg - data.input() - data.updateHW() - //fmt.Println(data.height, data.width) - fmt.Fprintf(w, `<?xml version="1.0" encoding="UTF-8" standalone="yes"?> +func (svg Svg) output(w io.Writer) { + bw := bufio.NewWriter(w) + fmt.Fprintf(bw, `<?xml version="1.0" encoding="UTF-8" standalone="yes"?> <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.0//EN" "http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd"> <svg height="%f" width="%f" xmlns="http://www.w3.org/2000/svg" xmlns:svg="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"> - <g id="lines" stroke="#369" stroke-width="4">`, data.height*2, data.width*2) - for _, l := range data.lines { - fmt.Fprintf(w, `<line x1="%f" x2="%f" y1="%f" y2="%f" />`, l.start.x, l.end.x, l.start.y, l.end.y) + <g id="lines" stroke="#369" stroke-width="4">`, svg.height*2, svg.width*2) + for _, l := range svg.lines { + fmt.Fprintf(bw, `<line x1="%f" x2="%f" y1="%f" y2="%f" />`, l.start.x, l.end.x, l.start.y, l.end.y) } - w.WriteString(`</g><g fill="#f73" id="points">`) - for _, p := range data.points { - fmt.Fprintf(w, `<circle cx="%f" cy="%f" r="3" />`, p.x, p.y) + bw.WriteString(`</g><g fill="#f73" id="points">`) + for _, p := range svg.points { + fmt.Fprintf(bw, `<circle cx="%f" cy="%f" r="3" />`, p.x, p.y) } - w.WriteString(`</g></svg>`) - w.Flush() + bw.WriteString(`</g></svg>`) + bw.Flush() +} + +func (svg Svg) ServeHTTP(w http.ResponseWriter, r *http.Request) { + buf := bytes.NewBuffer([]byte{}) + svg.output(buf) + w.Write(buf.Bytes()) + //w.Write([]byte(fmt.Sprint(time.Now()))) +} + +func main() { + var data Svg + data.input(os.Stdin) + if len(os.Args) > 1 { + out := os.Args[1] + if regexp.MustCompile(`^:\d+$`).MatchString(out) { + s := http.Server{ + Addr: out, + ReadTimeout: 30 * time.Second, + WriteTimeout: 90 * time.Second, + IdleTimeout: 120 * time.Second, + Handler: data, + } + fmt.Printf("Start http.Server at localhost%s to show the result\n", out) + err := s.ListenAndServe() + if err != nil { + if err != http.ErrServerClosed { + panic(err) + } + } + } else { + w, err := os.Create(out) + if err != nil { + log.Fatal(err) + } + defer w.Close() + data.output(w) + } + } else { + data.output(os.Stdout) + } + } diff --git a/challenge-165/pokgopun/go/ch-2.go b/challenge-165/pokgopun/go/ch-2.go index a3d0d9c451..93c868bc33 100644 --- a/challenge-165/pokgopun/go/ch-2.go +++ b/challenge-165/pokgopun/go/ch-2.go @@ -1,8 +1,12 @@ /* -### To pipe output to ch1.go to create svg file +### Pass output to ch-1.go to create svg file go run ch-2.go | go run ch-1.go ch-2.svg +### Pass output to ch-1.go and start http.Server at localhost:8080 to show the result: + +go run ch-2.go | go run ch-1.go :8080 + */ package main @@ -11,7 +15,7 @@ import ( "fmt" "log" "os" - "regexp" + "strings" ) func main() { @@ -24,18 +28,24 @@ func main() { 215,136 153,137 390,104 100,180 76,188 77,181 69,195 92,186 275,96 250,147 34,174 213,134 186,129 189,154 361,82 363,89` /**/ - var ds struct{ count, x, y, sumx, sumy, sumxx, sumxy, m, b, x1, x2, y1, y2 float64 } + var ds struct { + count, x, y, sumx, sumy, sumxx, sumxy, m, b, x1, x2, y1, y2 float64 + xy string + } _, err := fmt.Sscanf(rawin, "%f,%f %f,%f", &ds.x1, &ds.y1, &ds.x2, &ds.y2) if err != nil { log.Fatal(err) } w := bufio.NewWriter(os.Stdout) - for _, v := range regexp.MustCompile(`\d+,\d+`).FindAllString(rawin, -1) { - _, err := fmt.Sscanf(v, "%f,%f", &ds.x, &ds.y) + scanner := bufio.NewScanner(strings.NewReader(rawin)) + scanner.Split(bufio.ScanWords) + for scanner.Scan() { + ds.xy = scanner.Text() + _, err := fmt.Sscanf(ds.xy, "%f,%f", &ds.x, &ds.y) if err != nil { log.Fatal(err) } - fmt.Fprintln(w, v) + fmt.Fprintln(w, ds.xy) ds.count++ ds.sumx += ds.x ds.sumy += ds.y @@ -47,14 +57,6 @@ func main() { if ds.x2 < ds.x { ds.x2 = ds.x } - /* - if ds.y1 > ds.y { - ds.y1 = ds.y - } - if ds.y2 < ds.y { - ds.y2 = ds.y - } - */ } ds.m = (ds.count*ds.sumxy - ds.sumx*ds.sumy) / (ds.count*ds.sumxx - ds.sumx*ds.sumx) ds.b = (ds.sumy - ds.m*ds.sumx) / ds.count |
