10. Prompting for programmers
AIs can generate code, find bugs, explain complex concepts, and refactor. The quality of the code you get depends on how you formulate your prompts.
Specific principles for code
1. Specify language and version:
Create a function in Python 3.11 that sorts an array of integers. Use type hints and docstrings following PEP 257.
2. Mention the project context:
I'm working on a REST API with FastAPI. I need to add email validation to my Pydantic user model. The email must be unique in the database. Use Pydantic validators and handle the error appropriately.
3. Specify constraints:
AIs need to know allowed libraries, performance constraints, the team's code standards, and required compatibility.
Generating code from scratch
Basic example: simple function
Weak prompt:
Make a Fibonacci function.
Professional prompt:
Create a function in Python that calculates the n-th Fibonacci number.
Requirements:
- Use memoization to optimize performance
- Include type hints (Python 3.10+)
- Add a docstring with usage examples
- Handle edge cases (n=0, n=1, negative n)
- If n is negative, raise ValueError
Format:
- Name: fibonacci
- Parameter: n (int)
- Return: int
Expected example: fibonacci(10) -> 55
Advanced example: complete class
Create a Stack class in TypeScript with the following specifications:
Functional requirements:
- Methods: push, pop, peek, isEmpty, size
- Must be generic (support any type)
- push: adds an element to the top
- pop: removes and returns the element from the top (throws an error if empty)
- peek: returns the element from the top without removing it
- isEmpty: returns a boolean
- size: returns the number of elements
Technical requirements:
- Use an internal private array
- Implement with TypeScript strict mode
- All methods must have explicit types
- Add JSDoc comments to each method
- Include a commented usage example at the end
Error handling:
- pop on an empty stack: throw an Error with the message "Stack is empty"
- peek on an empty stack: throw an Error with the message "Stack is empty"
Debugging
Effective prompt:
I have a bug in this Python code:
<code>import csvdef process_csv(filename): with open(filename) as f: reader = csv.reader(f) for row in reader: print(row[3])
</code>
<error>IndexError: list index out of range</error>Context:
- Some CSVs have 3 columns, others 5
- I only need to process column 4 when it exists
- Python 3.10
Provide:
<diagnosis>Explanation of the error</diagnosis><solution>Corrected code</solution><improvements>Suggestions to make it more robust</improvements>
Explaining code
Explain this code step by step. I'm a junior developer.
<code>const debounce = (func, delay) => { let timeoutId; return (...args) => { clearTimeout(timeoutId); timeoutId = setTimeout(() => func(...args), delay); }; };</code>I need:
- A line-by-line explanation
- What problem it solves (debouncing)
- A practical usage example
- Why closures are used
Use simple language, avoid unnecessary jargon.
Refactoring
Refactor for better structure:
Refactor this JavaScript code following SOLID principles and clean code:
<code>function processUser(user) { if (user.age >= 18) { if (user.country === "ES") { if (user.hasLicense) { console.log("Can rent car"); return true; } } } console.log("Cannot rent car"); return false; }</code>Goals:
- Reduce nesting levels
- Improve readability
- Make the code more maintainable
- Early returns where appropriate
- Add constants for magic values
Provide:
<refactored>Improved code</refactored><explanation>Changes made and why they improve the code</explanation>
Modernize legacy code:
I have ES5 JavaScript code that needs to be updated to ES6+:
<code>var calculateTotal = function(items) { var total = 0; for (var i = 0; i < items.length; i++) { total += items[i].price; } return total; };</code>Modernize it using:
- const/let instead of var
- Arrow functions
- Modern array methods (map, reduce, filter, etc.)
- Template literals if applicable
Include a brief comment explaining which modern features you used.
Writing tests
Generate unit tests:
I need complete unit tests for this function:
<code>function divide(a, b) { if (b === 0) { throw new Error("Division by zero"); } return a / b; }</code>Framework: Jest Language: JavaScript
Generate tests that cover:
- Normal cases (valid division)
- Division by zero (must throw an error)
- Negative numbers
- Division resulting in a decimal
- Edge cases (0/5, very large numbers)
Include:
- An appropriate describe block
- Test cases with descriptive names
- Appropriate expects
- Comments explaining what each test checks
Integration tests:
I have this function that calls an external API:
<code>async function fetchUserData(userId) { const response = await fetch(https://api.example.com/users/${userId}); if (!response.ok) { throw new Error(HTTP error! status: ${response.status}); } return await response.json(); }</code>Framework: Jest with node-fetch Language: JavaScript/Node.js
Generate tests that:
- Mock the fetch call
- Test a successful response (200)
- Test a 404 error
- Test a 500 error
- Verify that JSON is parsed correctly
Include:
- Mock setup with jest.mock()
- beforeEach to reset mocks if needed
- Complete and descriptive tests
Code review
Ask the AI to review your code before sending it to human review.
Prompt for code review:
Act as a senior developer doing a code review.
Review this code with a critical eye:
<code>class UserService: def init(self): self.users = []def add_user(self, name, email, age): user = { "name": name, "email": email, "age": age } self.users.append(user) return user def get_user_by_email(self, email): for user in self.users: if user["email"] == email: return user
</code>Language: Python 3.11 Context: Flask web application, will be used in production
Review:
- Possible bugs or unhandled edge cases
- Security issues
- Performance improvements
- Python best practices not followed
- Design suggestions (OOP, SOLID, etc.)
Format:
<problems>[List of problems found, prioritized by severity]</problems>
<improved_code>[Improved version of the code]</improved_code>
<explanation>[Explanation of each change]</explanation>
Specific best practices
1. Always specify the environment:
Framework: React 18 with TypeScript 5.0 State: Redux Toolkit Styling: Tailwind CSS
Create a form component...
Provide related code:
I have these TypeScript types:
<types>interface User { id: string; name: string; role: "admin" | "user"; }</types>I need to create a function that filters users by role...
3. Specify the optimization level:
Generate a binary search function in Python.
Priority: Code clarity > Extreme performance Audience: Junior developers who are learning
Include:
- Abundant explanatory comments
- Descriptive variable names
- No premature optimizations that make reading harder
Or alternatively:
Generate a binary search function in Python.
Priority: Maximum performance Context: It will process millions of records
Optimize for:
- Minimal operations
- Efficient memory use
- You can sacrifice readability for performance
4. Ask for alternatives when they exist:
I need to sort an array of objects by date in JavaScript.
Provide 2 different approaches:
- Using the native sort()
- Using a library (date-fns or similar)
For each one include:
- Code
- Pros and cons
- When to use each approach
Advanced use cases
Generate complex regexes:
I need a regular expression in JavaScript to validate passwords.
Requirements:
- Minimum 8 characters
- At least one uppercase letter
- At least one lowercase letter
- At least one number
- At least one special character (@$!%*?&)
- No spaces
Provide:
- The regex
- An explanation of each part of the regex
- A complete validation function with examples
- Tests with valid and invalid cases
Query optimization:
I have this SQL query that is very slow:
<sql>SELECT u.name, COUNT(o.id) as order_count FROM users u LEFT JOIN orders o ON u.id = o.user_id WHERE u.created_at > '2024-01-01' GROUP BY u.id ORDER BY order_count DESC;</sql>Database: PostgreSQL 15 users table: 1 million records orders table: 5 million records
The query takes 8 seconds. I need to optimize it.
Provide:
- An analysis of the performance problem
- An optimized version of the query
- Recommended indexes with CREATE INDEX commands
- An explanation of why each change improves performance
Always validate the code
Never blindly trust AI-generated code. Always:
- Review it line by line
- Run it in a test environment
- Verify edge cases
- Make sure it follows your project's standards
- Check for security vulnerabilities
AIs are powerful assistants for development, but they are assistants, not replacements for a programmer's critical thinking.
Applying prompting to software development requires clear technical specifications: language, version, project context, constraints, and code standards. With well-crafted prompts, you can generate code, debug, refactor, and write tests with professional quality.
You have mastered the fundamental techniques and seen their application to code. To close the course, in the next lesson you will see real-world practical cases: from writing delicate emails to analyzing data and creating content, consolidating everything you have learned in concrete situations.
This work is under a Attribution-NonCommercial-NoDerivatives 4.0 International license.
Desafíos de programación atemporales y multiparadigmáticos
Te encuentras ante un librillo de actividades, divididas en 2 niveles de dificultad. Te enfrentarás a los casos más comunes que te puedes encontrar en pruebas técnicas o aprender conceptos elementales de programación.
Buy the bookWill you buy me a coffee?
This is how I keep writing without ads or paywalls.
Sure, it's on me!
Comments
There are no comments yet.