Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Select an option

  • Save NorbertFenk/34c9256c5f022b586d074a60c85297b9 to your computer and use it in GitHub Desktop.

Select an option

Save NorbertFenk/34c9256c5f022b586d074a60c85297b9 to your computer and use it in GitHub Desktop.
# Go coding kata with the important features of the language
/*
The Story (What you should try to build from memory):
- You are receiving telemetry batches from electric vehicle battery stations.
Define a BatteryTelemetry struct and an Optimizer interface.
- Write a method for the battery struct using a pointer receiver to calculate its optimal charging efficiency.
If the battery is running too hot, return an overheating error.
- Create a function that mocks an incoming batch (returning a slice of telemetry pointers and a map of station names).
- Spin up goroutines to process the telemetry concurrently using a sync.WaitGroup.
- Send the optimization logs through a buffered channel.
- Print the logs using a switch statement to handle the overheating errors gracefully.
*/
package main
import (
"errors"
"fmt"
"sync"
)
// 1. Constants & Variables
const batchSize = 5
var ErrOverheating = errors.New("thermal throttling active")
// 2. Interfaces
type Optimizer interface {
OptimizeCharge() error
}
// 3. Structs
type BatteryTelemetry struct {
UnitID int
Temperature float64
ChargeLevel float64
Efficiency float64
}
// 4. Methods & Pointers
func (b *BatteryTelemetry) OptimizeCharge() error {
// 5. Control Flow (If)
if b.Temperature > 45.0 {
b.Efficiency = 0.0 // Cut off charge for safety
return ErrOverheating
}
// Calculate new efficiency based on current charge state
b.Efficiency = (100.0 - b.ChargeLevel) * 0.85
return nil
}
// 6. Functions & Multiple Return Values
func ingestTelemetry(count int) ([]*BatteryTelemetry, map[int]string) {
// 7. Slices & Maps
payloads := make([]*BatteryTelemetry, count)
registry := make(map[int]string)
// 8. Loops (Standard)
for i := 0; i < count; i++ {
// Simulate some hot batteries and some cool ones
temp := 35.0 + float64(i*4)
payloads[i] = &BatteryTelemetry{
UnitID: 100 + i,
Temperature: temp,
ChargeLevel: 20.0 + float64(i*10),
}
registry[payloads[i].UnitID] = fmt.Sprintf("Station-Alpha-%d", 100+i)
}
return payloads, registry
}
func main() {
telemetryBatch, registry := ingestTelemetry(batchSize)
// 9. Channels & Concurrency Primitives
metricsStream := make(chan string, len(telemetryBatch))
var wg sync.WaitGroup
// 10. Loops (Range)
for _, telemetry := range telemetryBatch {
wg.Add(1)
// 11. Goroutines & Anonymous Functions (Closures)
go func(t *BatteryTelemetry) {
// 12. Defer
defer wg.Done()
err := t.OptimizeCharge()
// 13. Switch Statements & Error Handling
switch {
case err != nil:
metricsStream <- fmt.Sprintf("⚠️ %s (ID: %d) skipped: %v", registry[t.UnitID], t.UnitID, err)
default:
metricsStream <- fmt.Sprintf("⚡ %s (ID: %d) optimized. New Efficiency: %.2f%%", registry[t.UnitID], t.UnitID, t.Efficiency)
}
}(telemetry)
}
// 14. Background channel closing
go func() {
wg.Wait()
close(metricsStream)
}()
// 15. Ranging over channels
for metric := range metricsStream {
fmt.Println(metric)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment