Skip to content
Open
Changes from all 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
24 changes: 24 additions & 0 deletions string_utils.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
"""String utility helpers."""


def truncate(s: str, max_length: int) -> str:
if max_length < 0:
raise ValueError("max_length must be non-negative")

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Missing test coverage: The ValueError path for negative max_length is untested. A unit test passing -1 should assert this raises ValueError. Without it, any future refactor of this guard could silently drop the validation.

  • Mark as noise

return s[:max_length]


def capitalize_words(s: str) -> str:
return ' '.join(word.capitalize() for word in s.split())


def count_vowels(s: str) -> int:
return sum(1 for c in s.lower() if c in 'aeiou')


def reverse_words(s: str) -> str:
return ' '.join(s.split()[::-1])


def is_palindrome(s: str) -> bool:
cleaned = ''.join(c.lower() for c in s if c.isalnum())
return cleaned == cleaned[::-1]
Comment on lines +22 to +24

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Missing test coverage: The cleaning step (strip non-alphanumeric, lowercase) is non-trivial and has at least two untested edge cases:

  • Empty string input ("") — returns True (vacuously a palindrome); confirm this is intentional.
  • Mixed-case input with punctuation (e.g. "A man, a plan, a canal: Panama") — exercises both the isalnum() filter and the .lower() call together.

A unit test covering each of these would catch regressions in the cleaning logic independently of the palindrome check itself.

  • Mark as noise

Loading