diff --git a/.gitignore b/.gitignore index 6c2a629a..8a626d8b 100644 --- a/.gitignore +++ b/.gitignore @@ -6,3 +6,6 @@ support/dist/ # Ignore JetBrains IDE settings .idea + +# AI generated files +CLAUDE.md \ No newline at end of file diff --git a/shared-modules/using-ai-in-development/README.md b/shared-modules/using-ai-in-development/README.md index 46fe1f39..d70c7f72 100644 --- a/shared-modules/using-ai-in-development/README.md +++ b/shared-modules/using-ai-in-development/README.md @@ -4,9 +4,9 @@ This module aims to help you understand the role, techniques and risks of using ## Contents -| Week | Topic | Preparation | Session Plan | Assignment | -| ---- | ---------------------------------------- | ------------------------------------- | ----------------------------------------------------- | ----------------------------------- | -| 1. | [TODO, Session Title](./week1/README.md) | [Preparation](./week1/preparation.md) | [Session Plan](./week1/session-plan.md) (for mentors) | [Assignment](./week1/assignment.md) | +| Week | Topic | Preparation | Session Plan | Assignment | +| ---- | --------------------------------------------------- | ------------------------------------- | ----------------------------------------------------- | ----------------------------------- | +| 1. | [AI in the Development Workflow](./week1/README.md) | [Preparation](./week1/preparation.md) | [Session Plan](./week1/session-plan.md) (for mentors) | [Assignment](./week1/assignment.md) | ## Module Learning Goals diff --git a/shared-modules/using-ai-in-development/week1/README.md b/shared-modules/using-ai-in-development/week1/README.md index df5c9063..81dfa6d7 100644 --- a/shared-modules/using-ai-in-development/week1/README.md +++ b/shared-modules/using-ai-in-development/week1/README.md @@ -1,3 +1,11 @@ -# Week 1 +# AI in the Development Workflow (Week 1) -TODO +## Contents + +- [Preparation](./preparation.md) +- [Session Plan](./session-plan.md) (for mentors) +- [Assignment](./assignment.md) + +## Session Learning Goals + +See [module learning goals](../README.md). diff --git a/shared-modules/using-ai-in-development/week1/assignment.md b/shared-modules/using-ai-in-development/week1/assignment.md index 44794476..561622c9 100644 --- a/shared-modules/using-ai-in-development/week1/assignment.md +++ b/shared-modules/using-ai-in-development/week1/assignment.md @@ -1,3 +1,33 @@ # Assignment -TODO +## Part A: Review and Improve Portfolio + +In the previous AI module, you created an initial version of your portfolio. In this assignment, you'll use AI to review, improve, and document your work. + +1. **Get a code review** - Use AI to review your portfolio code. Ask for feedback on readability, best practices, potential bugs, and security. + +2. **Note improvements** - From the feedback, identify at least 3 improvements or changes you want to make. Write these down. + +3. **Implement the changes** - Make the improvements to your code. Use AI to help if needed, but make sure you understand each change. + +4. **Generate a diagram** - Use AI to generate an ASCII diagram that describes the structure of your portfolio project. + +5. **Reflect on learnings** - Write down 3 new things you learned from the review and implementation process. + +## Part B: Ethics and Risks + +Choose 3 ethical issues or risks associated with the use of AI in development (refer to the session material if you need a reminder). + +For each one, describe: + +- What the issue/risk is, in your own words +- How you will personally mitigate it in your own use of AI + +## Submission + +Submit your updated portfolio code, along with a `reflection.md` file containing: + +- Your list of improvements from Part A +- Your diagram from Part A +- Your 3 learnings from Part A +- Your 3 ethical issues and mitigations from Part B diff --git a/shared-modules/using-ai-in-development/week1/preparation.md b/shared-modules/using-ai-in-development/week1/preparation.md index a75ac939..717c5083 100644 --- a/shared-modules/using-ai-in-development/week1/preparation.md +++ b/shared-modules/using-ai-in-development/week1/preparation.md @@ -1,3 +1,26 @@ # Preparation -TODO +## Refresher on the HYF AI guidelines + +Re-read our guidelines so you're clear on the acceptable (and unacceptable) usages of AI at HYF: + +- [Using Generative AI at HackYourFuture](https://program.hackyourfuture.dk/trainee/agreements/ai-usage) + +## GitHub Copilot + +- Read [Best practices for using GitHub Copilot - GitHub Docs](https://docs.github.com/en/copilot/using-github-copilot/best-practices-for-using-github-copilot) +- Read [Prompt engineering for GitHub Copilot - GitHub Docs](https://docs.github.com/en/copilot/concepts/prompt-engineering) + +## AI agents + +- Watch [What are AI Agents? - IBM](https://mediacenter.ibm.com/media/What+are+AI+Agents/1_bem8aulj) (12 mins) + +## Ethics and risks for developers + +- Read [The Risks of Using AI in Software Development - Jellyfish](https://jellyfish.co/library/ai-in-software-development/risks-of-using-generative-ai/) + +## Further reading + +An example of how an engineer might use AI in their day to day at work: + +- Read [My LLM Coding Workflow - Addy Osmani](https://addyosmani.com/blog/ai-coding-workflow/) diff --git a/shared-modules/using-ai-in-development/week1/session-materials/exercise2.js b/shared-modules/using-ai-in-development/week1/session-materials/exercise2.js new file mode 100644 index 00000000..1a21284c --- /dev/null +++ b/shared-modules/using-ai-in-development/week1/session-materials/exercise2.js @@ -0,0 +1,76 @@ +// A utility module for data processing + +function prc(arr, fn) { + const res = []; + const seen = new Map(); + for (let i = 0; i < arr.length; i++) { + const key = fn(arr[i]); + if (!seen.has(key)) { + seen.set(key, true); + res.push(arr[i]); + } + } + return res; +} + +function tfm(data, specs) { + return data.reduce((acc, item) => { + const group = specs.groupBy(item); + if (!acc[group]) { + acc[group] = { items: [], total: 0 }; + } + acc[group].items.push(specs.transform(item)); + acc[group].total += specs.getValue(item); + return acc; + }, {}); +} + +function vld(obj, rules) { + const errors = []; + for (const [field, checks] of Object.entries(rules)) { + const value = obj[field]; + for (const check of checks) { + if (!check.test(value)) { + errors.push({ field, message: check.message }); + } + } + } + return errors.length === 0 ? { valid: true } : { valid: false, errors }; +} + +function main() { + const orders = [ + { id: 1, customer: "Alice", product: "Book", amount: 25 }, + { id: 2, customer: "Bob", product: "Pen", amount: 5 }, + { id: 3, customer: "Alice", product: "Notebook", amount: 15 }, + { id: 4, customer: "Alice", product: "Book", amount: 25 }, + { id: 5, customer: "Bob", product: "Pencil", amount: 3 }, + ]; + + console.log("--- input ---"); + console.log(orders); + + console.log("\n--- prc ---"); + const unique = prc(orders, (o) => o.customer + o.product); + console.log(unique); + + console.log("\n--- tfm ---"); + const grouped = tfm(orders, { + groupBy: (o) => o.customer, + transform: (o) => o.product, + getValue: (o) => o.amount, + }); + console.log(grouped); + + console.log("\n--- vld ---"); + const newOrder = { id: 6, customer: "", product: "Eraser", amount: -2 }; + const result = vld(newOrder, { + customer: [{ test: (v) => v && v.length > 0, message: "required" }], + amount: [{ test: (v) => v > 0, message: "must be positive" }], + }); + console.log(result); +} + +main(); + +export { prc, tfm, vld }; diff --git a/shared-modules/using-ai-in-development/week1/session-materials/exercise3.js b/shared-modules/using-ai-in-development/week1/session-materials/exercise3.js new file mode 100644 index 00000000..661b5ffc --- /dev/null +++ b/shared-modules/using-ai-in-development/week1/session-materials/exercise3.js @@ -0,0 +1,35 @@ +// A utility for working with URL query strings + +function parseQuery(queryString) { + // TODO: implement this function +} + +function buildUrl(base, params) { + const query = Object.entries(params) + .map( + ([key, value]) => + `${encodeURIComponent(key)}=${encodeURIComponent(value)}`, + ) + .join("&"); + return `${base}?${query}`; +} + +function main() { + const url = "https://example.com/search?name=Alice&age=30&city=Copenhagen"; + const queryString = url.split("?")[1]; + + console.log("--- input ---"); + console.log(queryString); + + console.log("\n--- parseQuery ---"); + const params = parseQuery(queryString); + console.log(params); + + console.log("\n--- buildUrl ---"); + const newUrl = buildUrl("https://example.com/profile", params); + console.log(newUrl); +} + +main(); + +export { parseQuery, buildUrl }; diff --git a/shared-modules/using-ai-in-development/week1/session-materials/exercise4.js b/shared-modules/using-ai-in-development/week1/session-materials/exercise4.js new file mode 100644 index 00000000..b1fe4855 --- /dev/null +++ b/shared-modules/using-ai-in-development/week1/session-materials/exercise4.js @@ -0,0 +1,45 @@ +// A function that compares three numbers and returns the sum of the positive ones. + +function sumPositiveNumbers(a, b, c) { + if (a > 0) { + if (b > 0) { + if (c > 0) { + return a + b + c; + } else { + return a + b; + } + } else { + if (c > 0) { + return a + c; + } else { + return a; + } + } + } else { + if (b > 0) { + if (c > 0) { + return b + c; + } else { + return b; + } + } else { + if (c > 0) { + return c; + } else { + return 0; + } + } + } +} + +function main() { + console.log("--- sumPositiveNumbers ---"); + console.log(sumPositiveNumbers(1, 2, 3)); + console.log(sumPositiveNumbers(-1, 2, 3)); + console.log(sumPositiveNumbers(-1, -2, 3)); + console.log(sumPositiveNumbers(-1, -2, -3)); +} + +main(); + +export { sumPositiveNumbers }; diff --git a/shared-modules/using-ai-in-development/week1/session-materials/exercise5.js b/shared-modules/using-ai-in-development/week1/session-materials/exercise5.js new file mode 100644 index 00000000..fe15ea84 --- /dev/null +++ b/shared-modules/using-ai-in-development/week1/session-materials/exercise5.js @@ -0,0 +1,18 @@ +// A function to add two numbers + +function add(x, y) { + return x + y; +} + +function main() { + console.log("--- add ---"); + console.log(add(2, 3)); + console.log(add(2, "3")); + console.log(add("2", "3")); + console.log(add("2", 3)); + console.log(add(2, 3.0)); +} + +main(); + +export { add }; diff --git a/shared-modules/using-ai-in-development/week1/session-materials/exercise6.js b/shared-modules/using-ai-in-development/week1/session-materials/exercise6.js new file mode 100644 index 00000000..da24f075 --- /dev/null +++ b/shared-modules/using-ai-in-development/week1/session-materials/exercise6.js @@ -0,0 +1,89 @@ +// A utility module for data processing + +function deduplicateBy(array, getKey) { + const uniqueItems = []; + const seenKeys = new Map(); + + for (const item of array) { + const key = getKey(item); + if (!seenKeys.has(key)) { + seenKeys.set(key, true); + uniqueItems.push(item); + } + } + + return uniqueItems; +} + +function groupAndAggregate(data, options) { + return data.reduce((groups, item) => { + const groupName = options.groupBy(item); + + if (!groups[groupName]) { + groups[groupName] = { items: [], total: 0 }; + } + + groups[groupName].items.push(options.transform(item)); + groups[groupName].total += options.getValue(item); + + return groups; + }, {}); +} + +function validate(object, validationRules) { + const errors = []; + + for (const [fieldName, rules] of Object.entries(validationRules)) { + const fieldValue = object[fieldName]; + + for (const rule of rules) { + if (!rule.test(fieldValue)) { + errors.push({ field: fieldName, message: rule.message }); + } + } + } + + return errors.length === 0 ? { valid: true } : { valid: false, errors }; +} + +function main() { + const orders = [ + { id: 1, customer: "Alice", product: "Book", amount: 25 }, + { id: 2, customer: "Bob", product: "Pen", amount: 5 }, + { id: 3, customer: "Alice", product: "Notebook", amount: 15 }, + { id: 4, customer: "Alice", product: "Book", amount: 25 }, + { id: 5, customer: "Bob", product: "Pencil", amount: 3 }, + ]; + + console.log("--- input ---"); + console.log(orders); + + console.log("\n--- deduplicateBy ---"); + const uniqueOrders = deduplicateBy( + orders, + (order) => order.customer + order.product, + ); + console.log(uniqueOrders); + + console.log("\n--- groupAndAggregate ---"); + const ordersByCustomer = groupAndAggregate(orders, { + groupBy: (order) => order.customer, + transform: (order) => order.product, + getValue: (order) => order.amount, + }); + console.log(ordersByCustomer); + + console.log("\n--- validate ---"); + const newOrder = { id: 6, customer: "", product: "Eraser", amount: -2 }; + const validationResult = validate(newOrder, { + customer: [ + { test: (value) => value && value.length > 0, message: "required" }, + ], + amount: [{ test: (value) => value > 0, message: "must be positive" }], + }); + console.log(validationResult); +} + +main(); + +export { deduplicateBy, groupAndAggregate, validate }; diff --git a/shared-modules/using-ai-in-development/week1/session-materials/exercise8.js b/shared-modules/using-ai-in-development/week1/session-materials/exercise8.js new file mode 100644 index 00000000..d95d484d --- /dev/null +++ b/shared-modules/using-ai-in-development/week1/session-materials/exercise8.js @@ -0,0 +1,17 @@ +// String formatting utilities + +function capitalize(str) { + if (!str) return ""; + return str.charAt(0).toUpperCase() + str.slice(1).toLowerCase(); +} + +function main() { + console.log("--- capitalize ---"); + console.log(capitalize("hello")); + console.log(capitalize("WORLD")); + console.log(capitalize("javaScript")); +} + +main(); + +export { capitalize }; diff --git a/shared-modules/using-ai-in-development/week1/session-plan.md b/shared-modules/using-ai-in-development/week1/session-plan.md index 424860b9..69546d49 100644 --- a/shared-modules/using-ai-in-development/week1/session-plan.md +++ b/shared-modules/using-ai-in-development/week1/session-plan.md @@ -90,87 +90,227 @@ That is the moment where learning happens, so don't miss out by skipping ahead! While preparing ideas for a particular solution in the Design phase, you'll likely come across the challenge of needing to understand existing code. -TODO add some prompting examples here, as well as good follow up prompts +#### 1. "Code explanation" prompt -#### Exercise 2 +When you encounter unfamiliar code, start by asking for a high-level explanation. + +```prompt +Explain what this code does at a high level: + + + +Focus on: +1. The overall purpose +2. The main components and how they interact +3. Any important patterns or techniques being used +``` + +#### 2. "Dig deeper" follow-up prompt + +Once you understand the big picture, ask targeted follow-up questions to clarify specifics. + +```prompt +In the code above, I don't understand . Can you explain: +1. What this specific section is doing step by step +2. Why it's written this way instead of +3. What would happen if this part was removed or changed +``` -Use AI to help explain the code in [Exercise 2](TODO create and insert link here). Ask follow up questions until you have a good grasp of what every function and line of code is achieving. +#### Exercise 2 -TODO write the exercise code, inspired by [exercise](https://github.com/hosseinzahed/github-copilot-use-cases/blob/main/01-code-explanation.py) +Use AI to help explain the code in [Exercise 2](session-materials/exercise2.js). Ask follow up questions until you have a good grasp of what every function and line of code is achieving. ### Implementation - Learning new approaches While writing code, you may come across a roadblock where you're not entirely sure how to implement something. -TODO add some prompting examples here +#### 1. "Explore approaches" prompt -#### Exercise 3 +When you're stuck on how to implement something, ask for multiple options to consider. -Use AI to give you some suggestions on possible solutions to [Exercise 3](TODO create and insert link here). +```prompt +I need to implement . -TODO write the exercise and supporting code + + +What are 2-3 different approaches I could take? For each approach: +1. Briefly explain how it works +2. List the pros and cons +3. When would this approach be the best choice +4. Highlight any common mistakes to avoid +``` + +#### Exercise 3 + +Use AI to give you some suggestions on possible solutions to [Exercise 3](session-materials/exercise3.js). ### Implementation - Code refactoring After you write a solution, you may wonder if there's a neater or better way to structure the code. -TODO add some prompting examples here +#### 1. "Refactor my code" prompt -#### Exercise 4 +Refactoring can mean different things depending on what you want to improve. Some common goals include: + +- Improved readability +- Better naming +- Extracting reusable functions +- Reducing duplication +- Simplifying complex logic +- Following a specific pattern or convention + +```prompt +Refactor this code to : -Use AI to help you refactor the code in [Exercise 4](TODO create and insert link here). + + +For each change you suggest: +1. Explain what you changed +2. Explain why it's an improvement +``` + +#### Exercise 4 -TODO write the exercise code, inspired by [exercise](https://github.com/hosseinzahed/github-copilot-use-cases/blob/main/03-code-refactoring.ts) +Use AI to help you refactor the code to be more readable in [Exercise 4](session-materials/exercise4.js). ### Implementation - Bug fixing Before your solution is finished, you'll need to make sure it's bug free. -TODO add some prompting examples here +#### 1. "Find and fix the bug" prompt -#### Exercise 5 +When your code isn't working as expected, ask AI to help identify, explain, and fix the issue. + +```prompt +This code is producing unexpected results: + + -Use AI to help you uncover the bug in the [Exercise 5](TODO create and insert link here) code, understand why it's happening, and fix it. +Expected output: +Actual output: + +1. What is the bug? +2. Why is this happening? +3. What options do I have for fixing it? +``` + +#### Exercise 5 -TODO write the exercise code, inspired by [exercise](https://github.com/hosseinzahed/github-copilot-use-cases/blob/main/04-bug-fixing.py) +Use AI to help you uncover the bug in the [Exercise 5](session-materials/exercise5.js) code, understand why it's happening, and fix it. ### Implementation - Documentation generation -AI is not only useful in generating code, but also documentation. +AI is not only useful in generating code, but also documentation. There are many types of documentation AI can help you generate, for example: -TODO add some prompting examples here +- Function and code comments +- README files +- API documentation +- Architecture diagrams +- User guides -#### Exercise 6 +#### 1. "Add a code comment" prompt + +```prompt +Generate a clear, concise comment to this function explaining what it does, its parameters, and what it returns: + + +``` -Use AI to draw a diagram to explain how the code in [Exercise 6](TODO create and insert link here) works. Confirm that it is correct, and fix any mistakes. +#### 2. "Generate a diagram" prompt -TODO write the exercise code, inspired by [exercise](https://github.com/hosseinzahed/github-copilot-use-cases/blob/main/05-document-generation.py) +```prompt +Create an ASCII diagram that visualises how this code works: + + + +Show the flow of data and the key steps. +``` + +#### Exercise 6 + +Use AI to draw a diagram to explain how the code in [Exercise 6](session-materials/exercise6.js) works. This code should look familiar to you, since it implements the same functionality as you saw in Exercise 2, but this code has been refactored to be easier to read. Confirm that the diagrams are correct and match your understanding of the code - do you spot any mistakes? ### Code review - Feedback assistance When your code is ready, it will be time for getting feedback from other developers. Before you do that, save some time and get some initial feedback from AI on improving your code. -TODO add some prompting examples here +#### 1. "First pass review" prompt + +Get a quick, structured overview of potential improvements before asking colleagues for a full review. + +```prompt +Review this code and give me concise feedback organised by category: + + + +Categories to cover: +- Readability +- Performance +- Security +- Best practices +- Potential bugs + +For each issue, give a brief pointer (one sentence max) rather than a detailed explanation. +``` #### Exercise 7 -Use AI to get some structured feedback on improving the code in [Exercise 7](TODO create and insert link here), and make the changes. +Getting feedback is useful before you submit your assignments, but to check out how it can look, choose a previous assignment you've submitted and ask AI for feedback on it. -TODO write the exercise and supporting code +Review the suggestions - which ones are useful, and which ones would you ignore? ### Agent mode -TODO explain a little what agent mode is and how it differs to "edit" mode. Maybe warn that it will use up a lot more of your usage credits. Reminder of our [AI usage guidelines](https://program.hackyourfuture.dk/guidelines/ai-usage), and for HYF assignments and projects +So far we've been using AI in "chat" or "edit" mode - you ask a question or request a change, and AI responds. Agent mode is different: you give AI a goal, and it autonomously plans and executes multiple steps to achieve it, including running commands, creating files, talking with external systems and making decisions along the way. + +**Chat/Edit mode**: You control each step, AI assists one task at a time. + +**Agent mode**: AI takes control, executing multiple steps autonomously to reach a goal. + +GitHub Copilot has an agent mode you can try - instead of asking for a single edit, you can ask it to complete a larger task and it will work through the steps itself. + +{% hint style="warning" %} +**Before using agent mode:** + +- Agent mode uses significantly more of your AI usage credits than chat mode. +- Remember our [AI usage guidelines](https://program.hackyourfuture.dk/guidelines/ai-usage) - for HYF assignments and projects, you must understand and be able to explain any code you submit. Therefore, Agent mode is something more suitable to practice using outside of your HYF work. + {% endhint %} #### Exercise 8 -TODO this should be a small exercise to show how the agent flow works. Could be something similar to [this](https://github.com/hosseinzahed/github-copilot-use-cases/blob/main/19-copilot-agent.md). Suggest instead that trainees explore using agent mode further on their own personal projects we do not allow generating full coding solutions. +Try this small task in both modes to see the difference: + +**Task**: Add a `titleCase` function to [Exercise 8](session-materials/exercise8.js) that converts a sentence to title case (e.g., "hello world" → "Hello World"). + +1. **Chat mode**: Ask Copilot "How would I add a titleCase function to this file?" - notice it explains what to do, but you have to make the changes yourself. + +2. **Agent mode**: Ask Copilot "Add a titleCase function to exercise8.js that converts sentences to title case, and add an example in main()" - watch as it reads the file, adds the function, updates the exports, and modifies main() autonomously. + +Notice how agent mode takes multiple steps without asking for permission at each stage. This is powerful but means you need to carefully review everything it produces. ## AI in the workplace ### Ethics, legal and risk considerations -TODO these follow on from the foundation content, but should be give more software dev specific examples, like the risk of pasting protected IP code or customer data into third party AI tools. +Building on what you learned in the foundation module, here are some specific risks to consider as a developer: + +**Confidential code and data** +Never paste proprietary code, API keys, or customer data into AI tools - it may be stored or used for training. Example: pasting a database query containing real user emails. + +**Intellectual property** +Code you paste into AI tools may belong to your employer. Check your company's policy before sharing any work code with external AI services. + +**License compliance** +AI may generate code copied from open source projects with licenses that are incompatible with your project. Always verify you have the right to use generated code. + +**Security vulnerabilities** +AI-generated code can contain security flaws like SQL injection or missing input validation. Review all generated code with the same scrutiny as code from any other source. + +**Accuracy and hallucinations** +AI can confidently produce incorrect code, non-existent APIs, or outdated syntax. Always test and verify - don't assume it works because it looks right. + +**Company policies** +Many employers have specific rules about which AI tools are approved for use with work code. Check before using any AI tool on company projects. ### The future of AI in development @@ -184,7 +324,7 @@ We don't know the future for sure, that's what makes it exciting. There are some 4. Understanding the "why" 5. Super fast industry shifts -#### Tips +#### Tips and final takeaways 1. Stay in the loop of AI developments - Follow key organisations in the space (OpenAI, Anthropic, Microsoft/Github, Google/Gemini)