Skip to content
Closed
Show file tree
Hide file tree
Changes from 6 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 31 additions & 0 deletions internal/exercises/catalog.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,37 @@ concepts:
test_regex: ".*"
hints:
- Define a custom error type and return it from a function.
- slug: 28_defer
title: Defer
test_regex: ".*"
hints:
- Use `f.close()` with `defer` keyword.
Comment on lines +137 to +141

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Fix the method name in the defer hint.

Line 141 references f.close(), but in Go, the correct method is f.Close() (capitalized). File close methods follow Go's exported identifier conventions.

Apply this diff:

   hints:
-    - Use `f.close()` with `defer` keyword.
+    - Use `f.Close()` with `defer` keyword.
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
- slug: 28_defer
title: Defer
test_regex: ".*"
hints:
- Use `f.close()` with `defer` keyword.
- slug: 28_defer
title: Defer
test_regex: ".*"
hints:
- Use `f.Close()` with `defer` keyword.
🤖 Prompt for AI Agents
In internal/exercises/catalog.yaml around lines 137 to 141, the hint uses the
incorrect Go method name `f.close()`; update the hint to use the exported Go
method `f.Close()` (capital C) so the guidance matches Go's identifier
conventions and will compile when referenced.

- slug: 29_go_routines
title: Go Routines
test_regex: ".*"
hints:
- Use `go` keyword to execute functions concurrently using go routines.
- slug: 30_channels
title: Channels
test_regex: ".*"
hints:
- Use `make(chan T)` to create a channel and `<-` to send and receive on it.
- slug: 31_mutexes
title: Mutexes
test_regex: ".*"
hints:
- Use `sync.Mutex` to synchronize access to a shared resource.
- slug: 32_sorting
title: Sorting
test_regex: ".*"
hints:
- Use `slice.Sort` for sorting slices.
- slug: 33_string_formatting
Comment on lines +157 to +162

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Fix the package name in the sorting hint.

Line 161 references slice.Sort, but the correct package for the sorting function is slices.Sort (available in Go 1.21+). This should be corrected to match the actual implementation in the solution files.

Apply this diff:

   hints:
-    - Use `slice.Sort` for sorting slices.
+    - Use `slices.Sort` for sorting slices.
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
- slug: 32_sorting
title: Sorting
test_regex: ".*"
hints:
- Use `slice.Sort` for sorting slices.
- slug: 33_string_formatting
- slug: 32_sorting
title: Sorting
test_regex: ".*"
hints:
- Use `slices.Sort` for sorting slices.
- slug: 33_string_formatting
🤖 Prompt for AI Agents
In internal/exercises/catalog.yaml around lines 157 to 162, update the hint that
currently references the wrong package name; replace the incorrect `slice.Sort`
with the correct `slices.Sort` (Go 1.21+) so the hint matches the implementation
in the solution files and use backticks around the symbol if the file format
expects code formatting.

title: String Formatting
test_regex: ".*"
hints:
- Use `%s`, `%d`, and `%f` to format strings, integers, and floats.

- slug: 37_xml
title: XML Encoding and Decoding
test_regex: ".*"
Expand Down
29 changes: 29 additions & 0 deletions internal/exercises/solutions/28_defer/defer.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package deferr

import (
"fmt"
"os"
"sync"
)

var (
fileInstance *os.File
once sync.Once
)

func CreateFile() *os.File {
once.Do(func() {
f, err := os.CreateTemp("", "example.txt")
if err != nil {
panic(err)
}
fileInstance = f
})
return fileInstance
}

func WriteToFile(*os.File) {
f := CreateFile()
defer f.Close()
fmt.Fprintln(f, "data")
}
25 changes: 25 additions & 0 deletions internal/exercises/solutions/29_go_routines/go_routines.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package go_routines

import (
"time"
)

func sleepForOneHundredMillisecond() {
time.Sleep(100 * time.Millisecond)
}

func sleepForTwoHundredMilliseconds() {
time.Sleep(200 * time.Millisecond)
}

func RunConcurrently() {
go sleepForOneHundredMillisecond()
go sleepForTwoHundredMilliseconds()

Comment thread
kawpii marked this conversation as resolved.
// go func() {
// sleepForOneHundredMillisecond()
// }()
// go func() {
// sleepForTwoHundredMilliseconds()
// }()
}
13 changes: 13 additions & 0 deletions internal/exercises/solutions/30_channels/channels.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package channels

func ReadMessage() string {
chat := make(chan string)
go func() {
senderMessage := "Hi!"
chat <- senderMessage
}()

msg := <-chat

return msg
}
31 changes: 31 additions & 0 deletions internal/exercises/solutions/31_mutexes/mutexes.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
package mutexes

import "sync"

const numWorkers = 10_000

func Counting() int {

count := 0
done := make(chan bool, numWorkers)
var wg sync.WaitGroup
var mu sync.Mutex

for i := 1; i <= numWorkers; i++ {
wg.Add(1)
go func() {
defer wg.Done()
mu.Lock()
count += 1
mu.Unlock()
done <- true
}()
}

for i := 1; i <= numWorkers; i++ {
<-done
}

wg.Wait()
return count
}
18 changes: 18 additions & 0 deletions internal/exercises/solutions/32_sorting/sorting.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package sorting

import (
"slices"
)

var Years = []int{2017, 2003, 2026}
var Pets = []string{"Dog", "Cat", "Parrot"}

func SortNumbers() []int {
slices.Sort(Years)
return Years
}

func SortAnimals() []string {
slices.Sort(Pets)
return Pets
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package string_formatting

import "fmt"

func FormatName() string {
return fmt.Sprintf("Name: %s", "\"John\"")
}

func FormatAge() string {
return fmt.Sprintf("Age: %d", 17)
}

func FormatGpa() string {
return fmt.Sprintf("GPA: %.2f", 3.75)
}
29 changes: 29 additions & 0 deletions internal/exercises/templates/28_defer/defer.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package deferr

import (
"fmt"
"os"
"sync"
)

var (
fileInstance *os.File
once sync.Once
)

func CreateFile() *os.File {
once.Do(func() {
f, err := os.CreateTemp("", "example.txt")
if err != nil {
panic(err)
}
fileInstance = f
})
return fileInstance
}

func WriteToFile(*os.File) {
f := CreateFile()
// TODO: Add your code here
fmt.Fprintln(f, "data")
}
17 changes: 17 additions & 0 deletions internal/exercises/templates/28_defer/defer_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package deferr

import (
"fmt"
"testing"
)

func TestClosingFileAfterWriting(t *testing.T) {
f := CreateFile()
WriteToFile(f)

// trying to write to the file after closing
_, err := fmt.Fprintln(f, "data")
if err == nil {
t.Fatal("File wasn't closed!")
}
}
19 changes: 19 additions & 0 deletions internal/exercises/templates/29_go_routines/go_routines.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package go_routines

import (
"time"
)

func sleepForOneHundredMillisecond() {
time.Sleep(100 * time.Millisecond)
}

func sleepForTwoHundredMilliseconds() {
time.Sleep(200 * time.Millisecond)
}

func RunConcurrently() {
// TODO: update following code
sleepForOneHundredMillisecond()
sleepForTwoHundredMilliseconds()
}
24 changes: 24 additions & 0 deletions internal/exercises/templates/29_go_routines/go_routines_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package go_routines

import (
"testing"
"time"
)

func TestGoRoutines(t *testing.T) {
start := time.Now()
RunConcurrently()
elapsed := time.Since(start)

// according to benchmark it is about ~2 microseconds
// x2 for more breathing room, so 4
if elapsed.Microseconds() >= 4 {
t.Fatal("Go routines was not used!")
}
}
Comment thread
kawpii marked this conversation as resolved.

func BenchmarkRunConcurrently(b *testing.B) {
for i := 0; i < b.N; i++ {
RunConcurrently()
}
}
Comment thread
kawpii marked this conversation as resolved.
15 changes: 15 additions & 0 deletions internal/exercises/templates/30_channels/channels.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package channels

import "fmt"

func ReadMessage() string {
// TODO: update following code
// to receive senderMessage in main goroutine
// and return it from ReadMessage function
go func() {
senderMessage := "Hi!"
fmt.Println(senderMessage)
}()

return ""
}
12 changes: 12 additions & 0 deletions internal/exercises/templates/30_channels/channels_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package channels

import "testing"

func TestReadMessage(t *testing.T) {
got := ReadMessage()
want := "Hi!"

if got != want {
t.Errorf("Expected %s, got %s", want, got)
}
}
30 changes: 30 additions & 0 deletions internal/exercises/templates/31_mutexes/mutexes.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package mutexes

import "sync"

const numWorkers = 10_000

func Counting() int {

// TODO: update following code to avoid race conditions
// using sync.Mutex
count := 0
done := make(chan bool, numWorkers)
var wg sync.WaitGroup

for i := 1; i <= numWorkers; i++ {
wg.Add(1)
go func() {
defer wg.Done()
count += 1
done <- true
}()
}

for i := 1; i <= numWorkers; i++ {
<-done
}

wg.Wait()
return count
}
12 changes: 12 additions & 0 deletions internal/exercises/templates/31_mutexes/mutexes_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package mutexes

import "testing"

func TestCounter(t *testing.T) {
got := Counting()
want := numWorkers

if got != want {
t.Fatalf("Expected %d, got %d", want, got)
}
}
14 changes: 14 additions & 0 deletions internal/exercises/templates/32_sorting/sorting.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package sorting

var Years = []int{2017, 2003, 2026}
var Pets = []string{"Dog", "Cat", "Parrot"}

func SortNumbers() []int {
// TODO: sort Years
return Years
}

func SortAnimals() []string {
// TODO: sort Pets
return Pets
}
22 changes: 22 additions & 0 deletions internal/exercises/templates/32_sorting/sorting_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package sorting

import (
"slices"
"testing"
)

func TestSorting(t *testing.T) {
t.Run("Sorting numbers", func(t *testing.T) {
SortNumbers()
if !slices.IsSorted(Years) {
t.Fatal("Strings are not sorted!")
}
})
Comment on lines +8 to +14

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Fix the error message to match the test context.

Line 12 reports "Strings are not sorted!" but this subtest is validating number sorting. The message should say "Numbers are not sorted!" for clarity.

Apply this diff:

 		if !slices.IsSorted(Years) {
-			t.Fatal("Strings are not sorted!")
+			t.Fatal("Numbers are not sorted!")
 		}
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
func TestSorting(t *testing.T) {
t.Run("Sorting numbers", func(t *testing.T) {
SortNumbers()
if !slices.IsSorted(Years) {
t.Fatal("Strings are not sorted!")
}
})
func TestSorting(t *testing.T) {
t.Run("Sorting numbers", func(t *testing.T) {
SortNumbers()
if !slices.IsSorted(Years) {
t.Fatal("Numbers are not sorted!")
}
})
🤖 Prompt for AI Agents
In internal/exercises/templates/32_sorting/sorting_test.go around lines 8 to 14,
the test's failure message is incorrect for the subtest; change the t.Fatal
message from "Strings are not sorted!" to "Numbers are not sorted!" so the error
text matches the "Sorting numbers" subtest context.


t.Run("Sorting strings", func(t *testing.T) {
SortAnimals()
if !slices.IsSorted(Pets) {
t.Fatal("Strings are not sorted!")
}
})
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package string_formatting

import "fmt"

func FormatName() string {
// TODO: format the name as a string
return fmt.Sprintf("Name: ", "\"John\"")

Check failure on line 7 in internal/exercises/templates/33_string_formatting/string_formatting.go

View workflow job for this annotation

GitHub Actions / test

fmt.Sprintf call has arguments but no formatting directives

Check failure on line 7 in internal/exercises/templates/33_string_formatting/string_formatting.go

View workflow job for this annotation

GitHub Actions / test

fmt.Sprintf call has arguments but no formatting directives
}

func FormatAge() string {
// TODO: format the age as a digit
return fmt.Sprintf("Age: ", 17)

Check failure on line 12 in internal/exercises/templates/33_string_formatting/string_formatting.go

View workflow job for this annotation

GitHub Actions / test

fmt.Sprintf call has arguments but no formatting directives

Check failure on line 12 in internal/exercises/templates/33_string_formatting/string_formatting.go

View workflow job for this annotation

GitHub Actions / test

fmt.Sprintf call has arguments but no formatting directives
}

func FormatGpa() string {
// TODO: format the GPA for floating point number with 2 decimal places
return fmt.Sprintf("GPA: ", 3.75)

Check failure on line 17 in internal/exercises/templates/33_string_formatting/string_formatting.go

View workflow job for this annotation

GitHub Actions / test

fmt.Sprintf call has arguments but no formatting directives

Check failure on line 17 in internal/exercises/templates/33_string_formatting/string_formatting.go

View workflow job for this annotation

GitHub Actions / test

fmt.Sprintf call has arguments but no formatting directives
}
Comment thread
kawpii marked this conversation as resolved.
Loading
Loading