Write a polite but firm email to a landlord who has not fixed the heating for three weeks. I want the repair, not a fight.
Claude Opus 5.5
Subject: Heating Repair Needed at [Your Address] – Request for Repair Date
Dear [Landlord's Name],
I'm writing about the heating at [your address, unit number], which has not been working since [date the problem started]. I first reported it on [date of first report] and followed up on [date(s) of later contact], but it has now been about three weeks without a repair.
I appreciate that things can get busy. However, with the current temperatures, the flat is getting very cold, and it is becoming difficult to live in comfortably. [Optional: add a specific detail, e.g., "The indoor temperature has been dropping to around X°C/°F overnight," or "This is especially difficult because I work from home / have a young child."]
Could you please confirm by [specific date, e.g., Friday, March 8] when a repair technician will come? I'm happy to be flexible with access. I'm generally available [list days/times], and I can arrange access at other times if needed.
If there is anything you need from me to help move this forward, such as photos, a description of the problem, or a contact number for the technician, please let me know and I'll send it straight away.
Thank you for your help. I'd like to get this resolved quickly and smoothly for both of us.
Kind regards, [Your Name] [Your Phone Number] [Your Address / Unit Number]
A few tips to help you get results without creating conflict:
Send it in writing (email or letter) so you have a dated record, even if you've only called before.
Keep copies of all messages and note the dates of any calls.
If you get no reply by your deadline, send a short, calm follow-up. You could add a line such as: "I understand landlords are generally required to keep heating in working order, so I'd be grateful if we could arrange this as soon as possible." This reminds them of their obligation without sounding like a threat.
If it still isn't fixed, check your local tenant rights. Most areas have a housing authority or tenant advice service that can help.
Asked Nov 1, 2026. Unedited.
Claude Sonnet 5.5
Subject: Heating repair needed at [Address/Unit #]: follow-up and request for a date
Dear [Landlord's name],
I hope you're well. I'm writing about the heating in my unit at [address], which has not been working since [date]. I first reported it on [date of first report, and how: call, text, email], and it has now been about three weeks without a repair.
With temperatures [currently around X° / dropping], this has become a real problem. The apartment is consistently cold, and I'd like to get it resolved quickly for both comfort and safety.
I'd appreciate it if you could:
Confirm by [date, ideally 2 business days out] when a technician will visit.
Have the repair completed by [date, ideally within 5-7 days], or let me know if parts or other issues are causing a delay.
I'm happy to be flexible about access. I can be home [days/times], or I can arrange for entry if that's easier. Please let me know what works best.
I value being a tenant here and would like to sort this out cooperatively. If I don't hear back by [date], I may need to look into my options under [state/local] tenant rules, but I'd much prefer to avoid that and simply get the heat working.
Thank you for your attention to this. I look forward to hearing from you soon.
Best regards, [Your name] [Unit/address] [Phone number]
Tips for making it more effective:
Send it in writing, even if you've already called or texted. Email creates a record.
Fill in the dates. Specific deadlines are harder to ignore than "soon."
Keep copies of earlier messages, photos of a thermostat reading, and notes on any temperature readings.
Check local rules. Many places treat heat as an "essential service" with legal repair timelines, and some allow rent withholding or repair-and-deduct. Look up your area's rules before mentioning specific remedies. A local tenant union or housing agency can help.
If you don't get a response, send a short follow-up and consider certified mail or a call to your local housing or code enforcement office.
If you tell me your location and what you've done so far, I can tailor the wording and point out relevant tenant protections.
Asked Nov 1, 2026. Unedited.
Write a React hook that debounces a value and cancels on unmount. Include the TypeScript types.
Claude Opus 5.5
useDebouncedValue and useDebouncedCallback
Below are two hooks:
useDebouncedValue: debounces a value. This is what you asked for.useDebouncedCallback: debounces a function, withcancelandflushcontrols. It's useful when you need to debounce an event handler rather than state.
Both cancel any pending timer when the component unmounts, so no state update or callback runs after unmount.
1. useDebouncedValue
// useDebouncedValue.ts
import { useEffect, useState } from 'react';
/**
* Returns `value` after it has stopped changing for `delay` ms.
* Any pending update is cancelled when `value` or `delay` changes,
* or when the component unmounts.
*/
export function useDebouncedValue<T>(value: T, delay: number = 300): T {
const [debouncedValue, setDebouncedValue] = useState<T>(value);
useEffect(() => {
const timeoutId: ReturnType<typeof setTimeout> = setTimeout(() => {
setDebouncedValue(value);
}, delay);
// Runs before the next effect (value/delay changed) AND on unmount.
return () => {
clearTimeout(timeoutId);
};
}, [value, delay]);
return debouncedValue;
}Usage
import { useEffect, useState } from 'react';
import { useDebouncedValue } from './useDebouncedValue';
interface User {
id: string;
name: string;
}
export function UserSearch() {
const [query, setQuery] = useState<string>('');
const [results, setResults] = useState<User[]>([]);
const debouncedQuery = useDebouncedValue(query, 400);
useEffect(() => {
if (!debouncedQuery) {
setResults([]);
return;
}
const controller = new AbortController();
fetch(`/api/users?q=${encodeURIComponent(debouncedQuery)}`, {
signal: controller.signal,
})
.then((res) => res.json() as Promise<User[]>)
.then(setResults)
.catch((err: unknown) => {
if ((err as Error).name !== 'AbortError') console.error(err);
});
return () => controller.abort(); // cancel in-flight request too
}, [debouncedQuery]);
return (
<>
<input value={query} onChange={(e) => setQuery(e.target.value)} />
<ul>
{results.map((u) => (
<li key={u.id}>{u.name}</li>
))}
</ul>
</>
);
}2. useDebouncedCallback (with cancel / flush)
// useDebouncedCallback.ts
import { useEffect, useLayoutEffect, useMemo, useRef } from 'react';
export interface DebouncedFunction<Args extends unknown[]> {
(...args: Args): void;
/** Cancel any pending invocation. */
cancel: () => void;
/** Immediately invoke the pending call, if any. */
flush: () => void;
/** Whether a call is currently scheduled. */
isPending: () => boolean;
}
// useLayoutEffect warns during SSR; fall back to useEffect on the server.
const useIsomorphicLayoutEffect =
typeof window !== 'undefined' ? useLayoutEffect : useEffect;
export function useDebouncedCallback<Args extends unknown[]>(
callback: (...args: Args) => void,
delay: number = 300
): DebouncedFunction<Args> {
const callbackRef = useRef(callback);
const timeoutRef = useRef<ReturnType<typeof setTimeout> | null>(null);
const pendingArgsRef = useRef<Args | null>(null);
// Always call the latest callback without resetting the debounce timer.
useIsomorphicLayoutEffect(() => {
callbackRef.current = callback;
}, [callback]);
const debounced = useMemo<DebouncedFunction<Args>>(() => {
const invoke = (): void => {
const args = pendingArgsRef.current;
timeoutRef.current = null;
pendingArgsRef.current = null;
if (args) callbackRef.current(...args);
};
const cancel = (): void => {
if (timeoutRef.current !== null) {
clearTimeout(timeoutRef.current);
timeoutRef.current = null;
}
pendingArgsRef.current = null;
};
const fn = ((...args: Args): void => {
pendingArgsRef.current = args;
if (timeoutRef.current !== null) clearTimeout(timeoutRef.current);
timeoutRef.current = setTimeout(invoke, delay);
}) as DebouncedFunction<Args>;
fn.cancel = cancel;
fn.flush = () => {
if (timeoutRef.current !== null) {
clearTimeout(timeoutRef.current);
invoke();
}
};
fn.isPending = () => timeoutRef.current !== null;
return fn;
}, [delay]);
// Cancel on unmount (and when `delay` changes, which creates a new function).
useEffect(() => {
return () => debounced.cancel();
}, [debounced]);
return debounced;
}Usage
import { useDebouncedCallback } from './useDebouncedCallback';
export function AutoSaveEditor({ docId }: { docId: string }) {
const save = useDebouncedCallback((content: string) => {
void fetch(`/api/docs/${docId}`, {
method: 'PUT',
body: JSON.stringify({ content }),
});
}, 1000);
return (
<textarea
onChange={(e) => save(e.target.value)} // typed: (content: string) => void
onBlur={() => save.flush()} // save immediately when leaving
/>
);
}Notes
ReturnType<typeof setTimeout>keeps the timer type correct in both browser (number) and Node (Timeout) environments.Cancellation on unmount comes from the effect cleanup functions. React calls them on unmount, so
clearTimeoutstops any pendingsetStateor callback.Stable callback identity:
useDebouncedCallbackstores the latestcallbackin a ref. Passing an inline arrow function therefore doesn't reset the timer on every render. The returned function only changes whendelaychanges.StrictMode double-mounts effects in development. Both hooks handle this correctly because cleanup clears the timer before the effect runs again.
Asked Nov 1, 2026. Unedited.
Claude Sonnet 5.5
useDebounce hook
// useDebounce.ts
import { useEffect, useState } from "react";
/**
* Returns a debounced copy of `value` that only updates after `delay` ms
* have passed without `value` changing.
*
* The pending timer is cleared when `value` or `delay` changes,
* and when the component unmounts.
*/
export function useDebounce<T>(value: T, delay: number = 300): T {
const [debouncedValue, setDebouncedValue] = useState<T>(value);
useEffect(() => {
const timeoutId: ReturnType<typeof setTimeout> = setTimeout(() => {
setDebouncedValue(value);
}, delay);
// Runs before the next effect and on unmount
return () => clearTimeout(timeoutId);
}, [value, delay]);
return debouncedValue;
}Usage
import { useEffect, useState } from "react";
import { useDebounce } from "./useDebounce";
export function Search() {
const [query, setQuery] = useState("");
const debouncedQuery = useDebounce(query, 500);
useEffect(() => {
if (!debouncedQuery) return;
const controller = new AbortController();
fetch(`/api/search?q=${encodeURIComponent(debouncedQuery)}`, {
signal: controller.signal,
}).catch(() => {});
return () => controller.abort();
}, [debouncedQuery]);
return (
<input
value={query}
onChange={(e) => setQuery(e.target.value)}
placeholder="Search…"
/>
);
}Why this cancels correctly
The effect's cleanup function calls
clearTimeout. React runs it before re-running the effect (so each new value restarts the timer) and on unmount (sosetDebouncedValuenever fires on an unmounted component).ReturnType<typeof setTimeout>keeps the timer type correct in both browser (number) and Node (NodeJS.Timeout) typings.
Optional: version with cancel and flush
If you need manual control (e.g. flush on Enter, cancel on Escape):
// useDebouncedValue.ts
import { useCallback, useEffect, useRef, useState } from "react";
export interface DebounceControls {
/** Cancel the pending update, if any. */
cancel: () => void;
/** Apply the latest value immediately and cancel the pending timer. */
flush: () => void;
}
export function useDebouncedValue<T>(
value: T,
delay: number = 300
): [T, DebounceControls] {
const [debounced, setDebounced] = useState<T>(value);
const timerRef = useRef<ReturnType<typeof setTimeout> | null>(null);
const latestValue = useRef<T>(value);
latestValue.current = value;
const cancel = useCallback(() => {
if (timerRef.current !== null) {
clearTimeout(timerRef.current);
timerRef.current = null;
}
}, []);
const flush = useCallback(() => {
cancel();
setDebounced(latestValue.current);
}, [cancel]);
useEffect(() => {
cancel();
timerRef.current = setTimeout(() => {
timerRef.current = null;
setDebounced(latestValue.current);
}, delay);
return cancel; // cancels on change and on unmount
}, [value, delay, cancel]);
return [debounced, { cancel, flush }];
}const [debounced, { flush, cancel }] = useDebouncedValue(query, 500);
<input
value={query}
onChange={(e) => setQuery(e.target.value)}
onKeyDown={(e) => {
if (e.key === "Enter") flush();
if (e.key === "Escape") cancel();
}}
/>Asked Nov 1, 2026. Unedited.
A drug test is 99% accurate, and 0.5% of people use the drug. Someone tests positive. What is the probability they use it, and why does the answer surprise people?
Claude Opus 5.5
About 33%, or roughly 1 in 3
This assumes "99% accurate" means the test correctly flags 99% of users (sensitivity) and correctly clears 99% of non-users (specificity).
The calculation (Bayes' theorem)
$$ P(\text{user} \mid +) = \frac{P(+ \mid \text{user})\,P(\text{user})}{P(+ \mid \text{user})\,P(\text{user}) + P(+ \mid \text{non-user})\,P(\text{non-user})} $$
$$ = \frac{0.99 \times 0.005}{0.99 \times 0.005 + 0.01 \times 0.995} = \frac{0.00495}{0.0149} \approx 0.332 $$
The intuitive version: imagine 10,000 people
| Test positive | Test negative | Total | |
|---|---|---|---|
| Users (0.5%) | ~50 (99% of 50) | ~0.5 | 50 |
| Non-users (99.5%) | ~100 (1% of 9,950) | ~9,850 | 9,950 |
| Total | ~150 | 10,000 |
Of about 150 positive results, only about 50 are real users. The other ~100 are false positives. So a positive result means roughly a 1 in 3 chance of actual drug use.
Why it surprises people
Base rate neglect. People focus on the vivid "99% accurate" figure and ignore how rare drug use is. When a condition is rare, even a small error rate applied to the huge non-user population produces more false positives than there are true positives.
Confusing the two conditional probabilities. The test tells you P(positive | user) = 99%. People instinctively treat that as P(user | positive). These are very different numbers. "Most users test positive" does not mean "most positives are users."
The 1% error feels negligible. But 1% of 9,950 non-users (~100 people) is double the entire user population (50 people).
Practical takeaway
This is why positive screening results are confirmed with a second, independent test. If someone tests positive twice, the probability jumps to about 98%, because the first positive raises the "base rate" from 0.5% to 33% before the second test is applied. The same logic applies to medical screening for rare diseases, fraud detection, and security screening.
Asked Nov 1, 2026. Unedited.
Claude Sonnet 5.5
Answer: about 33%, not 99%.
Assumptions
"99% accurate" is interpreted as both:
Sensitivity of 99%: 99% of users test positive
Specificity of 99%: 99% of non-users test negative (a 1% false-positive rate)
Calculation (Bayes' theorem)
Imagine 100,000 people:
| Group | Count | Test positive |
|---|---|---|
| Users (0.5%) | 500 | 99% × 500 = 495 (true positives) |
| Non-users (99.5%) | 99,500 | 1% × 99,500 = 995 (false positives) |
Total positives = 495 + 995 = 1,490
$$P(\text{user} \mid +) = \frac{495}{1{,}490} \approx 0.332$$
Or in formula form:
$$P(U|+) = \frac{0.99 \times 0.005}{0.99 \times 0.005 + 0.01 \times 0.995} \approx 33.2\%$$
Why it surprises people
1. Base rate neglect. People focus on the test's accuracy and ignore how rare the drug use is. Because users are so scarce (0.5%), even a small false-positive rate applied to the huge non-user population produces more false positives than the true positives from the small user group.
2. Confusing two different conditional probabilities.
P(positive | user) = 99%, which is what the test's accuracy tells you
P(user | positive) ≈ 33%, which is what you actually want to know
These are not the same, and intuition tends to treat them as if they were.
3. Percentages hide the counts. A 1% error rate sounds tiny, but 1% of 99,500 people is 995, which is about double the 495 true users who test positive.
Key takeaways
The meaning of a positive result depends heavily on who is being tested. If the test were given to a group where 50% use the drug, a positive would be right about 99% of the time.
This is why screening for rare conditions (diseases, drugs, terrorism, etc.) typically requires confirmatory testing.
A helpful mental trick is to use natural frequencies ("495 out of 1,490") instead of probabilities. People reason about these far more accurately.
Asked Nov 1, 2026. Unedited.
Head to head
Ranked against 42 models, from public leaderboards and our own blind tests where we have them. How we rank
| Task | Claude Opus 5.5 | Claude Sonnet 5.5 | Leads |
|---|---|---|---|
| Coding | #1 | #4 | Claude Opus 5.5 |
| Writing | #1 | #4 | Claude Opus 5.5 |
| Math | #1 | #4 | Claude Opus 5.5 |
| Research | #1 | #4 | Claude Opus 5.5 |
| Everyday chat | #1 | #4 | Claude Opus 5.5 |
The facts
Scores from artificialanalysis.ai and lmarena.ai.
| Fact | Claude Opus 5.5 | Claude Sonnet 5.5 |
|---|---|---|
| Made by | Anthropic | Anthropic |
| API price, per 1M tokens | $4 in, $20 out | $2 in, $10 out |
| Speed | 97 tokens a second | 138 tokens a second |
| Artificial Analysis Index | 57.6 | 56.0 |
| LMArena text | 1,516 | 1,473 |
| LMArena coding | 1,545 | 1,510 |
| Updated | Oct 26, 2026 | |