← All Kits · Exploratory Data Analysis · SQL Kit

Technical Tenacity: The Analyst Skill Nobody Puts on the Syllabus

Working through it when the data fights back · Part of the Analyst Prep Kit

Every tutorial sells the montage: import the data, write the query, admire the insight. Here is what an actual working day contains: a website's firewall blocks you for no reason, a table that visibly exists tells your script it doesn't, a query runs for thirty minutes with no end in sight, and a fix you know is correct changes nothing at all. None of that means you're doing it wrong. That IS the job. The skill that separates people who ship analyses from people who quit isn't analytical brilliance — it's technical tenacity: staying methodical when the tools fight back. And crucially, it is not a personality trait you either have or lack. It's a small, learnable procedure.

What's here
  1. The diagnosis loop (tenacity is a method, not a mood)
  2. Four true stories from one working day
  3. The rules, distilled
  4. Why the struggle is literally where the learning is
  5. References

The diagnosis loop (tenacity is a method, not a mood)

Gritting your teeth and re-running the same thing harder is not tenacity; it's frustration with extra steps. What experienced people actually run is a loop:

StepMove
1. Read the actual messageNot "it's broken" — the words. Error messages name the symptom precisely, even when the cause is elsewhere.
2. Form ONE hypothesis"The table isn't in the file the script reads." Specific enough to be wrong.
3. Run the cheapest test of itPrefer checks that take seconds — list the tables, count the rows, print one value.
4. Verify from a second vantage pointDon't ask the tool that's confusing you whether it's confused. Check the file from outside, the data from a different program, the value with a different query.
5. Change ONE thing, re-runChange three things and you'll never know which one mattered — or which one broke something new.
6. Timebox, then change strategyIf the current approach has eaten 30 minutes with no progress, stopping is a decision, not a defeat. There's usually a second road.

Four true stories from one working day

Everything below happened in a single day of real portfolio-project work — building a music dataset from a chart archive and a live API. Not a bad day, either. A normal one.

Story 1: the firewall says no

The wall: signing up for a free API key, the website's security firewall blocked the request outright — "Error 406", try again later. Nothing about the request was wrong.

The move: recognize the class of problem first: this one is environmental. No amount of staring at your own code fixes a remote firewall. The playbook for environmental blocks is its own little ladder — refresh once, log in first and retry, different browser, different network, wait and retry — cheapest first. The second rung worked.

The lesson: before debugging yourself, ask whether the problem is even yours. Environment problems get retry ladders, not code fixes.

Story 2: the table that existed and didn't

The wall: a Python script crashed with no such table: known_artists — while the database app, open at the same moment, showed that table plainly in its interface.

The move: verify from a second vantage point. Listing the tables inside the database FILE (from outside the app) showed the table genuinely absent — plus a tell-tale journal file next to the database. The app had been holding the new table in its unsaved-changes area; one click of Write Changes and both programs agreed.

The lesson: two tools disagreeing about reality means they're looking at different realities — find the second vantage point and ask which one is canonical. And: an error message names the missing thing, not the cause. "No such table" sounded like the table was never built; the real cause was one unclicked button.

Story 3: the thirty-minute query

The wall: a join between two modest tables (13,000 × 33,000 rows) ran for over half an hour. The stop button didn't even work; the app had to be killed from Task Manager.

The move: timebox and switch strategy. The cause was mechanical — both join keys were wrapped in functions, disabling any index and forcing ~427 million row-by-row comparisons (the full story is in the large-datasets guide). The first fix attempt (a fancier index) didn't take either. The second strategy — precompute the cleaned keys into real columns, index those, join plainly — worked in seconds. Two strategy changes, zero heroic waiting.

The lesson: a query that's still running is not progress you'd lose by stopping it. Killing a doomed approach IS the tenacious move; waiting on it is just hope. And when Plan A's fix doesn't take, there is almost always a Plan B shaped differently, not just a Plan A tried harder.

Story 4: the fix that changed nothing

The wall: a title-cleaning rule was added to recover missed matches — clearly correct, aimed at rows that visibly needed it ("Dreams - 2004 Remaster" failing to match "Dreams"). Re-run: the match rate was identical. Not close — identical to the digit.

The move: exactly-zero change is its own diagnosis. A wrong rule changes results a little; a rule that never executed changes them not at all. Testing the rule's logic directly (seconds) proved it worked perfectly — so the saved tables must have been built by something else. Culprit: an editor pane holding several look-alike code blocks, and the old one got run. Clear the editor, run only the new block, done.

The lesson: when a change produces exactly no difference, suspect the change never ran before suspecting it's wrong. Verify what actually executed — process failures masquerade as logic failures constantly.

The rules, distilled

RuleOne-line version
The errors are the jobPlan for them in your time estimates; they are not evidence you're failing.
Classify before debuggingEnvironmental, state, performance, or logic? Each class has a different playbook.
Cheapest test firstA ten-second count beats a ten-minute rebuild as a hypothesis test.
Second vantage pointConfirm reality with a tool other than the one confusing you.
One change at a timeOtherwise success and failure are both unexplainable.
Exactly-zero change = didn't runIdentical results to the digit point at process, not logic.
Timebox, then switch shapePersistence means trying the next strategy, not the same one louder.
Log the war storyEvery solved wall goes in the project's data-quality or troubleshooting notes — the working record — so it's a lesson once and never a mystery twice.

Why the struggle is literally where the learning is

Two findings from the research make the case that the fights are not wasted time. Duckworth and colleagues found that grit — sustained perseverance toward long-term goals — predicted achievement in demanding settings over and above talent measures (Duckworth, Peterson, Matthews, & Kelly, 2007). And Kapur's "productive failure" studies found that learners who struggled with problems before receiving the polished solution outperformed those taught the clean method first, on the deeper measures that matter (Kapur, 2008). The wall you hit and worked through is not the tax you paid to learn; it's a large part of the learning itself. Which is also why this site's project walkthroughs keep their mistakes in: a cleaned-up success story teaches less than a survived mess.

One honest caveat so this doesn't curdle into hustle-culture: tenacity is a method for solvable technical walls, not a duty to suffer. The timebox rule exists because knowing when to stop, ask, or route around is part of the skill. Ask-for-help is a debugging strategy with an excellent track record.

Build the reflexes on real data.

The Portfolio Projects and the Steam / Streaming Hidden Gems repos keep every wall and fix on the record, and the free SQL Kit covers the query skills the diagnosis loop leans on.

Open Portfolio Projects →

References

  1. Duckworth, A. L., Peterson, C., Matthews, M. D., & Kelly, D. R. (2007). Grit: Perseverance and passion for long-term goals. Journal of Personality and Social Psychology, 92(6), 1087–1101.
  2. Kapur, M. (2008). Productive failure. Cognition and Instruction, 26(3), 379–424. doi:10.1080/07370000802212669