- Understanding AI in Software Development
- Effective Prompting Techniques
- Practical Applications & Common Challenges
- Hands-on Examples
- Code Generation: Create boilerplate, functions, and entire components
- Code Explanation: Understand unfamiliar codebases or complex algorithms
- Debugging: Identify and fix errors in your code
- Refactoring: Improve existing code quality and structure
- Documentation: Generate clear documentation for code and APIs
- Testing: Create test cases and testing frameworks
- Learning: Accelerate learning of new languages or frameworks
- Large Language Models (ChatGPT, Claude, GitHub Copilot)
- Code-Specific Models (Amazon CodeWhisperer, Tabnine)
- Automated Testing Tools (Functionize, Testim)
- Code Review Assistants (DeepCode, CodeGuru)
- Natural Language to Code Converters (GPT-4, Claude)
- Productivity Boost: Reduce time spent on repetitive tasks
- Knowledge Expansion: Access to broad technical knowledge
- Error Reduction: Catch mistakes early in the development process
- Learning Acceleration: Quick understanding of new technologies
- Documentation Improvement: Better, more consistent documentation
- Focus on Creativity: More time for complex problem-solving
- Specificity: Clear context and requirements
- Structured Information: Well-organized input
- Technical Details: Relevant constraints and specifications
- Examples: Reference code or desired output format
- Step-by-Step Guidance: Breaking down complex requests
1. Context: What are you working on?
2. Task: What do you need?
3. Constraints: Any limitations or requirements?
4. Format: How should the response be structured?
5. Examples: Any reference implementations?
"Write a function to sort data"
"Write a TypeScript function that sorts an array of Product objects
by price in descending order. Each Product has: id (number),
name (string), price (number), and category (string).
Include error handling for empty arrays and handle ties by
sorting alphabetically by name. Use ES6 syntax and include JSDoc."
- Technical specifications: "TypeScript", "React", "RESTful API"
- Design patterns: "Singleton", "Factory", "Observer"
- Code style: "ES6", "functional programming", "immutable"
- Performance considerations: "O(n) time complexity", "memory efficient"
- Quality markers: "unit tested", "edge cases", "error handling"
- Chain of Thought: Guide the AI through complex reasoning
- Few-Shot Learning: Provide examples for the AI to learn from
- Role Assignment: "Act as a senior developer reviewing this code"
- Iterative Refinement: Start broad, then refine with follow-ups
- System Design Prompting: Break down architecture design step-by-step
- Bootstrapping Projects: Generate initial project structure
- API Development: Create endpoints, documentation, and tests
- Frontend Components: Build UI components from descriptions
- Data Processing: Transform data between formats
- Legacy Code Migration: Port code to new languages/frameworks
- Technical Debt Reduction: Refactor and improve code quality
- Code Hallucinations: AI generating plausible but incorrect code
- Outdated Knowledge: LLMs may not know recent frameworks/libraries
- Security Concerns: Potential for insecure code suggestions
- Dependency Understanding: Limited knowledge of project dependencies
- Over-Reliance: Reduced learning and critical thinking
- Integration Issues: Generated code may not fit larger architecture
- Verify All Output: Always review and test AI-generated code
- Maintain Security Standards: Check for vulnerabilities
- Use for Augmentation: Not replacement of developer skills
- Continuous Learning: Stay updated on AI capabilities
- Document AI Usage: Note where AI was used in your codebase
- Ethical Considerations: Be transparent about AI assistance
Prompt:
Create a Node.js Express API endpoint that handles user registration.
Include validation for email and password, hashing for password storage,
and proper error responses. Use async/await and include comments.
Result:
/**
* User registration endpoint
* Validates input, hashes password, and stores user
*/
app.post('/api/register', async (req, res) => {
try {
const { email, password, name } = req.body;
// Validation
if (!email || !password || !name) {
return res.status(400).json({ error: 'All fields are required' });
}
if (!/^[\w-\.]+@([\w-]+\.)+[\w-]{2,4}$/.test(email)) {
return res.status(400).json({ error: 'Invalid email format' });
}
if (password.length < 8) {
return res.status(400).json({
error: 'Password must be at least 8 characters long'
});
}
// Check if user already exists
const existingUser = await User.findOne({ email });
if (existingUser) {
return res.status(409).json({ error: 'Email already registered' });
}
// Hash password
const saltRounds = 10;
const hashedPassword = await bcrypt.hash(password, saltRounds);
// Create new user
const user = new User({
email,
password: hashedPassword,
name,
createdAt: new Date()
});
await user.save();
// Return success without exposing password
res.status(201).json({
message: 'User registered successfully',
userId: user._id
});
} catch (error) {
console.error('Registration error:', error);
res.status(500).json({ error: 'Server error during registration' });
}
});
Prompt:
Create a React functional component for a filterable product table.
It should display products grouped by category, allow searching by name,
and have a toggle to show only in-stock items. Use hooks for state
management and include proper TypeScript typing.
Result:
import React, { useState } from 'react';
interface Product {
id: number;
name: string;
price: number;
category: string;
inStock: boolean;
}
interface FilterableProductTableProps {
products: Product[];
}
const FilterableProductTable: React.FC<FilterableProductTableProps> = ({ products }) => {
const [searchText, setSearchText] = useState('');
const [inStockOnly, setInStockOnly] = useState(false);
// Filter products based on search and stock filter
const filteredProducts = products.filter(product => {
const matchesSearch = product.name.toLowerCase().includes(searchText.toLowerCase());
const matchesStock = inStockOnly ? product.inStock : true;
return matchesSearch && matchesStock;
});
// Group products by category
const groupedProducts: Record<string, Product[]> = {};
filteredProducts.forEach(product => {
if (!groupedProducts[product.category]) {
groupedProducts[product.category] = [];
}
groupedProducts[product.category].push(product);
});
return (
<div className="filterable-product-table">
<div className="search-bar">
<input
type="text"
placeholder="Search products..."
value={searchText}
onChange={(e) => setSearchText(e.target.value)}
/>
<label>
<input
type="checkbox"
checked={inStockOnly}
onChange={(e) => setInStockOnly(e.target.checked)}
/>
Only show products in stock
</label>
</div>
<div className="product-table">
{Object.keys(groupedProducts).length === 0 ? (
<p>No products found</p>
) : (
Object.entries(groupedProducts).map(([category, categoryProducts]) => (
<div key={category} className="category-section">
<h3>{category}</h3>
<table>
<thead>
<tr>
<th>Name</th>
<th>Price</th>
<th>Status</th>
</tr>
</thead>
<tbody>
{categoryProducts.map(product => (
<tr key={product.id}>
<td>{product.name}</td>
<td>${product.price.toFixed(2)}</td>
<td>{product.inStock ? 'In Stock' : 'Out of Stock'}</td>
</tr>
))}
</tbody>
</table>
</div>
))
)}
</div>
</div>
);
};
export default FilterableProductTable;
Prompt:
Refactor this function to be more readable and efficient:
function getData(id, callback) {
db.connect(function(err, connection) {
if (err) { callback(err, null); return; }
connection.query("SELECT * FROM users WHERE id = " + id, function(err, user) {
if (err) { callback(err, null); return; }
if (!user) { callback(new Error("User not found"), null); return; }
connection.query("SELECT * FROM orders WHERE user_id = " + id, function(err, orders) {
if (err) { callback(err, null); return; }
user.orders = orders;
callback(null, user);
connection.close();
});
});
});
}
Result:
/**
* Fetches user data and their orders by user ID
*
* @param {number} id - The user ID to query
* @returns {Promise<Object>} - Promise resolving to user object with orders
*/
async function getUserWithOrders(id) {
// Input validation
if (!id || typeof id !== 'number') {
throw new Error('Valid user ID is required');
}
let connection;
try {
// Establish database connection
connection = await db.connectAsync();
// Use parameterized queries for security
const userQuery = "SELECT * FROM users WHERE id = ?";
const user = await connection.queryAsync(userQuery, [id]);
if (!user || user.length === 0) {
throw new Error('User not found');
}
// Get user orders with parameterized query
const orderQuery = "SELECT * FROM orders WHERE user_id = ?";
const orders = await connection.queryAsync(orderQuery, [id]);
// Add orders to user object
const userData = user[0];
userData.orders = orders || [];
return userData;
} catch (error) {
// Rethrow with context for better debugging
throw new Error(`Error fetching user data: ${error.message}`);
} finally {
// Ensure connection is always closed
if (connection) {
await connection.closeAsync();
}
}
}
Prompt:
Write unit tests for a function that validates a password
according to these rules:
- At least 8 characters long
- Contains at least one uppercase letter
- Contains at least one number
- Contains at least one special character (!@#$%^&*)
- Does not contain spaces
Use Jest for testing and include tests for both valid and invalid cases.
Result:
import { validatePassword } from './passwordValidator';
describe('Password Validator', () => {
// Valid password tests
test('should accept a valid password with all requirements', () => {
expect(validatePassword('Passw0rd!')).toBe(true);
});
test('should accept a longer password that meets all criteria', () => {
expect(validatePassword('SecureP@ssw0rd123')).toBe(true);
});
// Length tests
test('should reject a password shorter than 8 characters', () => {
expect(validatePassword('P@ss1')).toBe(false);
});
test('should accept a password exactly 8 characters', () => {
expect(validatePassword('P@ssw0rd')).toBe(true);
});
// Character type tests
test('should reject a password without uppercase letters', () => {
expect(validatePassword('passw0rd!')).toBe(false);
});
test('should reject a password without numbers', () => {
expect(validatePassword('Password!')).toBe(false);
});
test('should reject a password without special characters', () => {
expect(validatePassword('Passw0rd')).toBe(false);
});
// Space test
test('should reject a password containing spaces', () => {
expect(validatePassword('Passw0rd !')).toBe(false);
});
// Edge cases
test('should reject an empty password', () => {
expect(validatePassword('')).toBe(false);
});
test('should reject null input', () => {
expect(validatePassword(null)).toBe(false);
});
test('should reject undefined input', () => {
expect(validatePassword(undefined)).toBe(false);
});
test('should reject non-string input', () => {
expect(validatePassword(12345678)).toBe(false);
});
});
Prompt:
Generate comprehensive API documentation for a user management REST API
with endpoints for user creation, authentication, profile management,
and password reset. Include request/response formats, status codes,
authentication requirements, and examples using JSON.
Result:
# User Management API Documentation
## Base URL
## Authentication
Most endpoints require a valid JWT token in the Authorization header:
Authorization: Bearer
## Endpoints
### 1. User Registration
Creates a new user account.
**URL**: `/users`
**Method**: `POST`
**Auth required**: No
#### Request Body
```json
{
"email": "[email protected]",
"password": "SecureP@ss123",
"firstName": "John",
"lastName": "Doe"
}
Code: 201 Created
Content:
{
"id": "12345",
"email": "[email protected]",
"firstName": "John",
"lastName": "Doe",
"createdAt": "2025-03-20T15:30:00Z"
}
Code: 400 Bad Request
Condition: Invalid input
Content:
{
"error": "Invalid input",
"details": ["Email is not valid", "Password must be at least 8 characters"]
}
Code: 409 Conflict
Condition: Email already registered
Content:
{
"error": "Email already registered"
}
...
[Documentation for other endpoints would continue here]
---
## Conclusion
### Key Takeaways
- **AI as a Development Partner**: Enhance productivity without replacing human expertise
- **Effective Prompting**: Be specific, structured, and provide context
- **Verify All Output**: Always review AI-generated code for correctness
- **Continuous Improvement**: Refine your prompting skills over time
- **Balanced Approach**: Use AI for appropriate tasks while maintaining critical thinking
---
### Next Steps
- **Experiment** with different AI tools and prompting techniques
- **Develop** team best practices for AI integration
- **Create** a prompt library for common development tasks
- **Share** successful AI implementations with the team
- **Evaluate** impact on development workflows and productivity
---
## Prompt Engineering Workshop
### Prompt Construction Exercise
Let's practice building effective prompts together:
---
### Example 1: Building a Data Validation Function
**Task**: Create a function to validate user input for a registration form
**Step 1: Start with basic request**
Write a function to validate form data
**Step 2: Add context and specifics**
Write a JavaScript function to validate user registration form data
**Step 3: Add technical details and constraints**
Write a JavaScript function that validates user registration form data with fields for email, password, name, and age. The function should return validation errors for each field.
**Step 4: Add requirements and edge cases**
Write a JavaScript function that validates user registration form data with these requirements:
- Email: Must be valid format and from allowed domains (.com, .org, .edu)
- Password: At least 8 chars with 1 uppercase, 1 number, 1 special char
- Name: 2-50 chars, letters and spaces only
- Age: Number between 18-120
Return an object with validation errors for each invalid field. Handle empty inputs appropriately.
**Step 5: Add format preferences and examples**
Write a modern JavaScript (ES6+) function that validates user registration form data with these requirements:
- Email: Must be valid format and from allowed domains (.com, .org, .edu)
- Password: At least 8 chars with 1 uppercase, 1 number, 1 special char
- Name: 2-50 chars, letters and spaces only
- Age: Number between 18-120
Return an object with validation errors for each invalid field. Handle empty inputs and edge cases appropriately.
Example usage: validateForm({ email: "[email protected]", password: "Pass123!", name: "John Doe", age: 25 }) // Should return { valid: true }
validateForm({ email: "invalid-email", password: "weak", name: "", age: 15 }) // Should return errors for each field
---
### Example 2: Building a Database Query Prompt
**Task**: Generate a SQL query for reporting
**Step 1: Basic request**
Write a SQL query to get sales data
**Step 2: Add database context**
Write a SQL query to get sales data from a database with tables for customers, orders, and products
**Step 3: Add specific requirements**
Write a SQL query that retrieves monthly sales totals by product category from a database with these tables:
- customers (id, name, email, region)
- orders (id, customer_id, order_date, total_amount)
- order_items (order_id, product_id, quantity, price)
- products (id, name, category_id, price)
- categories (id, name)
**Step 4: Add constraints and formatting requirements**
Write a SQL query that retrieves monthly sales totals by product category for the year 2024. Use these tables:
- customers (id, name, email, region)
- orders (id, customer_id, order_date, total_amount)
- order_items (order_id, product_id, quantity, price)
- products (id, name, category_id, price)
- categories (id, name)
Requirements:
- Group by month and category name
- Sort by month (ascending) and then by sales total (descending)
- Include only completed orders (status = 'completed')
- Format the date as 'Month Year' (e.g., 'January 2024')
- Round sales totals to 2 decimal places
---
### Example 3: Building a React Component Prompt
**Task**: Create a table component for displaying data
**Step 1: Basic request**
Create a React component for a data table
**Step 2: Add component details**
Create a React component for a sortable and filterable data table
**Step 3: Add technical specifications**
Create a React functional component with TypeScript for a sortable and filterable data table. The table should display a list of products.
**Step 4: Add detailed requirements and props**
Create a React functional component with TypeScript for a sortable and filterable data table with the following features:
- Display products with columns: name, category, price, and stock status
- Allow sorting by clicking on column headers
- Include a search box to filter products by name or category
- Add pagination with configurable items per page
- Highlight out-of-stock items in red
Props:
- products: Array of product objects
- initialSortColumn: String
- initialSortDirection: 'asc' | 'desc'
- itemsPerPage: Number
**Step 5: Add styling, accessibility and example data**
Create a React functional component with TypeScript for a sortable and filterable product data table with the following features:
- Display products with columns: name, category, price, and stock status
- Allow sorting by clicking on column headers (with sort indicators)
- Include a search box to filter products by name or category
- Add pagination with configurable items per page
- Highlight out-of-stock items in red
- Use CSS modules for styling
- Ensure keyboard accessibility for sorting and pagination
- Include proper ARIA attributes for screen readers
Props interface: interface ProductTableProps { products: Product[]; initialSortColumn?: string; initialSortDirection?: 'asc' | 'desc'; itemsPerPage?: number; onProductSelect?: (product: Product) => void; }
Example product data structure: interface Product { id: number; name: string; category: string; price: number; inStock: boolean; quantity: number; }
---
## Team Exercise: Prompt Building Challenge
### Instructions:
1. Form small groups of 2-3 people
2. Choose one of these development tasks:
- Creating a date formatting utility
- Building a password strength meter component
- Writing unit tests for an authentication service
- Creating an API error handling middleware
3. Follow these steps:
- Start with a basic prompt
- Add context and specific requirements
- Add technical constraints and preferences
- Include format requirements and examples
- Test your prompt with an AI assistant
4. Share your prompts and results with the team
5. Discuss what worked well and how to improve
---
### Questions?
Thank you for your attention!
Implement an website that allow users to test the speed typing.