Interview cheatsheet
Everything on one page. The TypeScript→Python map, the exact SDK shapes, the agent loop, and lines to say in the room.
TypeScript → Python, at a glance
| TypeScript | Python |
|---|---|
console.log(x) | print(x) |
// comment | # comment |
let x = 5 / const x = 5 | x = 5 |
\Hi ${name}`` | f"Hi {name}" |
{ } blocks | indentation (4 spaces) + : |
=== / !== | == / != |
&& / ` | |
null / undefined | None |
true / false | True / False |
x === null | x is None |
arr.push(x) | arr.append(x) |
arr.length | len(arr) |
arr.includes(x) | x in arr |
arr.map(f) | [f(x) for x in arr] |
arr.filter(p) | [x for x in arr if p(x)] |
obj.key | obj["key"] |
obj.key ?? d | obj.get("key", d) |
Object.entries(o) | o.items() |
JSON.parse / JSON.stringify | json.loads / json.dumps |
function f(a: string) {} | def f(a: str): |
async function / await | async def / await |
Promise.all([...]) | asyncio.gather(...) |
try { } catch (e) { } | try: ... except Exception as e: ... |
throw new Error("x") | raise ValueError("x") |
x => x * 2 | lambda x: x * 2 |
Data structures
nums = [1, 2, 3] # list (array)
nums.append(4); nums[-1] # push; last element
nums[1:3] # slice indices 1,2
point = (10, 20) # tuple (fixed-size)
x, y = point # unpack
msg = {"role": "user"} # dict (object / JSON)
msg["role"]; msg.get("k", 0) # access; safe default
for k, v in msg.items(): ... # iterate entries
names = {"ada", "grace"} # set (unique)
[n*2 for n in nums if n > 1] # comprehension = map + filter
Calling Claude (Anthropic Python SDK)
from anthropic import Anthropic
client = Anthropic() # reads ANTHROPIC_API_KEY
response = client.messages.create(
model="claude-opus-4-8", # default model
max_tokens=1024, # REQUIRED — output cap
system="You are concise.", # system prompt is top-level, NOT a message
messages=[
{"role": "user", "content": "Explain agents in one line."},
],
thinking={"type": "adaptive"}, # extended thinking on 4.6+ (no budget_tokens)
)
print(response.content[0].text) # content is a LIST of blocks
print(response.stop_reason) # "end_turn" | "tool_use" | "max_tokens" | ...
Stream long / high-max_tokens calls and grab the whole thing at the end:
with client.messages.stream(model="claude-opus-4-8", max_tokens=2048,
messages=messages) as stream:
final = stream.get_final_message()
Model IDs: claude-opus-4-8 (default) · claude-sonnet-5 · claude-haiku-4-5 · claude-fable-5 (most capable).
Tools & the agent loop
A tool = a JSON-schema description (for the model) + a function (for you).
tools = [{
"name": "get_weather",
"description": "Get current weather for a city.",
"input_schema": {
"type": "object",
"properties": {"city": {"type": "string"}},
"required": ["city"],
},
}]
The loop — the single most important thing to be able to whiteboard:
messages = [{"role": "user", "content": "Weather in Paris?"}]
while True:
resp = client.messages.create(
model="claude-opus-4-8", max_tokens=1024,
tools=tools, messages=messages,
)
if resp.stop_reason == "end_turn":
print(resp.content[0].text) # done
break
# 1) append the model's ENTIRE response
messages.append({"role": "assistant", "content": resp.content})
# 2) run each tool_use, collect a tool_result per call
results = []
for block in resp.content:
if block.type == "tool_use":
try:
out = TOOLS[block.name](**block.input) # your code runs
except Exception as e:
out = f"error: {e}" # never crash the loop
results.append({
"type": "tool_result",
"tool_use_id": block.id, # MUST match the tool_use id
"content": str(out),
})
# 3) send all results back in ONE user message, then loop
messages.append({"role": "user", "content": results})
Less boilerplate:
@beta_tool+client.beta.messages.tool_runner(...)runs this exact loop for you.
Structured output (JSON you can trust)
from pydantic import BaseModel
class Person(BaseModel):
name: str
age: int
# messages.parse() validates the reply against the schema for you:
resp = client.messages.parse(
model="claude-opus-4-8", max_tokens=1024,
messages=[{"role": "user", "content": "Ada Lovelace, 36"}],
output_config={"format": {"type": "json_schema", "schema": Person.model_json_schema()}},
)
person = resp.parsed_output # a validated Person
Production guardrails
- Cap turns —
for turn in range(max_turns), decide what happens if you hit it. - Catch tool exceptions — return the error as the
tool_result; don't crash the loop. - Retry with backoff — wrap the model call; double the delay each attempt; give up after N.
- Validate tool inputs — Pydantic on the model's arguments before any irreversible action.
- Async when it helps —
AsyncAnthropic+asyncio.gatherto overlap independent I/O.
Say these out loud
- "An agent is a loop: the model proposes an action, my code executes it, the result goes back, repeat until
end_turn." - "Every
tool_useneeds exactly onetool_resultwith a matchingtool_use_id, all in a single user message." - "
max_tokensis required;systemis a top-level arg, not a message; the reply is a list of content blocks." - "I cap turns, catch tool errors, retry the API call with exponential backoff, and validate arguments before side effects."
- "Sync client for one-shots;
AsyncAnthropic+gatherto parallelize; stream long responses and readget_final_message()."