Solution Review: Map Polar Points to Cartesian Points
This lesson discusses the solution to the challenge given in the previous lesson.
We'll cover the following...
We'll cover the following...
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
}Click the RUN button, and wait for the terminal to start. Type go run main.go and press ENTER.
The above program includes two major structs:
-
polar: takes twofloat64variables as fields:radiusandθ. -
cartesian: takes twofloat64variables as fields:xandy.
Line 20 defines a constant result string for the formatted output, and line 22 defines a string prompt for the command-line. This program also shows the use of an init function (from ...