Solution Review: Map Polar Points to Cartesian Points
This lesson discusses the solution to the challenge given in the previous lesson.
package main import ( "bufio" "fmt" "math" "os" "runtime" "strconv" "strings" ) type polar struct { radius, Θ float64 // greek character! } type cartesian struct { x, y float64 } const result = "Polar: radius=%.02f angle=%.02f degrees -- Cartesian: x=%.02f y=%.02f\n" var prompt = "Enter a radius and an angle (in degrees), e.g., 12.5 90, " + "or %s to quit." func init() { if runtime.GOOS == "windows" { prompt = fmt.Sprintf(prompt, "Ctrl+Z, Enter") } else { // Unix-like prompt = fmt.Sprintf(prompt, "Ctrl+C") } } func main() { questions := make(chan polar) defer close(questions) answers := createSolver(questions) defer close(answers) interact(questions, answers) } func createSolver(questions chan polar) chan cartesian { answers := make(chan cartesian) go func() { for { polarCoord := <-questions Θ := polarCoord.Θ * math.Pi / 180.0 // degrees to radians x := polarCoord.radius * math.Cos(Θ) y := polarCoord.radius * math.Sin(Θ) answers <- cartesian{x, y} } }() return answers } func interact(questions chan polar, answers chan cartesian) { reader := bufio.NewReader(os.Stdin) fmt.Println(prompt) for { fmt.Printf("Radius and angle: ") line, err := reader.ReadString('\n') if err != nil { break } line = line[:len(line)-1] // chop off newline character if numbers := strings.Fields(line); len(numbers) == 2 { polars, err := floatsToStrings(numbers) if err != nil { fmt.Fprintln(os.Stderr, "invalid number") continue } questions <- polar{polars[0], polars[1]} coord := <-answers fmt.Printf(result, polars[0], polars[1], coord.x, coord.y) } else { fmt.Fprintln(os.Stderr, "invalid input") } } fmt.Println() } func floatsToStrings(numbers []string) ([]float64, error) { var floats []float64 for _, number := range numbers { if x, err := strconv.ParseFloat(number, 64); err != nil { return nil, err } else { floats = append(floats, x) } } return floats, nil }
Get hands-on with 1400+ tech skills courses.