AI Skill Report Card

Using Python String Methods

B+78·Aug 12, 2026·Source: Web
13 / 15
Python
# Common patterns at a glance " hello world ".strip() # 'hello world' "hello,world,foo".split(",") # ['hello', 'world', 'foo'] ",".join(["a", "b", "c"]) # 'a,b,c' "Hello {}!".format("World") # 'Hello World!' f"Hello {name}!" # preferred over .format() for literals "HELLO".lower() # 'hello' "hello".startswith("he") # True "hello".replace("l", "L") # 'heLLo' b"data".decode("utf-8") # str "data".encode("utf-8") # bytes
Recommendation
Add a couple of 'bad outcome' examples showing incorrect code alongside the fix, since currently all examples show only correct usage
13 / 15
  1. Identify the data type: str (text), bytes/bytearray (binary/encoded). Never mix str and bytes in one operation — decide which you have and convert explicitly with .encode()/.decode().
  2. Pick the narrowest method for the task — don't hand-roll logic that a stdlib method already does (see table below).
  3. Prefer immutable-safe patterns: str and bytes are immutable; every "modifying" method returns a new object. Use bytearray only when in-place mutation is actually needed.
  4. Format output with f-strings unless building a template string dynamically at runtime (then use .format()) or doing legacy %-formatting (avoid in new code).

Method Selection Cheat Sheet

TaskMethod
Remove whitespace/chars from ends.strip(), .lstrip(), .rstrip()
Split on delimiter.split(sep), .rsplit(sep, maxsplit)
Split on any whitespace, drop empties.split() (no args)
Split into exactly 2 parts at first/last match.partition(sep), .rpartition(sep)
Split preserving line breaks.splitlines(keepends=False)
Join iterable of stringssep.join(iterable)
Case-insensitive-ish comparison.casefold() (not .lower(), for Unicode correctness)
Check prefix/suffix.startswith(x), .endswith(x) — accepts tuples
Find substring index (or -1).find(), .rfind()
Find substring index (raises if missing).index(), .rindex()
Count occurrences.count(sub)
Replace substring.replace(old, new, count=-1)
Pad string.ljust(), .rjust(), .zfill(), .center()
Test content type.isdigit(), .isalpha(), .isalnum(), .isspace(), .isupper(), etc.
Translate chars via mappingstr.maketrans() + .translate()
Template substitution.format(), f-strings, or string.Template for user-supplied templates
bytes ↔ str.encode(encoding), .decode(encoding)
Recommendation
The description is a bit generic ('parses, formats, searches...') — could tighten triggers to specific scenarios like 'validating filenames' or 'processing socket data' to sharpen when-to-use guidance
15 / 20

Example 1: Parsing a CSV-like line Input: line = " Alice, 30 , Engineer " Output:

Python
fields = [f.strip() for f in line.split(",")] # ['Alice', '30', 'Engineer']

Example 2: Safe substring check with multiple options Input: filename validation for .jpg/.png/.gif Output:

Python
if filename.lower().endswith((".jpg", ".png", ".gif")): process(filename)

Example 3: Splitting exactly once Input: "key=value=extra", need only first split Output:

Python
key, _, value = "key=value=extra".partition("=") # key='key', value='value=extra'

Example 4: bytes/str boundary Input: reading raw socket data data = sock.recv(1024) Output:

Python
text = data.decode("utf-8", errors="replace")
Recommendation
Consider adding a brief note on regex vs string methods tradeoff (when str methods are insufficient and re module is needed) to round out completeness
  • Use .casefold() over .lower() for case-insensitive comparisons (handles Unicode edge cases like German ß).
  • Use .partition()/.rpartition() instead of .split(sep, 1) when you need clean unpacking and no IndexError risk — partition always returns exactly 3 items.
  • Use in operator ("sub" in s) for existence checks instead of .find(sub) != -1 or .count(sub) > 0.
  • Use "".join(list_of_strs) for concatenating many strings — never build strings with += in a loop (O(n²)).
  • Always pass explicit encoding to .encode()/.decode() (default is 'utf-8' but being explicit avoids platform surprises and documents intent).
  • Use str.maketrans() + .translate() for fast multi-character replacement instead of chained .replace() calls.
  • For .split(), calling with no arguments (splits on any whitespace, collapses consecutive whitespace, strips empties) differs from .split(" ") (splits on literal single space, keeps empty strings) — pick deliberately.
  • Confusing .strip(chars) semantics: .strip("xy") strips any combination of characters x and y from ends, not the literal substring "xy".
  • Using .split(sep, 1)[1] for parsing: raises IndexError if sep is absent. Prefer .partition() which never raises.
  • Mixing str/bytes: TypeError: can't concat str to bytes. Always decode/encode at I/O boundaries, work in str internally.
  • Using .index()/.rindex() without a try/except or existence check when the substring might be absent — they raise ValueError; use .find() if -1 is an acceptable sentinel.
  • Locale/Unicode-unaware case comparisons with .lower() for security-sensitive checks (e.g., filename comparisons) — use .casefold().
  • Forgetting str.format()/f-strings don't validate types"{}".format(obj) calls __format__/__str__, which may hide bugs if obj isn't what you expect.
  • Using %-style formatting in new code — legacy, error-prone with tuples; prefer f-strings.
0
Grade B+AI Skill Framework
Scorecard
Criteria Breakdown
Quick Start
13/15
Workflow
13/15
Examples
15/20
Completeness
17/20
Format
13/15
Conciseness
14/15