From 6135f628b7af9e1d6933908776d54eb6a2f336b7 Mon Sep 17 00:00:00 2001 From: Michael Manring Date: Sat, 21 May 2022 10:38:19 +0700 Subject: Improve input handling and add option to start http.Server to show the result --- challenge-165/pokgopun/go/ch-1.go | 136 +++++++++++++++++++++++++------------- 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 -### 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, ` +func (svg Svg) output(w io.Writer) { + bw := bufio.NewWriter(w) + fmt.Fprintf(bw, ` - `, data.height*2, data.width*2) - for _, l := range data.lines { - fmt.Fprintf(w, ``, l.start.x, l.end.x, l.start.y, l.end.y) + `, svg.height*2, svg.width*2) + for _, l := range svg.lines { + fmt.Fprintf(bw, ``, l.start.x, l.end.x, l.start.y, l.end.y) } - w.WriteString(``) - for _, p := range data.points { - fmt.Fprintf(w, ``, p.x, p.y) + bw.WriteString(``) + for _, p := range svg.points { + fmt.Fprintf(bw, ``, p.x, p.y) } - w.WriteString(``) - w.Flush() + bw.WriteString(``) + 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 -- cgit