Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,6 @@ support/dist/

# Ignore JetBrains IDE settings
.idea

# AI generated files
CLAUDE.md
6 changes: 3 additions & 3 deletions shared-modules/using-ai-in-development/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
12 changes: 10 additions & 2 deletions shared-modules/using-ai-in-development/week1/README.md
Original file line number Diff line number Diff line change
@@ -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).
32 changes: 31 additions & 1 deletion shared-modules/using-ai-in-development/week1/assignment.md
Original file line number Diff line number Diff line change
@@ -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
25 changes: 24 additions & 1 deletion shared-modules/using-ai-in-development/week1/preparation.md
Original file line number Diff line number Diff line change
@@ -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/)
Original file line number Diff line number Diff line change
@@ -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 };
Original file line number Diff line number Diff line change
@@ -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 };
Original file line number Diff line number Diff line change
@@ -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 };
Original file line number Diff line number Diff line change
@@ -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 };
Original file line number Diff line number Diff line change
@@ -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 };
Original file line number Diff line number Diff line change
@@ -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 };
Loading