Strings (Text)
Make, slice, and clean text with concat, split, join, strip, and replace — the work of prompts and tool names.
A string (str) is text. Almost everything a model touches is a string: the prompt, the tool name, the JSON text, and the result you feed back. If you can cut, clean, glue, and search strings, you can debug a lot of agent failures.
Strings are immutable. That means you cannot change one character in place. Any “change” builds a new string. The old one stays if another name still points at it.
Quotes and new lines
Single quotes or double quotes both work. Use the other kind inside the string. "He said 'stop'" is fine. 'He said "stop"' is fine. If you need both kinds, you will later escape with a backslash, or use triple quotes.
Triple quotes make text with more than one line. That is useful for prompts. The line breaks inside the triple quotes are part of the string.
A backslash plus n in Python source is a new line. Those two characters tell Python to break the line. In a live box it is safer to build a multi-line string with chr(10).join(...), because chr(10) is the new-line character. splitlines() then splits on that character.
tool = class="tok-s">"search"
line = class="tok-s">'He said "stop"'
prompt = class="tok-s">"""You are a careful agent.
Call tools only when needed."""
print(tool)
print(line)
print(prompt)
print(chr(10).join([class="tok-s">"hello", class="tok-s">"world"]))An empty string is "". It is still a string. Its length is 0. It is not None.
Index and slice
Characters are numbered from 0. The first character is s[0]. The last character is s[-1]. s[1] is the second character.
A slice keeps a piece. The original string does not change. "Act" is the first three letters.
Letters in a row, counted from 0A slice is a piece of the text. s[:3] is the first three characters. s[0:3] is the same thing: characters at 0, 1, and 2. The 3 is where to stop. It is not included. s[3:] is from index 3 to the end.
s = class="tok-s">"Action"
print(s[0]) class="tok-c"># A
print(s[-1]) class="tok-c"># n
print(s[:3]) class="tok-c"># Act
print(s[3:]) class="tok-c"># ion
print(s[1:4]) class="tok-c"># ctiYou cannot change one character in place. s[0] = "a" fails with TypeError. Build a new string instead: "a" + s[1:].
A bad index raises IndexError. s[99] crashes on a short string. A slice does not crash. s[99:120] is "".
Glue text with +
To fill names into a line, concatenate: join strings with +. Every piece must be a string. Numbers need str(...).
tool = class="tok-s">"search"
city = class="tok-s">"nyc"
step = 1
print(class="tok-s">"Calling " + tool + class="tok-s">" for " + city)
print(class="tok-s">"step " + str(step))print("Calling", tool, "for", city) also works, because print inserts spaces. Use + when you need one string to store, not only to show: a prompt, a tool argument, a file name.
Do not build JSON by gluing quotes yourself if values can hold quotes. "{\"q\": " + city + "}" breaks when city has a quote. The json library comes later and does that job safely.
Repeating text uses : "ab" 3 is "ababab". Useful for a tiny fence of backticks later, not for prompts.
Clean text: strip, split, join, replace
| Method | What it does |
|---|---|
s.strip() | Remove spaces at the start and end |
s.split() | Break on spaces into a list (a row of values) |
s.split(",") | Break on a chosen mark |
",".join(parts) | Glue a row of strings into one string |
s.replace(a, b) | Copy the text with a change |
s.lower() | Make letters lowercase |
s.upper() | Make letters uppercase |
None of these change s. They return a new string or a new list. You must use the return value: clean = line.strip(). Writing line.strip() alone throws the clean copy away.
join belongs to the glue string. You write the glue first: " | ".join(parts). Every part must be a string. " ".join([1, 2]) fails. Convert first, or join names you already know are text.
len(s) counts characters. For a size limit, character count is a simple way to estimate tokens. It is not a real tokenizer. It is good enough to stop a prompt from growing without bound while you learn.
Model output often has extra spaces and extra new lines. strip() before you compare. "search" == "search\n" is False until you strip. In code, strip the model line, then compare.
Check the start, the end, and each line
| Method | What it does |
|---|---|
s.startswith("https://") | True if the text begins this way |
s.endswith(".json") | True if the text ends this way |
s.find("error") | Index of the first match, or -1 if missing |
s.splitlines() | Break on new lines into a list |
find is safer than index. index crashes when the piece is missing. find gives -1. Use find unless you want a crash.
splitlines() walks a multi-line model reply. It still works when the line break is Windows-style. Later you will use first-line / last-line checks to strip markdown fences.
in works on strings too: "act" in "action" is True. Warning: "error" in "terror" is True. For a full word, compare with ==, or use startswith / endswith, or split on spaces and test the list.
Common mistakes
"step " + 3—TypeError. Usestr(3).- Forgetting to save
strip()/replace()/lower(). - Off-by-one slices:
"abcdef"[1:4]is"bcd", not"bcde". - Using
indexon text that might not contain the piece. - Building JSON with
+and quotes. - Comparing without
strip, then wondering why the tool name never matches.
Run to execute this in your browser. Nothing is sent to a server.
Change city and run again. Then strip a tool name with extra spaces and compare it to "search". Matching names is most of tool routing.
How agents use this
Prompts, tool names, and model replies are all strings. You slice a long log to fit a size limit. You strip spaces, split lines, and glue names with + before you print a trace. You check startswith("https://") before a fetch tool runs. Clean the text first, then decide what the agent should do.
A typical tool-name path is: take the model line, strip(), maybe lower() if you chose case-insensitive names, then compare to an allowlist. If you skip strip, "search " is not "search", and the agent reports an unknown tool even though a human sees the right word.
JSON text is a string until you parse it. Fence stripping is string work: drop the first line if it starts with backticks, drop the last line if it is only backticks, then parse. You will write that parser later. It is this lesson’s methods in a row: splitlines, startswith, join, strip.
Character counts also gate cost. if len(prompt) > 8000: prompt = prompt[:8000] is a blunt knife, but it is a real budget. Better packing comes later. Knowing len and slices is how you hold the knife.
Check your understanding