add: calculator example to x-tba
This commit is contained in:
16
x-tba/foundations/calc/01-shortdecl-int-conv/main.go
Normal file
16
x-tba/foundations/calc/01-shortdecl-int-conv/main.go
Normal file
@ -0,0 +1,16 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
func main() {
|
||||
// lesson: multi-return funcs, %v, and _
|
||||
|
||||
a, _ := strconv.Atoi(os.Args[1])
|
||||
b, _ := strconv.Atoi(os.Args[2])
|
||||
|
||||
fmt.Printf("%v + %v = %v\n", a, b, a+b)
|
||||
}
|
21
x-tba/foundations/calc/02-if/main.go
Normal file
21
x-tba/foundations/calc/02-if/main.go
Normal file
@ -0,0 +1,21 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
func main() {
|
||||
// lesson: if
|
||||
|
||||
if len(os.Args) != 3 {
|
||||
fmt.Println("Usage: calc <number1> <number2>")
|
||||
return
|
||||
}
|
||||
|
||||
a, _ := strconv.Atoi(os.Args[1])
|
||||
b, _ := strconv.Atoi(os.Args[2])
|
||||
|
||||
fmt.Printf("%v + %v = %v\n", a, b, a+b)
|
||||
}
|
21
x-tba/foundations/calc/03-floats-conv/main.go
Normal file
21
x-tba/foundations/calc/03-floats-conv/main.go
Normal file
@ -0,0 +1,21 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
func main() {
|
||||
// lesson: floats encompass integers too
|
||||
|
||||
if len(os.Args) != 3 {
|
||||
fmt.Println("Usage: calc <number1> <number2>")
|
||||
return
|
||||
}
|
||||
|
||||
a, _ := strconv.ParseFloat(os.Args[1], 64)
|
||||
b, _ := strconv.ParseFloat(os.Args[2], 64)
|
||||
|
||||
fmt.Printf("%v + %v = %v\n", a, b, a+b)
|
||||
}
|
30
x-tba/foundations/calc/04-error-handling/main.go
Normal file
30
x-tba/foundations/calc/04-error-handling/main.go
Normal file
@ -0,0 +1,30 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
func main() {
|
||||
// lesson: error handling + short decl. assignment
|
||||
|
||||
if len(os.Args) != 3 {
|
||||
fmt.Println("Usage: calc <number1> <number2>")
|
||||
return
|
||||
}
|
||||
|
||||
a, err := strconv.ParseFloat(os.Args[1], 64)
|
||||
if err != nil {
|
||||
fmt.Println("Please provide a valid number")
|
||||
return
|
||||
}
|
||||
|
||||
b, err := strconv.ParseFloat(os.Args[2], 64)
|
||||
if err != nil {
|
||||
fmt.Println("Please provide a valid number")
|
||||
return
|
||||
}
|
||||
|
||||
fmt.Printf("%v + %v = %v\n", a, b, a+b)
|
||||
}
|
46
x-tba/foundations/calc/05-switch/main.go
Normal file
46
x-tba/foundations/calc/05-switch/main.go
Normal file
@ -0,0 +1,46 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
func main() {
|
||||
// lesson: switch
|
||||
|
||||
if len(os.Args) != 4 {
|
||||
fmt.Println("Usage: calc <number1> <operator> <number2>")
|
||||
return
|
||||
}
|
||||
|
||||
a, err := strconv.ParseFloat(os.Args[1], 64)
|
||||
if err != nil {
|
||||
fmt.Println("Please provide a valid number")
|
||||
return
|
||||
}
|
||||
|
||||
b, err := strconv.ParseFloat(os.Args[3], 64)
|
||||
if err != nil {
|
||||
fmt.Println("Please provide a valid number")
|
||||
return
|
||||
}
|
||||
|
||||
var (
|
||||
op = os.Args[2]
|
||||
res float64
|
||||
)
|
||||
|
||||
switch op {
|
||||
case "+":
|
||||
res = a + b
|
||||
case "-":
|
||||
res = a - b
|
||||
case "*":
|
||||
res = a * b
|
||||
case "/":
|
||||
res = a / b
|
||||
}
|
||||
|
||||
fmt.Printf("%v %v %v = %v\n", a, op, b, res)
|
||||
}
|
49
x-tba/foundations/calc/06-switch/main.go
Normal file
49
x-tba/foundations/calc/06-switch/main.go
Normal file
@ -0,0 +1,49 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
func main() {
|
||||
// lesson: switch default + multiple case
|
||||
|
||||
if len(os.Args) != 4 {
|
||||
fmt.Println("Usage: calc <number1> <operator> <number2>")
|
||||
return
|
||||
}
|
||||
|
||||
a, err := strconv.ParseFloat(os.Args[1], 64)
|
||||
if err != nil {
|
||||
fmt.Println("Please provide a valid number")
|
||||
return
|
||||
}
|
||||
|
||||
b, err := strconv.ParseFloat(os.Args[3], 64)
|
||||
if err != nil {
|
||||
fmt.Println("Please provide a valid number")
|
||||
return
|
||||
}
|
||||
|
||||
var (
|
||||
op = os.Args[2]
|
||||
res float64
|
||||
)
|
||||
|
||||
switch op {
|
||||
case "+", "plus":
|
||||
op, res = "+", a+b
|
||||
case "-", "minus":
|
||||
op, res = "-", a-b
|
||||
case "*", "times":
|
||||
op, res = "*", a*b
|
||||
case "/", "div":
|
||||
op, res = "/", a/b
|
||||
default:
|
||||
fmt.Println("Please provide a valid operation.")
|
||||
return
|
||||
}
|
||||
|
||||
fmt.Printf("%v %v %v = %v\n", a, op, b, res)
|
||||
}
|
51
x-tba/foundations/calc/07/main.go
Normal file
51
x-tba/foundations/calc/07/main.go
Normal file
@ -0,0 +1,51 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
func main() {
|
||||
// lesson: modulo operator and type conversion
|
||||
|
||||
if len(os.Args) != 4 {
|
||||
fmt.Println("Usage: calc <number1> <operator> <number2>")
|
||||
return
|
||||
}
|
||||
|
||||
a, err := strconv.ParseFloat(os.Args[1], 64)
|
||||
if err != nil {
|
||||
fmt.Println("Please provide a valid number")
|
||||
return
|
||||
}
|
||||
|
||||
b, err := strconv.ParseFloat(os.Args[3], 64)
|
||||
if err != nil {
|
||||
fmt.Println("Please provide a valid number")
|
||||
return
|
||||
}
|
||||
|
||||
var (
|
||||
op = os.Args[2]
|
||||
res float64
|
||||
)
|
||||
|
||||
switch op {
|
||||
case "+", "plus":
|
||||
op, res = "+", a+b
|
||||
case "-", "minus":
|
||||
op, res = "-", a-b
|
||||
case "*", "times":
|
||||
op, res = "*", a*b
|
||||
case "/", "div":
|
||||
op, res = "/", a/b
|
||||
case "%", "mod":
|
||||
res = float64(int(a) % int(b))
|
||||
default:
|
||||
fmt.Println("Please provide a valid operation.")
|
||||
return
|
||||
}
|
||||
|
||||
fmt.Printf("%v %v %v = %v\n", a, op, b, res)
|
||||
}
|
67
x-tba/foundations/calc/08-funcs/main.go
Normal file
67
x-tba/foundations/calc/08-funcs/main.go
Normal file
@ -0,0 +1,67 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"os"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
func main() {
|
||||
// lesson: many - split this
|
||||
|
||||
if len(os.Args) != 4 {
|
||||
fmt.Println("Usage: calc <number1> <operator> <number2>")
|
||||
return
|
||||
}
|
||||
|
||||
var (
|
||||
a, b float64
|
||||
err error
|
||||
)
|
||||
|
||||
if a, err = parse(os.Args[1]); err != nil {
|
||||
fmt.Println(err)
|
||||
return
|
||||
}
|
||||
|
||||
if b, err = parse(os.Args[3]); err != nil {
|
||||
fmt.Println(err)
|
||||
return
|
||||
}
|
||||
|
||||
op := os.Args[2]
|
||||
res, err := calc(a, b, op)
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
return
|
||||
}
|
||||
|
||||
fmt.Printf("%v %s %v = %v\n", a, op, b, res)
|
||||
}
|
||||
|
||||
func parse(snum string) (n float64, err error) {
|
||||
n, err = strconv.ParseFloat(snum, 64)
|
||||
if err != nil {
|
||||
err = errors.New("Please provide a valid number")
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func calc(a, b float64, op string) (res float64, err error) {
|
||||
switch op {
|
||||
case "+", "plus":
|
||||
op, res = "+", a+b
|
||||
case "-", "minus":
|
||||
op, res = "-", a-b
|
||||
case "*", "times":
|
||||
op, res = "*", a*b
|
||||
case "/", "div":
|
||||
op, res = "/", a/b
|
||||
case "%", "mod":
|
||||
res = float64(int(a) % int(b))
|
||||
default:
|
||||
return 0, errors.New("Wrong operation: '" + op + "'")
|
||||
}
|
||||
return
|
||||
}
|
36
x-tba/foundations/calc/09-packages/calc/calc.go
Normal file
36
x-tba/foundations/calc/09-packages/calc/calc.go
Normal file
@ -0,0 +1,36 @@
|
||||
package calc
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
// Parse ...
|
||||
func Parse(snum string) (n float64, err error) {
|
||||
n, err = strconv.ParseFloat(snum, 64)
|
||||
if err != nil {
|
||||
// Don't loose the actual error for debugging
|
||||
err = errors.New("Please provide a valid number: " +
|
||||
err.Error())
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// Do ...
|
||||
func Do(a, b float64, op string) (res float64, err error) {
|
||||
switch op {
|
||||
case "+", "plus":
|
||||
op, res = "+", a+b
|
||||
case "-", "minus":
|
||||
op, res = "-", a-b
|
||||
case "*", "times":
|
||||
op, res = "*", a*b
|
||||
case "/", "div":
|
||||
op, res = "/", a/b
|
||||
case "%", "mod":
|
||||
res = float64(int(a) % int(b))
|
||||
default:
|
||||
return 0, errors.New("Wrong operation: '" + op + "'")
|
||||
}
|
||||
return
|
||||
}
|
50
x-tba/foundations/calc/09-packages/main.go
Normal file
50
x-tba/foundations/calc/09-packages/main.go
Normal file
@ -0,0 +1,50 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
|
||||
"github.com/inancgumus/learngo/x-tba/foundations/calc/09-packages/calc"
|
||||
)
|
||||
|
||||
func main() {
|
||||
// lesson: packaging
|
||||
|
||||
// separate dependencies like getting and validating
|
||||
// user data as in here.
|
||||
//
|
||||
// we only put calc to another packages, not the other
|
||||
// stuff.
|
||||
//
|
||||
// so, we can reuse the same calc package and use it
|
||||
// over a web api if we want.
|
||||
|
||||
if len(os.Args) != 4 {
|
||||
fmt.Println("Usage: calc <number1> <operator> <number2>")
|
||||
return
|
||||
}
|
||||
|
||||
var (
|
||||
a, b float64
|
||||
err error
|
||||
)
|
||||
|
||||
if a, err = calc.Parse(os.Args[1]); err != nil {
|
||||
fmt.Println(err)
|
||||
return
|
||||
}
|
||||
|
||||
if b, err = calc.Parse(os.Args[3]); err != nil {
|
||||
fmt.Println(err)
|
||||
return
|
||||
}
|
||||
|
||||
op := os.Args[2]
|
||||
res, err := calc.Do(a, b, op)
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
return
|
||||
}
|
||||
|
||||
fmt.Printf("%v %s %v = %v\n", a, op, b, res)
|
||||
}
|
4
x-tba/foundations/calc/calc-scanner/calculations.txt
Normal file
4
x-tba/foundations/calc/calc-scanner/calculations.txt
Normal file
@ -0,0 +1,4 @@
|
||||
4 + 5
|
||||
6.5 + 2
|
||||
5 - 3
|
||||
q
|
66
x-tba/foundations/calc/calc-scanner/main.go
Normal file
66
x-tba/foundations/calc/calc-scanner/main.go
Normal file
@ -0,0 +1,66 @@
|
||||
/*
|
||||
go run main.go < ./calculations.txt
|
||||
|
||||
If you're not on Linux or OS X, etc but on Windows,
|
||||
Then, use Windows PowerShell to do the same thing.
|
||||
*/
|
||||
package main
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"fmt"
|
||||
"os"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// After functions, you'll see that how we're going to refactor this
|
||||
// into a more readable version.
|
||||
|
||||
func main() {
|
||||
const (
|
||||
promptChar = "> "
|
||||
errWrongOp = "%s operation is not supported\n"
|
||||
errWrongFormat = "operation is not recognized\n"
|
||||
usage = `
|
||||
usage: number operation number
|
||||
quit : type q to quit
|
||||
examples:
|
||||
3 + 5
|
||||
5 - 3
|
||||
`
|
||||
)
|
||||
|
||||
fmt.Println(strings.TrimSpace(usage))
|
||||
|
||||
for s := bufio.NewScanner(os.Stdin); ; {
|
||||
var (
|
||||
a, b, res float64
|
||||
op string
|
||||
)
|
||||
|
||||
fmt.Print(promptChar, " ")
|
||||
if !s.Scan() {
|
||||
break
|
||||
}
|
||||
|
||||
_, err := fmt.Sscanf(s.Text(), "%f %s %f", &a, &op, &b)
|
||||
if err != nil {
|
||||
fmt.Fprintf(os.Stderr, errWrongFormat)
|
||||
continue
|
||||
}
|
||||
|
||||
switch op {
|
||||
case "+":
|
||||
res = a + b
|
||||
case "-":
|
||||
res = a - b
|
||||
default:
|
||||
fmt.Printf(errWrongOp, op)
|
||||
continue
|
||||
}
|
||||
|
||||
fmt.Printf("%g %s %g = %g\n", a, op, b, res)
|
||||
}
|
||||
|
||||
fmt.Println("bye.")
|
||||
}
|
Reference in New Issue
Block a user