Skip to content

Conversation

@aryasoni98
Copy link

@aryasoni98 aryasoni98 commented Oct 16, 2025

Summary

Added String Functions exercise (#42) to teach Go's strings package fundamentals

This change implements issue #77 by adding a comprehensive String Functions exercise that teaches students essential string manipulation functions from Go's standard library. The exercise covers 7 key functions: Contains, HasPrefix, HasSuffix, Index, ToUpper, ToLower, and TrimSpace.

Motivation: Students need to understand Go's built-in string functions for effective string manipulation. This exercise fills a gap in the curriculum by providing hands-on practice with the most commonly used strings package functions.

Checklist

  • Tests pass: Template compiles and runs tests (fails as expected for incomplete exercise), solution passes all tests 100%
  • Docs updated: Added String Functions to docs/exercises.md in the Advanced section
  • No large new dependencies: Uses only Go's standard strings package

Screenshots / Output (if CLI UX)

Template Test Output (Expected Failures):

=== RUN   TestContains
    string_functions_test.go:21: Contains("hello world", "world") = false, want true
--- FAIL: TestContains (0.00s)

Solution Test Output (All Pass):

=== RUN   TestContains
--- PASS: TestContains (0.00s)
=== RUN   TestHasPrefix  
--- PASS: TestHasPrefix (0.00s)
=== RUN   TestHasSuffix
--- PASS: TestHasSuffix (0.00s)
=== RUN   TestIndex
--- PASS: TestIndex (0.00s)
=== RUN   TestToUpper
--- PASS: TestToUpper (0.00s)
=== RUN   TestToLower
--- PASS: TestToLower (0.00s)
=== RUN   TestTrimSpace
--- PASS: TestTrimSpace (0.00s)
PASS

Related issues

Fixes #77

Summary by CodeRabbit

  • New Exercises

    • Added String Functions exercise covering common string utilities
    • Added Sorting by Functions exercise for custom sorting patterns
    • Added Panic and Recover exercise for error handling
    • Added Timers and Rate Limiting exercises
    • Added JSON marshaling/unmarshaling exercise
  • Exercise Catalog Updates

    • Reorganized and restructured exercise catalog with improved organization
    • Enhanced hints and guidance throughout the exercise collection

✏️ Tip: You can customize this high-level summary in your review settings.

@coderabbitai
Copy link

coderabbitai bot commented Oct 16, 2025

Walkthrough

This PR adds a new "String Functions" exercise (47_string_functions) to the Go learning curriculum. Changes include updating documentation, adding catalog entries, creating template stubs with tests, and providing complete solutions that wrap standard library string utilities.

Changes

Cohort / File(s) Summary
Documentation
docs/exercises.md
Updated Advanced section header range from (21-37) to (21-47) and added 47_string_functions entry to exercise list.
Catalog Configuration
internal/exercises/catalog.yaml
Added new concept entries (36_json, 47_string_functions, 48_sorting_by_functions, 49_panic, 50_timers, 51_rate_limiting); reorganized project section with removals and re-additions of related exercises; updated hints across sections.
Exercise Templates
internal/exercises/templates/47_string_functions/string_functions.go, string_functions_test.go
Added stub functions (Contains, HasPrefix, HasSuffix, Index, ToUpper, ToLower, TrimSpace) with TODO markers and comprehensive table-driven tests covering edge cases.
Exercise Solutions
internal/exercises/solutions/47_string_functions/string_functions.go
Added implementation package delegating to standard library strings package functions for all seven exported functions.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

  • Catalog updates span multiple entries but follow consistent patterns (removals, additions, reorganizations)
  • Template stubs and solutions are straightforward pass-through wrappers with no complex logic
  • Tests are table-driven with standard patterns

Possibly related PRs

Suggested labels

patch

Suggested reviewers

  • zhravan

Poem

🐰 Seven strings, now bundled tight,
Contains and HasPrefix in sight,
ToUpper, ToLower, trimmed so clean,
The finest string exercise we've seen! ✨

Pre-merge checks and finishing touches

❌ Failed checks (2 warnings)
Check name Status Explanation Resolution
Out of Scope Changes check ⚠️ Warning Changes include updates to docs/exercises.md and catalog.yaml that go beyond the single String Functions exercise, addressing multiple concepts and projects unrelated to the linked issue scope. Limit changes to String Functions exercise only: revert unrelated updates to catalog.yaml (other concepts/projects) and keep docs/exercises.md focused on adding the String Functions entry to the Advanced section.
Docstring Coverage ⚠️ Warning Docstring coverage is 66.67% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The pull request title clearly and concisely describes the main change: adding String Functions exercise templates to the codebase.
Linked Issues check ✅ Passed All acceptance criteria from issue #77 are met: templates and tests added under internal/exercises/templates/47_string_functions/, exercise entry added to catalog.yaml, and helpful hints provided for the seven string functions.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

📜 Recent review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between f501ede and dcf2014.

📒 Files selected for processing (5)
  • docs/exercises.md (2 hunks)
  • internal/exercises/catalog.yaml (4 hunks)
  • internal/exercises/solutions/47_string_functions/string_functions.go (1 hunks)
  • internal/exercises/templates/47_string_functions/string_functions.go (1 hunks)
  • internal/exercises/templates/47_string_functions/string_functions_test.go (1 hunks)
🧰 Additional context used
🧠 Learnings (1)
📚 Learning: 2025-10-02T12:51:43.433Z
Learnt from: kaushalyap
Repo: zhravan/golearn PR: 94
File: internal/exercises/templates/28_defer/utils.go:0-0
Timestamp: 2025-10-02T12:51:43.433Z
Learning: In the defer exercise template (internal/exercises/templates/28_defer/utils.go), the temporary file created by CreateFile() intentionally lacks cleanup (no Close() or Remove()) as part of the pedagogical design, expecting students to implement proper resource cleanup using defer.

Applied to files:

  • internal/exercises/templates/47_string_functions/string_functions.go
🔇 Additional comments (5)
internal/exercises/templates/47_string_functions/string_functions_test.go (1)

1-153: LGTM! Well-structured test suite.

The test file demonstrates excellent practices:

  • Table-driven tests for all seven string functions
  • Good edge case coverage including empty strings, Unicode characters, and boundary conditions
  • Clear test naming and error messages
  • Appropriate use of subtests with t.Run()

The test coverage is comprehensive for a beginner-level exercise.

internal/exercises/catalog.yaml (1)

276-284: LGTM! The 47_string_functions catalog entry is well-structured.

The hints for the String Functions exercise are clear, actionable, and correctly reference the appropriate strings package functions. The entry follows the established pattern for other exercises in the catalog.

internal/exercises/solutions/47_string_functions/string_functions.go (1)

1-38: LGTM! Clean solution implementation.

The solution file provides straightforward wrapper functions that correctly delegate to the strings package. The implementation is appropriate for an educational exercise:

  • Clear function signatures matching the template
  • Proper documentation comments
  • Direct delegation to standard library functions
  • No unnecessary complexity

This serves as a good reference solution for students learning the strings package.

internal/exercises/templates/47_string_functions/string_functions.go (1)

1-46: LGTM! Well-designed template with intentional failures.

The template follows good pedagogical practices:

  • Stub implementations intentionally return incorrect values to make tests fail
  • Clear TODO comments guide students to the correct strings package functions
  • Function signatures and documentation are complete
  • File-level TODO reminds students to add the import statement

This approach aligns with the project's educational design where templates are expected to fail initially, encouraging students to implement the solution. Based on learnings, this is consistent with other exercises like the defer exercise where intentional gaps teach proper implementation.

docs/exercises.md (1)

43-54: Unfortunately, I'm unable to complete the verification of this review comment due to persistent repository cloning issues in the sandbox environment. While I can confirm that the zhravan/golearn repository exists and contains Go exercises, I cannot access the actual files to verify the specific claims made in the review comment.

Unable to verify the documentation gap claim due to repository access limitations.

The review comment makes specific factual assertions about:

  • The existence and contents of internal/exercises/catalog.yaml
  • Which exercises are currently listed in docs/exercises.md
  • Which exercises (28-35, 38-46) are missing from the documentation

Without direct access to these files, I cannot confirm:

  • Whether the catalog file contains the alleged exercises
  • What exercises are actually documented vs. missing
  • Whether there are legitimate reasons for any omissions

Manual verification is required to confirm these claims by examining the catalog file and documentation directly in the repository.

Tip

📝 Customizable high-level summaries are now available in beta!

You can now customize how CodeRabbit generates the high-level summary in your pull requests — including its content, structure, tone, and formatting.

  • Provide your own instructions using the high_level_summary_instructions setting.
  • Format the summary however you like (bullet lists, tables, multi-section layouts, contributor stats, etc.).
  • Use high_level_summary_in_walkthrough to move the summary from the description to the walkthrough section.

Example instruction:

"Divide the high-level summary into five sections:

  1. 📝 Description — Summarize the main change in 50–60 words, explaining what was done.
  2. 📓 References — List relevant issues, discussions, documentation, or related PRs.
  3. 📦 Dependencies & Requirements — Mention any new/updated dependencies, environment variable changes, or configuration updates.
  4. 📊 Contributor Summary — Include a Markdown table showing contributions:
    | Contributor | Lines Added | Lines Removed | Files Changed |
  5. ✔️ Additional Notes — Add any extra reviewer context.
    Keep each section concise (under 200 words) and use bullet or numbered lists for clarity."

Note: This feature is currently in beta for Pro-tier users, and pricing will be announced later.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 23993a6 and f501ede.

📒 Files selected for processing (8)
  • docs/exercises.md (1 hunks)
  • internal/exercises/catalog.yaml (3 hunks)
  • internal/exercises/solutions/41_regex/regex.go (1 hunks)
  • internal/exercises/solutions/42_string_functions/string_functions.go (1 hunks)
  • internal/exercises/templates/41_regex/regex.go (1 hunks)
  • internal/exercises/templates/41_regex/regex_test.go (1 hunks)
  • internal/exercises/templates/42_string_functions/string_functions.go (1 hunks)
  • internal/exercises/templates/42_string_functions/string_functions_test.go (1 hunks)
🧰 Additional context used
🧬 Code graph analysis (3)
internal/exercises/templates/42_string_functions/string_functions_test.go (1)
internal/exercises/templates/42_string_functions/string_functions.go (7)
  • Contains (7-10)
  • HasPrefix (13-16)
  • HasSuffix (19-22)
  • Index (25-28)
  • ToUpper (31-34)
  • ToLower (37-40)
  • TrimSpace (43-46)
internal/exercises/templates/42_string_functions/string_functions.go (1)
internal/exercises/solutions/42_string_functions/string_functions.go (7)
  • Contains (6-8)
  • HasPrefix (11-13)
  • HasSuffix (16-18)
  • Index (21-23)
  • ToUpper (26-28)
  • ToLower (31-33)
  • TrimSpace (36-38)
internal/exercises/solutions/42_string_functions/string_functions.go (1)
internal/exercises/templates/42_string_functions/string_functions.go (7)
  • Contains (7-10)
  • HasPrefix (13-16)
  • HasSuffix (19-22)
  • Index (25-28)
  • ToUpper (31-34)
  • ToLower (37-40)
  • TrimSpace (43-46)
🔇 Additional comments (25)
internal/exercises/templates/42_string_functions/string_functions_test.go (7)

5-25: LGTM! Comprehensive test coverage for Contains.

The test cases cover typical scenarios, edge cases (empty strings), and negative cases effectively. The table-driven approach is idiomatic Go.


27-46: LGTM! Good test coverage for HasPrefix.

The test cases appropriately validate prefix matching behavior including edge cases.


48-67: LGTM! Good test coverage for HasSuffix.

The test cases appropriately validate suffix matching behavior including edge cases.


69-89: LGTM! Good test coverage for Index.

The test cases correctly validate index finding behavior, including the -1 return for not found and first occurrence behavior.


91-110: LGTM! Excellent Unicode coverage.

The test cases include proper Unicode handling with accented characters, which is important for internationalization. Good comprehensive coverage.


112-131: LGTM! Excellent Unicode coverage.

The test cases include proper Unicode handling with accented characters, mirroring the ToUpper tests appropriately.


133-153: LGTM! Comprehensive whitespace handling.

The test cases cover various types of whitespace (spaces, tabs, newlines) and edge cases effectively.

internal/exercises/solutions/42_string_functions/string_functions.go (7)

5-8: LGTM! Clean wrapper implementation.

The function correctly delegates to the standard library strings.Contains.


10-13: LGTM! Clean wrapper implementation.

The function correctly delegates to the standard library strings.HasPrefix.


15-18: LGTM! Clean wrapper implementation.

The function correctly delegates to the standard library strings.HasSuffix.


20-23: LGTM! Clean wrapper implementation.

The function correctly delegates to the standard library strings.Index.


25-28: LGTM! Clean wrapper implementation.

The function correctly delegates to the standard library strings.ToUpper.


30-33: LGTM! Clean wrapper implementation.

The function correctly delegates to the standard library strings.ToLower.


35-38: LGTM! Clean wrapper implementation.

The function correctly delegates to the standard library strings.TrimSpace.

internal/exercises/templates/42_string_functions/string_functions.go (1)

1-46: LGTM! Well-structured exercise template.

The template correctly provides function skeletons with:

  • Clear TODO comments indicating which standard library function to use
  • Intentionally incorrect return values that will fail tests
  • Proper function signatures matching the solution
  • Helpful reminder to import the strings package

This structure will effectively guide learners through the exercise.

internal/exercises/templates/41_regex/regex_test.go (4)

5-25: LGTM! Comprehensive email validation test cases.

The test cases cover valid emails and common invalid patterns (missing @, missing domain, missing TLD, empty string).


27-52: LGTM! Good coverage for number extraction.

The test cases appropriately handle integers, decimals, and edge cases like "12.34.56" being parsed as two separate numbers.


54-74: LGTM! Thorough vowel replacement tests.

The test cases cover case-insensitive replacement, strings with no vowels, and strings composed entirely of vowels.


76-99: LGTM! Comprehensive phone number validation tests.

The test cases thoroughly validate the specific format (XXX) XXX-XXXX, testing various invalid formats including missing punctuation, wrong spacing, and incorrect digit counts.

internal/exercises/catalog.yaml (5)

177-184: LGTM! JSON exercise added to concepts.

The JSON exercise is properly configured with appropriate hints for marshaling/unmarshaling and error handling.


193-219: LGTM! Additional exercises added to concepts.

Exercises 37 (Sorting by Functions), 38 (Time Formatting), and 39 (Channel Directions) are properly configured with helpful hints.


226-238: LGTM! Regex exercise properly configured.

The regex exercise has comprehensive hints covering all four functions with specific regex patterns provided. This will be helpful for learners.


239-246: LGTM! String Functions exercise properly configured.

The string functions exercise has clear hints for all seven functions, properly guiding learners to the appropriate strings package functions.


247-295: LGTM! Projects section appropriately reorganized.

The removal of concept exercises (36-39) from the projects section aligns with their addition to the concepts section, creating better organizational structure.

internal/exercises/templates/41_regex/regex.go (1)

1-37: LGTM! Well-structured regex exercise template.

The template provides:

  • Clear task description with numbered objectives
  • Function skeletons with appropriate TODOs
  • Intentionally incorrect return values that will fail tests
  • Helpful comments indicating which regexp functions to use

This structure effectively guides learners through implementing regex functionality.

Comment on lines 52 to 54
<li>41_regex - Regular Expressions</li>
<li>42_string_functions - String Functions</li>
<li>36_json - JSON Processing</li>
Copy link

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion | 🟠 Major

🧩 Analysis chain

Verify exercise numbering sequence.

The new exercises 41_regex and 42_string_functions are listed before 36_json in the Advanced section. This breaks the numerical sequence. Consider either:

  • Reordering to maintain numerical sequence (36, 37, 41, 42)
  • Or renumbering these exercises to fit sequentially

However, if exercises 38-40 exist elsewhere and this ordering is intentional, this is acceptable.

Run this script to check if exercises 38, 39, and 40 exist in the catalog:


🏁 Script executed:

#!/bin/bash
# Check for exercises 38, 39, and 40 in the catalog
grep -E "slug: (38|39|40)_" internal/exercises/catalog.yaml

Length of output: 82


🏁 Script executed:

#!/bin/bash
# Check where exercises 38, 39, 40 appear in docs/exercises.md
grep -n "38_\|39_\|40_" docs/exercises.md

Length of output: 0


🏁 Script executed:

#!/bin/bash
# Show the full structure around lines 52-54 with context
sed -n '40,60p' docs/exercises.md

Length of output: 622


Reorder Advanced exercises in docs/exercises.md

  • In the Advanced (21-37) section, move <li>36_json – JSON Processing</li> and <li>37_xml – XML Processing</li> above the new entries (<li>41_regex – Regular Expressions</li>, <li>42_string_functions – String Functions</li>).
  • Update the section header to Advanced (21-42) if you intend to include 41 and 42 here.
🤖 Prompt for AI Agents
In docs/exercises.md around lines 52 to 54, the Advanced section items are out
of order and the header range is inconsistent: move the two existing items
<li>36_json – JSON Processing</li> and <li>37_xml – XML Processing</li> so they
appear above the new entries <li>41_regex – Regular Expressions</li> and
<li>42_string_functions – String Functions</li>, and update the Advanced section
header to read "Advanced (21-42)" to reflect inclusion of exercises 41 and 42.

Comment on lines 1 to 37
package regex

// Task:
// Implement regular expression functions using Go's regexp package.
//
// 1. Implement IsValidEmail to validate email addresses using regex.
// 2. Implement ExtractNumbers to extract all numbers from a string.
// 3. Implement ReplaceVowels to replace all vowels with asterisks.
// 4. Implement IsPhoneNumber to validate phone numbers in format (XXX) XXX-XXXX.

// IsValidEmail should return true if the email address is valid.
// A valid email should have the format: [email protected]
func IsValidEmail(email string) bool {
// TODO: implement using regexp.MustCompile and MatchString
return false
}

// ExtractNumbers should return all numbers found in the input string.
// Numbers can be integers or decimals (e.g., "123", "45.67").
func ExtractNumbers(text string) []string {
// TODO: implement using regexp.FindAllString
return nil
}

// ReplaceVowels should replace all vowels (a, e, i, o, u) with asterisks.
// Case-insensitive replacement.
func ReplaceVowels(text string) string {
// TODO: implement using regexp.MustCompile and ReplaceAllString
return ""
}

// IsPhoneNumber should return true if the phone number matches format (XXX) XXX-XXXX.
// Example: (123) 456-7890
func IsPhoneNumber(phone string) bool {
// TODO: implement using regexp.MustCompile and MatchString
return false
}
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🔴 Critical

🧩 Analysis chain

Solution file contains only placeholder implementations.

This file is located in the solutions/ directory but contains only TODO comments and placeholder return values. Solution files should provide working reference implementations that pass all tests, unlike template files which intentionally fail.

Verify whether this is intentional or if the actual regex implementations need to be added.


I'll verify the repository structure and conventions around solution files to determine if this is a legitimate concern.


🏁 Script executed:

#!/bin/bash
# Check if the file exists and examine surrounding structure
echo "=== File existence and location ==="
find . -type f -name "regex.go" | head -20

echo -e "\n=== Directory structure around solutions/41_regex/ ==="
fd -t d "41_regex|regex" | head -20

echo -e "\n=== Check for template vs solutions structure ==="
find . -type d \( -name "solutions" -o -name "template" -o -name "templates" \) | head -10

echo -e "\n=== List solution files to understand pattern ==="
find . -path "*/solutions/*" -name "*.go" -type f | head -15

Length of output: 1280


🏁 Script executed:

#!/bin/bash
# Examine content of a few solution files to see if they have implementations or just placeholders
echo "=== Sample solution files content ==="
for file in $(find . -path "*/solutions/*" -name "*.go" -type f | head -5); do
  echo "File: $file"
  echo "First 30 lines:"
  head -30 "$file"
  echo -e "\n---\n"
done

Length of output: 1896


🏁 Script executed:

#!/bin/bash
# Check for documentation about the exercise structure
echo "=== Looking for README or documentation ==="
find . -iname "readme*" -o -iname "*.md" | grep -E "(exercise|solution|regex)" | head -10

echo -e "\n=== General README files ==="
find . -maxdepth 3 -iname "readme*" -type f

Length of output: 105


🏁 Script executed:

#!/bin/bash
# Compare the template and solution regex.go files
echo "=== SOLUTIONS FILE: solutions/41_regex/regex.go ==="
cat ./internal/exercises/solutions/41_regex/regex.go

echo -e "\n=== TEMPLATES FILE: templates/41_regex/regex.go ==="
cat ./internal/exercises/templates/41_regex/regex.go

Length of output: 2756


🏁 Script executed:

#!/bin/bash
# Check documentation to understand the intent
echo "=== EXERCISES DOCUMENTATION ==="
cat ./docs/exercises.md

Length of output: 2798


Populate regex solution file with real implementations
The file internal/exercises/solutions/41_regex/regex.go is identical to its template and only contains TODO placeholders. Unlike other solution files, it needs working implementations of IsValidEmail, ExtractNumbers, ReplaceVowels, and IsPhoneNumber using Go’s regexp package so that all tests pass.

🤖 Prompt for AI Agents
In internal/exercises/solutions/41_regex/regex.go around lines 1-37 the four
functions are unimplemented; implement them using Go's regexp package:
IsValidEmail should compile a basic anchored email pattern (e.g.
`^[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,}$`) and return
regexp.MustCompile(...).MatchString(email); ExtractNumbers should use a regex
like `\d+(?:\.\d+)?` and return re.FindAllString(text, -1); ReplaceVowels should
use a case-insensitive vowel regex `(?i)[aeiou]` and return
re.ReplaceAllString(text, "*"); IsPhoneNumber should use an anchored pattern for
`(XXX) XXX-XXXX` like `^\(\d{3}\) \d{3}-\d{4}$` and return MatchString(phone).
Ensure proper return types and no panics by using regexp.MustCompile as
requested.

@kaushalyap
Copy link
Collaborator

@aryasoni98 Please limit the PR scope to a single exercise.

…ctions (zhravan#77)

- Removed all 41_regex exercise files (templates and solutions)
- Removed 41_regex entry from catalog.yaml
- Updated docs/exercises.md:
  - Removed regex reference
  - Reordered exercises (36_json, 37_xml before 44_string_functions)
  - Updated section header to 'Advanced (21-44)'
- PR now focuses solely on String Functions exercise as requested
- Integrated new exercises from main: 44_atomic_counters, 45_range_over_channels, 46_non_blocking_channel_operations
- Renumbered string_functions from 44 to 47 to avoid conflicts
- Updated catalog.yaml with all exercises in proper order
- Updated docs/exercises.md section header to Advanced (21-47)
@kaushalyap kaushalyap added the patch Bug fixes and small improvements label Nov 26, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

patch Bug fixes and small improvements

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Concept] String Functions - add exercise templates

2 participants