Introduction
Language models have become surprisingly capable code and data partners. Used well, they can generate working scripts, explain unfamiliar codebases, debug logic errors, convert data between formats, write SQL queries, and produce outputs in precise structured formats that downstream systems can consume directly. Used carelessly, they produce plausible-looking code that silently does the wrong thing, data transformations with edge-case bugs, and structured output that looks correct but breaks parsing.
This lesson is for practitioners who are not necessarily professional software engineers but who increasingly need to work with code and structured data — analysts, researchers, operations professionals, educators, and anyone who uses spreadsheets, databases, or automation tools. You do not need to be a developer to benefit from these capabilities, but you do need a framework for prompting, reviewing, and validating technical outputs that is more rigorous than what you would apply to a prose summary.
We will cover three areas: how to prompt effectively for code generation and debugging; how to work with tabular data, transformations, and analysis; and how to reliably produce structured outputs — JSON, CSV, and similar formats — that integrate cleanly with other tools and workflows.
Prompting for Code: What Works and What Does Not
The single most important principle for code generation is specificity about context. A prompt that says "write a Python script to process my data" will produce something generic and almost certainly not useful. A prompt that says "write a Python 3.11 script that reads a CSV file with columns 'name', 'email', 'signup_date', removes rows where email is blank, converts signup_date from MM/DD/YYYY to ISO 8601 format, and writes the result to a new CSV" will produce something targeted and often correct.
Include the language and version, the data structure or schema, the specific operation you want performed, the output format, and any constraints (libraries to use or avoid, performance considerations, error handling requirements). The more precisely you specify the task, the less the model has to guess — and guessing is where errors come from. If you are working with an existing codebase, paste the relevant function or class directly into the context window rather than describing it. Models cannot read your mind or your file system; everything they need must be in the prompt.
When debugging, do not just paste an error message and ask "what's wrong." Include the full error traceback, the relevant code, what you expected to happen, and what actually happened. This gives the model all the information a competent human debugger would need. Models are often very good at spotting off-by-one errors, type mismatches, and common library misuse — but only if they can see enough context. If the model suggests a fix, read it before running it. Understand what changed and why. Blindly applying AI-suggested code patches is how subtle bugs get introduced.
Always test AI-generated code against representative inputs, including edge cases: empty input, unexpectedly large input, inputs with special characters, missing fields. LLMs write code that handles the happy path very well and edge cases inconsistently. A code review mindset — reading the output skeptically before running it — is the essential complement to AI-assisted code generation.
Working with Tabular Data and Analysis
LLMs with access to a code interpreter (such as the Python environment available in several major AI assistants) can perform genuine data analysis: computing statistics, filtering rows, joining tables, generating charts, and running regressions. Without a code interpreter, they can only write code that you then run yourself — which is still valuable but requires an extra step and transfers the execution risk to you.
For data analysis tasks, structure your prompt around three things: the schema (what columns exist and what they contain), the question you want answered (not the method, but the business question), and any constraints on the output (table format, chart type, level of precision). Providing a sample of the data — even five to ten rows — dramatically improves output quality because it removes ambiguity about data types, null representations, and naming conventions.
Be alert to statistical errors in LLM-generated analysis. Models can produce code that computes a mean where a median is appropriate, aggregates data at the wrong granularity, fails to handle missing values correctly, or performs a join that silently drops or duplicates rows. These are not hallucinations in the usual sense — the code may run without errors and produce a number — but the number may be wrong. The solution is to validate analytical outputs by checking them against known reference points, testing with a subset of data whose answer you can verify manually, and reading the generated code rather than trusting only the final result.
When the goal is not analysis but data transformation — reshaping, cleaning, merging, or exporting data — LLMs are particularly useful and the outputs are easier to validate. Feed in a before-and-after example ("this is what the input looks like, this is what the output should look like") and ask the model to write the transformation. Then run it on a small subset, verify the output, and scale up. This few-shot approach to data transformation prompting is one of the highest-value applications of LLMs for non-technical professionals.
Producing and Consuming Structured Outputs
When you need LLM output that will be consumed programmatically — by another script, an API, a database, or a downstream pipeline step — you need structured output, not prose. The most common format is JSON. Prompting for structured output requires being explicit about the exact schema you expect: field names, data types, whether fields are optional or required, and how to handle cases where information is missing or ambiguous.
A reliable prompting pattern is to include an example of the exact output structure you want, using realistic but fictional data. This is more reliable than a prose description of the schema, because the model can pattern-match against the example. For critical applications, also instruct the model on what to do when it cannot determine a value — return null, return an empty string, return a specific sentinel value — rather than leaving it to guess. Inconsistent handling of missing data is one of the most common causes of downstream parsing failures.
Most modern API-accessible LLMs support a "structured output" or "JSON mode" feature that constrains the model to produce output matching a specified JSON schema. If your workflow allows API access, use this feature — it eliminates an entire category of format errors. If you are working with a chat interface that does not support this, add a validation step: parse the JSON in your code before using it, and if parsing fails, send the malformed output back to the model with an instruction to fix the formatting error.
Understanding the limits of structured output is also important. LLMs will sometimes invent field values that were not in the source material rather than return null, especially if the schema implies a field is always present. This is a form of hallucination specific to structured output tasks. Design your schemas to make absence explicit — include an "uncertain" or "not_found" option wherever the information might genuinely be missing.
Key Terms
- Code generation (ਕੋਡ ਉਤਪਾਦਨ): Using an LLM to produce executable source code from a natural-language description of the desired behavior.
- Schema (ਸਕੀਮਾ): A formal description of data structure — field names, types, and constraints — that defines what valid input or output looks like.
- JSON mode (ਜੇਸਨ ਮੋਡ): An API feature that constrains the LLM to produce output matching a specified JSON schema, eliminating format inconsistencies.
- Data transformation (ਡੇਟਾ ਰੂਪਾਂਤਰਣ): The process of converting data from one structure, format, or representation to another.
- Edge case (ਹਾਸ਼ੀਏ ਦੀ ਸਥਿਤੀ): An input scenario at the boundary of expected behavior — empty data, extreme values, missing fields — where code is most likely to fail.
- Validation (ਤਸਦੀਕ): The process of checking that an output meets required criteria before using or passing it downstream.
Discussion Questions
- How should the standard for reviewing AI-generated code differ between a one-off personal script and code that will run in a shared production environment? What review steps would you add for higher-stakes contexts?
- The lesson recommends providing sample data when prompting for data analysis. What are the privacy implications of pasting real data into a commercial AI assistant? How might you work around this?
- If an LLM produces an analysis that gives the wrong answer because it aggregated data at the wrong level of granularity, is this a prompting failure, a model failure, or a user responsibility failure? How do you allocate responsibility?
- What habits from traditional software development — code review, testing, version control — transfer directly to working with AI-generated code, and which new habits do you need to add?
Further Reading
- Zhengyuan Yang et al., "Code Generation with AlphaCode," Science (2022)
- Anthropic, Tool Use and Structured Outputs, Claude Documentation (2024)
- Simon Willison, Using LLMs for Data Analysis: Practical Patterns, simonwillison.net (2024)
Key Takeaways
- Effective code generation prompting requires specificity about language, version, data schema, expected behavior, and constraints — the more context you provide, the less the model guesses.
- AI-generated code must be read and reviewed before running, with particular attention to edge cases, data type handling, and error conditions.
- For structured output tasks, include an exact example of the output schema and specify how to handle missing or uncertain values; use JSON mode when API access is available.
- Data analysis outputs should be validated against known reference points before being trusted — a plausible-looking number is not the same as a correct number.
Homework
Choose a small, real data task from your work or studies — converting a list between formats, cleaning a set of records, summarizing tabular information, or writing a simple query. Write a prompt for an LLM that includes: the programming language or format, a description or sample of the input data, a precise description of the desired output, and at least one constraint (error handling, output format, or a library preference). Run the prompt, review the output critically, and test it against at least one edge case (empty input, a missing field, or an unusual value). Write 200–250 words documenting what worked, what failed, and what you changed in your prompt or in the code to fix the failure.