Calculator with History
A calculator that uses closures to maintain operation history, variadic functions for multi-operand math, and defer to print a summary at the end.
package main
import "fmt"
func makeCalculator() (func(string, ...float64) float64, func() []string) {
var history []string
calc := func(op string, nums ...float64) float64 {
if len(nums) == 0 {
return 0
}
result := nums[0]
for _, n := range nums[1:] {
switch op {
case "add":
result += n
case "sub":
result -= n
case "mul":
result *= n
case "div":
if n != 0 {
result /= n
}
}
}
entry := fmt.Sprintf("%s(%v) = %.2f", op, nums, result)
history = append(history, entry)
return result
}
getHistory := func() []string {
return history
}
return calc, getHistory
}
func divide(a, b float64) (float64, error) {
if b == 0 {
return 0, fmt.Errorf("cannot divide %.2f by zero", a)
}
return a / b, nil
}
func main() {
calc, getHistory := makeCalculator()
defer func() {
fmt.Println("\n--- Session Summary ---")
for i, entry := range getHistory() {
fmt.Printf(" %d. %s\n", i+1, entry)
}
fmt.Printf(" Total operations: %d\n", len(getHistory()))
}()
sum := calc("add", 10, 20, 30, 5)
fmt.Printf("add(10, 20, 30, 5) = %.2f\n", sum)
product := calc("mul", 3, 4, 5)
fmt.Printf("mul(3, 4, 5) = %.2f\n", product)
diff := calc("sub", 100, 25, 10)
fmt.Printf("sub(100, 25, 10) = %.2f\n", diff)
quotient := calc("div", 100, 4, 5)
fmt.Printf("div(100, 4, 5) = %.2f\n", quotient)
// Multiple return values with error handling
result, err := divide(10, 3)
if err != nil {
fmt.Println("Error:", err)
} else {
fmt.Printf("divide(10, 3) = %.4f\n", result)
}
_, err = divide(5, 0)
if err != nil {
fmt.Println("Error:", err)
}
}